From 60c8c1fcbf733659bc72d269a3a29a5d4bbd62e2 Mon Sep 17 00:00:00 2001 From: Cekis Date: Thu, 21 Oct 2021 17:45:04 -0400 Subject: [PATCH 01/46] Compiling 100% with Types change approach - still does not build. --- CMakeLists.txt | 2 +- .../src/shared/AuctionTransferClient.h | 10 +- .../AuctionTransferAPI.h | 10 +- .../AuctionTransferAPICore.cpp | 6 +- .../AuctionTransferGameAPI/Base/linux/Types.h | 7 +- .../AuctionTransferGameAPI/Base/win32/Types.h | 8 +- .../shared/AuctionTransferGameAPI/Request.cpp | 8 +- .../shared/AuctionTransferGameAPI/Request.h | 20 ++-- .../shared/AuctionTransferGameAPI/Response.h | 4 +- .../ChatServer/src/shared/ChatInterface.cpp | 16 +-- .../ChatServer/src/shared/ChatInterface.h | 2 +- .../src/shared/SessionApiClient.cpp | 2 +- .../src/shared/object/PlanetObject.cpp | 4 +- .../src/shared/object/PlayerObject.cpp | 6 +- .../src/shared/object/ResourcePoolObject.cpp | 2 +- .../src/shared/object/ServerObject.h | 4 +- .../library/serverGame/src/shared/pvp/Pvp.cpp | 4 +- .../src/shared/CityPathGraph.cpp | 54 ++++----- .../src/shared/CityPathGraph.h | 2 +- .../serverScript/src/shared/JavaLibrary.cpp | 10 +- .../src/shared/ServerConnection.h | 2 +- .../src/shared/core/DbBindableLong.h | 10 +- .../src_oci/DbBindableVarray.cpp | 82 ++++++------- .../src_oci/DbBindableVarray.h | 4 +- .../sharedDebug/src/linux/DebugHelp.cpp | 22 ++-- .../library/sharedDebug/src/linux/DebugHelp.h | 2 +- .../library/sharedDebug/src/win32/DebugHelp.h | 2 +- .../sharedFoundation/src/linux/PlatformGlue.h | 2 +- .../src/shared/FormattedString.h | 8 +- .../sharedFoundation/src/shared/Misc.h | 2 +- .../sharedFoundation/src/shared/NetworkId.h | 4 +- .../src/linux/FoundationTypesLinux.h | 11 +- .../src/win32/FoundationTypesWin32.h | 9 +- .../src/shared/object/AlterScheduler.cpp | 2 +- .../sharedPathfinding/src/shared/PathNode.h | 12 +- .../src/shared/PathSearch.cpp | 8 +- .../platform/utils/Base/BlockAllocator.h | 2 +- .../utils/Base/linux/BlockAllocator.cpp | 14 +-- .../library/platform/utils/Base/linux/Types.h | 7 +- .../library/platform/utils/Base/win32/Types.h | 8 +- .../CSAssist/utils/Base/BlockAllocator.h | 2 +- .../utils/Base/linux/BlockAllocator.cpp | 14 +-- .../CSAssist/utils/Base/linux/Types.h | 7 +- .../CSAssist/utils/Base/win32/Types.h | 8 +- .../CTServiceGameAPI/Base/linux/Types.h | 7 +- .../CTServiceGameAPI/Base/win32/Types.h | 8 +- .../ChatAPI/utils/Base/BlockAllocator.h | 2 +- .../utils/Base/linux/BlockAllocator.cpp | 14 +-- .../ChatAPI/utils/Base/linux/Types.h | 7 +- .../ChatAPI/utils/Base/win32/Types.h | 8 +- .../VChatAPI/utils2.0/utils/Base/types.h | 19 +-- .../archive/src/shared/AutoDeltaPackedMap.h | 38 +++++- .../crypto/src/shared/original/misc.cpp | 4 +- .../library/crypto/src/shared/original/misc.h | 112 +++++++++--------- 54 files changed, 347 insertions(+), 297 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbb410590..e3594347c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ elseif (UNIX) endif () # our "always on" flags - build by default for the system we're on but include all instruction sets - set(CMAKE_CXX_FLAGS "-m32 -pipe -march=native -mtune=native \ + set(CMAKE_CXX_FLAGS "-pipe -march=native -mtune=native \ -Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \ -Wno-write-strings -Wno-unknown-pragmas \ -Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare -Wno-stringop-overflow -Wno-address-of-packed-member") diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferClient.h b/engine/server/application/CentralServer/src/shared/AuctionTransferClient.h index 176ec79e6..617f75fd3 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferClient.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferClient.h @@ -40,7 +40,7 @@ class AuctionTransferClient : public AuctionTransfer::AuctionTransferAPI void onSendAbortTransaction(unsigned int, unsigned int, void *) {}; void onSendAuditAssetTransfer(unsigned int, unsigned int, void *) {}; - void onGetNewTransactionID(unsigned int, unsigned int, int64, void *) {}; + void onGetNewTransactionID(unsigned int, unsigned int, int64_t, void *) {}; // Responses to reply requests void onReplyReceivePrepareTransaction(unsigned int, unsigned int, void *) {}; @@ -52,10 +52,10 @@ class AuctionTransferClient : public AuctionTransfer::AuctionTransferAPI void onIdentifyHost(unsigned int, unsigned int, void *) {}; // callbacks initiated by auction - void onReceivePrepareTransaction(unsigned int, int64, unsigned int, unsigned int, int64, const char *) {}; - void onReceiveCommitTransaction(unsigned int, int64) {}; - void onReceiveAbortTransaction(unsigned int, int64) {}; - void onReceiveGetCharacterList(unsigned int, unsigned int, const char *) {}; + void onReceivePrepareTransaction(unsigned int, int64_t, unsigned int, unsigned int, int64_t, const char *) {}; + void onReceiveCommitTransaction(unsigned int, int64_t) {}; + void onReceiveAbortTransaction(unsigned int, int64_t) {}; + void onReceiveGetCharacterList(unsigned int, int64_t, const char *) {}; private: diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPI.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPI.h index a3d85096e..2ad6d405d 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPI.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPI.h @@ -62,7 +62,7 @@ class AuctionTransferAPI virtual void onSendCommitTransaction (unsigned trackingNumber, unsigned responseCode, void *user) = 0; virtual void onSendAbortTransaction (unsigned trackingNumber, unsigned responseCode, void *user) = 0; virtual void onSendAuditAssetTransfer(unsigned trackingNumber, unsigned responseCode, void *user) = 0; - virtual void onGetNewTransactionID( unsigned trackingNumber, unsigned responseCode, long long transactionID, void *user) = 0; + virtual void onGetNewTransactionID( unsigned trackingNumber, unsigned responseCode, int64_t transactionID, void *user) = 0; // responses to reply requests virtual void onReplyReceivePrepareTransaction (unsigned trackingNumber, unsigned responseCode, void *user) = 0; @@ -75,10 +75,10 @@ class AuctionTransferAPI // Callbacks initiated by the Auction System - virtual void onReceivePrepareTransaction (unsigned trackingNumber, long long transactionID, unsigned stationID, unsigned characterID, long long assetID, const char *newName) = 0; - virtual void onReceiveCommitTransaction (unsigned trackingNumber, long long transactionID) = 0; - virtual void onReceiveAbortTransaction (unsigned trackingNumber, long long transactionID) = 0; - virtual void onReceiveGetCharacterList(unsigned trackingNumber, unsigned stationID, const char *serverID) = 0; + virtual void onReceivePrepareTransaction (unsigned trackingNumber, int64_t transactionID, unsigned stationID, unsigned characterID, int64_t assetID, const char *newName) = 0; + virtual void onReceiveCommitTransaction (unsigned trackingNumber, int64_t transactionID) = 0; + virtual void onReceiveAbortTransaction (unsigned trackingNumber, int64_t transactionID) = 0; + virtual void onReceiveGetCharacterList(unsigned trackingNumber, int64_t stationID, const char *serverID) = 0; private: AuctionTransferAPICore *m_apiCore; diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPICore.cpp b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPICore.cpp index c2ccccb06..cc7d509d6 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPICore.cpp +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/AuctionTransferAPICore.cpp @@ -135,7 +135,7 @@ void AuctionTransferAPICore::responseCallback(short type, Base::ByteStream::Read ServerTrackObject *stobj = new ServerTrackObject(++m_mappedServerTrack, real_server_track, connection); m_serverTracks.insert(std::pair(m_mappedServerTrack, stobj)); - long long transactionID; + int64_t transactionID; get(iter, transactionID); switch (type) { @@ -143,7 +143,7 @@ void AuctionTransferAPICore::responseCallback(short type, Base::ByteStream::Read { unsigned stationID; unsigned characterID; - long long assetID; + int64_t assetID; std::string newName; get(iter, stationID); get(iter, characterID); @@ -167,7 +167,7 @@ void AuctionTransferAPICore::responseCallback(short type, Base::ByteStream::Read // this had the stationID read in as the transactionID std::string serverID; get(iter, serverID); - m_api->onReceiveGetCharacterList(m_mappedServerTrack, (unsigned int)transactionID, serverID.c_str()); + m_api->onReceiveGetCharacterList(m_mappedServerTrack, transactionID, serverID.c_str()); } default: break; diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h index 69419a0fc..a5eb04133 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h @@ -11,7 +11,8 @@ #ifndef BASE_LINUX_TYPES_H #define BASE_LINUX_TYPES_H -#include +//#include +#include #ifdef EXTERNAL_DISTRO namespace NAMESPACE @@ -34,9 +35,9 @@ typedef signed short int16; typedef unsigned short uint16; typedef int32_t int32; -typedef u_int32_t uint32; +typedef uint32_t uint32; typedef int64_t int64; -typedef u_int64_t uint64; +typedef uint64_t uint64; } #ifdef EXTERNAL_DISTRO }; diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/win32/Types.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/win32/Types.h index 0c64cb2cb..aa9ba015f 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/win32/Types.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/win32/Types.h @@ -28,10 +28,10 @@ typedef unsigned char uint8; typedef short int16; typedef unsigned short uint16; -typedef int int32; -typedef unsigned uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; }; #ifdef EXTERNAL_DISTRO diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.cpp b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.cpp index ed2e0ad3b..c12681592 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.cpp +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.cpp @@ -76,7 +76,7 @@ void ReplyRequest::pack(Base::ByteStream &msg) } ////////////////////////////////////////////////////////////////////////////////////// -CommonRequest::CommonRequest( RequestTypes type, unsigned serverTrack, long long transactionID ) +CommonRequest::CommonRequest( RequestTypes type, unsigned serverTrack, int64_t transactionID ) : GenericRequest((short)type, serverTrack), m_transactionID(transactionID) { } @@ -101,7 +101,7 @@ void GetIDRequest::pack(Base::ByteStream &msg) } ////////////////////////////////////////////////////////////////////////////////////// -SendPrepareCompressedRequest::SendPrepareCompressedRequest(RequestTypes type, unsigned serverTrack, const char *serverID, long long transactionID, unsigned stationID, unsigned characterID, long long assetID, const unsigned char *xmlAsset, unsigned length) +SendPrepareCompressedRequest::SendPrepareCompressedRequest(RequestTypes type, unsigned serverTrack, const char *serverID, int64_t transactionID, unsigned stationID, unsigned characterID, int64_t assetID, const unsigned char *xmlAsset, unsigned length) : GenericRequest((short)type, serverTrack), m_transactionID(transactionID), m_stationID(stationID), @@ -125,7 +125,7 @@ void SendPrepareCompressedRequest::pack(Base::ByteStream &msg) } ////////////////////////////////////////////////////////////////////////////////////// -SendPrepareRequest::SendPrepareRequest( RequestTypes type, unsigned serverTrack, const char *serverID, long long transactionID, unsigned stationID, unsigned characterID, long long assetID, const char *xml ) +SendPrepareRequest::SendPrepareRequest( RequestTypes type, unsigned serverTrack, const char *serverID, int64_t transactionID, unsigned stationID, unsigned characterID, int64_t assetID, const char *xml ) : GenericRequest((short)type, serverTrack), m_transactionID(transactionID), m_stationID(stationID), @@ -194,7 +194,7 @@ void IdentifyServerRequest::pack(Base::ByteStream &msg) ////////////////////////////////////////////////////////////////////////////////////// SendAuditRequest::SendAuditRequest( RequestTypes type, unsigned serverTrack, const char *gameCode, const char *serverCode, - long long inGameAssetID, unsigned stationID, const char *event, const char *message) + int64_t inGameAssetID, unsigned stationID, const char *event, const char *message) : GenericRequest((short)type, serverTrack), m_gameCode(gameCode), m_serverCode(serverCode), m_assetID(inGameAssetID), m_userID(stationID), m_event(event), m_message(message) { diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.h index f848c26b5..d59c86c93 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Request.h @@ -43,12 +43,12 @@ namespace AuctionTransfer class CommonRequest: public GenericRequest { public: - CommonRequest(RequestTypes type, unsigned serverTrack, long long transactionID); + CommonRequest(RequestTypes type, unsigned serverTrack, int64_t transactionID); virtual ~CommonRequest() {}; void pack(Base::ByteStream &msg); private: - long long m_transactionID; + int64_t m_transactionID; }; ////////////////////////////////////////////////////////////////////////////////////// @@ -66,15 +66,15 @@ namespace AuctionTransfer class SendPrepareRequest: public GenericRequest { public: - SendPrepareRequest(RequestTypes type, unsigned serverTrack, const char *serverID, long long transactionID, unsigned stationID, unsigned characterID, long long assetID, const char *xmlAsset); + SendPrepareRequest(RequestTypes type, unsigned serverTrack, const char *serverID, int64_t transactionID, unsigned stationID, unsigned characterID, int64_t assetID, const char *xmlAsset); virtual ~SendPrepareRequest() {}; void pack(Base::ByteStream &msg); private: - long long m_transactionID; + int64_t m_transactionID; unsigned m_stationID; unsigned m_characterID; - long long m_assetID; + int64_t m_assetID; std::string m_xml; std::string m_serverID; }; @@ -83,15 +83,15 @@ namespace AuctionTransfer class SendPrepareCompressedRequest: public GenericRequest { public: - SendPrepareCompressedRequest(RequestTypes type, unsigned serverTrack, const char *serverID, long long transactionID, unsigned stationID, unsigned characterID, long long assetID, const unsigned char *xmlAsset, unsigned length); + SendPrepareCompressedRequest(RequestTypes type, unsigned serverTrack, const char *serverID, int64_t transactionID, unsigned stationID, unsigned characterID, int64_t assetID, const unsigned char *xmlAsset, unsigned length); virtual ~SendPrepareCompressedRequest() {}; void pack(Base::ByteStream &msg); private: - long long m_transactionID; + int64_t m_transactionID; unsigned m_stationID; unsigned m_characterID; - long long m_assetID; + int64_t m_assetID; //std::string m_xml; std::string m_serverID; Blob m_data; @@ -127,13 +127,13 @@ namespace AuctionTransfer { public: SendAuditRequest( RequestTypes type, unsigned serverTrack, const char *gameCode, const char *serverCode, - long long inGameAssetID, unsigned stationID, const char *event, const char *message); + int64_t inGameAssetID, unsigned stationID, const char *event, const char *message); ~SendAuditRequest() {}; void pack(Base::ByteStream &msg); private: std::string m_gameCode; std::string m_serverCode; - long long m_assetID; + int64_t m_assetID; unsigned m_userID; std::string m_event; std::string m_message; diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Response.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Response.h index c7352fa20..709f4abc4 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Response.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Response.h @@ -22,10 +22,10 @@ namespace AuctionTransfer public: GetIDResponse(RequestTypes type, void *user); virtual ~GetIDResponse() {} - long long getNewID() { return m_transactionID; } + int64_t getNewID() { return m_transactionID; } virtual void unpack(Base::ByteStream::ReadIterator &iter); private: - long long m_transactionID; + int64_t m_transactionID; }; diff --git a/engine/server/application/ChatServer/src/shared/ChatInterface.cpp b/engine/server/application/ChatServer/src/shared/ChatInterface.cpp index c52044b8e..afc1b2f4d 100755 --- a/engine/server/application/ChatServer/src/shared/ChatInterface.cpp +++ b/engine/server/application/ChatServer/src/shared/ChatInterface.cpp @@ -355,7 +355,7 @@ void ChatInterface::OnGetRoom(unsigned track, unsigned result, const ChatRoom *r ChatServer::putSystemAvatarInRoom(roomName); } std::string lowerRoomName = toLower(roomName); - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; std::unordered_map::iterator f = roomList.find(lowerRoomName); if (f != roomList.end() && room) { @@ -416,7 +416,7 @@ void ChatInterface::OnGetRoom(unsigned track, unsigned result, const ChatRoom *r //----------------------------------------------------------------------- -void ChatInterface::queryRoom(const NetworkId & id, ConnectionServerConnection * connection, const unsigned int sequence, const std::string & roomName) +void ChatInterface::queryRoom(const NetworkId & id, ConnectionServerConnection * connection, const uint64_t sequence, const std::string & roomName) { UNREF(connection); ChatServer::fileLog(s_enableChatRoomLogs, "ChatInterface", "queryRoom() id(%s) connection(%s) sequence(%u) roomName(%s)", id.getValueString().c_str(), ChatServer::getConnectionAddress(connection).c_str(), sequence, roomName.c_str()); @@ -1579,7 +1579,7 @@ void ChatInterface::OnCreateRoom(unsigned track,unsigned result, const ChatRoom PROFILER_AUTO_BLOCK_DEFINE("ChatInterface - OnCreateRoom"); UNREF(user); - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; static Unicode::String wideSWG = Unicode::narrowToWide("SOE+SWG"); static Unicode::String wideFilter = Unicode::narrowToWide(""); static ChatUnicodeString swgNode(wideSWG.data(), wideSWG.size()); @@ -1882,7 +1882,7 @@ void ChatInterface::OnEnterRoom(unsigned track, unsigned result, const ChatAvata return; } - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; ChatAvatarId srcId; if (srcAvatar) @@ -2559,7 +2559,7 @@ void ChatInterface::OnLeaveRoom(unsigned track, unsigned result, const ChatAvata return; } - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; ChatAvatarId id; if (srcAvatar) @@ -2913,7 +2913,7 @@ void ChatInterface::OnSendRoomMessage(unsigned track, unsigned result, const Cha } UNREF(srcAvatar); UNREF(destRoom); - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; ChatOnSendRoomMessage chat(sequence, result); IGNORE_RETURN(ChatServer::sendResponseForTrackId(track, chat)); } @@ -2998,7 +2998,7 @@ void ChatInterface::OnSendInstantMessage(unsigned track, unsigned result, const } UNREF(srcAvatar); - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; ChatOnSendInstantMessage chat(sequence, result); IGNORE_RETURN(ChatServer::sendResponseForTrackId(track, chat)); @@ -3053,7 +3053,7 @@ void ChatInterface::OnSendPersistentMessage(unsigned track, unsigned result, con DEBUG_WARNING(true, ("We received an OnSendPersistentMessage with a success result code but nullptr data. This is an error that the API should never give.")); return; } - unsigned sequence = (unsigned)user; + uint64_t sequence = (uint64_t)user; UNREF(srcAvatar); ChatOnSendPersistentMessage chat(sequence, result); IGNORE_RETURN(ChatServer::sendResponseForTrackId(track, chat)); diff --git a/engine/server/application/ChatServer/src/shared/ChatInterface.h b/engine/server/application/ChatServer/src/shared/ChatInterface.h index 31c3bed67..3fc0f225d 100755 --- a/engine/server/application/ChatServer/src/shared/ChatInterface.h +++ b/engine/server/application/ChatServer/src/shared/ChatInterface.h @@ -68,7 +68,7 @@ class ChatInterface : public ChatAPI std::string getChatName(const NetworkId &id); - void queryRoom (const NetworkId & id, ConnectionServerConnection * connection, const unsigned int sequenceId, const std::string & roomName); + void queryRoom (const NetworkId & id, ConnectionServerConnection * connection, const uint64_t sequenceId, const std::string & roomName); void updateRoomForThisChatAPI(const ChatRoom *room, const ChatAvatar *additionalAvatar); void updateRooms(); diff --git a/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp b/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp index 73ff91aef..b9dc88ea7 100755 --- a/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp +++ b/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp @@ -120,7 +120,7 @@ void SessionApiClient::OnSessionValidate(const apiTrackingNumber trackingNumber, else { // attempt to validate a CS Tool associated with this request. - CSToolConnection::validateCSTool( ( uint32 )userData, result, session ); + CSToolConnection::validateCSTool( ( uint64 )userData, result, session ); } } diff --git a/engine/server/library/serverGame/src/shared/object/PlanetObject.cpp b/engine/server/library/serverGame/src/shared/object/PlanetObject.cpp index 0ecbb8d62..29ae6e719 100755 --- a/engine/server/library/serverGame/src/shared/object/PlanetObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/PlanetObject.cpp @@ -2349,7 +2349,7 @@ void PlanetObject::adjustGcwImperialScore(std::string const & source, CreatureOb // grant GCW Region Defender bonus float bonus = 0.0f; if (gcwCategoryData->gcwRegionDefender && PvpData::isImperialFactionId(sourceObject->getPvpFaction()) && (adjustment > 0) && (playerObject->getCurrentGcwRegion() == gcwCategory) && Pvp::getGcwDefenderRegionBonus(*sourceObject, *playerObject, bonus) && (bonus > 0.0f)) - adjustment += std::max(1ll, static_cast(static_cast(bonus) * static_cast(adjustment) / static_cast(100))); + adjustment += static_cast(std::max(static_cast(1), static_cast(bonus) * static_cast(adjustment) / 100)); } LOG("CustomerService", ("GcwScore: imperial %s %d (from %s - %s)", gcwCategory.c_str(), static_cast(adjustment), source.c_str(), sourceObject->getNetworkId().getValueString().c_str())); @@ -2394,7 +2394,7 @@ void PlanetObject::adjustGcwRebelScore(std::string const & source, CreatureObjec // grant GCW Region Defender bonus float bonus = 0.0f; if (gcwCategoryData->gcwRegionDefender && PvpData::isRebelFactionId(sourceObject->getPvpFaction()) && (adjustment > 0) && (playerObject->getCurrentGcwRegion() == gcwCategory) && Pvp::getGcwDefenderRegionBonus(*sourceObject, *playerObject, bonus) && (bonus > 0.0f)) - adjustment += std::max(1ll, static_cast(static_cast(bonus) * static_cast(adjustment) / static_cast(100))); + adjustment += static_cast(std::max(static_cast(1), static_cast(bonus) * static_cast(adjustment) / 100)); } LOG("CustomerService", ("GcwScore: rebel %s %d (from %s - %s)", gcwCategory.c_str(), static_cast(adjustment), source.c_str(), sourceObject->getNetworkId().getValueString().c_str())); diff --git a/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp b/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp index 615c88247..2c1df6ae9 100755 --- a/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp @@ -6115,7 +6115,7 @@ void PlayerObject::getByteStreamFromAutoVariable(const std::string & name, Archi { if(name == "quests") { - Archive::AutoDeltaMap(m_quests).pack(target); + Archive::AutoDeltaMap(m_quests).pack(target); } else if(name == "completedQuests") { @@ -6202,11 +6202,11 @@ void PlayerObject::setAutoVariableFromByteStream(const std::string & name, const Archive::ReadIterator ri(source); if(name == "quests") { - typedef Archive::AutoDeltaMap::Command Commands; + typedef Archive::AutoDeltaMap::Command Commands; std::vector quests; m_quests.clear(); - Archive::AutoDeltaMap(m_quests).unpack(ri, quests); + Archive::AutoDeltaMap(m_quests).unpack(ri, quests); for (std::vector::const_iterator questIter = quests.begin(); questIter != quests.end(); ++questIter) { diff --git a/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp b/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp index 82e2a710d..e08354332 100755 --- a/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp @@ -54,7 +54,7 @@ ResourcePoolObject::~ResourcePoolObject() */ float ResourcePoolObject::harvest(float installedEfficiency, uint32 lastHarvestTime) const { - int elapsedTime=static_cast(std::min(ServerClock::getInstance().getGameTimeSeconds(),m_depletedTimestamp) - lastHarvestTime); + int elapsedTime=static_cast(std::min(ServerClock::getInstance().getGameTimeSeconds(),static_cast(m_depletedTimestamp)) - lastHarvestTime); if (elapsedTime < 0) return 0; float elapsedTicks =static_cast(elapsedTime) / static_cast(ConfigServerGame::getSecondsPerResourceTick()); diff --git a/engine/server/library/serverGame/src/shared/object/ServerObject.h b/engine/server/library/serverGame/src/shared/object/ServerObject.h index 23e12f28b..90437a5ce 100755 --- a/engine/server/library/serverGame/src/shared/object/ServerObject.h +++ b/engine/server/library/serverGame/src/shared/object/ServerObject.h @@ -551,7 +551,7 @@ class ServerObject : public Object virtual bool isVisibleOnClient (const Client & client) const = 0; virtual void kill (); - void performSocial (const NetworkId & target, unsigned long socialType, bool animationOk, bool textOk); + void performSocial (const NetworkId & target, uint32 socialType, bool animationOk, bool textOk); void performSocial (const MessageQueueSocial & socialMsg); void performCombatSpam (const MessageQueueCombatSpam & combatSpam, bool sendToSelf, bool sendToTarget, bool sendToBystanders); @@ -583,7 +583,7 @@ class ServerObject : public Object virtual void setOwnerId(const NetworkId &id); void setSceneIdOnThisAndContents (const std::string & sceneId); void setPlayerControlled (bool newValue); - void speakText (NetworkId const &target, unsigned long chatType, unsigned long mood, unsigned long flags, Unicode::String const &speech, int language, Unicode::String const &oob); + void speakText (NetworkId const &target, uint32 chatType, uint32 mood, uint32 flags, Unicode::String const &speech, int language, Unicode::String const &oob); virtual void speakText (MessageQueueSpatialChat const &spatialChat); virtual void hearText (ServerObject const &source, MessageQueueSpatialChat const &spatialChat, int chatMessageIndex); void teleportObject (Vector const & position_w, NetworkId const &targetContainer, std::string const &targetCellName, Vector const &position_p, std::string const &scriptCallback, bool forceLoadScreen = false); diff --git a/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp b/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp index d6e291ae3..5cd42a725 100755 --- a/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp +++ b/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp @@ -843,14 +843,14 @@ int Pvp::calculateGcwImperialScorePercentile(std::string const & gcwCategory, st { std::map >::const_iterator const iterImperial = gcwImperialScore.find(gcwCategory); if (iterImperial != gcwImperialScore.end()) - totalImperial = static_cast(std::max(0ll, iterImperial->second.first)) + static_cast(std::max(0ll, iterImperial->second.second)); + totalImperial = static_cast(std::max(0l, iterImperial->second.first)) + static_cast(std::max(0l, iterImperial->second.second)); } uint64 total = totalImperial; { std::map >::const_iterator const iterRebel = gcwRebelScore.find(gcwCategory); if (iterRebel != gcwRebelScore.end()) - total += (static_cast(std::max(0ll, iterRebel->second.first)) + static_cast(std::max(0ll, iterRebel->second.second))); + total += (static_cast(std::max(0l, iterRebel->second.first)) + static_cast(std::max(0l, iterRebel->second.second))); } // if the score is less than 1, treat it as a tie; note that score is scaled by 1000 diff --git a/engine/server/library/serverPathfinding/src/shared/CityPathGraph.cpp b/engine/server/library/serverPathfinding/src/shared/CityPathGraph.cpp index 8ec08af53..b8ed9a839 100755 --- a/engine/server/library/serverPathfinding/src/shared/CityPathGraph.cpp +++ b/engine/server/library/serverPathfinding/src/shared/CityPathGraph.cpp @@ -709,32 +709,32 @@ void CityPathGraph::setLinkDistance ( float dist ) // we cast the addresses of all the neighbors to ints, multiply them // by a random large prime number, then xor the bits together. -int CityPathGraph::getNeighborCode ( int whichNode ) const -{ - CityPathNode const * node = _getNode(whichNode); - - if(node == nullptr) return 0; - - int edgeCount = node->getEdgeCount(); - - int code = 0; - - for(int i = 0; i < edgeCount; i++) - { - int neighborId = node->getNeighbor(i); - - CityPathNode const * neighbor = _getNode(neighborId); - - if(neighbor == nullptr) continue; - - int neighborInt = reinterpret_cast(neighbor); - - int mungedInt = neighborInt * 1295183; - - code ^= mungedInt; - } - - return code; -} +//int CityPathGraph::getNeighborCode ( int whichNode ) const +//{ +// CityPathNode const * node = _getNode(whichNode); +// +// if(node == nullptr) return 0; +// +// int edgeCount = node->getEdgeCount(); +// +// int code = 0; +// +// for(int i = 0; i < edgeCount; i++) +// { +// int neighborId = node->getNeighbor(i); +// +// CityPathNode const * neighbor = _getNode(neighborId); +// +// if(neighbor == nullptr) continue; +// +// int neighborInt = reinterpret_cast(neighbor); +// +// int mungedInt = neighborInt * 1295183; +// +// code ^= mungedInt; +// } +// +// return code; +//} // ---------------------------------------------------------------------- diff --git a/engine/server/library/serverPathfinding/src/shared/CityPathGraph.h b/engine/server/library/serverPathfinding/src/shared/CityPathGraph.h index 322f653c8..89835c999 100755 --- a/engine/server/library/serverPathfinding/src/shared/CityPathGraph.h +++ b/engine/server/library/serverPathfinding/src/shared/CityPathGraph.h @@ -84,7 +84,7 @@ class CityPathGraph : public DynamicPathGraph static float getLinkDistance ( void ); static void setLinkDistance ( float dist ); - int getNeighborCode ( int whichNode ) const; +// int getNeighborCode ( int whichNode ) const; protected: diff --git a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp index 75f83e68f..b1df5f350 100755 --- a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp +++ b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp @@ -790,7 +790,7 @@ void JavaLibrary::fatalHandler(int signum) char lib1[BUFLEN], lib2[BUFLEN]; char file1[BUFLEN], file2[BUFLEN]; int line1, line2; - bool result1 = DebugHelp::lookupAddress(reinterpret_cast(crashAddress1), lib1, file1, BUFLEN, line1); + bool result1 = DebugHelp::lookupAddress(reinterpret_cast(crashAddress1), lib1, file1, BUFLEN, line1); // do a second test based on the return address // it turns out that in some java crashes we don't even have 2 return @@ -801,25 +801,25 @@ void JavaLibrary::fatalHandler(int signum) void *crashAddress2c = nullptr; void *frameAddressA = nullptr; void *frameAddressB = nullptr; - uint32 frameAddressHigh = (reinterpret_cast(frameAddress) >> 16); + uint64 frameAddressHigh = (reinterpret_cast(frameAddress) >> 16); crashAddress2a = __builtin_return_address(0); if (crashAddress2a != nullptr) { frameAddressA = __builtin_frame_address(1); if (frameAddressA != nullptr && - (reinterpret_cast(frameAddressA) >> 16 == frameAddressHigh)) + (reinterpret_cast(frameAddressA) >> 16 == frameAddressHigh)) { crashAddress2b = __builtin_return_address(1); if (crashAddress2b != nullptr) { frameAddressB = __builtin_frame_address(2); if (frameAddressB != nullptr && - (reinterpret_cast(frameAddressB) >> 16 == frameAddressHigh)) + (reinterpret_cast(frameAddressB) >> 16 == frameAddressHigh)) { crashAddress2c = __builtin_return_address(2); if (crashAddress2c != nullptr) { - result2 = DebugHelp::lookupAddress(reinterpret_cast( + result2 = DebugHelp::lookupAddress(reinterpret_cast( crashAddress2c), lib2, file2, BUFLEN, line2); } } diff --git a/engine/server/library/serverUtility/src/shared/ServerConnection.h b/engine/server/library/serverUtility/src/shared/ServerConnection.h index d7fd6519c..e53b23d6b 100755 --- a/engine/server/library/serverUtility/src/shared/ServerConnection.h +++ b/engine/server/library/serverUtility/src/shared/ServerConnection.h @@ -41,7 +41,7 @@ class ServerConnection: public Connection, public MessageDispatch::Emitter virtual void reportReceive (const Archive::ByteStream & bs); virtual void reportSend (const Archive::ByteStream & bs); virtual void send (const GameNetworkMessage & message, const bool reliable); - virtual void setProcessId (const unsigned long newProcessId); + virtual void setProcessId (const uint32 newProcessId); public: class MessageConnectionCallback: public MessageDispatch::MessageBase diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h index f4dc519c3..c76c2621b 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h @@ -32,7 +32,7 @@ namespace DB { // following alternate getValue's are provided for convenience, particularly in // the auto-generated code: void getValue(unsigned int &buffer) const; - void getValue(uint32 &buffer) const; // for some reason, our compiler is convinced that uint32 != unsigned int +// void getValue(uint32 &buffer) const; // for some reason, our compiler is convinced that uint32 != unsigned int void getValue(long int &buffer) const; void getValue(int &buffer) const; void getValue(int8 &buffer) const; @@ -57,10 +57,10 @@ inline void DB::BindableLong::getValue(unsigned int &buffer) const // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint32 &buffer) const -{ - buffer=static_cast(getValue()); -} +//inline void DB::BindableLong::getValue(uint32 &buffer) const +//{ +// buffer=static_cast(getValue()); +//} // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp index b0cec73dd..39e3303a5 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp @@ -154,22 +154,22 @@ bool BindableVarrayNumber::push_back(long int value) return true; } // ---------------------------------------------------------------------- - -bool BindableVarrayNumber::push_back(int64 value) -{ - OCINumber buffer; - - OCIInd buffer_indicator (OCI_IND_NOTNULL); - - OCISession *localSession = safe_cast(m_session); - - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; - - return true; -} +// +//bool BindableVarrayNumber::push_back(int64 value) +//{ +// OCINumber buffer; +// +// OCIInd buffer_indicator (OCI_IND_NOTNULL); +// +// OCISession *localSession = safe_cast(m_session); +// +// if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) +// return false; +// if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) +// return false; +// +// return true; +//} // ---------------------------------------------------------------------- @@ -255,31 +255,31 @@ bool BindableVarrayNumber::push_back(bool IsNULL, long int value) return true; } // ---------------------------------------------------------------------- - -bool BindableVarrayNumber::push_back(bool IsNULL, int64 value) -{ - OCINumber buffer; - - OCIInd buffer_indicator; - - if ( IsNULL ) - { - buffer_indicator = OCI_IND_NULL; - } - else - { - buffer_indicator = OCI_IND_NOTNULL; - } - - OCISession *localSession = safe_cast(m_session); - - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; - - return true; -} +// +//bool BindableVarrayNumber::push_back(bool IsNULL, int64 value) +//{ +// OCINumber buffer; +// +// OCIInd buffer_indicator; +// +// if ( IsNULL ) +// { +// buffer_indicator = OCI_IND_NULL; +// } +// else +// { +// buffer_indicator = OCI_IND_NOTNULL; +// } +// +// OCISession *localSession = safe_cast(m_session); +// +// if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) +// return false; +// if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) +// return false; +// +// return true; +//} // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h index a9233b6f2..297370059 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h @@ -60,11 +60,11 @@ namespace DB bool push_back(bool IsNULL, int value); bool push_back(bool IsNULL, double value); bool push_back(bool IsNULL, long int value); - bool push_back(bool IsNULL, int64 value); +// bool push_back(bool IsNULL, int64 value); bool push_back(int value); bool push_back(double value); bool push_back(long int value); - bool push_back(int64 value); +// bool push_back(int64 value); virtual std::string outputValue() const; }; diff --git a/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp b/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp index c1639ebde..e7a2fb7b9 100755 --- a/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp +++ b/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp @@ -174,6 +174,14 @@ inline unsigned int dwarfGet(char const *src, u_int32_t &dest) // ---------------------------------------------------------------------- +inline unsigned int dwarfGet(char const *src, u_int64_t &dest) +{ + memcpy(&dest, src, sizeof(u_int64_t)); + return sizeof(u_int64_t); +} + +// ---------------------------------------------------------------------- + class LEB128 { public: @@ -294,7 +302,7 @@ static bool dwarfSearch(char const *dwarfLines, unsigned int linesLength, void c { int progFile = 0; int progLine = 1; - u_int32_t progAddr = 0; + u_int64_t progAddr = 0; bool done = false; bool valid = false; @@ -384,9 +392,9 @@ static bool dwarfSearch(char const *dwarfLines, unsigned int linesLength, void c if (valid) { - unsigned int addrOffset = 0; - if (progAddr < reinterpret_cast(info.dli_fbase)) - addrOffset = reinterpret_cast(info.dli_fbase); + u_int64_t addrOffset = 0; + if (progAddr < reinterpret_cast(info.dli_fbase)) + addrOffset = reinterpret_cast(info.dli_fbase); const void *testAddr = reinterpret_cast(progAddr+addrOffset); if (testAddr >= addr) { @@ -509,12 +517,12 @@ static bool stabSearch(Stab const *stab, unsigned int stabSize, char const *stab if (reinterpret_cast(stab->n_value) > info.dli_fbase) funcBase = reinterpret_cast(stab->n_value); else - funcBase = reinterpret_cast(reinterpret_cast(info.dli_fbase)+stab->n_value); + funcBase = reinterpret_cast(reinterpret_cast(info.dli_fbase)+stab->n_value); foundSrcLine = -1; } else if (stab->n_type == N_SLINE && addr >= funcBase) // source line { - if (stab->n_value < reinterpret_cast(addr)-reinterpret_cast(funcBase)) + if (stab->n_value < reinterpret_cast(addr)-reinterpret_cast(funcBase)) foundSrcLine = stab->n_desc; else { @@ -667,7 +675,7 @@ void DebugHelp::remove() // ---------------------------------------------------------------------- -bool DebugHelp::lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line) +bool DebugHelp::lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line) { return lookupAddressInfo(reinterpret_cast(address), libName, fileName, line, fileNameLength); } diff --git a/engine/shared/library/sharedDebug/src/linux/DebugHelp.h b/engine/shared/library/sharedDebug/src/linux/DebugHelp.h index 972b49790..e297f8ebf 100755 --- a/engine/shared/library/sharedDebug/src/linux/DebugHelp.h +++ b/engine/shared/library/sharedDebug/src/linux/DebugHelp.h @@ -20,7 +20,7 @@ class DebugHelp static void remove(); static void getCallStack(uint32 *callStack, int sizeOfCallStack); - static bool lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line); + static bool lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line); }; // ====================================================================== diff --git a/engine/shared/library/sharedDebug/src/win32/DebugHelp.h b/engine/shared/library/sharedDebug/src/win32/DebugHelp.h index ead64d75b..74e379abe 100755 --- a/engine/shared/library/sharedDebug/src/win32/DebugHelp.h +++ b/engine/shared/library/sharedDebug/src/win32/DebugHelp.h @@ -10,7 +10,7 @@ // ====================================================================== -typedef unsigned long uint32; +typedef uint32_t uint32; // ====================================================================== diff --git a/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.h b/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.h index 867d7086f..374994cd6 100755 --- a/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.h +++ b/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.h @@ -10,7 +10,7 @@ #include typedef unsigned short int WORD; -typedef unsigned long int DWORD; +typedef uint32_t DWORD; typedef bool BOOL; typedef long long __int64; //lint !e13 !e19 // Error: 13 (Bad type), Error: 19 (Useless declaration) // -TRF- Lint preprocessor discrepency, @todo look into this. typedef __int64 LARGE_INTEGER; diff --git a/engine/shared/library/sharedFoundation/src/shared/FormattedString.h b/engine/shared/library/sharedFoundation/src/shared/FormattedString.h index d778be27b..7d5b80016 100755 --- a/engine/shared/library/sharedFoundation/src/shared/FormattedString.h +++ b/engine/shared/library/sharedFoundation/src/shared/FormattedString.h @@ -18,8 +18,8 @@ class FormattedString FormattedString(); - char const * sprintf(char const * format, ...); - char const * vsprintf(char const * format, va_list const & va); + char const * sprintf(const char * format, ...); + char const * vsprintf(const char * format, va_list va); private: @@ -40,7 +40,7 @@ inline FormattedString::FormattedString() //----------------------------------------------------------------------------- template -inline char const * FormattedString::sprintf(char const * const format, ...) +inline char const * FormattedString::sprintf(const char * format, ...) { char const * result = nullptr; va_list va; @@ -56,7 +56,7 @@ inline char const * FormattedString::sprintf(char const * const form // ---------------------------------------------------------------------- template -inline char const * FormattedString::vsprintf(char const * const format, va_list const & va) +inline char const * FormattedString::vsprintf(const char * format, va_list va) { // Format the string diff --git a/engine/shared/library/sharedFoundation/src/shared/Misc.h b/engine/shared/library/sharedFoundation/src/shared/Misc.h index 1c29b6edb..d0e70c941 100755 --- a/engine/shared/library/sharedFoundation/src/shared/Misc.h +++ b/engine/shared/library/sharedFoundation/src/shared/Misc.h @@ -230,7 +230,7 @@ inline void *memmove(void *destination, const void *source, int length) { DEBUG_FATAL(!destination, ("nullptr destination arg")); DEBUG_FATAL(!source, ("nullptr source arg")); - return memmove(destination, source, static_cast(length)); + return memmove(destination, source, static_cast(length)); } // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedFoundation/src/shared/NetworkId.h b/engine/shared/library/sharedFoundation/src/shared/NetworkId.h index 18ada6192..112fc96c6 100755 --- a/engine/shared/library/sharedFoundation/src/shared/NetworkId.h +++ b/engine/shared/library/sharedFoundation/src/shared/NetworkId.h @@ -68,8 +68,8 @@ class NetworkId friend class DB::BindableNetworkId; - private: - explicit NetworkId(int value); // catch people who incorrectly try to construct one of these from an int +// private: +// explicit NetworkId(int value); // catch people who incorrectly try to construct one of these from an int // also makes constructing one of these from any other incorrect numeric type ambiguous }; diff --git a/engine/shared/library/sharedFoundationTypes/src/linux/FoundationTypesLinux.h b/engine/shared/library/sharedFoundationTypes/src/linux/FoundationTypesLinux.h index 386c4ffb4..347b06b4a 100755 --- a/engine/shared/library/sharedFoundationTypes/src/linux/FoundationTypesLinux.h +++ b/engine/shared/library/sharedFoundationTypes/src/linux/FoundationTypesLinux.h @@ -10,18 +10,19 @@ #define PLATFORM_LINUX #include +#include // ====================================================================== // basic types that we assume to be around -typedef unsigned int uint; +typedef uint32_t uint; typedef unsigned char uint8; typedef unsigned short uint16; -typedef unsigned long uint32; +typedef uint32_t uint32; typedef signed char int8; typedef signed short int16; -typedef signed long int32; -typedef signed long long int int64; -typedef unsigned long long int uint64; +typedef int32_t int32; +typedef int64_t int64; +typedef uint64_t uint64; typedef float real; typedef FILE* FILE_HANDLE; diff --git a/engine/shared/library/sharedFoundationTypes/src/win32/FoundationTypesWin32.h b/engine/shared/library/sharedFoundationTypes/src/win32/FoundationTypesWin32.h index 622039d8b..43a297abd 100755 --- a/engine/shared/library/sharedFoundationTypes/src/win32/FoundationTypesWin32.h +++ b/engine/shared/library/sharedFoundationTypes/src/win32/FoundationTypesWin32.h @@ -15,17 +15,18 @@ #define PLATFORM_WIN32 +#include // ====================================================================== // basic types that we assume to be around typedef unsigned char uint8; typedef unsigned short uint16; -typedef unsigned long uint32; -typedef unsigned __int64 uint64; +typedef uint32_t uint32; +typedef uint64_t uint64; typedef signed char int8; typedef signed short int16; -typedef signed long int32; -typedef signed __int64 int64; +typedef int32_t int32; +typedef int64_t int64; typedef int FILE_HANDLE; // ====================================================================== diff --git a/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp b/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp index dc2a932c4..2ae617993 100755 --- a/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp +++ b/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp @@ -313,7 +313,7 @@ void AlterSchedulerNamespace::validateObject(Object const *object) } catch (...) { //lint !e1775 // catch block does not declare any exception // that's right: I want to catch it all. - WARNING(true, ("validateObject(): Object-derived class with address [%x] failed to return valid C++ type info; likely a deleted Object.", reinterpret_cast(object))); + WARNING(true, ("validateObject(): Object-derived class with address [%x] failed to return valid C++ type info; likely a deleted Object.", reinterpret_cast(object))); isInvalid = true; } } diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathNode.h b/engine/shared/library/sharedPathfinding/src/shared/PathNode.h index fd62f52c3..aeaeaaf75 100755 --- a/engine/shared/library/sharedPathfinding/src/shared/PathNode.h +++ b/engine/shared/library/sharedPathfinding/src/shared/PathNode.h @@ -67,8 +67,8 @@ class PathNode int getUserId ( void ) const; void setUserId ( int newId ) const; - int getMark ( int whichMark ) const; - void setMark ( int whichMark, int newValue ) const; + int64_t getMark ( int whichMark ) const; + void setMark ( int whichMark, int64_t newValue ) const; void clearMarks ( void ) const; // ---------- @@ -95,8 +95,8 @@ class PathNode // These are used to speed up some algorithms. They're not persisted. // Code that uses the marks MUST clear them after use. - mutable int m_userId; - mutable int m_marks[4]; + mutable int m_userId; + mutable int64_t m_marks[4]; }; // ---------------------------------------------------------------------- @@ -214,12 +214,12 @@ inline void PathNode::setUserId ( int newId ) const // ---------- -inline int PathNode::getMark ( int whichMark ) const +inline int64_t PathNode::getMark ( int whichMark ) const { return m_marks[whichMark]; } -inline void PathNode::setMark ( int whichMark, int newMark ) const +inline void PathNode::setMark ( int whichMark, int64_t newMark ) const { m_marks[whichMark] = newMark; } diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp index e09a5cab6..f708a3157 100755 --- a/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp +++ b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp @@ -182,7 +182,7 @@ PathSearchNode * PathSearchNode::createSearchNode( PathNode const * node ) PathSearchNode * oldNode = nullptr; - int mark = node->getMark(3); + int64_t mark = node->getMark(3); if(mark != -1) { @@ -193,7 +193,7 @@ PathSearchNode * PathSearchNode::createSearchNode( PathNode const * node ) PathSearchNode * searchNode = new PathSearchNode(m_search,m_graph,node); - node->setMark( 3, (int)((void*)searchNode) ); + node->setMark( 3, (int64)((void*)searchNode) ); m_search->m_visitedNodes->push_back(node); @@ -208,7 +208,7 @@ PathSearchNode * PathSearchNode::getSearchNode( PathNode const * node ) PathSearchNode * searchNode = nullptr; - int mark = node->getMark(3); + int64_t mark = node->getMark(3); if(mark != -1) { @@ -493,7 +493,7 @@ void PathSearch::cleanup ( void ) { PathNode const * visitedNode = m_visitedNodes->at(i); - int mark = visitedNode->getMark(3); + int64_t mark = visitedNode->getMark(3); if(mark != -1) { diff --git a/external/3rd/library/platform/utils/Base/BlockAllocator.h b/external/3rd/library/platform/utils/Base/BlockAllocator.h index bbfbf2738..f9f9f8632 100755 --- a/external/3rd/library/platform/utils/Base/BlockAllocator.h +++ b/external/3rd/library/platform/utils/Base/BlockAllocator.h @@ -17,7 +17,7 @@ namespace Base BlockAllocator(); ~BlockAllocator(); void *getBlock(unsigned accum); - void returnBlock(unsigned *handle); + void returnBlock(uintptr_t *handle); private: uintptr_t *m_blocks[31]; diff --git a/external/3rd/library/platform/utils/Base/linux/BlockAllocator.cpp b/external/3rd/library/platform/utils/Base/linux/BlockAllocator.cpp index 29d910749..f4042d1f6 100755 --- a/external/3rd/library/platform/utils/Base/linux/BlockAllocator.cpp +++ b/external/3rd/library/platform/utils/Base/linux/BlockAllocator.cpp @@ -23,8 +23,8 @@ namespace Base { while(m_blocks[i] != nullptr) { - unsigned *tmp = m_blocks[i]; - m_blocks[i] = (unsigned *)*m_blocks[i]; + uintptr_t *tmp = m_blocks[i]; + m_blocks[i] = (uintptr_t *)*m_blocks[i]; free(tmp); } } @@ -36,7 +36,7 @@ namespace Base void *BlockAllocator::getBlock(unsigned bytes) { unsigned accum = 16, bits = 16; - unsigned *handle = nullptr; + uintptr_t *handle = nullptr; // Perform a binary search looking for the highest bit. @@ -79,7 +79,7 @@ namespace Base if(m_blocks[accum] == 0) { // remove the pre allocated block from the linked list - handle = (unsigned *)calloc(((1 << accum) / 4) + 2, sizeof(unsigned)); + handle = (uintptr_t *)calloc(((1 << accum) / 4) + 2, sizeof(uintptr_t)); handle[1] = accum; handle[0] = 0; } @@ -87,20 +87,20 @@ namespace Base { // Allocate a new block handle = m_blocks[accum]; - m_blocks[accum] = (unsigned *)handle[0]; + m_blocks[accum] = (uintptr_t *)handle[0]; handle[0] = 0; } // return a pointer that skips over the header used for the allocator's purposes return(handle + 2); } - void BlockAllocator::returnBlock(unsigned *handle) + void BlockAllocator::returnBlock(uintptr_t *handle) { // C++ allows for safe deletion of a nullptr pointer if(handle) { // Update the allocator linked list, insert this entry at the head - *(handle - 2) = (unsigned)m_blocks[*(handle - 1)]; + *(handle - 2) = (uintptr_t)m_blocks[*(handle - 1)]; // Add this entry to the proper linked list node m_blocks[*(handle - 1)] = (handle - 2); } diff --git a/external/3rd/library/platform/utils/Base/linux/Types.h b/external/3rd/library/platform/utils/Base/linux/Types.h index 6ee504505..a685807d6 100755 --- a/external/3rd/library/platform/utils/Base/linux/Types.h +++ b/external/3rd/library/platform/utils/Base/linux/Types.h @@ -11,7 +11,8 @@ #ifndef BASE_LINUX_TYPES_H #define BASE_LINUX_TYPES_H -#include +//#include +#include #ifdef EXTERNAL_DISTRO namespace NAMESPACE @@ -31,9 +32,9 @@ typedef signed short int16; typedef unsigned short uint16; typedef int32_t int32; -typedef u_int32_t uint32; +typedef uint32_t uint32; typedef int64_t int64; -typedef u_int64_t uint64; +typedef uint64_t uint64; } #ifdef EXTERNAL_DISTRO }; diff --git a/external/3rd/library/platform/utils/Base/win32/Types.h b/external/3rd/library/platform/utils/Base/win32/Types.h index 0c64cb2cb..aa9ba015f 100755 --- a/external/3rd/library/platform/utils/Base/win32/Types.h +++ b/external/3rd/library/platform/utils/Base/win32/Types.h @@ -28,10 +28,10 @@ typedef unsigned char uint8; typedef short int16; typedef unsigned short uint16; -typedef int int32; -typedef unsigned uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; }; #ifdef EXTERNAL_DISTRO diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/BlockAllocator.h b/external/3rd/library/soePlatform/CSAssist/utils/Base/BlockAllocator.h index bbfbf2738..f9f9f8632 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/BlockAllocator.h +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/BlockAllocator.h @@ -17,7 +17,7 @@ namespace Base BlockAllocator(); ~BlockAllocator(); void *getBlock(unsigned accum); - void returnBlock(unsigned *handle); + void returnBlock(uintptr_t *handle); private: uintptr_t *m_blocks[31]; diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/BlockAllocator.cpp b/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/BlockAllocator.cpp index 29d910749..f4042d1f6 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/BlockAllocator.cpp +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/BlockAllocator.cpp @@ -23,8 +23,8 @@ namespace Base { while(m_blocks[i] != nullptr) { - unsigned *tmp = m_blocks[i]; - m_blocks[i] = (unsigned *)*m_blocks[i]; + uintptr_t *tmp = m_blocks[i]; + m_blocks[i] = (uintptr_t *)*m_blocks[i]; free(tmp); } } @@ -36,7 +36,7 @@ namespace Base void *BlockAllocator::getBlock(unsigned bytes) { unsigned accum = 16, bits = 16; - unsigned *handle = nullptr; + uintptr_t *handle = nullptr; // Perform a binary search looking for the highest bit. @@ -79,7 +79,7 @@ namespace Base if(m_blocks[accum] == 0) { // remove the pre allocated block from the linked list - handle = (unsigned *)calloc(((1 << accum) / 4) + 2, sizeof(unsigned)); + handle = (uintptr_t *)calloc(((1 << accum) / 4) + 2, sizeof(uintptr_t)); handle[1] = accum; handle[0] = 0; } @@ -87,20 +87,20 @@ namespace Base { // Allocate a new block handle = m_blocks[accum]; - m_blocks[accum] = (unsigned *)handle[0]; + m_blocks[accum] = (uintptr_t *)handle[0]; handle[0] = 0; } // return a pointer that skips over the header used for the allocator's purposes return(handle + 2); } - void BlockAllocator::returnBlock(unsigned *handle) + void BlockAllocator::returnBlock(uintptr_t *handle) { // C++ allows for safe deletion of a nullptr pointer if(handle) { // Update the allocator linked list, insert this entry at the head - *(handle - 2) = (unsigned)m_blocks[*(handle - 1)]; + *(handle - 2) = (uintptr_t)m_blocks[*(handle - 1)]; // Add this entry to the proper linked list node m_blocks[*(handle - 1)] = (handle - 2); } diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h b/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h index 69419a0fc..a5eb04133 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h @@ -11,7 +11,8 @@ #ifndef BASE_LINUX_TYPES_H #define BASE_LINUX_TYPES_H -#include +//#include +#include #ifdef EXTERNAL_DISTRO namespace NAMESPACE @@ -34,9 +35,9 @@ typedef signed short int16; typedef unsigned short uint16; typedef int32_t int32; -typedef u_int32_t uint32; +typedef uint32_t uint32; typedef int64_t int64; -typedef u_int64_t uint64; +typedef uint64_t uint64; } #ifdef EXTERNAL_DISTRO }; diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h b/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h index 0c64cb2cb..aa9ba015f 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h @@ -28,10 +28,10 @@ typedef unsigned char uint8; typedef short int16; typedef unsigned short uint16; -typedef int int32; -typedef unsigned uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; }; #ifdef EXTERNAL_DISTRO diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h index 69419a0fc..a5eb04133 100755 --- a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h @@ -11,7 +11,8 @@ #ifndef BASE_LINUX_TYPES_H #define BASE_LINUX_TYPES_H -#include +//#include +#include #ifdef EXTERNAL_DISTRO namespace NAMESPACE @@ -34,9 +35,9 @@ typedef signed short int16; typedef unsigned short uint16; typedef int32_t int32; -typedef u_int32_t uint32; +typedef uint32_t uint32; typedef int64_t int64; -typedef u_int64_t uint64; +typedef uint64_t uint64; } #ifdef EXTERNAL_DISTRO }; diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h index 0c64cb2cb..aa9ba015f 100755 --- a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h @@ -28,10 +28,10 @@ typedef unsigned char uint8; typedef short int16; typedef unsigned short uint16; -typedef int int32; -typedef unsigned uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; }; #ifdef EXTERNAL_DISTRO diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/BlockAllocator.h b/external/3rd/library/soePlatform/ChatAPI/utils/Base/BlockAllocator.h index bbfbf2738..f9f9f8632 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/BlockAllocator.h +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/BlockAllocator.h @@ -17,7 +17,7 @@ namespace Base BlockAllocator(); ~BlockAllocator(); void *getBlock(unsigned accum); - void returnBlock(unsigned *handle); + void returnBlock(uintptr_t *handle); private: uintptr_t *m_blocks[31]; diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/BlockAllocator.cpp b/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/BlockAllocator.cpp index 29d910749..f4042d1f6 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/BlockAllocator.cpp +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/BlockAllocator.cpp @@ -23,8 +23,8 @@ namespace Base { while(m_blocks[i] != nullptr) { - unsigned *tmp = m_blocks[i]; - m_blocks[i] = (unsigned *)*m_blocks[i]; + uintptr_t *tmp = m_blocks[i]; + m_blocks[i] = (uintptr_t *)*m_blocks[i]; free(tmp); } } @@ -36,7 +36,7 @@ namespace Base void *BlockAllocator::getBlock(unsigned bytes) { unsigned accum = 16, bits = 16; - unsigned *handle = nullptr; + uintptr_t *handle = nullptr; // Perform a binary search looking for the highest bit. @@ -79,7 +79,7 @@ namespace Base if(m_blocks[accum] == 0) { // remove the pre allocated block from the linked list - handle = (unsigned *)calloc(((1 << accum) / 4) + 2, sizeof(unsigned)); + handle = (uintptr_t *)calloc(((1 << accum) / 4) + 2, sizeof(uintptr_t)); handle[1] = accum; handle[0] = 0; } @@ -87,20 +87,20 @@ namespace Base { // Allocate a new block handle = m_blocks[accum]; - m_blocks[accum] = (unsigned *)handle[0]; + m_blocks[accum] = (uintptr_t *)handle[0]; handle[0] = 0; } // return a pointer that skips over the header used for the allocator's purposes return(handle + 2); } - void BlockAllocator::returnBlock(unsigned *handle) + void BlockAllocator::returnBlock(uintptr_t *handle) { // C++ allows for safe deletion of a nullptr pointer if(handle) { // Update the allocator linked list, insert this entry at the head - *(handle - 2) = (unsigned)m_blocks[*(handle - 1)]; + *(handle - 2) = (uintptr_t)m_blocks[*(handle - 1)]; // Add this entry to the proper linked list node m_blocks[*(handle - 1)] = (handle - 2); } diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h b/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h index 6ee504505..a685807d6 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h @@ -11,7 +11,8 @@ #ifndef BASE_LINUX_TYPES_H #define BASE_LINUX_TYPES_H -#include +//#include +#include #ifdef EXTERNAL_DISTRO namespace NAMESPACE @@ -31,9 +32,9 @@ typedef signed short int16; typedef unsigned short uint16; typedef int32_t int32; -typedef u_int32_t uint32; +typedef uint32_t uint32; typedef int64_t int64; -typedef u_int64_t uint64; +typedef uint64_t uint64; } #ifdef EXTERNAL_DISTRO }; diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h b/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h index 0c64cb2cb..aa9ba015f 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h @@ -28,10 +28,10 @@ typedef unsigned char uint8; typedef short int16; typedef unsigned short uint16; -typedef int int32; -typedef unsigned uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; }; #ifdef EXTERNAL_DISTRO diff --git a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h index ba396c51e..389d8a490 100755 --- a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h +++ b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h @@ -6,7 +6,8 @@ #define STRINGIFY(S) #S #ifdef linux -#include +//#include +#include #endif #define DECLSPEC @@ -38,17 +39,17 @@ namespace soe typedef unsigned short uint16; #ifdef WIN32 - typedef int int32; - typedef unsigned uint32; - typedef __int64 int64; - typedef unsigned __int64 uint64; + typedef int32_t int32; + typedef uint32_t uint32; + typedef int64_t int64; + typedef uint64_t uint64; #elif linux - typedef int32_t int32; - typedef u_int32_t uint32; - typedef int64_t int64; - typedef u_int64_t uint64; + typedef int32_t int32; + typedef uint32_t uint32; + typedef int64_t int64; + typedef uint64_t uint64; //! the previous seem erroneous // typedef signed int int32; // typedef unsigned int uint32; diff --git a/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h index e73b56b30..466bbde35 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h +++ b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h @@ -204,6 +204,18 @@ namespace Archive internal_unpack(source, buffer, "%i %i:"); } + template<> + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%i %i"); + } + + template<> + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%i %i:"); + } + template<> inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) { @@ -217,6 +229,17 @@ namespace Archive } #ifdef WIN32 + template<> + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%lu %I64u"); + } + + template<> + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%lu %I64u:"); + } template<> inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) { @@ -231,13 +254,24 @@ namespace Archive #else template<> - inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%lu %llu"); + } + + template<> + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%lu %llu:"); + } + template<> + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) { internal_pack(target, buffer, "%lu %llu"); } template<> - inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) { internal_unpack(source, buffer, "%lu %llu:"); } diff --git a/external/ours/library/crypto/src/shared/original/misc.cpp b/external/ours/library/crypto/src/shared/original/misc.cpp index 5e49edfc0..c1a7d078f 100755 --- a/external/ours/library/crypto/src/shared/original/misc.cpp +++ b/external/ours/library/crypto/src/shared/original/misc.cpp @@ -10,7 +10,7 @@ byte OAEP_P_DEFAULT[1]; void xorbuf(byte *buf, const byte *mask, unsigned int count) { - if (((unsigned int)buf | (unsigned int)mask | count) % WORD_SIZE == 0) + if (((size_t)buf | (size_t)mask | count) % WORD_SIZE == 0) XorWords((word *)buf, (const word *)mask, count/WORD_SIZE); else { @@ -21,7 +21,7 @@ void xorbuf(byte *buf, const byte *mask, unsigned int count) void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count) { - if (((unsigned int)output | (unsigned int)input | (unsigned int)mask | count) % WORD_SIZE == 0) + if (((size_t)output | (size_t)input | (size_t)mask | count) % WORD_SIZE == 0) XorWords((word *)output, (const word *)input, (const word *)mask, count/WORD_SIZE); else { diff --git a/external/ours/library/crypto/src/shared/original/misc.h b/external/ours/library/crypto/src/shared/original/misc.h index 8eb15e2e0..862970a96 100755 --- a/external/ours/library/crypto/src/shared/original/misc.h +++ b/external/ours/library/crypto/src/shared/original/misc.h @@ -15,39 +15,39 @@ NAMESPACE_BEGIN(CryptoPP) // ************** misc functions *************** -#define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255) +#define GETBYTE(x, y) (uint32_t)(((x)>>(8*(y)))&255) // this one may be faster on a Pentium // #define GETBYTE(x, y) (((byte *)&(x))[y]) -unsigned int Parity(unsigned long); -unsigned int BytePrecision(unsigned long); -unsigned int BitPrecision(unsigned long); -unsigned long Crop(unsigned long, unsigned int size); +uint32_t Parity(unsigned long); +uint32_t BytePrecision(unsigned long); +uint32_t BitPrecision(unsigned long); +unsigned long Crop(unsigned long, uint32_t size); -inline unsigned int bitsToBytes(unsigned int bitCount) +inline uint32_t bitsToBytes(uint32_t bitCount) { return ((bitCount+7)/(8)); } -inline unsigned int bytesToWords(unsigned int byteCount) +inline uint32_t bytesToWords(uint32_t byteCount) { return ((byteCount+WORD_SIZE-1)/WORD_SIZE); } -inline unsigned int bitsToWords(unsigned int bitCount) +inline uint32_t bitsToWords(uint32_t bitCount) { return ((bitCount+WORD_BITS-1)/(WORD_BITS)); } -void xorbuf(byte *buf, const byte *mask, unsigned int count); -void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count); +void xorbuf(byte *buf, const byte *mask, uint32_t count); +void xorbuf(byte *output, const byte *input, const byte *mask, uint32_t count); -inline unsigned int RoundDownToMultipleOf(unsigned int n, unsigned int m) +inline uint32_t RoundDownToMultipleOf(uint32_t n, uint32_t m) { return n - n%m; } -inline unsigned int RoundUpToMultipleOf(unsigned int n, unsigned int m) +inline uint32_t RoundUpToMultipleOf(uint32_t n, uint32_t m) { return RoundDownToMultipleOf(n+m-1, m); } @@ -91,37 +91,37 @@ std::string IntToString(T a) // ************** rotate functions *************** -template inline T rotlFixed(T x, unsigned int y) +template inline T rotlFixed(T x, uint32_t y) { assert(y < sizeof(T)*8); return (x<>(sizeof(T)*8-y)); } -template inline T rotrFixed(T x, unsigned int y) +template inline T rotrFixed(T x, uint32_t y) { assert(y < sizeof(T)*8); return (x>>y) | (x<<(sizeof(T)*8-y)); } -template inline T rotlVariable(T x, unsigned int y) +template inline T rotlVariable(T x, uint32_t y) { assert(y < sizeof(T)*8); return (x<>(sizeof(T)*8-y)); } -template inline T rotrVariable(T x, unsigned int y) +template inline T rotrVariable(T x, uint32_t y) { assert(y < sizeof(T)*8); return (x>>y) | (x<<(sizeof(T)*8-y)); } -template inline T rotlMod(T x, unsigned int y) +template inline T rotlMod(T x, uint32_t y) { y %= sizeof(T)*8; return (x<>(sizeof(T)*8-y)); } -template inline T rotrMod(T x, unsigned int y) +template inline T rotrMod(T x, uint32_t y) { y %= sizeof(T)*8; return (x>>y) | (x<<(sizeof(T)*8-y)); @@ -129,36 +129,36 @@ template inline T rotrMod(T x, unsigned int y) #ifdef INTEL_INTRINSICS -template<> inline word32 rotlFixed(word32 x, unsigned int y) +template<> inline word32 rotlFixed(word32 x, uint32_t y) { assert(y < 32); return y ? _lrotl(x, y) : x; } -template<> inline word32 rotrFixed(word32 x, unsigned int y) +template<> inline word32 rotrFixed(word32 x, uint32_t y) { assert(y < 32); return y ? _lrotr(x, y) : x; } -template<> inline word32 rotlVariable(word32 x, unsigned int y) +template<> inline word32 rotlVariable(word32 x, uint32_t y) { assert(y < 32); return _lrotl(x, y); } -template<> inline word32 rotrVariable(word32 x, unsigned int y) +template<> inline word32 rotrVariable(word32 x, uint32_t y) { assert(y < 32); return _lrotr(x, y); } -template<> inline word32 rotlMod(word32 x, unsigned int y) +template<> inline word32 rotlMod(word32 x, uint32_t y) { return _lrotl(x, y); } -template<> inline word32 rotrMod(word32 x, unsigned int y) +template<> inline word32 rotrMod(word32 x, uint32_t y) { return _lrotr(x, y); } @@ -167,36 +167,36 @@ template<> inline word32 rotrMod(word32 x, unsigned int y) #ifdef PPC_INTRINSICS -template<> inline word32 rotlFixed(word32 x, unsigned int y) +template<> inline word32 rotlFixed(word32 x, uint32_t y) { assert(y < 32); return y ? __rlwinm(x,y,0,31) : x; } -template<> inline word32 rotrFixed(word32 x, unsigned int y) +template<> inline word32 rotrFixed(word32 x, uint32_t y) { assert(y < 32); return y ? __rlwinm(x,32-y,0,31) : x; } -template<> inline word32 rotlVariable(word32 x, unsigned int y) +template<> inline word32 rotlVariable(word32 x, uint32_t y) { assert(y < 32); return (__rlwnm(x,y,0,31)); } -template<> inline word32 rotrVariable(word32 x, unsigned int y) +template<> inline word32 rotrVariable(word32 x, uint32_t y) { assert(y < 32); return (__rlwnm(x,32-y,0,31)); } -template<> inline word32 rotlMod(word32 x, unsigned int y) +template<> inline word32 rotlMod(word32 x, uint32_t y) { return (__rlwnm(x,y,0,31)); } -template<> inline word32 rotrMod(word32 x, unsigned int y) +template<> inline word32 rotrMod(word32 x, uint32_t y) { return (__rlwnm(x,32-y,0,31)); } @@ -297,17 +297,17 @@ inline T bitReverse(T value) } template -void byteReverse(T *out, const T *in, unsigned int byteCount) +void byteReverse(T *out, const T *in, uint32_t byteCount) { - unsigned int count = (byteCount+sizeof(T)-1)/sizeof(T); - for (unsigned int i=0; i -inline void GetUserKeyLittleEndian(T *out, unsigned int outlen, const byte *in, unsigned int inlen) +inline void GetUserKeyLittleEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) { - const unsigned int U = sizeof(T); + const uint32_t U = sizeof(T); assert(inlen <= outlen*U); memcpy(out, in, inlen); memset((byte *)out+inlen, 0, outlen*U-inlen); @@ -317,9 +317,9 @@ inline void GetUserKeyLittleEndian(T *out, unsigned int outlen, const byte *in, } template -inline void GetUserKeyBigEndian(T *out, unsigned int outlen, const byte *in, unsigned int inlen) +inline void GetUserKeyBigEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) { - const unsigned int U = sizeof(T); + const uint32_t U = sizeof(T); assert(inlen <= outlen*U); memcpy(out, in, inlen); memset((byte *)out+inlen, 0, outlen*U-inlen); @@ -468,23 +468,23 @@ T StringToWord(const std::string &str, bool highFirst = true) // ************** key length query *************** /// support query of fixed key length -template +template class FixedKeyLength { public: enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N}; /// returns the key length - static unsigned int KeyLength(unsigned int) {return KEYLENGTH;} + static uint32_t KeyLength(uint32_t) {return KEYLENGTH;} }; /// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) -template +template class VariableKeyLength { public: enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q}; /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) - static unsigned int KeyLength(unsigned int n) + static uint32_t KeyLength(uint32_t n) { assert(KEYLENGTH_MULTIPLE > 0 && MIN_KEYLENGTH % KEYLENGTH_MULTIPLE == 0 && MAX_KEYLENGTH % KEYLENGTH_MULTIPLE == 0); if (n < MIN_KEYLENGTH) @@ -503,7 +503,7 @@ class SameKeyLengthAs public: enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH}; /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) - static unsigned int KeyLength(unsigned int keylength) + static uint32_t KeyLength(uint32_t keylength) {return T::KeyLength(keylength);} }; @@ -520,11 +520,11 @@ class SameKeyLengthAs //! a block of memory allocated using SecAlloc template struct SecBlock { - explicit SecBlock(unsigned int size=0) + explicit SecBlock(uint32_t size=0) : size(size) {ptr = SecAlloc(T, size);} SecBlock(const SecBlock &t) : size(t.size) {ptr = SecAlloc(T, size); memcpy(ptr, t.ptr, size*sizeof(T));} - SecBlock(const T *t, unsigned int len) + SecBlock(const T *t, uint32_t len) : size(len) {ptr = SecAlloc(T, len); memcpy(ptr, t, len*sizeof(T));} ~SecBlock() {SecFree(ptr, size);} @@ -551,13 +551,13 @@ template struct SecBlock // CodeWarrior defines _MSC_VER #if !defined(_MSC_VER) || defined(__MWERKS__) - T *operator +(unsigned int offset) + T *operator +(uint32_t offset) {return ptr+offset;} - const T *operator +(unsigned int offset) const + const T *operator +(uint32_t offset) const {return ptr+offset;} - T& operator[](unsigned int index) + T& operator[](uint32_t index) {assert(index struct SecBlock T* End() {return ptr+size;} - unsigned int Size() const {return size;} + uint32_t Size() const {return size;} - void Assign(const T *t, unsigned int len) + void Assign(const T *t, uint32_t len) { New(len); memcpy(ptr, t, len*sizeof(T)); @@ -600,7 +600,7 @@ template struct SecBlock return !operator==(t); } - void New(unsigned int newSize) + void New(uint32_t newSize) { if (newSize != size) { @@ -611,7 +611,7 @@ template struct SecBlock } } - void CleanNew(unsigned int newSize) + void CleanNew(uint32_t newSize) { if (newSize != size) { @@ -623,7 +623,7 @@ template struct SecBlock memset(ptr, 0, size*sizeof(T)); } - void Grow(unsigned int newSize) + void Grow(uint32_t newSize) { if (newSize > size) { @@ -635,7 +635,7 @@ template struct SecBlock } } - void CleanGrow(unsigned int newSize) + void CleanGrow(uint32_t newSize) { if (newSize > size) { @@ -648,7 +648,7 @@ template struct SecBlock } } - void Resize(unsigned int newSize) + void Resize(uint32_t newSize) { if (newSize != size) { @@ -662,7 +662,7 @@ template struct SecBlock void swap(SecBlock &b); - unsigned int size; + uint32_t size; T *ptr; }; From 0139fd830ac30d0ff2ad3d04366b55fee465a59b Mon Sep 17 00:00:00 2001 From: Cekis Date: Fri, 29 Oct 2021 16:39:28 -0400 Subject: [PATCH 02/46] Added Crypto++ v8.6 - does not yet build as a whole --- cmake/linux/FindOracle.cmake | 30 - .../crypto/src/shared/original-old/config.h | 165 + .../src/shared/original-old/cryptlib.cpp | 488 ++ .../crypto/src/shared/original-old/cryptlib.h | 818 +++ .../src/shared/original-old/filters.cpp | 424 ++ .../crypto/src/shared/original-old/filters.h | 560 ++ .../src/shared/original-old/iterhash.cpp | 14 + .../crypto/src/shared/original-old/iterhash.h | 187 + .../crypto/src/shared/original-old/md5.cpp | 109 + .../crypto/src/shared/original-old/md5.h | 24 + .../crypto/src/shared/original-old/misc.cpp | 77 + .../crypto/src/shared/original-old/misc.h | 689 +++ .../crypto/src/shared/original-old/mqueue.cpp | 44 + .../crypto/src/shared/original-old/mqueue.h | 61 + .../crypto/src/shared/original-old/queue.cpp | 500 ++ .../crypto/src/shared/original-old/queue.h | 128 + .../crypto/src/shared/original-old/smartptr.h | 195 + .../src/shared/original-old/tftables.cpp | 317 ++ .../src/shared/original-old/twofish.cpp | 166 + .../crypto/src/shared/original-old/twofish.h | 53 + .../crypto/src/shared/original-old/words.h | 103 + .../crypto/src/shared/original/3way.cpp | 143 + .../library/crypto/src/shared/original/3way.h | 63 + .../crypto/src/shared/original/GNUmakefile | 1795 ++++++ .../src/shared/original/GNUmakefile-cross | 1060 ++++ .../crypto/src/shared/original/adhoc.cpp | 42 + .../crypto/src/shared/original/adler32.cpp | 82 + .../crypto/src/shared/original/adler32.h | 33 + .../crypto/src/shared/original/adv_simd.h | 1281 +++++ .../library/crypto/src/shared/original/aes.h | 30 + .../crypto/src/shared/original/aes_armv4.h | 30 + .../crypto/src/shared/original/algebra.cpp | 341 ++ .../crypto/src/shared/original/algebra.h | 453 ++ .../crypto/src/shared/original/algparam.cpp | 75 + .../crypto/src/shared/original/algparam.h | 520 ++ .../crypto/src/shared/original/allocate.cpp | 107 + .../crypto/src/shared/original/allocate.h | 74 + .../crypto/src/shared/original/arc4.cpp | 122 + .../library/crypto/src/shared/original/arc4.h | 89 + .../crypto/src/shared/original/argnames.h | 99 + .../crypto/src/shared/original/aria.cpp | 343 ++ .../library/crypto/src/shared/original/aria.h | 71 + .../crypto/src/shared/original/aria_simd.cpp | 194 + .../crypto/src/shared/original/ariatab.cpp | 166 + .../crypto/src/shared/original/arm_simd.h | 449 ++ .../crypto/src/shared/original/asn.cpp | 717 +++ .../library/crypto/src/shared/original/asn.h | 965 ++++ .../crypto/src/shared/original/authenc.cpp | 188 + .../crypto/src/shared/original/authenc.h | 87 + .../crypto/src/shared/original/base32.cpp | 97 + .../crypto/src/shared/original/base32.h | 158 + .../crypto/src/shared/original/base64.cpp | 111 + .../crypto/src/shared/original/base64.h | 158 + .../crypto/src/shared/original/basecode.cpp | 247 + .../crypto/src/shared/original/basecode.h | 146 + .../crypto/src/shared/original/bench.h | 105 + .../crypto/src/shared/original/bench1.cpp | 520 ++ .../crypto/src/shared/original/bench2.cpp | 267 + .../crypto/src/shared/original/bench3.cpp | 480 ++ .../crypto/src/shared/original/bfinit.cpp | 277 + .../crypto/src/shared/original/blake2.cpp | 797 +++ .../crypto/src/shared/original/blake2.h | 444 ++ .../src/shared/original/blake2b_simd.cpp | 1276 +++++ .../src/shared/original/blake2s_simd.cpp | 1091 ++++ .../crypto/src/shared/original/blowfish.cpp | 99 + .../crypto/src/shared/original/blowfish.h | 54 + .../crypto/src/shared/original/blumshub.cpp | 64 + .../crypto/src/shared/original/blumshub.h | 70 + .../crypto/src/shared/original/camellia.cpp | 539 ++ .../crypto/src/shared/original/camellia.h | 49 + .../crypto/src/shared/original/cast.cpp | 292 + .../library/crypto/src/shared/original/cast.h | 109 + .../crypto/src/shared/original/casts.cpp | 545 ++ .../crypto/src/shared/original/cbcmac.cpp | 62 + .../crypto/src/shared/original/cbcmac.h | 63 + .../crypto/src/shared/original/ccm.cpp | 139 + .../library/crypto/src/shared/original/ccm.h | 123 + .../crypto/src/shared/original/chacha.cpp | 568 ++ .../crypto/src/shared/original/chacha.h | 223 + .../crypto/src/shared/original/chacha_avx.cpp | 422 ++ .../src/shared/original/chacha_simd.cpp | 1109 ++++ .../crypto/src/shared/original/chachapoly.cpp | 211 + .../crypto/src/shared/original/chachapoly.h | 322 ++ .../crypto/src/shared/original/cham.cpp | 365 ++ .../library/crypto/src/shared/original/cham.h | 179 + .../crypto/src/shared/original/cham_simd.cpp | 478 ++ .../crypto/src/shared/original/channels.cpp | 316 ++ .../crypto/src/shared/original/channels.h | 142 + .../crypto/src/shared/original/cmac.cpp | 164 + .../library/crypto/src/shared/original/cmac.h | 76 + .../crypto/src/shared/original/config.h | 198 +- .../crypto/src/shared/original/config_align.h | 72 + .../crypto/src/shared/original/config_asm.h | 480 ++ .../crypto/src/shared/original/config_cpu.h | 211 + .../crypto/src/shared/original/config_cxx.h | 247 + .../crypto/src/shared/original/config_dll.h | 178 + .../crypto/src/shared/original/config_int.h | 253 + .../crypto/src/shared/original/config_misc.h | 194 + .../crypto/src/shared/original/config_ns.h | 76 + .../crypto/src/shared/original/config_os.h | 169 + .../crypto/src/shared/original/config_ver.h | 90 + .../crypto/src/shared/original/cpu.cpp | 1459 +++++ .../library/crypto/src/shared/original/cpu.h | 1085 ++++ .../crypto/src/shared/original/crc.cpp | 367 ++ .../library/crypto/src/shared/original/crc.h | 78 + .../crypto/src/shared/original/crc_simd.cpp | 172 + .../crypto/src/shared/original/cryptest.nmake | 363 ++ .../crypto/src/shared/original/cryptlib.cpp | 1542 ++++-- .../crypto/src/shared/original/cryptlib.h | 4197 +++++++++++--- .../crypto/src/shared/original/darn.cpp | 236 + .../library/crypto/src/shared/original/darn.h | 95 + .../crypto/src/shared/original/datatest.cpp | 1358 +++++ .../crypto/src/shared/original/default.cpp | 307 ++ .../crypto/src/shared/original/default.h | 310 ++ .../crypto/src/shared/original/des.cpp | 465 ++ .../library/crypto/src/shared/original/des.h | 163 + .../crypto/src/shared/original/dessp.cpp | 88 + .../library/crypto/src/shared/original/dh.cpp | 21 + .../library/crypto/src/shared/original/dh.h | 275 + .../crypto/src/shared/original/dh2.cpp | 69 + .../library/crypto/src/shared/original/dh2.h | 70 + .../crypto/src/shared/original/dll.cpp | 169 + .../library/crypto/src/shared/original/dll.h | 71 + .../crypto/src/shared/original/dlltest.cpp | 212 + .../library/crypto/src/shared/original/dmac.h | 114 + .../crypto/src/shared/original/donna.h | 178 + .../crypto/src/shared/original/donna_32.cpp | 2102 +++++++ .../crypto/src/shared/original/donna_32.h | 411 ++ .../crypto/src/shared/original/donna_64.cpp | 1815 ++++++ .../crypto/src/shared/original/donna_64.h | 457 ++ .../crypto/src/shared/original/donna_sse.cpp | 1123 ++++ .../crypto/src/shared/original/donna_sse.h | 86 + .../library/crypto/src/shared/original/drbg.h | 718 +++ .../crypto/src/shared/original/dsa.cpp | 66 + .../library/crypto/src/shared/original/dsa.h | 53 + .../crypto/src/shared/original/eax.cpp | 59 + .../library/crypto/src/shared/original/eax.h | 112 + .../crypto/src/shared/original/ec2n.cpp | 320 ++ .../library/crypto/src/shared/original/ec2n.h | 136 + .../crypto/src/shared/original/eccrypto.cpp | 840 +++ .../crypto/src/shared/original/eccrypto.h | 686 +++ .../crypto/src/shared/original/ecp.cpp | 506 ++ .../library/crypto/src/shared/original/ecp.h | 167 + .../crypto/src/shared/original/ecpoint.h | 146 + .../crypto/src/shared/original/elgamal.cpp | 22 + .../crypto/src/shared/original/elgamal.h | 308 ++ .../crypto/src/shared/original/emsa2.cpp | 44 + .../crypto/src/shared/original/emsa2.h | 101 + .../crypto/src/shared/original/eprecomp.cpp | 114 + .../crypto/src/shared/original/eprecomp.h | 162 + .../crypto/src/shared/original/esign.cpp | 233 + .../crypto/src/shared/original/esign.h | 169 + .../crypto/src/shared/original/factory.h | 179 + .../crypto/src/shared/original/fhmqv.h | 408 ++ .../crypto/src/shared/original/files.cpp | 300 + .../crypto/src/shared/original/files.h | 181 + .../crypto/src/shared/original/filters.cpp | 1694 ++++-- .../crypto/src/shared/original/filters.h | 2089 +++++-- .../crypto/src/shared/original/fips140.cpp | 84 + .../crypto/src/shared/original/fips140.h | 112 + .../crypto/src/shared/original/fipsalgt.cpp | 1293 +++++ .../crypto/src/shared/original/fipstest.cpp | 652 +++ .../crypto/src/shared/original/fltrimpl.h | 87 + .../crypto/src/shared/original/gcm.cpp | 852 +++ .../library/crypto/src/shared/original/gcm.h | 139 + .../crypto/src/shared/original/gcm_simd.cpp | 734 +++ .../crypto/src/shared/original/gf256.cpp | 34 + .../crypto/src/shared/original/gf256.h | 72 + .../crypto/src/shared/original/gf2_32.cpp | 99 + .../crypto/src/shared/original/gf2_32.h | 73 + .../crypto/src/shared/original/gf2n.cpp | 1070 ++++ .../library/crypto/src/shared/original/gf2n.h | 404 ++ .../crypto/src/shared/original/gf2n_simd.cpp | 614 +++ .../crypto/src/shared/original/gfpcrypt.cpp | 334 ++ .../crypto/src/shared/original/gfpcrypt.h | 1036 ++++ .../crypto/src/shared/original/gost.cpp | 123 + .../library/crypto/src/shared/original/gost.h | 66 + .../crypto/src/shared/original/gzip.cpp | 208 + .../library/crypto/src/shared/original/gzip.h | 144 + .../crypto/src/shared/original/hashfwd.h | 38 + .../crypto/src/shared/original/hc128.cpp | 279 + .../crypto/src/shared/original/hc128.h | 67 + .../crypto/src/shared/original/hc256.cpp | 158 + .../crypto/src/shared/original/hc256.h | 67 + .../crypto/src/shared/original/hex.cpp | 58 + .../library/crypto/src/shared/original/hex.h | 50 + .../crypto/src/shared/original/hight.cpp | 271 + .../crypto/src/shared/original/hight.h | 81 + .../library/crypto/src/shared/original/hkdf.h | 179 + .../crypto/src/shared/original/hmac.cpp | 90 + .../library/crypto/src/shared/original/hmac.h | 80 + .../library/crypto/src/shared/original/hmqv.h | 417 ++ .../crypto/src/shared/original/hrtimer.cpp | 174 + .../crypto/src/shared/original/hrtimer.h | 134 + .../crypto/src/shared/original/ida.cpp | 418 ++ .../library/crypto/src/shared/original/ida.h | 182 + .../crypto/src/shared/original/idea.cpp | 191 + .../library/crypto/src/shared/original/idea.h | 66 + .../crypto/src/shared/original/integer.cpp | 4910 +++++++++++++++++ .../crypto/src/shared/original/integer.h | 837 +++ .../crypto/src/shared/original/iterhash.cpp | 214 +- .../crypto/src/shared/original/iterhash.h | 405 +- .../crypto/src/shared/original/kalyna.cpp | 1362 +++++ .../crypto/src/shared/original/kalyna.h | 218 + .../crypto/src/shared/original/kalynatab.cpp | 1232 +++++ .../crypto/src/shared/original/keccak.cpp | 67 + .../crypto/src/shared/original/keccak.h | 118 + .../src/shared/original/keccak_core.cpp | 261 + .../src/shared/original/keccak_simd.cpp | 2681 +++++++++ .../crypto/src/shared/original/lea.cpp | 899 +++ .../library/crypto/src/shared/original/lea.h | 108 + .../crypto/src/shared/original/lea_simd.cpp | 1072 ++++ .../library/crypto/src/shared/original/lsh.h | 262 + .../crypto/src/shared/original/lsh256.cpp | 817 +++ .../crypto/src/shared/original/lsh256_avx.cpp | 648 +++ .../crypto/src/shared/original/lsh256_sse.cpp | 710 +++ .../crypto/src/shared/original/lsh512.cpp | 893 +++ .../crypto/src/shared/original/lsh512_avx.cpp | 760 +++ .../crypto/src/shared/original/lsh512_sse.cpp | 938 ++++ .../crypto/src/shared/original/lubyrack.h | 137 + .../crypto/src/shared/original/luc.cpp | 231 + .../library/crypto/src/shared/original/luc.h | 338 ++ .../crypto/src/shared/original/mars.cpp | 154 + .../library/crypto/src/shared/original/mars.h | 60 + .../crypto/src/shared/original/marss.cpp | 140 + .../crypto/src/shared/original/md2.cpp | 120 + .../library/crypto/src/shared/original/md2.h | 56 + .../crypto/src/shared/original/md4.cpp | 110 + .../library/crypto/src/shared/original/md4.h | 35 + .../crypto/src/shared/original/md5.cpp | 233 +- .../library/crypto/src/shared/original/md5.h | 59 +- .../library/crypto/src/shared/original/mdc.h | 84 + .../crypto/src/shared/original/mersenne.h | 231 + .../crypto/src/shared/original/misc.cpp | 471 +- .../library/crypto/src/shared/original/misc.h | 3465 +++++++++--- .../crypto/src/shared/original/modarith.h | 344 ++ .../crypto/src/shared/original/modes.cpp | 306 + .../crypto/src/shared/original/modes.h | 609 ++ .../crypto/src/shared/original/modexppc.h | 48 + .../crypto/src/shared/original/mqueue.cpp | 219 +- .../crypto/src/shared/original/mqueue.h | 206 +- .../crypto/src/shared/original/mqv.cpp | 46 + .../library/crypto/src/shared/original/mqv.h | 268 + .../crypto/src/shared/original/naclite.h | 438 ++ .../crypto/src/shared/original/nbtheory.cpp | 1141 ++++ .../crypto/src/shared/original/nbtheory.h | 317 ++ .../crypto/src/shared/original/neon_simd.cpp | 197 + .../library/crypto/src/shared/original/nr.h | 11 + .../crypto/src/shared/original/oaep.cpp | 98 + .../library/crypto/src/shared/original/oaep.h | 54 + .../library/crypto/src/shared/original/oids.h | 197 + .../crypto/src/shared/original/osrng.cpp | 300 + .../crypto/src/shared/original/osrng.h | 304 + .../crypto/src/shared/original/ossig.h | 128 + .../crypto/src/shared/original/padlkrng.cpp | 105 + .../crypto/src/shared/original/padlkrng.h | 138 + .../crypto/src/shared/original/panama.cpp | 533 ++ .../crypto/src/shared/original/panama.h | 169 + .../crypto/src/shared/original/pch.cpp | 1 + .../library/crypto/src/shared/original/pch.h | 31 + .../crypto/src/shared/original/pkcspad.cpp | 160 + .../crypto/src/shared/original/pkcspad.h | 123 + .../crypto/src/shared/original/poly1305.cpp | 403 ++ .../crypto/src/shared/original/poly1305.h | 241 + .../crypto/src/shared/original/polynomi.cpp | 577 ++ .../crypto/src/shared/original/polynomi.h | 463 ++ .../crypto/src/shared/original/ppc_power7.cpp | 93 + .../crypto/src/shared/original/ppc_power8.cpp | 246 + .../crypto/src/shared/original/ppc_power9.cpp | 136 + .../crypto/src/shared/original/ppc_simd.cpp | 96 + .../crypto/src/shared/original/ppc_simd.h | 2764 ++++++++++ .../crypto/src/shared/original/pssr.cpp | 163 + .../library/crypto/src/shared/original/pssr.h | 105 + .../crypto/src/shared/original/pubkey.cpp | 170 + .../crypto/src/shared/original/pubkey.h | 2378 ++++++++ .../crypto/src/shared/original/pwdbased.h | 481 ++ .../crypto/src/shared/original/queue.cpp | 1101 ++-- .../crypto/src/shared/original/queue.h | 400 +- .../crypto/src/shared/original/rabbit.cpp | 259 + .../crypto/src/shared/original/rabbit.h | 112 + .../crypto/src/shared/original/rabin.cpp | 241 + .../crypto/src/shared/original/rabin.h | 135 + .../crypto/src/shared/original/randpool.cpp | 174 + .../crypto/src/shared/original/randpool.h | 104 + .../crypto/src/shared/original/rc2.cpp | 118 + .../library/crypto/src/shared/original/rc2.h | 90 + .../crypto/src/shared/original/rc5.cpp | 80 + .../library/crypto/src/shared/original/rc5.h | 59 + .../crypto/src/shared/original/rc6.cpp | 96 + .../library/crypto/src/shared/original/rc6.h | 60 + .../crypto/src/shared/original/rdrand.cpp | 327 ++ .../crypto/src/shared/original/rdrand.h | 145 + .../crypto/src/shared/original/rdtables.cpp | 166 + .../crypto/src/shared/original/regtest1.cpp | 160 + .../crypto/src/shared/original/regtest2.cpp | 105 + .../crypto/src/shared/original/regtest3.cpp | 156 + .../crypto/src/shared/original/regtest4.cpp | 58 + .../crypto/src/shared/original/resource.h | 15 + .../crypto/src/shared/original/rijndael.cpp | 1334 +++++ .../crypto/src/shared/original/rijndael.h | 109 + .../src/shared/original/rijndael_simd.cpp | 734 +++ .../crypto/src/shared/original/ripemd.cpp | 803 +++ .../crypto/src/shared/original/ripemd.h | 65 + .../crypto/src/shared/original/rng.cpp | 166 + .../library/crypto/src/shared/original/rng.h | 111 + .../crypto/src/shared/original/rsa.cpp | 330 ++ .../library/crypto/src/shared/original/rsa.h | 263 + .../library/crypto/src/shared/original/rw.cpp | 314 ++ .../library/crypto/src/shared/original/rw.h | 146 + .../crypto/src/shared/original/safer.cpp | 157 + .../crypto/src/shared/original/safer.h | 98 + .../crypto/src/shared/original/salsa.cpp | 759 +++ .../crypto/src/shared/original/salsa.h | 104 + .../crypto/src/shared/original/scrypt.cpp | 329 ++ .../crypto/src/shared/original/scrypt.h | 103 + .../crypto/src/shared/original/seal.cpp | 222 + .../library/crypto/src/shared/original/seal.h | 59 + .../crypto/src/shared/original/secblock.h | 1310 +++++ .../crypto/src/shared/original/secblockfwd.h | 29 + .../crypto/src/shared/original/seckey.h | 444 ++ .../crypto/src/shared/original/seed.cpp | 113 + .../library/crypto/src/shared/original/seed.h | 44 + .../crypto/src/shared/original/serpent.cpp | 125 + .../crypto/src/shared/original/serpent.h | 72 + .../crypto/src/shared/original/serpentp.h | 439 ++ .../crypto/src/shared/original/sha.cpp | 1414 +++++ .../library/crypto/src/shared/original/sha.h | 210 + .../crypto/src/shared/original/sha1_armv4.h | 23 + .../crypto/src/shared/original/sha256_armv4.h | 23 + .../crypto/src/shared/original/sha3.cpp | 71 + .../library/crypto/src/shared/original/sha3.h | 106 + .../crypto/src/shared/original/sha512_armv4.h | 23 + .../crypto/src/shared/original/sha_simd.cpp | 1506 +++++ .../crypto/src/shared/original/shacal2.cpp | 172 + .../crypto/src/shared/original/shacal2.h | 66 + .../src/shared/original/shacal2_simd.cpp | 94 + .../crypto/src/shared/original/shake.cpp | 85 + .../crypto/src/shared/original/shake.h | 161 + .../crypto/src/shared/original/shark.cpp | 163 + .../crypto/src/shared/original/shark.h | 77 + .../crypto/src/shared/original/sharkbox.cpp | 4166 ++++++++++++++ .../crypto/src/shared/original/simeck.cpp | 154 + .../crypto/src/shared/original/simeck.h | 162 + .../crypto/src/shared/original/simon.cpp | 505 ++ .../crypto/src/shared/original/simon.h | 206 + .../src/shared/original/simon128_simd.cpp | 862 +++ .../crypto/src/shared/original/simple.cpp | 13 + .../crypto/src/shared/original/simple.h | 506 ++ .../crypto/src/shared/original/siphash.h | 313 ++ .../crypto/src/shared/original/skipjack.cpp | 202 + .../crypto/src/shared/original/skipjack.h | 80 + .../crypto/src/shared/original/sm3.cpp | 255 + .../library/crypto/src/shared/original/sm3.h | 61 + .../crypto/src/shared/original/sm4.cpp | 212 + .../library/crypto/src/shared/original/sm4.h | 96 + .../crypto/src/shared/original/sm4_simd.cpp | 323 ++ .../crypto/src/shared/original/smartptr.h | 452 +- .../crypto/src/shared/original/sosemanuk.cpp | 728 +++ .../crypto/src/shared/original/sosemanuk.h | 62 + .../crypto/src/shared/original/speck.cpp | 487 ++ .../crypto/src/shared/original/speck.h | 206 + .../src/shared/original/speck128_simd.cpp | 754 +++ .../crypto/src/shared/original/square.cpp | 187 + .../crypto/src/shared/original/square.h | 63 + .../crypto/src/shared/original/squaretb.cpp | 582 ++ .../crypto/src/shared/original/sse_simd.cpp | 115 + .../crypto/src/shared/original/stdcpp.h | 101 + .../crypto/src/shared/original/strciphr.cpp | 328 ++ .../crypto/src/shared/original/strciphr.h | 728 +++ .../crypto/src/shared/original/tea.cpp | 165 + .../library/crypto/src/shared/original/tea.h | 161 + .../crypto/src/shared/original/test.cpp | 1095 ++++ .../crypto/src/shared/original/tftables.cpp | 640 +-- .../crypto/src/shared/original/threefish.cpp | 503 ++ .../crypto/src/shared/original/threefish.h | 201 + .../crypto/src/shared/original/tiger.cpp | 282 + .../crypto/src/shared/original/tiger.h | 61 + .../crypto/src/shared/original/tigertab.cpp | 525 ++ .../library/crypto/src/shared/original/trap.h | 163 + .../crypto/src/shared/original/trunhash.h | 63 + .../crypto/src/shared/original/ttmac.cpp | 348 ++ .../crypto/src/shared/original/ttmac.h | 44 + .../crypto/src/shared/original/tweetnacl.cpp | 924 ++++ .../crypto/src/shared/original/tweetnacl.h | 281 + .../crypto/src/shared/original/twofish.cpp | 337 +- .../crypto/src/shared/original/twofish.h | 117 +- .../crypto/src/shared/original/validat0.cpp | 1669 ++++++ .../crypto/src/shared/original/validat1.cpp | 1225 ++++ .../crypto/src/shared/original/validat10.cpp | 535 ++ .../crypto/src/shared/original/validat2.cpp | 1270 +++++ .../crypto/src/shared/original/validat3.cpp | 1341 +++++ .../crypto/src/shared/original/validat4.cpp | 1813 ++++++ .../crypto/src/shared/original/validat5.cpp | 2225 ++++++++ .../crypto/src/shared/original/validat6.cpp | 408 ++ .../crypto/src/shared/original/validat7.cpp | 705 +++ .../crypto/src/shared/original/validat8.cpp | 624 +++ .../crypto/src/shared/original/validat9.cpp | 704 +++ .../crypto/src/shared/original/validate.h | 395 ++ .../crypto/src/shared/original/vmac.cpp | 894 +++ .../library/crypto/src/shared/original/vmac.h | 91 + .../crypto/src/shared/original/wake.cpp | 111 + .../library/crypto/src/shared/original/wake.h | 59 + .../crypto/src/shared/original/whrlpool.cpp | 730 +++ .../crypto/src/shared/original/whrlpool.h | 42 + .../crypto/src/shared/original/words.h | 328 +- .../crypto/src/shared/original/xed25519.cpp | 900 +++ .../crypto/src/shared/original/xed25519.h | 825 +++ .../crypto/src/shared/original/xtr.cpp | 120 + .../library/crypto/src/shared/original/xtr.h | 219 + .../crypto/src/shared/original/xtrcrypt.cpp | 122 + .../crypto/src/shared/original/xtrcrypt.h | 55 + .../crypto/src/shared/original/xts.cpp | 512 ++ .../library/crypto/src/shared/original/xts.h | 224 + .../crypto/src/shared/original/zdeflate.cpp | 821 +++ .../crypto/src/shared/original/zdeflate.h | 174 + .../crypto/src/shared/original/zinflate.cpp | 662 +++ .../crypto/src/shared/original/zinflate.h | 164 + .../crypto/src/shared/original/zlib.cpp | 93 + .../library/crypto/src/shared/original/zlib.h | 65 + 419 files changed, 161469 insertions(+), 5152 deletions(-) create mode 100755 external/ours/library/crypto/src/shared/original-old/config.h create mode 100755 external/ours/library/crypto/src/shared/original-old/cryptlib.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/cryptlib.h create mode 100755 external/ours/library/crypto/src/shared/original-old/filters.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/filters.h create mode 100755 external/ours/library/crypto/src/shared/original-old/iterhash.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/iterhash.h create mode 100755 external/ours/library/crypto/src/shared/original-old/md5.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/md5.h create mode 100755 external/ours/library/crypto/src/shared/original-old/misc.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/misc.h create mode 100755 external/ours/library/crypto/src/shared/original-old/mqueue.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/mqueue.h create mode 100755 external/ours/library/crypto/src/shared/original-old/queue.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/queue.h create mode 100755 external/ours/library/crypto/src/shared/original-old/smartptr.h create mode 100755 external/ours/library/crypto/src/shared/original-old/tftables.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/twofish.cpp create mode 100755 external/ours/library/crypto/src/shared/original-old/twofish.h create mode 100755 external/ours/library/crypto/src/shared/original-old/words.h create mode 100755 external/ours/library/crypto/src/shared/original/3way.cpp create mode 100755 external/ours/library/crypto/src/shared/original/3way.h create mode 100755 external/ours/library/crypto/src/shared/original/GNUmakefile create mode 100755 external/ours/library/crypto/src/shared/original/GNUmakefile-cross create mode 100755 external/ours/library/crypto/src/shared/original/adhoc.cpp create mode 100755 external/ours/library/crypto/src/shared/original/adler32.cpp create mode 100755 external/ours/library/crypto/src/shared/original/adler32.h create mode 100755 external/ours/library/crypto/src/shared/original/adv_simd.h create mode 100755 external/ours/library/crypto/src/shared/original/aes.h create mode 100755 external/ours/library/crypto/src/shared/original/aes_armv4.h create mode 100755 external/ours/library/crypto/src/shared/original/algebra.cpp create mode 100755 external/ours/library/crypto/src/shared/original/algebra.h create mode 100755 external/ours/library/crypto/src/shared/original/algparam.cpp create mode 100755 external/ours/library/crypto/src/shared/original/algparam.h create mode 100755 external/ours/library/crypto/src/shared/original/allocate.cpp create mode 100755 external/ours/library/crypto/src/shared/original/allocate.h create mode 100755 external/ours/library/crypto/src/shared/original/arc4.cpp create mode 100755 external/ours/library/crypto/src/shared/original/arc4.h create mode 100755 external/ours/library/crypto/src/shared/original/argnames.h create mode 100755 external/ours/library/crypto/src/shared/original/aria.cpp create mode 100755 external/ours/library/crypto/src/shared/original/aria.h create mode 100755 external/ours/library/crypto/src/shared/original/aria_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ariatab.cpp create mode 100755 external/ours/library/crypto/src/shared/original/arm_simd.h create mode 100755 external/ours/library/crypto/src/shared/original/asn.cpp create mode 100755 external/ours/library/crypto/src/shared/original/asn.h create mode 100755 external/ours/library/crypto/src/shared/original/authenc.cpp create mode 100755 external/ours/library/crypto/src/shared/original/authenc.h create mode 100755 external/ours/library/crypto/src/shared/original/base32.cpp create mode 100755 external/ours/library/crypto/src/shared/original/base32.h create mode 100755 external/ours/library/crypto/src/shared/original/base64.cpp create mode 100755 external/ours/library/crypto/src/shared/original/base64.h create mode 100755 external/ours/library/crypto/src/shared/original/basecode.cpp create mode 100755 external/ours/library/crypto/src/shared/original/basecode.h create mode 100755 external/ours/library/crypto/src/shared/original/bench.h create mode 100755 external/ours/library/crypto/src/shared/original/bench1.cpp create mode 100755 external/ours/library/crypto/src/shared/original/bench2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/bench3.cpp create mode 100755 external/ours/library/crypto/src/shared/original/bfinit.cpp create mode 100755 external/ours/library/crypto/src/shared/original/blake2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/blake2.h create mode 100755 external/ours/library/crypto/src/shared/original/blake2b_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/blake2s_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/blowfish.cpp create mode 100755 external/ours/library/crypto/src/shared/original/blowfish.h create mode 100755 external/ours/library/crypto/src/shared/original/blumshub.cpp create mode 100755 external/ours/library/crypto/src/shared/original/blumshub.h create mode 100755 external/ours/library/crypto/src/shared/original/camellia.cpp create mode 100755 external/ours/library/crypto/src/shared/original/camellia.h create mode 100755 external/ours/library/crypto/src/shared/original/cast.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cast.h create mode 100755 external/ours/library/crypto/src/shared/original/casts.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cbcmac.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cbcmac.h create mode 100755 external/ours/library/crypto/src/shared/original/ccm.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ccm.h create mode 100755 external/ours/library/crypto/src/shared/original/chacha.cpp create mode 100755 external/ours/library/crypto/src/shared/original/chacha.h create mode 100755 external/ours/library/crypto/src/shared/original/chacha_avx.cpp create mode 100755 external/ours/library/crypto/src/shared/original/chacha_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/chachapoly.cpp create mode 100755 external/ours/library/crypto/src/shared/original/chachapoly.h create mode 100755 external/ours/library/crypto/src/shared/original/cham.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cham.h create mode 100755 external/ours/library/crypto/src/shared/original/cham_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/channels.cpp create mode 100755 external/ours/library/crypto/src/shared/original/channels.h create mode 100755 external/ours/library/crypto/src/shared/original/cmac.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cmac.h create mode 100755 external/ours/library/crypto/src/shared/original/config_align.h create mode 100755 external/ours/library/crypto/src/shared/original/config_asm.h create mode 100755 external/ours/library/crypto/src/shared/original/config_cpu.h create mode 100755 external/ours/library/crypto/src/shared/original/config_cxx.h create mode 100755 external/ours/library/crypto/src/shared/original/config_dll.h create mode 100755 external/ours/library/crypto/src/shared/original/config_int.h create mode 100755 external/ours/library/crypto/src/shared/original/config_misc.h create mode 100755 external/ours/library/crypto/src/shared/original/config_ns.h create mode 100755 external/ours/library/crypto/src/shared/original/config_os.h create mode 100755 external/ours/library/crypto/src/shared/original/config_ver.h create mode 100755 external/ours/library/crypto/src/shared/original/cpu.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cpu.h create mode 100755 external/ours/library/crypto/src/shared/original/crc.cpp create mode 100755 external/ours/library/crypto/src/shared/original/crc.h create mode 100755 external/ours/library/crypto/src/shared/original/crc_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/cryptest.nmake create mode 100755 external/ours/library/crypto/src/shared/original/darn.cpp create mode 100755 external/ours/library/crypto/src/shared/original/darn.h create mode 100755 external/ours/library/crypto/src/shared/original/datatest.cpp create mode 100755 external/ours/library/crypto/src/shared/original/default.cpp create mode 100755 external/ours/library/crypto/src/shared/original/default.h create mode 100755 external/ours/library/crypto/src/shared/original/des.cpp create mode 100755 external/ours/library/crypto/src/shared/original/des.h create mode 100755 external/ours/library/crypto/src/shared/original/dessp.cpp create mode 100755 external/ours/library/crypto/src/shared/original/dh.cpp create mode 100755 external/ours/library/crypto/src/shared/original/dh.h create mode 100755 external/ours/library/crypto/src/shared/original/dh2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/dh2.h create mode 100755 external/ours/library/crypto/src/shared/original/dll.cpp create mode 100755 external/ours/library/crypto/src/shared/original/dll.h create mode 100755 external/ours/library/crypto/src/shared/original/dlltest.cpp create mode 100755 external/ours/library/crypto/src/shared/original/dmac.h create mode 100755 external/ours/library/crypto/src/shared/original/donna.h create mode 100755 external/ours/library/crypto/src/shared/original/donna_32.cpp create mode 100755 external/ours/library/crypto/src/shared/original/donna_32.h create mode 100755 external/ours/library/crypto/src/shared/original/donna_64.cpp create mode 100755 external/ours/library/crypto/src/shared/original/donna_64.h create mode 100755 external/ours/library/crypto/src/shared/original/donna_sse.cpp create mode 100755 external/ours/library/crypto/src/shared/original/donna_sse.h create mode 100755 external/ours/library/crypto/src/shared/original/drbg.h create mode 100755 external/ours/library/crypto/src/shared/original/dsa.cpp create mode 100755 external/ours/library/crypto/src/shared/original/dsa.h create mode 100755 external/ours/library/crypto/src/shared/original/eax.cpp create mode 100755 external/ours/library/crypto/src/shared/original/eax.h create mode 100755 external/ours/library/crypto/src/shared/original/ec2n.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ec2n.h create mode 100755 external/ours/library/crypto/src/shared/original/eccrypto.cpp create mode 100755 external/ours/library/crypto/src/shared/original/eccrypto.h create mode 100755 external/ours/library/crypto/src/shared/original/ecp.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ecp.h create mode 100755 external/ours/library/crypto/src/shared/original/ecpoint.h create mode 100755 external/ours/library/crypto/src/shared/original/elgamal.cpp create mode 100755 external/ours/library/crypto/src/shared/original/elgamal.h create mode 100755 external/ours/library/crypto/src/shared/original/emsa2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/emsa2.h create mode 100755 external/ours/library/crypto/src/shared/original/eprecomp.cpp create mode 100755 external/ours/library/crypto/src/shared/original/eprecomp.h create mode 100755 external/ours/library/crypto/src/shared/original/esign.cpp create mode 100755 external/ours/library/crypto/src/shared/original/esign.h create mode 100755 external/ours/library/crypto/src/shared/original/factory.h create mode 100755 external/ours/library/crypto/src/shared/original/fhmqv.h create mode 100755 external/ours/library/crypto/src/shared/original/files.cpp create mode 100755 external/ours/library/crypto/src/shared/original/files.h create mode 100755 external/ours/library/crypto/src/shared/original/fips140.cpp create mode 100755 external/ours/library/crypto/src/shared/original/fips140.h create mode 100755 external/ours/library/crypto/src/shared/original/fipsalgt.cpp create mode 100755 external/ours/library/crypto/src/shared/original/fipstest.cpp create mode 100755 external/ours/library/crypto/src/shared/original/fltrimpl.h create mode 100755 external/ours/library/crypto/src/shared/original/gcm.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gcm.h create mode 100755 external/ours/library/crypto/src/shared/original/gcm_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gf256.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gf256.h create mode 100755 external/ours/library/crypto/src/shared/original/gf2_32.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gf2_32.h create mode 100755 external/ours/library/crypto/src/shared/original/gf2n.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gf2n.h create mode 100755 external/ours/library/crypto/src/shared/original/gf2n_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gfpcrypt.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gfpcrypt.h create mode 100755 external/ours/library/crypto/src/shared/original/gost.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gost.h create mode 100755 external/ours/library/crypto/src/shared/original/gzip.cpp create mode 100755 external/ours/library/crypto/src/shared/original/gzip.h create mode 100755 external/ours/library/crypto/src/shared/original/hashfwd.h create mode 100755 external/ours/library/crypto/src/shared/original/hc128.cpp create mode 100755 external/ours/library/crypto/src/shared/original/hc128.h create mode 100755 external/ours/library/crypto/src/shared/original/hc256.cpp create mode 100755 external/ours/library/crypto/src/shared/original/hc256.h create mode 100755 external/ours/library/crypto/src/shared/original/hex.cpp create mode 100755 external/ours/library/crypto/src/shared/original/hex.h create mode 100755 external/ours/library/crypto/src/shared/original/hight.cpp create mode 100755 external/ours/library/crypto/src/shared/original/hight.h create mode 100755 external/ours/library/crypto/src/shared/original/hkdf.h create mode 100755 external/ours/library/crypto/src/shared/original/hmac.cpp create mode 100755 external/ours/library/crypto/src/shared/original/hmac.h create mode 100755 external/ours/library/crypto/src/shared/original/hmqv.h create mode 100755 external/ours/library/crypto/src/shared/original/hrtimer.cpp create mode 100755 external/ours/library/crypto/src/shared/original/hrtimer.h create mode 100755 external/ours/library/crypto/src/shared/original/ida.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ida.h create mode 100755 external/ours/library/crypto/src/shared/original/idea.cpp create mode 100755 external/ours/library/crypto/src/shared/original/idea.h create mode 100755 external/ours/library/crypto/src/shared/original/integer.cpp create mode 100755 external/ours/library/crypto/src/shared/original/integer.h create mode 100755 external/ours/library/crypto/src/shared/original/kalyna.cpp create mode 100755 external/ours/library/crypto/src/shared/original/kalyna.h create mode 100755 external/ours/library/crypto/src/shared/original/kalynatab.cpp create mode 100755 external/ours/library/crypto/src/shared/original/keccak.cpp create mode 100755 external/ours/library/crypto/src/shared/original/keccak.h create mode 100755 external/ours/library/crypto/src/shared/original/keccak_core.cpp create mode 100755 external/ours/library/crypto/src/shared/original/keccak_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lea.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lea.h create mode 100755 external/ours/library/crypto/src/shared/original/lea_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lsh.h create mode 100755 external/ours/library/crypto/src/shared/original/lsh256.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lsh256_avx.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lsh256_sse.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lsh512.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lsh512_avx.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lsh512_sse.cpp create mode 100755 external/ours/library/crypto/src/shared/original/lubyrack.h create mode 100755 external/ours/library/crypto/src/shared/original/luc.cpp create mode 100755 external/ours/library/crypto/src/shared/original/luc.h create mode 100755 external/ours/library/crypto/src/shared/original/mars.cpp create mode 100755 external/ours/library/crypto/src/shared/original/mars.h create mode 100755 external/ours/library/crypto/src/shared/original/marss.cpp create mode 100755 external/ours/library/crypto/src/shared/original/md2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/md2.h create mode 100755 external/ours/library/crypto/src/shared/original/md4.cpp create mode 100755 external/ours/library/crypto/src/shared/original/md4.h create mode 100755 external/ours/library/crypto/src/shared/original/mdc.h create mode 100755 external/ours/library/crypto/src/shared/original/mersenne.h create mode 100755 external/ours/library/crypto/src/shared/original/modarith.h create mode 100755 external/ours/library/crypto/src/shared/original/modes.cpp create mode 100755 external/ours/library/crypto/src/shared/original/modes.h create mode 100755 external/ours/library/crypto/src/shared/original/modexppc.h create mode 100755 external/ours/library/crypto/src/shared/original/mqv.cpp create mode 100755 external/ours/library/crypto/src/shared/original/mqv.h create mode 100755 external/ours/library/crypto/src/shared/original/naclite.h create mode 100755 external/ours/library/crypto/src/shared/original/nbtheory.cpp create mode 100755 external/ours/library/crypto/src/shared/original/nbtheory.h create mode 100755 external/ours/library/crypto/src/shared/original/neon_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/nr.h create mode 100755 external/ours/library/crypto/src/shared/original/oaep.cpp create mode 100755 external/ours/library/crypto/src/shared/original/oaep.h create mode 100755 external/ours/library/crypto/src/shared/original/oids.h create mode 100755 external/ours/library/crypto/src/shared/original/osrng.cpp create mode 100755 external/ours/library/crypto/src/shared/original/osrng.h create mode 100755 external/ours/library/crypto/src/shared/original/ossig.h create mode 100755 external/ours/library/crypto/src/shared/original/padlkrng.cpp create mode 100755 external/ours/library/crypto/src/shared/original/padlkrng.h create mode 100755 external/ours/library/crypto/src/shared/original/panama.cpp create mode 100755 external/ours/library/crypto/src/shared/original/panama.h create mode 100755 external/ours/library/crypto/src/shared/original/pch.cpp create mode 100755 external/ours/library/crypto/src/shared/original/pch.h create mode 100755 external/ours/library/crypto/src/shared/original/pkcspad.cpp create mode 100755 external/ours/library/crypto/src/shared/original/pkcspad.h create mode 100755 external/ours/library/crypto/src/shared/original/poly1305.cpp create mode 100755 external/ours/library/crypto/src/shared/original/poly1305.h create mode 100755 external/ours/library/crypto/src/shared/original/polynomi.cpp create mode 100755 external/ours/library/crypto/src/shared/original/polynomi.h create mode 100755 external/ours/library/crypto/src/shared/original/ppc_power7.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ppc_power8.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ppc_power9.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ppc_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ppc_simd.h create mode 100755 external/ours/library/crypto/src/shared/original/pssr.cpp create mode 100755 external/ours/library/crypto/src/shared/original/pssr.h create mode 100755 external/ours/library/crypto/src/shared/original/pubkey.cpp create mode 100755 external/ours/library/crypto/src/shared/original/pubkey.h create mode 100755 external/ours/library/crypto/src/shared/original/pwdbased.h create mode 100755 external/ours/library/crypto/src/shared/original/rabbit.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rabbit.h create mode 100755 external/ours/library/crypto/src/shared/original/rabin.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rabin.h create mode 100755 external/ours/library/crypto/src/shared/original/randpool.cpp create mode 100755 external/ours/library/crypto/src/shared/original/randpool.h create mode 100755 external/ours/library/crypto/src/shared/original/rc2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rc2.h create mode 100755 external/ours/library/crypto/src/shared/original/rc5.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rc5.h create mode 100755 external/ours/library/crypto/src/shared/original/rc6.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rc6.h create mode 100755 external/ours/library/crypto/src/shared/original/rdrand.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rdrand.h create mode 100755 external/ours/library/crypto/src/shared/original/rdtables.cpp create mode 100755 external/ours/library/crypto/src/shared/original/regtest1.cpp create mode 100755 external/ours/library/crypto/src/shared/original/regtest2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/regtest3.cpp create mode 100755 external/ours/library/crypto/src/shared/original/regtest4.cpp create mode 100755 external/ours/library/crypto/src/shared/original/resource.h create mode 100755 external/ours/library/crypto/src/shared/original/rijndael.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rijndael.h create mode 100755 external/ours/library/crypto/src/shared/original/rijndael_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ripemd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ripemd.h create mode 100755 external/ours/library/crypto/src/shared/original/rng.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rng.h create mode 100755 external/ours/library/crypto/src/shared/original/rsa.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rsa.h create mode 100755 external/ours/library/crypto/src/shared/original/rw.cpp create mode 100755 external/ours/library/crypto/src/shared/original/rw.h create mode 100755 external/ours/library/crypto/src/shared/original/safer.cpp create mode 100755 external/ours/library/crypto/src/shared/original/safer.h create mode 100755 external/ours/library/crypto/src/shared/original/salsa.cpp create mode 100755 external/ours/library/crypto/src/shared/original/salsa.h create mode 100755 external/ours/library/crypto/src/shared/original/scrypt.cpp create mode 100755 external/ours/library/crypto/src/shared/original/scrypt.h create mode 100755 external/ours/library/crypto/src/shared/original/seal.cpp create mode 100755 external/ours/library/crypto/src/shared/original/seal.h create mode 100755 external/ours/library/crypto/src/shared/original/secblock.h create mode 100755 external/ours/library/crypto/src/shared/original/secblockfwd.h create mode 100755 external/ours/library/crypto/src/shared/original/seckey.h create mode 100755 external/ours/library/crypto/src/shared/original/seed.cpp create mode 100755 external/ours/library/crypto/src/shared/original/seed.h create mode 100755 external/ours/library/crypto/src/shared/original/serpent.cpp create mode 100755 external/ours/library/crypto/src/shared/original/serpent.h create mode 100755 external/ours/library/crypto/src/shared/original/serpentp.h create mode 100755 external/ours/library/crypto/src/shared/original/sha.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sha.h create mode 100755 external/ours/library/crypto/src/shared/original/sha1_armv4.h create mode 100755 external/ours/library/crypto/src/shared/original/sha256_armv4.h create mode 100755 external/ours/library/crypto/src/shared/original/sha3.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sha3.h create mode 100755 external/ours/library/crypto/src/shared/original/sha512_armv4.h create mode 100755 external/ours/library/crypto/src/shared/original/sha_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/shacal2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/shacal2.h create mode 100755 external/ours/library/crypto/src/shared/original/shacal2_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/shake.cpp create mode 100755 external/ours/library/crypto/src/shared/original/shake.h create mode 100755 external/ours/library/crypto/src/shared/original/shark.cpp create mode 100755 external/ours/library/crypto/src/shared/original/shark.h create mode 100755 external/ours/library/crypto/src/shared/original/sharkbox.cpp create mode 100755 external/ours/library/crypto/src/shared/original/simeck.cpp create mode 100755 external/ours/library/crypto/src/shared/original/simeck.h create mode 100755 external/ours/library/crypto/src/shared/original/simon.cpp create mode 100755 external/ours/library/crypto/src/shared/original/simon.h create mode 100755 external/ours/library/crypto/src/shared/original/simon128_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/simple.cpp create mode 100755 external/ours/library/crypto/src/shared/original/simple.h create mode 100755 external/ours/library/crypto/src/shared/original/siphash.h create mode 100755 external/ours/library/crypto/src/shared/original/skipjack.cpp create mode 100755 external/ours/library/crypto/src/shared/original/skipjack.h create mode 100755 external/ours/library/crypto/src/shared/original/sm3.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sm3.h create mode 100755 external/ours/library/crypto/src/shared/original/sm4.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sm4.h create mode 100755 external/ours/library/crypto/src/shared/original/sm4_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sosemanuk.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sosemanuk.h create mode 100755 external/ours/library/crypto/src/shared/original/speck.cpp create mode 100755 external/ours/library/crypto/src/shared/original/speck.h create mode 100755 external/ours/library/crypto/src/shared/original/speck128_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/square.cpp create mode 100755 external/ours/library/crypto/src/shared/original/square.h create mode 100755 external/ours/library/crypto/src/shared/original/squaretb.cpp create mode 100755 external/ours/library/crypto/src/shared/original/sse_simd.cpp create mode 100755 external/ours/library/crypto/src/shared/original/stdcpp.h create mode 100755 external/ours/library/crypto/src/shared/original/strciphr.cpp create mode 100755 external/ours/library/crypto/src/shared/original/strciphr.h create mode 100755 external/ours/library/crypto/src/shared/original/tea.cpp create mode 100755 external/ours/library/crypto/src/shared/original/tea.h create mode 100755 external/ours/library/crypto/src/shared/original/test.cpp create mode 100755 external/ours/library/crypto/src/shared/original/threefish.cpp create mode 100755 external/ours/library/crypto/src/shared/original/threefish.h create mode 100755 external/ours/library/crypto/src/shared/original/tiger.cpp create mode 100755 external/ours/library/crypto/src/shared/original/tiger.h create mode 100755 external/ours/library/crypto/src/shared/original/tigertab.cpp create mode 100755 external/ours/library/crypto/src/shared/original/trap.h create mode 100755 external/ours/library/crypto/src/shared/original/trunhash.h create mode 100755 external/ours/library/crypto/src/shared/original/ttmac.cpp create mode 100755 external/ours/library/crypto/src/shared/original/ttmac.h create mode 100755 external/ours/library/crypto/src/shared/original/tweetnacl.cpp create mode 100755 external/ours/library/crypto/src/shared/original/tweetnacl.h create mode 100755 external/ours/library/crypto/src/shared/original/validat0.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat1.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat10.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat2.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat3.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat4.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat5.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat6.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat7.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat8.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validat9.cpp create mode 100755 external/ours/library/crypto/src/shared/original/validate.h create mode 100755 external/ours/library/crypto/src/shared/original/vmac.cpp create mode 100755 external/ours/library/crypto/src/shared/original/vmac.h create mode 100755 external/ours/library/crypto/src/shared/original/wake.cpp create mode 100755 external/ours/library/crypto/src/shared/original/wake.h create mode 100755 external/ours/library/crypto/src/shared/original/whrlpool.cpp create mode 100755 external/ours/library/crypto/src/shared/original/whrlpool.h create mode 100755 external/ours/library/crypto/src/shared/original/xed25519.cpp create mode 100755 external/ours/library/crypto/src/shared/original/xed25519.h create mode 100755 external/ours/library/crypto/src/shared/original/xtr.cpp create mode 100755 external/ours/library/crypto/src/shared/original/xtr.h create mode 100755 external/ours/library/crypto/src/shared/original/xtrcrypt.cpp create mode 100755 external/ours/library/crypto/src/shared/original/xtrcrypt.h create mode 100755 external/ours/library/crypto/src/shared/original/xts.cpp create mode 100755 external/ours/library/crypto/src/shared/original/xts.h create mode 100755 external/ours/library/crypto/src/shared/original/zdeflate.cpp create mode 100755 external/ours/library/crypto/src/shared/original/zdeflate.h create mode 100755 external/ours/library/crypto/src/shared/original/zinflate.cpp create mode 100755 external/ours/library/crypto/src/shared/original/zinflate.h create mode 100755 external/ours/library/crypto/src/shared/original/zlib.cpp create mode 100755 external/ours/library/crypto/src/shared/original/zlib.h diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index 957463aa9..0cd0e9446 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -34,36 +34,6 @@ if(DEFINED ENV{ORACLE_HOME}) find_path(ORACLE_INCLUDE_DIR NAMES oci.h PATHS - /usr/include/oracle/12.1/client64 - /usr/include/oracle/12.1/client - /usr/lib/oracle/12.1/client64 - /usr/share/oracle/12.1/client64 - /usr/lib/oracle/12.1/client - /usr/share/oracle/12.1/client - /usr/include/oracle/10.2.0.4/client64 - /usr/include/oracle/10.2.0.4/client - /usr/lib/oracle/10.2.0.4/client64 - /usr/share/oracle/10.2.0.4/client64 - /usr/lib/oracle/10.2.0.4/client - /usr/share/oracle/10.2.0.4/client - /usr/include/oracle/12.2/client64 - /usr/include/oracle/12.2/client - /usr/lib/oracle/12.2/client64 - /usr/share/oracle/12.2/client64 - /usr/lib/oracle/12.2/client - /usr/share/oracle/12.2/client - /usr/include/oracle/18.3/client64 - /usr/include/oracle/18.3/client - /usr/lib/oracle/18.3/client64 - /usr/share/oracle/18.3/client64 - /usr/lib/oracle/18.3/client - /usr/share/oracle/18.3/client - /usr/include/oracle/19.6/client64 - /usr/include/oracle/19.6/client - /usr/lib/oracle/19.6/client64 - /usr/share/oracle/19.6/client64 - /usr/lib/oracle/19.6/client - /usr/share/oracle/19.6/client /usr/include/oracle/19.12/client64 /usr/include/oracle/19.12/client /usr/lib/oracle/19.12/client64 diff --git a/external/ours/library/crypto/src/shared/original-old/config.h b/external/ours/library/crypto/src/shared/original-old/config.h new file mode 100755 index 000000000..f0dfb23ee --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/config.h @@ -0,0 +1,165 @@ +#ifndef CRYPTOPP_CONFIG_H +#define CRYPTOPP_CONFIG_H + +// ***************** Important Settings ******************** + +// define this if running on a big-endian CPU +#if defined(__sparc__) || defined(__hppa__) || defined(__ppc__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__)) +#define IS_BIG_ENDIAN +#endif + +// define this if running on a little-endian CPU +// big endian will be assumed if IS_LITTLE_ENDIAN is not defined +#ifndef IS_BIG_ENDIAN +#define IS_LITTLE_ENDIAN +#endif + +// define this if you want to disable all OS-dependent features, +// such as sockets and OS-provided random number generators +// #define NO_OS_DEPENDENCE + +// Define this to use features provided by Microsoft's CryptoAPI. +// Currently the only feature used is random number generation. +// This macro will be ignored if NO_OS_DEPENDENCE is defined. +#define USE_MS_CRYPTOAPI + +// define this if your compiler does not support namespaces +// #define NO_NAMESPACE +#ifdef NO_NAMESPACE +#define std +#define CryptoPP +#define USING_NAMESPACE(x) +#define NAMESPACE_BEGIN(x) +#define NAMESPACE_END +#define ANONYMOUS_NAMESPACE_BEGIN +#else +#define USING_NAMESPACE(x) using namespace x; +#define NAMESPACE_BEGIN(x) namespace x { +#define ANONYMOUS_NAMESPACE_BEGIN namespace { +#define NAMESPACE_END } +#endif + +// ***************** Less Important Settings *************** + +// switch between different secure memory allocation mechnisms, this is the only +// one available right now +#define SECALLOC_DEFAULT + +#define GZIP_OS_CODE 0 + +// Try this if your CPU has 256K internal cache or a slow multiply instruction +// and you want a (possibly) faster IDEA implementation using log tables +// #define IDEA_LARGECACHE + +// Try this if you have a large cache or your CPU is slow manipulating +// individual bytes. +// #define DIAMOND_USE_PERMTABLE + +// Define this if, for the linear congruential RNG, you want to use +// the original constants as specified in S.K. Park and K.W. Miller's +// CACM paper. +// #define LCRNG_ORIGINAL_NUMBERS + +// choose which style of sockets to wrap (mostly useful for cygwin which has both) +#define PREFER_BERKELEY_STYLE_SOCKETS +// #define PREFER_WINDOWS_STYLE_SOCKETS + +// ***************** Important Settings Again ******************** +// But the defaults should be ok. + +typedef unsigned char byte; // moved outside namespace for Borland C++Builder 5 + +NAMESPACE_BEGIN(CryptoPP) + +typedef unsigned short word16; +#if defined(__alpha) && !defined(_MSC_VER) +typedef unsigned int word32; +#else +typedef unsigned long word32; +#endif + +#if defined(__GNUC__) || defined(__MWERKS__) +#define WORD64_AVAILABLE +typedef unsigned long long word64; +#define W64LIT(x) x##LL +#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) +#define WORD64_AVAILABLE +typedef unsigned __int64 word64; +#define W64LIT(x) x##ui64 +#endif + +// defined this if your CPU is not 64-bit +#if defined(WORD64_AVAILABLE) && !defined(__alpha) +#define SLOW_WORD64 +#endif + +// word should have the same size as your CPU registers +// dword should be twice as big as word + +#if (defined(__GNUC__) && !defined(__alpha)) || defined(__MWERKS__) +typedef unsigned long word; +typedef unsigned long long dword; +#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) +typedef unsigned __int32 word; +typedef unsigned __int64 dword; +#else +typedef unsigned int word; +typedef unsigned long dword; +#endif + +const unsigned int WORD_SIZE = sizeof(word); +const unsigned int WORD_BITS = WORD_SIZE * 8; + +#define LOW_WORD(x) (word)(x) + +union dword_union +{ + dword_union (const dword &dw) : dw(dw) {} + dword dw; + word w[2]; +}; + +#ifdef IS_LITTLE_ENDIAN +#define HIGH_WORD(x) (dword_union(x).w[1]) +#else +#define HIGH_WORD(x) (dword_union(x).w[0]) +#endif + +// if the above HIGH_WORD macro doesn't work (if you are not sure, compile it +// and run the validation tests), try this: +// #define HIGH_WORD(x) (word)((x)>>WORD_BITS) + +#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) +#define INTEL_INTRINSICS +#define FAST_ROTATE +#elif defined(__MWERKS__) && TARGET_CPU_PPC +#define PPC_INTRINSICS +#define FAST_ROTATE +#elif defined(__GNUC__) && defined(__i386__) +// GCC does peephole optimizations which should result in using rotate instructions +#define FAST_ROTATE +#endif + +// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0 +template +inline const _Tp& STDMIN(const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; +} + +template +inline const _Tp& STDMAX(const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; +} + +#ifdef _MSC_VER +// 4250: dominance +// 4660: explicitly instantiating a class that's already implicitly instantiated +// 4786: identifer was truncated in debug information +// 4355: 'this' : used in base member initializer list +// 4800: converting int to bool +#pragma warning(disable: 4250 4660 4786 4355 4800 4710) +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/cryptlib.cpp b/external/ours/library/crypto/src/shared/original-old/cryptlib.cpp new file mode 100755 index 000000000..174cea86d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/cryptlib.cpp @@ -0,0 +1,488 @@ +// cryptlib.cpp - written and placed in the public domain by Wei Dai + +#include "FirstCrypto.h" +#include "cryptlib.h" +#include "misc.h" +#include "filters.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +const std::string BufferedTransformation::NULL_CHANNEL; + +unsigned int RandomNumberGenerator::GenerateBit() +{ + return Parity(GetByte()); +} + +void RandomNumberGenerator::GenerateBlock(byte *output, unsigned int size) +{ + while (size--) + *output++ = GetByte(); +} + +word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) +{ + word32 range = max-min; + const int maxBytes = BytePrecision(range); + const int maxBits = BitPrecision(range); + + word32 value; + + do + { + value = 0; + for (int i=0; i range); + + return value+min; +} + +void StreamCipher::ProcessString(byte *outString, const byte *inString, unsigned int length) +{ + while(length--) + *outString++ = ProcessByte(*inString++); +} + +void StreamCipher::ProcessString(byte *inoutString, unsigned int length) +{ + while(length--) { + (*inoutString)++; + *inoutString = ProcessByte(*inoutString); + } +} + +bool HashModule::Verify(const byte *digestIn) +{ + SecByteBlock digest(DigestSize()); + Final(digest); + return memcmp(digest, digestIn, DigestSize()) == 0; +} + +BufferedTransformation::Err::Err(ErrorType errorType, const std::string &s) + : Exception(s), m_errorType(errorType) +{ + if (GetWhat().empty()) + { + switch (errorType) + { + case CANNOT_FLUSH: + SetWhat("BufferedTransformation: cannot flush buffer"); + break; + case DATA_INTEGRITY_CHECK_FAILED: + SetWhat("BufferedTransformation: data integrity check failed"); + break; + case INVALID_DATA_FORMAT: + SetWhat("BufferedTransformation: invalid data format"); + break; + case OUTPUT_ERROR: + SetWhat("BufferedTransformation: cannot write to output device"); + break; + case OTHER_ERROR: + SetWhat("BufferedTransformation: unknown error"); + break; + default: + assert(false); + break; + } + } +} + +void BufferedTransformation::Put(byte b) +{ + if (AttachedTransformation()) + AttachedTransformation()->Put(b); +} + +void BufferedTransformation::Put(const byte *inString, unsigned int length) +{ + if (AttachedTransformation()) + AttachedTransformation()->Put(inString, length); +} + +void BufferedTransformation::Flush(bool completeFlush, int propagation) +{ + if (AttachedTransformation() && propagation) + AttachedTransformation()->Flush(completeFlush, propagation-1); +} + +void BufferedTransformation::MessageEnd(int propagation) +{ + if (AttachedTransformation() && propagation) + AttachedTransformation()->MessageEnd(propagation-1); +} + +void BufferedTransformation::MessageSeriesEnd(int propagation) +{ + if (AttachedTransformation() && propagation) + AttachedTransformation()->MessageSeriesEnd(propagation-1); +} + +void BufferedTransformation::PutMessageEnd(const byte *inString, unsigned int length, int propagation) +{ + Put(inString, length); + MessageEnd(propagation); +} + +void BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation) +{ + if (channel.empty()) + Flush(completeFlush, propagation); + else if (AttachedTransformation() && propagation) + AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation-1); +} + +void BufferedTransformation::ChannelMessageEnd(const std::string &channel, int propagation) +{ + if (channel.empty()) + MessageEnd(propagation); + else if (AttachedTransformation() && propagation) + AttachedTransformation()->ChannelMessageEnd(channel, propagation-1); +} + +void BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation) +{ + if (channel.empty()) + MessageSeriesEnd(propagation); + else if (AttachedTransformation() && propagation) + AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1); +} + +void BufferedTransformation::ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation) +{ + if (channel.empty()) + PutMessageEnd(inString, length, propagation); + else + { + ChannelPut(channel, inString, length); + ChannelMessageEnd(channel, propagation); + } +} + +unsigned long BufferedTransformation::MaxRetrievable() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->MaxRetrievable(); + else + return CopyTo(g_bitBucket); +} + +bool BufferedTransformation::AnyRetrievable() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->AnyRetrievable(); + else + { + byte b; + return Peek(b) != 0; + } +} + +unsigned int BufferedTransformation::Get(byte &outByte) +{ + if (AttachedTransformation()) + return AttachedTransformation()->Get(outByte); + else + return Get(&outByte, 1); +} + +unsigned int BufferedTransformation::Get(byte *outString, unsigned int getMax) +{ + if (AttachedTransformation()) + return AttachedTransformation()->Get(outString, getMax); + else + { + ArraySink arraySink(outString, getMax); + return TransferTo(arraySink, getMax); + } +} + +unsigned int BufferedTransformation::Peek(byte &outByte) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->Peek(outByte); + else + return Peek(&outByte, 1); +} + +unsigned int BufferedTransformation::Peek(byte *outString, unsigned int peekMax) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->Peek(outString, peekMax); + else + { + ArraySink arraySink(outString, peekMax); + return CopyTo(arraySink, peekMax); + } +} + +unsigned long BufferedTransformation::Skip(unsigned long skipMax) +{ + if (AttachedTransformation()) + return AttachedTransformation()->Skip(skipMax); + else + return TransferTo(g_bitBucket, skipMax); +} + +unsigned long BufferedTransformation::CopyTo(BufferedTransformation &target, unsigned long copyMax) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->CopyTo(target, copyMax); + else + return 0; +} + +unsigned long BufferedTransformation::TransferTo(BufferedTransformation &target, unsigned long size) +{ + if (AttachedTransformation()) + return AttachedTransformation()->TransferTo(target, size); + else + return 0; +} + +unsigned long BufferedTransformation::TotalBytesRetrievable() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->TotalBytesRetrievable(); + else + return MaxRetrievable(); +} + +unsigned int BufferedTransformation::NumberOfMessages() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->NumberOfMessages(); + else + return CopyMessagesTo(g_bitBucket); +} + +bool BufferedTransformation::AnyMessages() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->NumberOfMessages(); + else + return NumberOfMessages() != 0; +} + +bool BufferedTransformation::GetNextMessage() +{ + if (AttachedTransformation()) + return AttachedTransformation()->GetNextMessage(); + else + return false; +} + +unsigned int BufferedTransformation::SkipMessages(unsigned int count) +{ + if (AttachedTransformation()) + return AttachedTransformation()->SkipMessages(count); + else + return TransferMessagesTo(g_bitBucket, count); +} + +unsigned int BufferedTransformation::TransferMessagesTo(BufferedTransformation &target, unsigned int count) +{ + if (AttachedTransformation()) + return AttachedTransformation()->TransferMessagesTo(target, count); + else + { + unsigned int i; + for (i=0; i (result); + target.MessageEnd(GetAutoSignalPropagation()); + } + return i; + } +} + +unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->CopyMessagesTo(target, count); + else + return 0; +} + +void BufferedTransformation::SkipAll() +{ + if (AttachedTransformation()) + AttachedTransformation()->SkipAll(); + else + { + while (SkipMessages()) {} + while (Skip()) {} + } +} + +void BufferedTransformation::TransferAllTo(BufferedTransformation &target) +{ + if (AttachedTransformation()) + AttachedTransformation()->TransferAllTo(target); + else + { + while (TransferMessagesTo(target)) {} + while (TransferTo(target)) {} + } +} + +void BufferedTransformation::CopyAllTo(BufferedTransformation &target) const +{ + if (AttachedTransformation()) + AttachedTransformation()->CopyAllTo(target); + else + { + CopyMessagesTo(target); + CopyTo(target); + } +} + +void BufferedTransformation::SetRetrievalChannel(const std::string &channel) +{ + if (AttachedTransformation()) + AttachedTransformation()->SetRetrievalChannel(channel); +} + +void BufferedTransformation::ChannelPut(const std::string &channel, byte inByte) +{ + if (channel.empty()) + Put(inByte); +} + +void BufferedTransformation::ChannelPut(const std::string &channel, const byte *inString, unsigned int length) +{ + if (channel.empty()) + Put(inString, length); +} + +void BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, bool highFirst) +{ + if (highFirst) + { + ChannelPut(channel, value>>8); + ChannelPut(channel, byte(value)); + } + else + { + ChannelPut(channel, byte(value)); + ChannelPut(channel, value>>8); + } +} + +void BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, bool highFirst) +{ + if (highFirst) + { + for (int i=0; i<4; i++) + ChannelPut(channel, byte(value>>((3-i)*8))); + } + else + { + for (int i=0; i<4; i++) + ChannelPut(channel, byte(value>>(i*8))); + } +} + +void BufferedTransformation::PutWord16(word16 value, bool highFirst) +{ + ChannelPutWord16(NULL_CHANNEL, value, highFirst); +} + +void BufferedTransformation::PutWord32(word32 value, bool highFirst) +{ + ChannelPutWord32(NULL_CHANNEL, value, highFirst); +} + +unsigned int BufferedTransformation::PeekWord16(word16 &value, bool highFirst) +{ + byte buf[2] = {0, 0}; + unsigned int len = Peek(buf, 2); + + if (highFirst) + value = (buf[0] << 8) | buf[1]; + else + value = (buf[1] << 8) | buf[0]; + + return len; +} + +unsigned int BufferedTransformation::PeekWord32(word32 &value, bool highFirst) +{ + byte buf[4] = {0, 0, 0, 0}; + unsigned int len = Peek(buf, 4); + + if (highFirst) + value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; + else + value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; + + return len; +} + +unsigned int BufferedTransformation::GetWord16(word16 &value, bool highFirst) +{ + return Skip(PeekWord16(value, highFirst)); +} + +unsigned int BufferedTransformation::GetWord32(word32 &value, bool highFirst) +{ + return Skip(PeekWord32(value, highFirst)); +} + +void BufferedTransformation::Attach(BufferedTransformation *newOut) +{ + if (!Attachable()) + return; + + if (AttachedTransformation() && AttachedTransformation()->Attachable()) + AttachedTransformation()->Attach(newOut); + else + Detach(newOut); +} + +unsigned int PK_FixedLengthCryptoSystem::MaxPlainTextLength(unsigned int cipherTextLength) const +{ + if (cipherTextLength == CipherTextLength()) + return MaxPlainTextLength(); + else + return 0; +} + +unsigned int PK_FixedLengthCryptoSystem::CipherTextLength(unsigned int plainTextLength) const +{ + if (plainTextLength <= MaxPlainTextLength()) + return CipherTextLength(); + else + return 0; +} + +unsigned int PK_FixedLengthDecryptor::Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) +{ + if (cipherTextLength != CipherTextLength()) + return 0; + + return Decrypt(cipherText, plainText); +} + +void PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const +{ + std::unique_ptr accumulator(NewMessageAccumulator()); + accumulator->Update(message, messageLen); + Sign(rng, accumulator.release(), signature); +} + +bool PK_Verifier::VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const +{ + std::unique_ptr accumulator(NewMessageAccumulator()); + accumulator->Update(message, messageLen); + return Verify(accumulator.release(), sig); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/cryptlib.h b/external/ours/library/crypto/src/shared/original-old/cryptlib.h new file mode 100755 index 000000000..fd2587063 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/cryptlib.h @@ -0,0 +1,818 @@ +// cryptlib.h - written and placed in the public domain by Wei Dai +/*! \file + This file contains the declarations for the abstract base + classes that provide a uniform interface to this library. +*/ + +/*! \mainpage Crypto++ Reference Manual +
+
Abstract Base Classes
+ cryptlib.h +
Algebraic Structures
+ Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, + ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, + GF2NP, GF256, GF2_32, EC2N, ECP +
Block Ciphers (in ECB mode)
+ 3way.h, blowfish.h, cast.h, des.h, diamond.h, gost.h, + idea.h, lubyrack.h, mars.h, mdc.h, + rc2.h, rc5.h, rc6.h, rijndael.h, safer.h, serpent.h, shark.h, skipjack.h, + square.h, tea.h, twofish.h +
Block Cipher Modes
+ modes.h, cbc.h +
Compression
+ Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor +
Secret Sharing and Information Dispersal
+ SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery +
Stream Ciphers
+ ARC4, PanamaCipher, BlumBlumShub, SEAL, SapphireEncryption, WAKEEncryption +
Hash Functions
+ HAVAL, MD2, MD5, PanamaHash, RIPEMD160, SHA, SHA256, SHA384, SHA512, Tiger +
Non-Cryptographic Checksums
+ CRC32, Adler32 +
Message Authentication Codes
+ MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC +
Random Number Generators
+ NullRNG, LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool +
Public Key Cryptography
+ blumgold.h, dh.h, dh2.h, dsa.h, eccrypto.h, luc.h, mqv.h, + nr.h, rsa.h, rabin.h, rw.h, xtrcrypt.h +
Input Source Classes
+ StringSource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource +
Output Sink Classes
+ StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink +
Filter Wrappers
+ StreamCipherFilter, HashFilter, HashVerifier, SignerFilter, VerifierFilter +
Binary to Text Encoders and Decoders
+ HexEncoder, HexDecoder, Base64Encoder, Base64Decoder +
Wrappers for OS features
+ Timer, Socket, WindowsHandle, WindowsReadPipe, WindowsWritePipe +
+ +

This reference manual is very much a work in progress. Many classes are still lacking detailed descriptions. +

Click here to download a zip archive containing this manual. +

Thanks to Ryan Phillips for providing the Doxygen configuration file +and getting me started with this manual. +*/ + +#ifndef CRYPTOPP_CRYPTLIB_H +#define CRYPTOPP_CRYPTLIB_H + +#include "config.h" +#include +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! base class for all exceptions thrown by Crypto++ + +class Exception : public std::exception +{ +public: + explicit Exception(const std::string &s) : m_what(s) {} + virtual ~Exception() throw() {} + const char *what() const throw() {return (m_what.c_str());} + const std::string &GetWhat() const {return m_what;} + void SetWhat(const std::string &s) {m_what = s;} + +private: + std::string m_what; +}; + +//! used to specify a direction for a cipher to operate in (encrypt or decrypt) +enum CipherDir { + //! + ENCRYPTION, + //! + DECRYPTION}; + + +//! abstract base class for block ciphers + +/*! All classes derived from BlockTransformation are block ciphers + in ECB mode (for example the DESEncryption class), which are stateless. + These classes should not be used directly, but only in combination with + a mode class (see CipherMode). + + Note: BlockTransformation objects may assume that pointers to input and + output blocks are aligned on 32-bit word boundaries. +*/ +class BlockTransformation +{ +public: + //! + virtual ~BlockTransformation() {} + + //! encrypt or decrypt one block in place + /*! \pre size of inoutBlock == BlockSize() */ + virtual void ProcessBlock(byte *inoutBlock) const =0; + + //! encrypt or decrypt one block, may assume inBlock != outBlock + /*! \pre size of inBlock and outBlock == BlockSize() */ + virtual void ProcessBlock(const byte *inBlock, byte *outBlock) const =0; + + //! block size of the cipher in bytes + virtual unsigned int BlockSize() const =0; +}; + +//! provides an implementation of BlockSize() +template +class FixedBlockSize : public BlockTransformation +{ +public: + enum {BLOCKSIZE = N}; + virtual unsigned int BlockSize() const {return BLOCKSIZE;} +}; + +//! abstract base class for stream ciphers + +class StreamCipher +{ +public: + //! + virtual ~StreamCipher() {} + + //! encrypt or decrypt one byte + virtual byte ProcessByte(byte input) =0; + + //! encrypt or decrypt an array of bytes of specified length in place + virtual void ProcessString(byte *inoutString, unsigned int length); + //! encrypt or decrypt an array of bytes of specified length, may assume inString != outString + virtual void ProcessString(byte *outString, const byte *inString, unsigned int length); +}; + +//! abstract base class for random access stream ciphers + +class RandomAccessStreamCipher : public virtual StreamCipher +{ +public: + //! + virtual ~RandomAccessStreamCipher() {} + /*/ specify that the next byte to be processed is at absolute position n + in the plaintext/ciphertext stream */ + virtual void Seek(unsigned long n) =0; +}; + +//! abstract base class for random number generators + +/*! All return values are uniformly distributed over the range specified. +*/ +class RandomNumberGenerator +{ +public: + //! + virtual ~RandomNumberGenerator() {} + + //! generate new random byte and return it + virtual byte GenerateByte() =0; + + //! generate new random bit and return it + /*! Default implementation is to call GenerateByte() and return its parity. */ + virtual unsigned int GenerateBit(); + + //! generate a random 32 bit word in the range min to max, inclusive + virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); + + //! generate random array of bytes + //* Default implementation is to call GenerateByte() size times. + virtual void GenerateBlock(byte *output, unsigned int size); + + //! randomly shuffle the specified array, resulting permutation is uniformly distributed + template void Shuffle(IT begin, IT end) + { + for (; begin != end; ++begin) + std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); + } + + // for backwards compatibility, maybe be remove later + byte GetByte() {return GenerateByte();} + unsigned int GetBit() {return GenerateBit();} + word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} + word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} + void GetBlock(byte *output, unsigned int size) {GenerateBlock(output, size);} +}; + +//! abstract base class for hash functions + +/*! HashModule objects are stateful. They are created in an initial state, + change state as Update() is called, and return to the initial + state when Final() is called. This interface allows a large message to + be hashed in pieces by calling Update() on each piece followed by + calling Final(). +*/ +class HashModule +{ +public: + //! + virtual ~HashModule() {} + + //! process more input + virtual void Update(const byte *input, unsigned int length) =0; + + /*/ calculate hash for the current message (the concatenation of all + inputs passed in via Update()), then reinitialize the object */ + //* Precondition: size of digest == DigestSize(). + virtual void Final(byte *digest) =0; + + //! size of the hash returned by Final() + virtual unsigned int DigestSize() const =0; + + //! use this if your input is short and you don't want to call Update() and Final() seperately + virtual void CalculateDigest(byte *digest, const byte *input, int length) + {Update(input, length); Final(digest);} + + //! verify that digest is a valid digest for the current message, then reinitialize the object + /*! Default implementation is to call Final() and do a bitwise comparison + between its output and digest. */ + virtual bool Verify(const byte *digest); + + //! use this if your input is short and you don't want to call Update() and Verify() seperately + virtual bool VerifyDigest(const byte *digest, const byte *input, int length) + {Update(input, length); return Verify(digest);} +}; + +//! abstract base class for message authentication codes + +/*! The main differences between a MAC and an hash function (in terms of + programmatic interface) is that a MAC is keyed, and that calculating + a MAC for the same message twice may produce two different results so + verifying a MAC may not be simply recalculating it and doing a bitwise + comparison. +*/ +class MessageAuthenticationCode : public virtual HashModule +{ +public: + //! + virtual ~MessageAuthenticationCode() {} +}; + +//! abstract base class for buffered transformations + +/*! BufferedTransformation is a generalization of BlockTransformation, + StreamCipher, and HashModule. + + A buffered transformation is an object that takes a stream of bytes + as input (this may be done in stages), does some computation on them, and + then places the result into an internal buffer for later retrieval. Any + partial result already in the output buffer is not modified by further + input. + + Computation is generally done as soon as possible, but some buffering + on the input may be done for performance reasons. + \nosubgrouping +*/ +class BufferedTransformation +{ +public: + //! + virtual ~BufferedTransformation() {} + + //! \name INPUT + //@{ + //! input a byte for processing + virtual void Put(byte inByte) =0; + //! input multiple bytes + virtual void Put(const byte *inString, unsigned int length) =0; + + //! input a 16-bit word, big-endian or little-endian depending on highFirst + void PutWord16(word16 value, bool highFirst=true); + //! input a 32-bit word + void PutWord32(word32 value, bool highFirst=true); + //@} + + //! \name SIGNALS + //@{ + //! process everything in internal buffers and output them + /*! throws exception if completeFlush == true and it's + not possible to flush everything */ + virtual void Flush(bool completeFlush, int propagation=-1); + //! mark end of an input segment, message, or packet + /*! propagation != 0 means pass on the signal to attached + BufferedTransformation objects, with propagation + decremented at each step until it reaches 0. + -1 means unlimited propagation. */ + virtual void MessageEnd(int propagation=-1); + //! same as Put() followed by MessageEnd() but may be more efficient + virtual void PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); + //! mark end of a series of messages + /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ + virtual void MessageSeriesEnd(int propagation=-1); + + //! set propagation of automatically generated and transfered signals + /*! propagation == 0 means do not automaticly generate signals */ + virtual void SetAutoSignalPropagation(int propagation) {} + + //! + virtual int GetAutoSignalPropagation() const {return 0;} + + // for backwards compatibility + void Close() {MessageEnd();} + //@} + + //! \name ERRORS + //@{ + //! error types + enum ErrorType { + //! received a Flush(true) signal but can't flush buffers + CANNOT_FLUSH, + //! data integerity check (such as CRC or MAC) failed + DATA_INTEGRITY_CHECK_FAILED, + //! received input data that doesn't conform to expected format + INVALID_DATA_FORMAT, + //! error reading from input device + INPUT_ERROR, + //! error writing to output device + OUTPUT_ERROR, + //! some error not belong to any of the above categories + OTHER_ERROR + }; + + //! exception thrown by BufferedTransformation + class Err : public Exception + { + public: + Err(ErrorType errorType, const std::string &s=""); + ErrorType GetErrorType() const {return m_errorType;} + void SetErrorType(ErrorType errorType) {m_errorType = errorType;} + private: + ErrorType m_errorType; + }; + //@} + + //! \name RETRIEVAL OF ONE MESSAGE + //@{ + //! returns number of bytes that is currently ready for retrieval + /*! All retrieval functions return the actual number of bytes + retrieved, which is the lesser of the request number and + MaxRetrievable(). */ + virtual unsigned long MaxRetrievable() const; + + // old mispelled name + unsigned long MaxRetrieveable() const {return MaxRetrievable();} + + //! returns whether any bytes are currently ready for retrieval + virtual bool AnyRetrievable() const; + + //! try to retrieve a single byte + virtual unsigned int Get(byte &outByte); + //! try to retrieve multiple bytes + virtual unsigned int Get(byte *outString, unsigned int getMax); + + //! peek at the next byte without removing it from the output buffer + virtual unsigned int Peek(byte &outByte) const; + //! peek at multiple bytes without removing them from the output buffer + virtual unsigned int Peek(byte *outString, unsigned int peekMax) const; + + //! try to retrieve a 16-bit word, big-endian or little-endian depending on highFirst + unsigned int GetWord16(word16 &value, bool highFirst=true); + //! try to retrieve a 32-bit word + unsigned int GetWord32(word32 &value, bool highFirst=true); + + //! try to peek at a 16-bit word, big-endian or little-endian depending on highFirst + unsigned int PeekWord16(word16 &value, bool highFirst=true); + //! try to peek at a 32-bit word + unsigned int PeekWord32(word32 &value, bool highFirst=true); + + //! move transferMax bytes of the buffered output to target as input + virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); + + //! discard skipMax bytes from the output buffer + virtual unsigned long Skip(unsigned long skipMax=ULONG_MAX); + + //! copy copyMax bytes of the buffered output to target as input + virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; + //@} + + //! \name RETRIEVAL OF MULTIPLE MESSAGES + //@{ + //! + virtual unsigned long TotalBytesRetrievable() const; + //! number of times MessageEnd() has been received minus messages retrieved or skipped + virtual unsigned int NumberOfMessages() const; + //! returns true if NumberOfMessages() > 0 + virtual bool AnyMessages() const; + //! start retrieving the next message + /*! + Returns false if no more messages exist or this message + is not completely retrieved. + */ + virtual bool GetNextMessage(); + //! skip count number of messages + virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); + //! + virtual unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX); + //! + virtual unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; + + //! + virtual void SkipAll(); + //! + virtual void TransferAllTo(BufferedTransformation &target); + //! + virtual void CopyAllTo(BufferedTransformation &target) const; + //@} + + //! \name CHANNELS + //@{ + virtual void ChannelPut(const std::string &channel, byte inByte); + virtual void ChannelPut(const std::string &channel, const byte *inString, unsigned int length); + + void ChannelPutWord16(const std::string &channel, word16 value, bool highFirst=true); + void ChannelPutWord32(const std::string &channel, word32 value, bool highFirst=true); + + virtual void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1); + virtual void ChannelMessageEnd(const std::string &channel, int propagation=-1); + virtual void ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation=-1); + virtual void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1); + + virtual void SetRetrievalChannel(const std::string &channel); + + static const std::string NULL_CHANNEL; + //@} + + /*! \name ATTACHMENT + Some BufferedTransformation objects (e.g. Filter objects) + allow other BufferedTransformation objects to be attached. When + this is done, the first object instead of buffering its output, + sents that output to the attached object as input. The entire + attachment chain is deleted when the anchor object is destructed. + */ + //@{ + //! returns whether this object allows attachment + virtual bool Attachable() {return false;} + //! returns the object immediately attached to this object or nullptr for no attachment + virtual BufferedTransformation *AttachedTransformation() {return 0;} + //! + virtual const BufferedTransformation *AttachedTransformation() const + {return const_cast(this)->AttachedTransformation();} + //! delete the current attachment chain and replace it with newAttachment + virtual void Detach(BufferedTransformation *newAttachment = 0) {} + //! add newAttachment to the end of attachment chain + virtual void Attach(BufferedTransformation *newAttachment); + //@} +}; + +//! abstract base class for public-key encryptors and decryptors + +/*! This class provides an interface common to encryptors and decryptors + for querying their plaintext and ciphertext lengths. +*/ +class PK_CryptoSystem +{ +public: + //! + virtual ~PK_CryptoSystem() {} + + //! maximum length of plaintext for a given ciphertext length + //* This function returns 0 if cipherTextLength is not valid (too long or too short). + virtual unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const =0; + + //! calculate length of ciphertext given length of plaintext + //* This function returns 0 if plainTextLength is not valid (too long). + virtual unsigned int CipherTextLength(unsigned int plainTextLength) const =0; +}; + +//! abstract base class for public-key encryptors + +/*! An encryptor is also a public encryption key. It contains both the + key and the algorithm to perform the encryption. +*/ +class PK_Encryptor : public virtual PK_CryptoSystem +{ +public: + //! encrypt a byte string + /*! Preconditions: + \begin{itemize} + \item CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long) + \item size of cipherText == CipherTextLength(plainTextLength) + \end{itemize} + */ + virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) =0; +}; + +//! abstract base class for public-key decryptors + +/*! An decryptor is also a private decryption key. It contains both the + key and the algorithm to perform the decryption. +*/ +class PK_Decryptor : public virtual PK_CryptoSystem +{ +public: + //! decrypt a byte string, and return the length of plaintext + /*! Precondition: size of plainText == MaxPlainTextLength(cipherTextLength) + bytes. + + The function returns the actual length of the plaintext, or 0 + if decryption fails. + */ + virtual unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) =0; +}; + +//! abstract base class for encryptors and decryptors with fixed length ciphertext + +/*! A simplified interface (as embodied in this + class and its subclasses) is provided for crypto systems (such + as RSA) whose ciphertext length depend only on the key, not on the length + of the plaintext. The maximum plaintext length also depend only on + the key. +*/ +class PK_FixedLengthCryptoSystem : public virtual PK_CryptoSystem +{ +public: + //! + virtual unsigned int MaxPlainTextLength() const =0; + //! + virtual unsigned int CipherTextLength() const =0; + + unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const; + unsigned int CipherTextLength(unsigned int plainTextLength) const; +}; + +//! abstract base class for encryptors with fixed length ciphertext + +class PK_FixedLengthEncryptor : public virtual PK_Encryptor, public virtual PK_FixedLengthCryptoSystem +{ +}; + +//! abstract base class for decryptors with fixed length ciphertext + +class PK_FixedLengthDecryptor : public virtual PK_Decryptor, public virtual PK_FixedLengthCryptoSystem +{ +public: + //! decrypt a byte string, and return the length of plaintext + /*! Preconditions: + \begin{itemize} + \item length of cipherText == CipherTextLength() + \item size of plainText == MaxPlainTextLength() + \end{itemize} + + The function returns the actual length of the plaintext, or 0 + if decryption fails. + */ + virtual unsigned int Decrypt(const byte *cipherText, byte *plainText) =0; + + unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText); +}; + +//! abstract base class for public-key signers and verifiers + +/*! This class provides an interface common to signers and verifiers + for querying their signature lengths and creating message + accumulators. +*/ +class PK_SignatureSystem +{ +public: + //! + virtual ~PK_SignatureSystem() {}; + + //! signature length support by this object (as either input or output) + virtual unsigned int SignatureLength() const =0; + + //! create a new HashModule to accumulate the message to be signed or verified + virtual HashModule * NewMessageAccumulator() const =0; +}; + +//! abstract base class for public-key signers + +/*! A signer is also a private signature key. It contains both the + key and the algorithm to perform the signature. +*/ +class PK_Signer : public virtual PK_SignatureSystem +{ +public: + //! key too short exception, may be thrown by Sign() or SignMessage() + class KeyTooShort : public Exception + { + public: + KeyTooShort() : Exception("PK_Signer: key too short") {} + }; + + //! sign and delete messageAccumulator + /*! Preconditions: + \begin{itemize} + \item messageAccumulator was obtained by calling NewMessageAccumulator() + \item HashModule::Final() has not been called on messageAccumulator + \item size of signature == SignatureLength() + \end{itemize} + */ + virtual void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const =0; + + //! sign a message + /*! Precondition: size of signature == SignatureLength() */ + virtual void SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const; +}; + +//! abstract base class for public-key verifiers + +/*! A verifier is also a public verification key. It contains both the + key and the algorithm to perform the verification. +*/ +class PK_Verifier : public virtual PK_SignatureSystem +{ +public: + //! check whether sig is a valid signature for messageAccumulator, and delete messageAccumulator + /*! Preconditions: + \begin{itemize} + \item messageAccumulator was obtained by calling NewMessageAccumulator() + \item HashModule::Final() has not been called on messageAccumulator + \item length of signature == SignatureLength() + \end{itemize} + */ + virtual bool Verify(HashModule *messageAccumulator, const byte *sig) const =0; + + //! check whether sig is a valid signature for message + /*! Precondition: size of signature == SignatureLength() */ + virtual bool VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const; +}; + +//! abstract base class for public-key signers and verifiers with recovery + +/*! In a signature scheme with recovery, a verifier is able to extract + a message from its valid signature. +*/ +class PK_SignatureSystemWithRecovery : public virtual PK_SignatureSystem +{ +public: + //! length of longest message that can be fully recovered + virtual unsigned int MaximumRecoverableLength() const =0; + + //! whether or not messages longer than MaximumRecoverableLength() can be signed + /*! If this function returns false, any message longer than + MaximumRecoverableLength() will be truncated for signature + and will fail verification. + */ + virtual bool AllowLeftoverMessage() const =0; +}; + +//! abstract base class for public-key signers with recovery + +class PK_SignerWithRecovery : public virtual PK_SignatureSystemWithRecovery, public PK_Signer +{ +}; + +//! abstract base class for public-key verifiers with recovery + +/*! A PK_VerifierWithRecovery can also be used the same way as a PK_Verifier, + where the signature and the entire message is given to Verify() or + VerifyMessage() as input. +*/ +class PK_VerifierWithRecovery : public virtual PK_SignatureSystemWithRecovery, public PK_Verifier +{ +public: + //! create a new HashModule to accumulate leftover message + virtual HashModule * NewLeftoverMessageAccumulator(const byte *signature) const =0; + + //! partially recover a message from its signature, return length of recoverd message, or 0 if signature is invalid + /*! Preconditions: + \begin{itemize} + \item leftoverMessageAccumulator was obtained by calling NewLeftoverMessageAccumulator(signature) + \item HashModule::Final() has not been called on leftoverMessageAccumulator + \item length of signature == SignatureLength() + \item size of recoveredMessage == MaximumRecoverableLength() + \end{itemize} + */ + virtual unsigned int PartialRecover(HashModule *leftoverMessageAccumulator, byte *recoveredMessage) const =0; + + //! recover a message from its signature, return length of message, or 0 if signature is invalid + /*! This function should be equivalent to PartialRecover(NewLeftoverMessageAccumulator(signature), recoveredMessage). + Preconditions: + \begin{itemize} + \item length of signature == SignatureLength() + \item size of recoveredMessage == MaximumRecoverableLength() + \end{itemize} + */ + virtual unsigned int Recover(const byte *signature, byte *recoveredMessage) const =0; +}; + +//! abstract base class for domains of simple key agreement protocols + +/*! A key agreement domain is a set of parameters that must be shared + by two parties in a key agreement protocol, along with the algorithms + for generating key pairs and deriving agreed values. +*/ +class PK_SimpleKeyAgreementDomain +{ +public: + virtual ~PK_SimpleKeyAgreementDomain() {} + + //! return whether the domain parameters stored in this object are valid + virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const =0; + //! return length of agreed value produced + virtual unsigned int AgreedValueLength() const =0; + //! return length of private keys in this domain + virtual unsigned int PrivateKeyLength() const =0; + //! return length of public keys in this domain + virtual unsigned int PublicKeyLength() const =0; + //! generate private/public key pair + /*! Preconditions: + \begin{itemize} + \item size of privateKey == PrivateKeyLength() + \item size of publicKey == PublicKeyLength() + \end{itemize} + */ + virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; + /*! derive agreed value from your private key and couterparty's public key, return false in case of failure + //! Note: If you have previously validated the public key, use validateOtherPublicKey=false to save time. + //! Preconditions: + \begin{itemize} + \item size of agreedValue == AgreedValueLength() + \item length of privateKey == PrivateKeyLength() + \item length of otherPublicKey == PublicKeyLength() + \end{itemize} + */ + virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; +}; + +//! abstract base class for domains of authenticated key agreement protocols + +/*! In an authenticated key agreement protocol, each party has two + key pairs. The long-lived key pair is called the static key pair, + and the short-lived key pair is called the ephemeral key pair. +*/ +class PK_AuthenticatedKeyAgreementDomain +{ +public: + virtual ~PK_AuthenticatedKeyAgreementDomain() {} + + //! return whether the domain parameters stored in this object are valid + virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const =0; + //! return length of agreed value produced + virtual unsigned int AgreedValueLength() const =0; + + //! return length of static private keys in this domain + virtual unsigned int StaticPrivateKeyLength() const =0; + //! return length of static public keys in this domain + virtual unsigned int StaticPublicKeyLength() const =0; + //! generate static private/public key pair + /*! Preconditions: + \begin{itemize} + \item size of privateKey == StaticPrivateKeyLength() + \item size of publicKey == StaticPublicKeyLength() + \end{itemize} + */ + virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; + + //! return length of ephemeral private keys in this domain + virtual unsigned int EphemeralPrivateKeyLength() const =0; + //! return length of ephemeral public keys in this domain + virtual unsigned int EphemeralPublicKeyLength() const =0; + //! generate ephemeral private/public key pair + /*! Preconditions: + \begin{itemize} + \item size of privateKey == EphemeralPrivateKeyLength() + \item size of publicKey == EphemeralPublicKeyLength() + \end{itemize} + */ + virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! Note: The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + Preconditions: + \begin{itemize} + \item size of agreedValue == AgreedValueLength() + \item length of staticPrivateKey == StaticPrivateKeyLength() + \item length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \item length of staticOtherPublicKey == StaticPublicKeyLength() + \item length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + \end{itemize} + */ + virtual bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const =0; +}; + +//! abstract base class for all objects that support precomputation + +/*! The class defines a common interface for doing precomputation, + and loading and saving precomputation. +*/ +class PK_Precomputation +{ +public: + //! + virtual ~PK_Precomputation() {} + + //! + /*! The exact semantics of Precompute() is varies, but + typically it means calculate a table of n objects + that can be used later to speed up computation. + */ + virtual void Precompute(unsigned int n) =0; + + //! retrieve previously saved precomputation + virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) =0; + //! save precomputation for later use + virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const =0; +}; + +//! . +template class PK_WithPrecomputation : public virtual T, public virtual PK_Precomputation +{ +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/filters.cpp b/external/ours/library/crypto/src/shared/original-old/filters.cpp new file mode 100755 index 000000000..852a7b7fa --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/filters.cpp @@ -0,0 +1,424 @@ +// filters.cpp - written and placed in the public domain by Wei Dai + +#include "FirstCrypto.h" +#include "filters.h" +#include "mqueue.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +BitBucket g_bitBucket; + +Filter::Filter(BufferedTransformation *outQ) + : m_outQueue(outQ ? outQ : new MessageQueue) +{ +} + +void Filter::Detach(BufferedTransformation *newOut) +{ + m_outQueue.reset(newOut ? newOut : new MessageQueue); + NotifyAttachmentChange(); +} + +void Filter::Insert(Filter *filter) +{ + filter->m_outQueue.reset(m_outQueue.release()); + m_outQueue.reset(filter); + NotifyAttachmentChange(); +} + +// ************************************************************* + +FilterWithBufferedInput::BlockQueue::BlockQueue(unsigned int blockSize, unsigned int maxBlocks) + : m_buffer(blockSize * maxBlocks) +{ + ResetQueue(blockSize, maxBlocks); +} + +void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int maxBlocks) +{ + m_buffer.Resize(blockSize * maxBlocks); + m_blockSize = blockSize; + m_maxBlocks = maxBlocks; + m_size = 0; + m_begin = m_buffer; +} + +const byte *FilterWithBufferedInput::BlockQueue::GetBlock() +{ + if (m_size >= m_blockSize) + { + const byte *ptr = m_begin; + if ((m_begin+=m_blockSize) == m_buffer.End()) + m_begin = m_buffer; + m_size -= m_blockSize; + return ptr; + } + else + return nullptr; +} + +const byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBlocks) +{ + numberOfBlocks = STDMIN(numberOfBlocks, STDMIN((unsigned int)(m_buffer.End()-m_begin), m_size)/m_blockSize); + const byte *ptr = m_begin; + if ((m_begin+=m_blockSize*numberOfBlocks) == m_buffer.End()) + m_begin = m_buffer; + m_size -= m_blockSize*numberOfBlocks; + return ptr; +} + +unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) +{ + unsigned int size = m_size; + unsigned int numberOfBlocks = m_maxBlocks; + const byte *ptr = GetContigousBlocks(numberOfBlocks); + memcpy(outString, ptr, numberOfBlocks*m_blockSize); + memcpy(outString+numberOfBlocks*m_blockSize, m_begin, m_size); + m_size = 0; + return size; +} + +void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length) +{ + assert(m_size + length <= m_buffer.size); + byte *end = (m_size < (unsigned)(m_buffer+m_buffer.size-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size; + unsigned int len = STDMIN(length, (unsigned int)(m_buffer+m_buffer.size-end)); + memcpy(end, inString, len); + if (len < length) + memcpy(m_buffer, inString+len, length-len); + m_size += length; +} + +FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ) + : Filter(outQ), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize) + , m_firstInputDone(false) + , m_queue(1, m_firstSize) +{ +} + +void FilterWithBufferedInput::Put(byte inByte) +{ + Put(&inByte, 1); +} + +void FilterWithBufferedInput::Put(const byte *inString, unsigned int length) +{ + if (length == 0) + return; + + unsigned int newLength = m_queue.CurrentSize() + length; + + if (!m_firstInputDone && newLength >= m_firstSize) + { + unsigned int len = m_firstSize - m_queue.CurrentSize(); + m_queue.Put(inString, len); + FirstPut(m_queue.GetContigousBlocks(m_firstSize)); + assert(m_queue.CurrentSize() == 0); + m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); + + inString += len; + newLength -= m_firstSize; + m_firstInputDone = true; + } + + if (m_firstInputDone) + { + if (m_blockSize == 1) + { + while (newLength > m_lastSize && m_queue.CurrentSize() > 0) + { + unsigned int len = newLength - m_lastSize; + const byte *ptr = m_queue.GetContigousBlocks(len); + NextPut(ptr, len); + newLength -= len; + } + + if (newLength > m_lastSize) + { + unsigned int len = newLength - m_lastSize; + NextPut(inString, len); + inString += len; + newLength -= len; + } + } + else + { + while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) + { + NextPut(m_queue.GetBlock(), m_blockSize); + newLength -= m_blockSize; + } + + if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) + { + assert(m_queue.CurrentSize() < m_blockSize); + unsigned int len = m_blockSize - m_queue.CurrentSize(); + m_queue.Put(inString, len); + inString += len; + NextPut(m_queue.GetBlock(), m_blockSize); + newLength -= m_blockSize; + } + + while (newLength >= m_blockSize + m_lastSize) + { + NextPut(inString, m_blockSize); + inString += m_blockSize; + newLength -= m_blockSize; + } + } + } + + m_queue.Put(inString, newLength - m_queue.CurrentSize()); +} + +void FilterWithBufferedInput::MessageEnd(int propagation) +{ + if (!m_firstInputDone && m_firstSize==0) + FirstPut(nullptr); + + SecByteBlock temp(m_queue.CurrentSize()); + m_queue.GetAll(temp); + LastPut(temp, temp.size); + + m_firstInputDone = false; + m_queue.ResetQueue(1, m_firstSize); + + Filter::MessageEnd(propagation); +} + +void FilterWithBufferedInput::ForceNextPut() +{ + if (m_firstInputDone && m_queue.CurrentSize() >= m_blockSize) + NextPut(m_queue.GetBlock(), m_blockSize); +} + +// ************************************************************* + + + +// ************************************************************* + +ProxyFilter::ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ) + : FilterWithBufferedInput(firstSize, 1, lastSize, outQ), m_filter(filter), m_proxy(nullptr) +{ + if (m_filter.get()) + m_filter->Attach(m_proxy = new OutputProxy(*this, false)); +} + +void ProxyFilter::Flush(bool completeFlush, int propagation) +{ + if (m_filter.get()) + { + bool passSignal = m_proxy->GetPassSignal(); + m_proxy->SetPassSignal(false); + m_filter->Flush(completeFlush, -1); + m_proxy->SetPassSignal(passSignal); + } + Filter::Flush(completeFlush, propagation); +} + +void ProxyFilter::SetFilter(Filter *filter) +{ + bool passSignal = m_proxy ? m_proxy->GetPassSignal() : false; + m_filter.reset(filter); + if (filter) + { + std::unique_ptr temp(m_proxy = new OutputProxy(*this, passSignal)); + m_filter->TransferAllTo(*m_proxy); + m_filter->Attach(temp.release()); + } + else + m_proxy=nullptr; +} + +void ProxyFilter::NextPut(const byte *s, unsigned int len) +{ + if (m_filter.get()) + m_filter->Put(s, len); +} + +// ************************************************************* + +void StreamCipherFilter::Put(const byte *inString, unsigned int length) +{ + SecByteBlock temp(length); + cipher.ProcessString(temp, inString, length); + AttachedTransformation()->Put(temp, length); +} + +void HashFilter::Put(byte inByte) +{ + m_hashModule.Update(&inByte, 1); + if (m_putMessage) + AttachedTransformation()->Put(inByte); +} + +void HashFilter::Put(const byte *inString, unsigned int length) +{ + m_hashModule.Update(inString, length); + if (m_putMessage) + AttachedTransformation()->Put(inString, length); +} + +void HashFilter::MessageEnd(int propagation) +{ + SecByteBlock buf(m_hashModule.DigestSize()); + m_hashModule.Final(buf); + AttachedTransformation()->Put(buf, buf.size); + Filter::MessageEnd(propagation); +} + +// ************************************************************* + +HashVerifier::HashVerifier(HashModule &hm, BufferedTransformation *outQueue, word32 flags) + : FilterWithBufferedInput(flags & HASH_AT_BEGIN ? hm.DigestSize() : 0, 1, flags & HASH_AT_BEGIN ? 0 : hm.DigestSize(), outQueue) + , m_hashModule(hm), m_flags(flags) + , m_expectedHash(flags & HASH_AT_BEGIN ? hm.DigestSize() : 0), m_verified(false) +{ +} + +void HashVerifier::FirstPut(const byte *inString) +{ + if (m_flags & HASH_AT_BEGIN) + { + memcpy(m_expectedHash, inString, m_expectedHash.size); + if (m_flags & PUT_HASH) + AttachedTransformation()->Put(inString, m_expectedHash.size); + } +} + +void HashVerifier::NextPut(const byte *inString, unsigned int length) +{ + m_hashModule.Update(inString, length); + if (m_flags & PUT_MESSAGE) + AttachedTransformation()->Put(inString, length); +} + +void HashVerifier::LastPut(const byte *inString, unsigned int length) +{ + if (m_flags & HASH_AT_BEGIN) + { + assert(length == 0); + m_verified = m_hashModule.Verify(m_expectedHash); + } + else + { + m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString)); + if (m_flags & PUT_HASH) + AttachedTransformation()->Put(inString, length); + } + + if (m_flags & PUT_RESULT) + AttachedTransformation()->Put(m_verified); + + if ((m_flags & THROW_EXCEPTION) && !m_verified) + throw HashVerificationFailed(); +} + +// ************************************************************* + +void SignerFilter::MessageEnd(int propagation) +{ + SecByteBlock buf(m_signer.SignatureLength()); + m_signer.Sign(m_rng, m_messageAccumulator.release(), buf); + AttachedTransformation()->Put(buf, buf.size); + Filter::MessageEnd(propagation); + m_messageAccumulator.reset(m_signer.NewMessageAccumulator()); +} + +void VerifierFilter::PutSignature(const byte *sig) +{ + memcpy(m_signature.ptr, sig, m_signature.size); +} + +void VerifierFilter::MessageEnd(int propagation) +{ + AttachedTransformation()->Put((byte)m_verifier.Verify(m_messageAccumulator.release(), m_signature)); + Filter::MessageEnd(propagation); + m_messageAccumulator.reset(m_verifier.NewMessageAccumulator()); +} + +// ************************************************************* + +void Source::PumpAll() +{ + while (PumpMessages()) {} + while (Pump()) {} +} + +StringSource::StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue) + : Source(outQueue), m_store(string) +{ + if (pumpAll) + PumpAll(); +} + +StringSource::StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue) + : Source(outQueue), m_store(string, length) +{ + if (pumpAll) + PumpAll(); +} + +bool Store::GetNextMessage() +{ + if (!m_messageEnd && !AnyRetrievable()) + { + m_messageEnd=true; + return true; + } + else + return false; +} + +unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const +{ + if (m_messageEnd || count == 0) + return 0; + else + { + CopyTo(target); + if (GetAutoSignalPropagation()) + target.MessageEnd(GetAutoSignalPropagation()-1); + return 1; + } +} + +unsigned long StringStore::TransferTo(BufferedTransformation &target, unsigned long transferMax) +{ + unsigned long result = CopyTo(target, transferMax); + m_count += result; + return result; +} + +unsigned long StringStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const +{ + unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); + target.Put(m_store+m_count, len); + return len; +} + +unsigned long RandomNumberStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const +{ + unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); + for (unsigned int i=0; i m_outQueue; +}; + +//! . +class TransparentFilter : public Filter +{ +public: + TransparentFilter(BufferedTransformation *outQ=nullptr) : Filter(outQ) {} + void Put(byte inByte) {AttachedTransformation()->Put(inByte);} + void Put(const byte *inString, unsigned int length) {AttachedTransformation()->Put(inString, length);} +}; + +//! . +class OpaqueFilter : public Filter +{ +public: + OpaqueFilter(BufferedTransformation *outQ=nullptr) : Filter(outQ) {} + void Put(byte inByte) {} + void Put(const byte *inString, unsigned int length) {} +}; + +/*! FilterWithBufferedInput divides up the input stream into + a first block, a number of middle blocks, and a last block. + First and last blocks are optional, and middle blocks may + be a stream instead (i.e. blockSize == 1). +*/ +class FilterWithBufferedInput : public Filter +{ +public: + /// firstSize and lastSize may be 0, blockSize must be at least 1 + FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ); + void Put(byte inByte); + void Put(const byte *inString, unsigned int length); + void MessageEnd(int propagation=-1); + + /*! the input buffer may contain more than blockSize bytes if lastSize != 0 + ForceNextPut() forces a call to NextPut() if this is the case + */ + void ForceNextPut(); + +protected: + bool DidFirstPut() {return m_firstInputDone;} + + // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize) + // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)) + virtual void FirstPut(const byte *inString) =0; + // NextPut() is called if totalLength >= firstSize+blockSize+lastSize + // length parameter is always blockSize unless blockSize == 1 + virtual void NextPut(const byte *inString, unsigned int length) =0; + // LastPut() is always called + // if totalLength < firstSize then length == totalLength + // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize + // else lastSize <= length < lastSize+blockSize + virtual void LastPut(const byte *inString, unsigned int length) =0; + +private: + class BlockQueue + { + public: + BlockQueue(unsigned int blockSize, unsigned int maxBlocks); + void ResetQueue(unsigned int blockSize, unsigned int maxBlocks); + const byte *GetBlock(); + const byte *GetContigousBlocks(unsigned int &numberOfBlocks); + unsigned int GetAll(byte *outString); + void Put(const byte *inString, unsigned int length); + unsigned int CurrentSize() const {return m_size;} + unsigned int MaxSize() const {return m_buffer.size;} + + private: + SecByteBlock m_buffer; + unsigned int m_blockSize, m_maxBlocks, m_size; + byte *m_begin; + }; + + unsigned int m_firstSize, m_blockSize, m_lastSize; + bool m_firstInputDone; + BlockQueue m_queue; +}; + +//! . +class FilterWithInputQueue : public Filter +{ +public: + FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {} + void Put(byte inByte) {m_inQueue.Put(inByte);} + void Put(const byte *inString, unsigned int length) {m_inQueue.Put(inString, length);} + +protected: + ByteQueue m_inQueue; +}; + +//! Filter Wrapper for StreamCipher +class StreamCipherFilter : public Filter +{ +public: + StreamCipherFilter(StreamCipher &c, + BufferedTransformation *outQueue = nullptr) + : cipher(c), Filter(outQueue) {} + + void Put(byte inByte) + {AttachedTransformation()->Put(cipher.ProcessByte(inByte));} + + void Put(const byte *inString, unsigned int length); + +private: + StreamCipher &cipher; +}; + +//! Filter Wrapper for HashModule +class HashFilter : public Filter +{ +public: + HashFilter(HashModule &hm, BufferedTransformation *outQueue = nullptr, bool putMessage=false) + : Filter(outQueue), m_hashModule(hm), m_putMessage(putMessage) {} + + void MessageEnd(int propagation=-1); + + void Put(byte inByte); + void Put(const byte *inString, unsigned int length); + +private: + HashModule &m_hashModule; + bool m_putMessage; +}; + +//! Filter Wrapper for HashModule +class HashVerifier : public FilterWithBufferedInput +{ +public: + class HashVerificationFailed : public BufferedTransformation::Err + { + public: + HashVerificationFailed() + : BufferedTransformation::Err(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not correct") {} + }; + + enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16}; + HashVerifier(HashModule &hm, BufferedTransformation *outQueue = nullptr, word32 flags = HASH_AT_BEGIN | PUT_RESULT); + + bool GetLastResult() const {return m_verified;} + +protected: + void FirstPut(const byte *inString); + void NextPut(const byte *inString, unsigned int length); + void LastPut(const byte *inString, unsigned int length); + +private: + HashModule &m_hashModule; + word32 m_flags; + SecByteBlock m_expectedHash; + bool m_verified; +}; + +//! Filter Wrapper for PK_Signer +class SignerFilter : public Filter +{ +public: + SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *outQueue = nullptr) + : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewMessageAccumulator()), Filter(outQueue) {} + + void MessageEnd(int propagation); + + void Put(byte inByte) + {m_messageAccumulator->Update(&inByte, 1);} + + void Put(const byte *inString, unsigned int length) + {m_messageAccumulator->Update(inString, length);} + +private: + RandomNumberGenerator &m_rng; + const PK_Signer &m_signer; + member_ptr m_messageAccumulator; +}; + +//! Filter Wrapper for PK_Verifier +class VerifierFilter : public Filter +{ +public: + VerifierFilter(const PK_Verifier &verifier, BufferedTransformation *outQueue = nullptr) + : m_verifier(verifier), m_messageAccumulator(verifier.NewMessageAccumulator()) + , m_signature(verifier.SignatureLength()), Filter(outQueue) {} + + // this function must be called before MessageEnd() + void PutSignature(const byte *sig); + + void MessageEnd(int propagation); + + void Put(byte inByte) + {m_messageAccumulator->Update(&inByte, 1);} + + void Put(const byte *inString, unsigned int length) + {m_messageAccumulator->Update(inString, length);} + +private: + const PK_Verifier &m_verifier; + member_ptr m_messageAccumulator; + SecByteBlock m_signature; +}; + +//! A BufferedTransformation that doesn't produce any retrievable output +class Sink : public BufferedTransformation +{ +}; + +//! . +class BitBucket : public Sink +{ +public: + void Put(byte) {} + void Put(const byte *, unsigned int) {} +}; + +extern BitBucket g_bitBucket; + +//! Redirect input to another BufferedTransformation without owning it +class Redirector : public Sink +{ +public: + Redirector() : m_target(nullptr), m_passSignal(true) {} + Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {} + + void Redirect(BufferedTransformation &target) {m_target = ⌖} + void StopRedirect() {m_target = nullptr;} + bool GetPassSignal() const {return m_passSignal;} + void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} + + void Put(byte b) + {if (m_target) m_target->Put(b);} + void Put(const byte *string, unsigned int len) + {if (m_target) m_target->Put(string, len);} + void Flush(bool completeFlush, int propagation=-1) + {if (m_target && m_passSignal) m_target->Flush(completeFlush, propagation);} + void MessageEnd(int propagation=-1) + {if (m_target && m_passSignal) m_target->MessageEnd(propagation);} + void MessageSeriesEnd(int propagation=-1) + {if (m_target && m_passSignal) m_target->MessageSeriesEnd(propagation);} + + void ChannelPut(const std::string &channel, byte b) + {if (m_target) m_target->ChannelPut(channel, b);} + void ChannelPut(const std::string &channel, const byte *string, unsigned int len) + {if (m_target) m_target->ChannelPut(channel, string, len);} + void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1) + {if (m_target && m_passSignal) m_target->ChannelFlush(channel, completeFlush, propagation);} + void ChannelMessageEnd(const std::string &channel, int propagation=-1) + {if (m_target && m_passSignal) m_target->ChannelMessageEnd(channel, propagation);} + void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) + {if (m_target && m_passSignal) m_target->ChannelMessageSeriesEnd(channel, propagation);} + +private: + BufferedTransformation *m_target; + bool m_passSignal; +}; + +// Used By ProxyFilter +class OutputProxy : public Sink +{ +public: + OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {} + + bool GetPassSignal() const {return m_passSignal;} + void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} + + void Put(byte b) + {m_owner.AttachedTransformation()->Put(b);} + void Put(const byte *string, unsigned int len) + {m_owner.AttachedTransformation()->Put(string, len);} + void Flush(bool completeFlush, int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->Flush(completeFlush, propagation);} + void MessageEnd(int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->MessageEnd(propagation);} + void MessageSeriesEnd(int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->MessageSeriesEnd(propagation);} + + void ChannelPut(const std::string &channel, byte b) + {m_owner.AttachedTransformation()->ChannelPut(channel, b);} + void ChannelPut(const std::string &channel, const byte *string, unsigned int len) + {m_owner.AttachedTransformation()->ChannelPut(channel, string, len);} + void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation);} + void ChannelMessageEnd(const std::string &channel, int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageEnd(channel, propagation);} + void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation);} + +private: + BufferedTransformation &m_owner; + bool m_passSignal; +}; + +//! Base class for Filter classes that are proxies for a chain of other filters. +class ProxyFilter : public FilterWithBufferedInput +{ +public: + ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ); + + void Flush(bool completeFlush, int propagation=-1); + + void SetFilter(Filter *filter); + void NextPut(const byte *s, unsigned int len); + +protected: + member_ptr m_filter; + OutputProxy *m_proxy; +}; + +//! Append input to a string object +template +class StringSinkTemplate : public Sink +{ +public: + // VC60 workaround: no T::char_type + typedef typename T::traits_type::char_type char_type; + + StringSinkTemplate(T &output) + : m_output(output) {assert(sizeof(output[0])==1);} + void Put(byte b) + {m_output += (char_type)b;} + void Put(const byte *str, unsigned int bc) + {m_output.append((const char_type *)str, bc);} + +private: + T &m_output; +}; + +//! Append input to an std::string +typedef StringSinkTemplate StringSink; + +//! Copy input to a memory buffer +class ArraySink : public Sink +{ +public: + ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {} + + unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);} + unsigned long TotalPutLength() {return m_total;} + + void Put(byte b) + { + if (m_total < m_size) + m_buf[m_total] = b; + m_total++; + } + + void Put(const byte *str, unsigned int len) + { + if (m_total < m_size) + memcpy(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total))); + m_total += len; + } + +protected: + byte *m_buf; + unsigned int m_size; + unsigned long m_total; +}; + +//! Xor input to a memory buffer +class ArrayXorSink : public ArraySink +{ +public: + ArrayXorSink(byte *buf, unsigned int size) + : ArraySink(buf, size) {} + + void Put(byte b) + { + if (m_total < m_size) + m_buf[m_total] ^= b; + m_total++; + } + + void Put(const byte *str, unsigned int len) + { + if (m_total < m_size) + xorbuf(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total))); + m_total += len; + } +}; + +//! Provide implementation of SetAutoSignalPropagation and GetAutoSignalPropagation +class BufferedTransformationWithAutoSignal : virtual public BufferedTransformation +{ +public: + BufferedTransformationWithAutoSignal(int propagation=-1) : m_autoSignalPropagation(propagation) {} + + void SetAutoSignalPropagation(int propagation) + {m_autoSignalPropagation = propagation;} + int GetAutoSignalPropagation() const + {return m_autoSignalPropagation;} + +private: + int m_autoSignalPropagation; +}; + +//! A BufferedTransformation that only contains pre-existing output +class Store : public BufferedTransformationWithAutoSignal +{ +public: + Store() : m_messageEnd(false) {} + + void Put(byte) + {} + void Put(const byte *, unsigned int length) + {} + + virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) =0; + virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const =0; + + unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;} + bool GetNextMessage(); + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; + +private: + bool m_messageEnd; +}; + +//! . +class StringStore : public Store +{ +public: + StringStore(const char *string) + : m_store((const byte *)string), m_length(strlen(string)), m_count(0) {} + StringStore(const byte *string, unsigned int length) + : m_store(string), m_length(length), m_count(0) {} + template StringStore(const T &string) + : m_store((const byte *)string.data()), m_length(string.length()), m_count(0) {assert(sizeof(string[0])==1);} + + unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); + unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; + +private: + const byte *m_store; + unsigned int m_length, m_count; +}; + +//! . +class RandomNumberStore : public Store +{ +public: + RandomNumberStore(RandomNumberGenerator &rng, unsigned long length) + : m_rng(rng), m_length(length), m_count(0) {} + + unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); + unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; + +private: + RandomNumberGenerator &m_rng; + unsigned long m_length, m_count; +}; + +//! A Filter that pumps data into its attachment as input +class Source : public Filter +{ +public: + Source(BufferedTransformation *outQ) + : Filter(outQ) {} + + virtual unsigned long Pump(unsigned long pumpMax=ULONG_MAX) =0; + virtual unsigned int PumpMessages(unsigned int count=UINT_MAX) {return 0;} + void PumpAll(); + + void Put(byte) + {Pump(1);} + void Put(const byte *, unsigned int length) + {Pump(length);} + void MessageEnd(int propagation=-1) + {PumpAll();} +}; + +//! Turn a Store into a Source +class GeneralSource : public Source +{ +public: + GeneralSource(BufferedTransformation &store, bool pumpAll, BufferedTransformation *outQueue = nullptr) + : Source(outQueue), m_store(store) + { + if (pumpAll) PumpAll(); + } + + unsigned long Pump(unsigned long pumpMax=ULONG_MAX) + {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} + unsigned int PumpMessages(unsigned int count=UINT_MAX) + {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} + +private: + BufferedTransformation &m_store; +}; + +//! . +class StringSource : public Source +{ +public: + StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue = nullptr); + StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = nullptr); + +#ifdef __MWERKS__ // CW60 workaround + StringSource(const std::string &string, bool pumpAll, BufferedTransformation *outQueue = nullptr) +#else + template StringSource(const T &string, bool pumpAll, BufferedTransformation *outQueue = nullptr) +#endif + : Source(outQueue), m_store(string) + { + if (pumpAll) + PumpAll(); + } + + unsigned long Pump(unsigned long pumpMax=ULONG_MAX) + {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} + unsigned int PumpMessages(unsigned int count=UINT_MAX) + {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} + +private: + StringStore m_store; +}; + +//! . +class RandomNumberSource : public Source +{ +public: + RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = nullptr); + + unsigned long Pump(unsigned long pumpMax=ULONG_MAX) + {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} + unsigned int PumpMessages(unsigned int count=UINT_MAX) + {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} + +private: + RandomNumberStore m_store; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/iterhash.cpp b/external/ours/library/crypto/src/shared/original-old/iterhash.cpp new file mode 100755 index 000000000..1730ce941 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/iterhash.cpp @@ -0,0 +1,14 @@ +// iterhash.cpp - written and placed in the public domain by Wei Dai + +#include "FirstCrypto.h" +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef WORD64_AVAILABLE +template class IteratedHashBase; +#endif + +template class IteratedHashBase; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/iterhash.h b/external/ours/library/crypto/src/shared/original-old/iterhash.h new file mode 100755 index 000000000..a0abd0e73 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/iterhash.h @@ -0,0 +1,187 @@ +#ifndef CRYPTOPP_ITERHASH_H +#define CRYPTOPP_ITERHASH_H + +#include "cryptlib.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/*! The following classes are explicitly instantiated in iterhash.cpp + + IteratedHashBase + IteratedHashBase // #ifdef WORD64_AVAILABLE +*/ +template +class IteratedHashBase : public virtual HashModule +{ +public: + typedef T HashWordType; + + IteratedHashBase(unsigned int blockSize, unsigned int digestSize); + unsigned int DigestSize() const {return digest.size * sizeof(T);}; + void Update(const byte *input, unsigned int length); + +protected: + virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); + void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); + void Reinit(); + virtual void Init() =0; + virtual void HashBlock(const T *input) =0; + + unsigned int blockSize; + word32 countLo, countHi; // 64-bit bit count + SecBlock data; // Data buffer + SecBlock digest; // Message digest +}; + +template +IteratedHashBase::IteratedHashBase(unsigned int blockSize, unsigned int digestSize) + : blockSize(blockSize), countLo(0), countHi(0) + , data(blockSize/sizeof(T)), digest(digestSize/sizeof(T)) +{ +} + +template void IteratedHashBase::Update(const byte *input, unsigned int len) +{ + HashWordType tmp = countLo; + if ((countLo = tmp + ((word32)len << 3)) < tmp) + countHi++; // Carry from low to high + + int rshift = (8*sizeof(HashWordType)-3); + if (rshift<32) + { + countHi += len >> rshift; + } + + assert((blockSize & (blockSize-1)) == 0); // blockSize is a power of 2 + unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1); + + if (num != 0) + { + if ((num+len) >= blockSize) + { + memcpy((byte *)data.ptr+num, input, blockSize-num); + HashBlock(data); + input += (blockSize-num); + len-=(blockSize - num); + num=0; + // drop through and do the rest + } + else + { + memcpy((byte *)data.ptr+num, input, len); + return; + } + } + + // we now can process the input data in blocks of blockSize + // chars and save the leftovers to this->data. + if (len >= blockSize) + { + if (IsAligned(input)) + { + unsigned int leftOver = HashMultipleBlocks((T *)input, len); + input += (len - leftOver); + len = leftOver; + } + else + do + { // copy input first if it's not aligned correctly + memcpy(data, input, blockSize); + HashBlock(data); + input+=blockSize; + len-=blockSize; + } while (len >= blockSize); + } + + memcpy(data, input, len); +} + +template unsigned int IteratedHashBase::HashMultipleBlocks(const T *input, unsigned int length) +{ + do + { + HashBlock(input); + input += blockSize/sizeof(T); + length -= blockSize; + } + while (length >= blockSize); + return length; +} + +template void IteratedHashBase::PadLastBlock(unsigned int lastBlockSize, byte padFirst) +{ + unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1); + assert(num < blockSize); + ((byte *)data.ptr)[num++]=padFirst; + if (num <= lastBlockSize) + memset((byte *)data.ptr+num, 0, lastBlockSize-num); + else + { + memset((byte *)data.ptr+num, 0, blockSize-num); + HashBlock(data); + memset(data, 0, lastBlockSize); + } +} + +template void IteratedHashBase::Reinit() +{ + countLo = countHi = 0; + Init(); +} + +// provide empty definitions to avoid instantiation warnings +template void IteratedHashBase::Init() {} +template void IteratedHashBase::HashBlock(const T *input) {} + +//! . +template +class IteratedHash : public IteratedHashBase +{ +public: + typedef T HashWordType; + enum {HIGHFIRST = H, BLOCKSIZE = S}; + + IteratedHash(unsigned int digestSize) : IteratedHashBase(BLOCKSIZE, digestSize) {} + + inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount) + { + if (!CheckEndianess(HIGHFIRST)) + byteReverse(out, in, byteCount); + else if (in!=out) + memcpy(out, in, byteCount); + } + + void Final(byte *hash) + { + this->PadLastBlock(BLOCKSIZE - 2*sizeof(HashWordType)); + CorrectEndianess(this->data, this->data, BLOCKSIZE - 2*sizeof(HashWordType)); + + this->data[this->data.size-2] = HIGHFIRST ? this->countHi : this->countLo; + this->data[this->data.size-1] = HIGHFIRST ? this->countLo : this->countHi; + + vTransform(this->data); + CorrectEndianess(this->digest, this->digest, this->DigestSize()); + memcpy(hash, this->digest, this->DigestSize()); + + this->Reinit(); // reinit for next use + } + +protected: + void HashBlock(const HashWordType *input) + { + if (CheckEndianess(HIGHFIRST)) + vTransform(input); + else + { + byteReverse(this->data.ptr, input, (unsigned int)BLOCKSIZE); + vTransform(this->data); + } + } + + virtual void vTransform(const HashWordType *data) =0; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/md5.cpp b/external/ours/library/crypto/src/shared/original-old/md5.cpp new file mode 100755 index 000000000..68f60925a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/md5.cpp @@ -0,0 +1,109 @@ +// md5.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c +// any modifications are placed in the public domain + +#include "FirstCrypto.h" +#include "md5.h" + +NAMESPACE_BEGIN(CryptoPP) + +void MD5::Init() +{ + digest[0u] = 0x67452301L; + digest[1u] = 0xefcdab89L; + digest[2u] = 0x98badcfeL; + digest[3u] = 0x10325476L; +} + +void MD5::Transform (word32 *digest, const word32 *in) +{ +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, data, s) \ + w = rotlFixed(w + f(x, y, z) + data, s) + x + + word32 a, b, c, d; + + a=digest[0]; + b=digest[1]; + c=digest[2]; + d=digest[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + digest[0]+=a; + digest[1]+=b; + digest[2]+=c; + digest[3]+=d; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/md5.h b/external/ours/library/crypto/src/shared/original-old/md5.h new file mode 100755 index 000000000..d58d6eabd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/md5.h @@ -0,0 +1,24 @@ +#ifndef CRYPTOPP_MD5_H +#define CRYPTOPP_MD5_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// MD5 +/** 128 Bit Hash */ +class MD5 : public IteratedHash +{ +public: + enum {DIGESTSIZE = 16}; + MD5() : IteratedHash(DIGESTSIZE) {Init();} + static void Transform(word32 *digest, const word32 *data); + +protected: + void Init(); + void vTransform(const word32 *data) {Transform(digest, data);} +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/misc.cpp b/external/ours/library/crypto/src/shared/original-old/misc.cpp new file mode 100755 index 000000000..c1a7d078f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/misc.cpp @@ -0,0 +1,77 @@ +// misc.cpp - written and placed in the public domain by Wei Dai + +#include "FirstCrypto.h" +#include "misc.h" +#include "words.h" + +NAMESPACE_BEGIN(CryptoPP) + +byte OAEP_P_DEFAULT[1]; + +void xorbuf(byte *buf, const byte *mask, unsigned int count) +{ + if (((size_t)buf | (size_t)mask | count) % WORD_SIZE == 0) + XorWords((word *)buf, (const word *)mask, count/WORD_SIZE); + else + { + for (unsigned int i=0; i0; i/=2) + value ^= value >> i; + return (unsigned int)value&1; +} + +unsigned int BytePrecision(unsigned long value) +{ + unsigned int i; + for (i=sizeof(value); i; --i) + if (value >> (i-1)*8) + break; + + return i; +} + +unsigned int BitPrecision(unsigned long value) +{ + if (!value) + return 0; + + unsigned int l=0, h=8*sizeof(value); + + while (h-l > 1) + { + unsigned int t = (l+h)/2; + if (value >> t) + l = t; + else + h = t; + } + + return h; +} + +unsigned long Crop(unsigned long value, unsigned int size) +{ + if (size < 8*sizeof(value)) + return (value & ((1L << size) - 1)); + else + return value; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/misc.h b/external/ours/library/crypto/src/shared/original-old/misc.h new file mode 100755 index 000000000..862970a96 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/misc.h @@ -0,0 +1,689 @@ +#ifndef CRYPTOPP_MISC_H +#define CRYPTOPP_MISC_H + +#include "config.h" +#include +#include // CodeWarrior doesn't have memory.h +#include +#include + +#ifdef INTEL_INTRINSICS +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// ************** misc functions *************** + +#define GETBYTE(x, y) (uint32_t)(((x)>>(8*(y)))&255) +// this one may be faster on a Pentium +// #define GETBYTE(x, y) (((byte *)&(x))[y]) + +uint32_t Parity(unsigned long); +uint32_t BytePrecision(unsigned long); +uint32_t BitPrecision(unsigned long); +unsigned long Crop(unsigned long, uint32_t size); + +inline uint32_t bitsToBytes(uint32_t bitCount) +{ + return ((bitCount+7)/(8)); +} + +inline uint32_t bytesToWords(uint32_t byteCount) +{ + return ((byteCount+WORD_SIZE-1)/WORD_SIZE); +} + +inline uint32_t bitsToWords(uint32_t bitCount) +{ + return ((bitCount+WORD_BITS-1)/(WORD_BITS)); +} + +void xorbuf(byte *buf, const byte *mask, uint32_t count); +void xorbuf(byte *output, const byte *input, const byte *mask, uint32_t count); + +inline uint32_t RoundDownToMultipleOf(uint32_t n, uint32_t m) +{ + return n - n%m; +} + +inline uint32_t RoundUpToMultipleOf(uint32_t n, uint32_t m) +{ + return RoundDownToMultipleOf(n+m-1, m); +} + +template +inline bool IsAligned(const void *p) +{ + return (uintptr_t)p % sizeof(T) == 0; +} + +inline bool CheckEndianess(bool highFirst) +{ +#ifdef IS_LITTLE_ENDIAN + return !highFirst; +#else + return highFirst; +#endif +} + +template // can't use because GCC 2.95.2 doesn't have it +std::string IntToString(T a) +{ + if (a == 0) + return "0"; + bool negate = false; + if (a < 0) + { + negate = true; + a = -a; + } + std::string result; + while (a > 0) + { + result = char('0' + a % 10) + result; + a = a / 10; + } + if (negate) + result = "-" + result; + return result; +} + +// ************** rotate functions *************** + +template inline T rotlFixed(T x, uint32_t y) +{ + assert(y < sizeof(T)*8); + return (x<>(sizeof(T)*8-y)); +} + +template inline T rotrFixed(T x, uint32_t y) +{ + assert(y < sizeof(T)*8); + return (x>>y) | (x<<(sizeof(T)*8-y)); +} + +template inline T rotlVariable(T x, uint32_t y) +{ + assert(y < sizeof(T)*8); + return (x<>(sizeof(T)*8-y)); +} + +template inline T rotrVariable(T x, uint32_t y) +{ + assert(y < sizeof(T)*8); + return (x>>y) | (x<<(sizeof(T)*8-y)); +} + +template inline T rotlMod(T x, uint32_t y) +{ + y %= sizeof(T)*8; + return (x<>(sizeof(T)*8-y)); +} + +template inline T rotrMod(T x, uint32_t y) +{ + y %= sizeof(T)*8; + return (x>>y) | (x<<(sizeof(T)*8-y)); +} + +#ifdef INTEL_INTRINSICS + +template<> inline word32 rotlFixed(word32 x, uint32_t y) +{ + assert(y < 32); + return y ? _lrotl(x, y) : x; +} + +template<> inline word32 rotrFixed(word32 x, uint32_t y) +{ + assert(y < 32); + return y ? _lrotr(x, y) : x; +} + +template<> inline word32 rotlVariable(word32 x, uint32_t y) +{ + assert(y < 32); + return _lrotl(x, y); +} + +template<> inline word32 rotrVariable(word32 x, uint32_t y) +{ + assert(y < 32); + return _lrotr(x, y); +} + +template<> inline word32 rotlMod(word32 x, uint32_t y) +{ + return _lrotl(x, y); +} + +template<> inline word32 rotrMod(word32 x, uint32_t y) +{ + return _lrotr(x, y); +} + +#endif // #ifdef INTEL_INTRINSICS + +#ifdef PPC_INTRINSICS + +template<> inline word32 rotlFixed(word32 x, uint32_t y) +{ + assert(y < 32); + return y ? __rlwinm(x,y,0,31) : x; +} + +template<> inline word32 rotrFixed(word32 x, uint32_t y) +{ + assert(y < 32); + return y ? __rlwinm(x,32-y,0,31) : x; +} + +template<> inline word32 rotlVariable(word32 x, uint32_t y) +{ + assert(y < 32); + return (__rlwnm(x,y,0,31)); +} + +template<> inline word32 rotrVariable(word32 x, uint32_t y) +{ + assert(y < 32); + return (__rlwnm(x,32-y,0,31)); +} + +template<> inline word32 rotlMod(word32 x, uint32_t y) +{ + return (__rlwnm(x,y,0,31)); +} + +template<> inline word32 rotrMod(word32 x, uint32_t y) +{ + return (__rlwnm(x,32-y,0,31)); +} + +#endif // #ifdef PPC_INTRINSICS + +// ************** endian reversal *************** + +inline word16 byteReverse(word16 value) +{ + return rotlFixed(value, 8U); +} + +inline word32 byteReverse(word32 value) +{ +#ifdef PPC_INTRINSICS + // PPC: load reverse indexed instruction + return (word32)__lwbrx(&value,0); +#elif defined(FAST_ROTATE) + // 5 instructions with rotate instruction, 9 without + return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); +#else + // 6 instructions with rotate instruction, 8 without + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return rotlFixed(value, 16U); +#endif +} + +#ifdef WORD64_AVAILABLE +inline word64 byteReverse(word64 value) +{ +#ifdef SLOW_WORD64 + return (word64(byteReverse(word32(value))) << 32) | byteReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); + value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); + return rotlFixed(value, 32U); +#endif +} +#endif + +inline byte bitReverse(byte value) +{ + value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); + value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); + return rotlFixed(value, 4); +} + +inline word16 bitReverse(word16 value) +{ + value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); + value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); + value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); + return byteReverse(value); +} + +inline word32 bitReverse(word32 value) +{ + value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1); + value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2); + value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4); + return byteReverse(value); +} + +#ifdef WORD64_AVAILABLE +inline word64 bitReverse(word64 value) +{ +#ifdef SLOW_WORD64 + return (word64(bitReverse(word32(value))) << 32) | bitReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1); + value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2); + value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); + return byteReverse(value); +#endif +} +#endif + +template +inline T bitReverse(T value) +{ + if (sizeof(T) == 1) + return bitReverse((byte)value); + else if (sizeof(T) == 2) + return bitReverse((word16)value); + else if (sizeof(T) == 4) + return bitReverse((word32)value); + else + { +#ifdef WORD64_AVAILABLE + assert(sizeof(T) == 8); + return bitReverse((word64)value); +#else + assert(false); + return 0; +#endif + } +} + +template +void byteReverse(T *out, const T *in, uint32_t byteCount) +{ + uint32_t count = (byteCount+sizeof(T)-1)/sizeof(T); + for (uint32_t i=0; i +inline void GetUserKeyLittleEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) +{ + const uint32_t U = sizeof(T); + assert(inlen <= outlen*U); + memcpy(out, in, inlen); + memset((byte *)out+inlen, 0, outlen*U-inlen); +#ifndef IS_LITTLE_ENDIAN + byteReverse(out, out, inlen); +#endif +} + +template +inline void GetUserKeyBigEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) +{ + const uint32_t U = sizeof(T); + assert(inlen <= outlen*U); + memcpy(out, in, inlen); + memset((byte *)out+inlen, 0, outlen*U-inlen); +#ifdef IS_LITTLE_ENDIAN + byteReverse(out, out, inlen); +#endif +} + +// Fetch 2 words from user's buffer into "a", "b" in LITTLE-endian order +template +inline void GetBlockLittleEndian(const byte *block, T &a, T &b) +{ +#ifdef IS_LITTLE_ENDIAN + a = ((T *)block)[0]; + b = ((T *)block)[1]; +#else + a = byteReverse(((T *)block)[0]); + b = byteReverse(((T *)block)[1]); +#endif +} + +// Put 2 words back into user's buffer in LITTLE-endian order +template +inline void PutBlockLittleEndian(byte *block, T a, T b) +{ +#ifdef IS_LITTLE_ENDIAN + ((T *)block)[0] = a; + ((T *)block)[1] = b; +#else + ((T *)block)[0] = byteReverse(a); + ((T *)block)[1] = byteReverse(b); +#endif +} + +// Fetch 4 words from user's buffer into "a", "b", "c", "d" in LITTLE-endian order +template +inline void GetBlockLittleEndian(const byte *block, T &a, T &b, T &c, T &d) +{ +#ifdef IS_LITTLE_ENDIAN + a = ((T *)block)[0]; + b = ((T *)block)[1]; + c = ((T *)block)[2]; + d = ((T *)block)[3]; +#else + a = byteReverse(((T *)block)[0]); + b = byteReverse(((T *)block)[1]); + c = byteReverse(((T *)block)[2]); + d = byteReverse(((T *)block)[3]); +#endif +} + +// Put 4 words back into user's buffer in LITTLE-endian order +template +inline void PutBlockLittleEndian(byte *block, T a, T b, T c, T d) +{ +#ifdef IS_LITTLE_ENDIAN + ((T *)block)[0] = a; + ((T *)block)[1] = b; + ((T *)block)[2] = c; + ((T *)block)[3] = d; +#else + ((T *)block)[0] = byteReverse(a); + ((T *)block)[1] = byteReverse(b); + ((T *)block)[2] = byteReverse(c); + ((T *)block)[3] = byteReverse(d); +#endif +} + +// Fetch 2 words from user's buffer into "a", "b" in BIG-endian order +template +inline void GetBlockBigEndian(const byte *block, T &a, T &b) +{ +#ifndef IS_LITTLE_ENDIAN + a = ((T *)block)[0]; + b = ((T *)block)[1]; +#else + a = byteReverse(((T *)block)[0]); + b = byteReverse(((T *)block)[1]); +#endif +} + +// Put 2 words back into user's buffer in BIG-endian order +template +inline void PutBlockBigEndian(byte *block, T a, T b) +{ +#ifndef IS_LITTLE_ENDIAN + ((T *)block)[0] = a; + ((T *)block)[1] = b; +#else + ((T *)block)[0] = byteReverse(a); + ((T *)block)[1] = byteReverse(b); +#endif +} + +// Fetch 4 words from user's buffer into "a", "b", "c", "d" in BIG-endian order +template +inline void GetBlockBigEndian(const byte *block, T &a, T &b, T &c, T &d) +{ +#ifndef IS_LITTLE_ENDIAN + a = ((T *)block)[0]; + b = ((T *)block)[1]; + c = ((T *)block)[2]; + d = ((T *)block)[3]; +#else + a = byteReverse(((T *)block)[0]); + b = byteReverse(((T *)block)[1]); + c = byteReverse(((T *)block)[2]); + d = byteReverse(((T *)block)[3]); +#endif +} + +// Put 4 words back into user's buffer in BIG-endian order +template +inline void PutBlockBigEndian(byte *block, T a, T b, T c, T d) +{ +#ifndef IS_LITTLE_ENDIAN + ((T *)block)[0] = a; + ((T *)block)[1] = b; + ((T *)block)[2] = c; + ((T *)block)[3] = d; +#else + ((T *)block)[0] = byteReverse(a); + ((T *)block)[1] = byteReverse(b); + ((T *)block)[2] = byteReverse(c); + ((T *)block)[3] = byteReverse(d); +#endif +} + +template +std::string WordToString(T value, bool highFirst = true) +{ + if (!CheckEndianess(highFirst)) + value = byteReverse(value); + + return std::string((char *)&value, sizeof(value)); +} + +template +T StringToWord(const std::string &str, bool highFirst = true) +{ + T value = 0; + memcpy(&value, str.data(), STDMIN(sizeof(value), str.size())); + return CheckEndianess(highFirst) ? value : byteReverse(value); +} + +// ************** key length query *************** + +/// support query of fixed key length +template +class FixedKeyLength +{ +public: + enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N}; + /// returns the key length + static uint32_t KeyLength(uint32_t) {return KEYLENGTH;} +}; + +/// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) +template +class VariableKeyLength +{ +public: + enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q}; + /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) + static uint32_t KeyLength(uint32_t n) + { + assert(KEYLENGTH_MULTIPLE > 0 && MIN_KEYLENGTH % KEYLENGTH_MULTIPLE == 0 && MAX_KEYLENGTH % KEYLENGTH_MULTIPLE == 0); + if (n < MIN_KEYLENGTH) + return MIN_KEYLENGTH; + else if (n > MAX_KEYLENGTH) + return MAX_KEYLENGTH; + else + return RoundUpToMultipleOf(n, KEYLENGTH_MULTIPLE); + } +}; + +/// support query of key length that's the same as another class +template +class SameKeyLengthAs +{ +public: + enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH}; + /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) + static uint32_t KeyLength(uint32_t keylength) + {return T::KeyLength(keylength);} +}; + +// ************** secure memory allocation *************** + +#ifdef SECALLOC_DEFAULT +#define SecAlloc(type, number) (new type[(number)]) +#define SecFree(ptr, number) (memset((ptr), 0, (number)*sizeof(*(ptr))), delete [] (ptr)) +#else +#define SecAlloc(type, number) (new type[(number)]) +#define SecFree(ptr, number) (delete [] (ptr)) +#endif + +//! a block of memory allocated using SecAlloc +template struct SecBlock +{ + explicit SecBlock(uint32_t size=0) + : size(size) {ptr = SecAlloc(T, size);} + SecBlock(const SecBlock &t) + : size(t.size) {ptr = SecAlloc(T, size); memcpy(ptr, t.ptr, size*sizeof(T));} + SecBlock(const T *t, uint32_t len) + : size(len) {ptr = SecAlloc(T, len); memcpy(ptr, t, len*sizeof(T));} + ~SecBlock() + {SecFree(ptr, size);} + +#if defined(__GNUC__) || defined(__BCPLUSPLUS__) + operator const void *() const + {return ptr;} + operator void *() + {return ptr;} +#endif +#if defined(__GNUC__) // reduce warnings + operator const void *() + {return ptr;} +#endif + + operator const T *() const + {return ptr;} + operator T *() + {return ptr;} +#if defined(__GNUC__) // reduce warnings + operator const T *() + {return ptr;} +#endif + +// CodeWarrior defines _MSC_VER +#if !defined(_MSC_VER) || defined(__MWERKS__) + T *operator +(uint32_t offset) + {return ptr+offset;} + const T *operator +(uint32_t offset) const + {return ptr+offset;} + T& operator[](uint32_t index) + {assert(index &t) + { + New(t.size); + memcpy(ptr, t.ptr, size*sizeof(T)); + } + + SecBlock& operator=(const SecBlock &t) + { + Assign(t); + return *this; + } + + bool operator==(const SecBlock &t) const + { + return size == t.size && memcmp(ptr, t.ptr, size*sizeof(T)) == 0; + } + + bool operator!=(const SecBlock &t) const + { + return !operator==(t); + } + + void New(uint32_t newSize) + { + if (newSize != size) + { + T *newPtr = SecAlloc(T, newSize); + SecFree(ptr, size); + ptr = newPtr; + size = newSize; + } + } + + void CleanNew(uint32_t newSize) + { + if (newSize != size) + { + T *newPtr = SecAlloc(T, newSize); + SecFree(ptr, size); + ptr = newPtr; + size = newSize; + } + memset(ptr, 0, size*sizeof(T)); + } + + void Grow(uint32_t newSize) + { + if (newSize > size) + { + T *newPtr = SecAlloc(T, newSize); + memcpy(newPtr, ptr, size*sizeof(T)); + SecFree(ptr, size); + ptr = newPtr; + size = newSize; + } + } + + void CleanGrow(uint32_t newSize) + { + if (newSize > size) + { + T *newPtr = SecAlloc(T, newSize); + memcpy(newPtr, ptr, size*sizeof(T)); + memset(newPtr+size, 0, (newSize-size)*sizeof(T)); + SecFree(ptr, size); + ptr = newPtr; + size = newSize; + } + } + + void Resize(uint32_t newSize) + { + if (newSize != size) + { + T *newPtr = SecAlloc(T, newSize); + memcpy(newPtr, ptr, STDMIN(newSize, size)*sizeof(T)); + SecFree(ptr, size); + ptr = newPtr; + size = newSize; + } + } + + void swap(SecBlock &b); + + uint32_t size; + T *ptr; +}; + +template void SecBlock::swap(SecBlock &b) +{ + std::swap(size, b.size); + std::swap(ptr, b.ptr); +} + +typedef SecBlock SecByteBlock; +typedef SecBlock SecWordBlock; + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template +inline void swap(CryptoPP::SecBlock &a, CryptoPP::SecBlock &b) +{ + a.swap(b); +} + +NAMESPACE_END + +#endif // MISC_H diff --git a/external/ours/library/crypto/src/shared/original-old/mqueue.cpp b/external/ours/library/crypto/src/shared/original-old/mqueue.cpp new file mode 100755 index 000000000..314d6f758 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/mqueue.cpp @@ -0,0 +1,44 @@ +// mqueue.cpp - written and placed in the public domain by Wei Dai + +#include "FirstCrypto.h" +#include "mqueue.h" + +NAMESPACE_BEGIN(CryptoPP) + +MessageQueue::MessageQueue(unsigned int nodeSize) + : m_queue(nodeSize), m_lengths(1, 0) +{ +} + +bool MessageQueue::RetrieveNextMessage() +{ + if (NumberOfMessages() > 0 && !AnyRetrievable()) + { + m_lengths.pop_front(); + return true; + } + else + return false; +} + +unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const +{ + ByteQueue::Walker walker(m_queue); + std::deque::const_iterator it = m_lengths.begin(); + unsigned int i; + for (i=0; i + +NAMESPACE_BEGIN(CryptoPP) + +//! Message Queue +class MessageQueue : public BufferedTransformationWithAutoSignal +{ +public: + MessageQueue(unsigned int nodeSize=256); + + void Put(byte inByte) + {m_queue.Put(inByte); m_lengths.back()++;} + void Put(const byte *inString, unsigned int length) + {m_queue.Put(inString, length); m_lengths.back()+=length;} + + unsigned long MaxRetrievable() const + {return m_lengths.front();} + bool AnyRetrievable() const + {return m_lengths.front() > 0;} + + unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) + {return Got(m_queue.TransferTo(target, STDMIN(MaxRetrievable(), transferMax)));} + unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const + {return m_queue.CopyTo(target, STDMIN(MaxRetrievable(), copyMax));} + + void MessageEnd(int=-1) + {m_lengths.push_back(0);} + + unsigned long TotalBytesRetrievable() const + {return m_queue.MaxRetrievable();} + unsigned int NumberOfMessages() const + {return m_lengths.size()-1;} + bool RetrieveNextMessage(); + + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; + + void swap(MessageQueue &rhs); + +private: + unsigned long Got(unsigned long length) + {assert(m_lengths.front() >= length); m_lengths.front() -= length; return length;} + + ByteQueue m_queue; + std::deque m_lengths; +}; + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/queue.cpp b/external/ours/library/crypto/src/shared/original-old/queue.cpp new file mode 100755 index 000000000..590b8899d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/queue.cpp @@ -0,0 +1,500 @@ +// queue.cpp - written and placed in the public domain by Wei Dai + +#include "FirstCrypto.h" +#include "queue.h" +#include "filters.h" + +NAMESPACE_BEGIN(CryptoPP) + +// this class for use by ByteQueue only +class ByteQueueNode +{ +public: + ByteQueueNode(unsigned int maxSize) + : buf(maxSize) + { + m_head = m_tail = 0; + next = 0; + } + + inline unsigned int MaxSize() const { return buf.size; } + + inline unsigned int CurrentSize() const + { + return m_tail - m_head; + } + + inline bool UsedUp() const + { + return (m_head == MaxSize()); + } + + inline void Clear() + { + m_head = m_tail = 0; + } + + inline unsigned int Put(byte inByte) + { + if (MaxSize() == m_tail) + return 0; + + buf[m_tail++] = inByte; + return 1; + } + + inline unsigned int Put(const byte *inString, unsigned int length) + { + unsigned int l = STDMIN(length, MaxSize() - m_tail); + memcpy(buf + m_tail, inString, l); + m_tail += l; + return l; + } + + inline unsigned int Peek(byte &outByte) const + { + if (m_tail == m_head) + return 0; + + outByte = buf[m_head]; + return 1; + } + + inline unsigned int Peek(byte *target, unsigned int copyMax) const + { + unsigned int len = STDMIN(copyMax, m_tail - m_head); + memcpy(target, buf + m_head, len); + return len; + } + + inline unsigned int CopyTo(BufferedTransformation &target) const + { + unsigned int len = m_tail - m_head; + target.Put(buf + m_head, len); + return len; + } + + inline unsigned int CopyTo(BufferedTransformation &target, unsigned int copyMax) const + { + unsigned int len = STDMIN(copyMax, m_tail - m_head); + target.Put(buf + m_head, len); + return len; + } + + inline unsigned int Get(byte &outByte) + { + unsigned int len = Peek(outByte); + m_head += len; + return len; + } + + inline unsigned int Get(byte *outString, unsigned int getMax) + { + unsigned int len = Peek(outString, getMax); + m_head += len; + return len; + } + + inline unsigned int TransferTo(BufferedTransformation &target) + { + unsigned int len = CopyTo(target); + m_head += len; + return len; + } + + inline unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax) + { + unsigned int len = CopyTo(target, transferMax); + m_head += len; + return len; + } + + inline unsigned int Skip(unsigned int skipMax) + { + unsigned int len = STDMIN(skipMax, m_tail - m_head); + m_head += len; + return len; + } + + inline byte operator[](unsigned int i) const + { + return buf[m_head + i]; + } + + ByteQueueNode *next; + + SecByteBlock buf; + unsigned int m_head, m_tail; +}; + +// ******************************************************** + +ByteQueue::ByteQueue(unsigned int m_nodeSize) + : m_nodeSize(0), m_lazyLength(0), m_lazyString(nullptr) +{ + m_head = m_tail = new ByteQueueNode(m_nodeSize); +} + +ByteQueue::ByteQueue(const ByteQueue ©) +{ + CopyFrom(copy); +} + +void ByteQueue::CopyFrom(const ByteQueue ©) +{ + m_lazyLength = 0; + m_nodeSize = copy.m_nodeSize; + m_head = m_tail = new ByteQueueNode(*copy.m_head); + + for (ByteQueueNode *current = copy.m_head->next; current; current = current->next) + { + m_tail->next = new ByteQueueNode(*current); + m_tail = m_tail->next; + } + + m_tail->next = nullptr; + + Put(copy.m_lazyString, copy.m_lazyLength); +} + +ByteQueue::~ByteQueue() +{ + Destroy(); +} + +void ByteQueue::Destroy() +{ + ByteQueueNode *next; + + for (ByteQueueNode *current = m_head; current; current = next) + { + next = current->next; + delete current; + } +} + +unsigned long ByteQueue::CurrentSize() const +{ + unsigned long size = 0; + + for (ByteQueueNode *current = m_head; current; current = current->next) + size += current->CurrentSize(); + + return size + m_lazyLength; +} + +bool ByteQueue::IsEmpty() const +{ + return m_head == m_tail && m_head->CurrentSize() == 0 && m_lazyLength == 0; +} + +void ByteQueue::Clear() +{ + Destroy(); + m_head = m_tail = new ByteQueueNode(m_nodeSize); + m_lazyLength = 0; +} + +void ByteQueue::Put(byte inByte) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + if (!m_tail->Put(inByte)) + { + m_tail->next = new ByteQueueNode(m_nodeSize); + m_tail = m_tail->next; + m_tail->Put(inByte); + } +} + +void ByteQueue::Put(const byte *inString, unsigned int length) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + unsigned int len; + while ((len = m_tail->Put(inString, length)) < length) + { + m_tail->next = new ByteQueueNode(m_nodeSize); + m_tail = m_tail->next; + inString += len; + length -= len; + } +} + +void ByteQueue::CleanupUsedNodes() +{ + while (m_head != m_tail && m_head->UsedUp()) + { + ByteQueueNode *temp = m_head; + m_head = m_head->next; + delete temp; + } + + if (m_head->CurrentSize() == 0) + m_head->Clear(); +} + +void ByteQueue::LazyPut(const byte *inString, unsigned int size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + m_lazyString = inString; + m_lazyLength = size; +} + +void ByteQueue::FinalizeLazyPut() +{ + unsigned int len = m_lazyLength; + m_lazyLength = 0; + Put(m_lazyString, len); +} + +unsigned int ByteQueue::Get(byte &outByte) +{ + if (m_head->Get(outByte)) + { + if (m_head->UsedUp()) + CleanupUsedNodes(); + return 1; + } + else if (m_lazyLength > 0) + { + outByte = *m_lazyString++; + m_lazyLength--; + return 1; + } + else + return 0; +} + +unsigned int ByteQueue::Get(byte *outString, unsigned int getMax) +{ + ArraySink sink(outString, getMax); + return TransferTo(sink, getMax); +} + +unsigned int ByteQueue::Peek(byte &outByte) const +{ + if (m_head->Peek(outByte)) + return 1; + else if (m_lazyLength > 0) + { + outByte = *m_lazyString; + return 1; + } + else + return 0; +} + +unsigned int ByteQueue::Peek(byte *outString, unsigned int peekMax) const +{ + ArraySink sink(outString, peekMax); + return CopyTo(sink, peekMax); +} + +unsigned long ByteQueue::Skip(unsigned long skipMax) +{ + return TransferTo(g_bitBucket, skipMax); +} + +unsigned long ByteQueue::TransferTo(BufferedTransformation &target, unsigned long transferMax) +{ + unsigned long bytesLeft = transferMax; + for (ByteQueueNode *current = m_head; bytesLeft && current; current = current->next) + bytesLeft -= current->TransferTo(target, bytesLeft); + CleanupUsedNodes(); + + unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); + if (len) + { + target.Put(m_lazyString, len); + m_lazyString += len; + m_lazyLength -= len; + bytesLeft -= len; + } + return transferMax - bytesLeft; +} + +unsigned long ByteQueue::CopyTo(BufferedTransformation &target, unsigned long copyMax) const +{ + unsigned long bytesLeft = copyMax; + for (ByteQueueNode *current = m_head; bytesLeft && current; current = current->next) + bytesLeft -= current->CopyTo(target, bytesLeft); + if (bytesLeft && m_lazyLength) + { + unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); + target.Put(m_lazyString, len); + bytesLeft -= len; + } + return copyMax - bytesLeft; +} + +void ByteQueue::Unget(byte inByte) +{ + Unget(&inByte, 1); +} + +void ByteQueue::Unget(const byte *inString, unsigned int length) +{ + ByteQueueNode *newHead = new ByteQueueNode(length); + newHead->next = m_head; + m_head = newHead; + m_head->Put(inString, length); +} +/* +byte * ByteQueue::Spy(unsigned int &contiguousSize) +{ + contiguousSize = m_head->m_tail - m_head->m_head; + return m_head->buf + m_head->m_head; +} +*/ +const byte * ByteQueue::Spy(unsigned int &contiguousSize) const +{ + contiguousSize = m_head->m_tail - m_head->m_head; + if (contiguousSize == 0 && m_lazyLength > 0) + { + contiguousSize = m_lazyLength; + return m_lazyString; + } + else + return m_head->buf + m_head->m_head; +} + +byte * ByteQueue::MakeNewSpace(unsigned int &contiguousSize) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + if (m_tail->m_tail == m_tail->MaxSize()) + { + m_tail->next = new ByteQueueNode(m_nodeSize); + m_tail = m_tail->next; + } + + contiguousSize = m_tail->MaxSize() - m_tail->m_tail; + return m_tail->buf + m_tail->m_tail; +} + +void ByteQueue::OccupyNewSpace(unsigned int size) +{ + m_tail->m_tail += size; + assert(m_tail->m_tail <= m_tail->MaxSize()); +} + +ByteQueue & ByteQueue::operator=(const ByteQueue &rhs) +{ + Destroy(); + CopyFrom(rhs); + return *this; +} + +bool ByteQueue::operator==(const ByteQueue &rhs) const +{ + const unsigned long currentSize = CurrentSize(); + + if (currentSize != rhs.CurrentSize()) + return false; + + Walker walker1(*this), walker2(rhs); + byte b1, b2; + + while (walker1.Get(b1) && walker2.Get(b2)) + if (b1 != b2) + return false; + + return true; +} + +byte ByteQueue::operator[](unsigned long i) const +{ + for (ByteQueueNode *current = m_head; current; current = current->next) + { + if (i < current->CurrentSize()) + return (*current)[i]; + + i -= current->CurrentSize(); + } + + assert(i < m_lazyLength); + return m_lazyString[i]; +} + +void ByteQueue::swap(ByteQueue &rhs) +{ + std::swap(m_nodeSize, rhs.m_nodeSize); + std::swap(m_head, rhs.m_head); + std::swap(m_tail, rhs.m_tail); + std::swap(m_lazyString, rhs.m_lazyString); + std::swap(m_lazyLength, rhs.m_lazyLength); +} + +// ******************************************************** + +unsigned int ByteQueue::Walker::Get(byte &outByte) +{ + ArraySink sink(&outByte, 1); + return TransferTo(sink, 1); +} + +unsigned int ByteQueue::Walker::Get(byte *outString, unsigned int getMax) +{ + ArraySink sink(outString, getMax); + return TransferTo(sink, getMax); +} + +unsigned int ByteQueue::Walker::Peek(byte &outByte) const +{ + ArraySink sink(&outByte, 1); + return CopyTo(sink, 1); +} + +unsigned int ByteQueue::Walker::Peek(byte *outString, unsigned int peekMax) const +{ + ArraySink sink(outString, peekMax); + return CopyTo(sink, peekMax); +} + +unsigned long ByteQueue::Walker::TransferTo(BufferedTransformation &target, unsigned long transferMax) +{ + unsigned long bytesLeft = transferMax; + while (m_node) + { + unsigned int len = STDMIN(bytesLeft, (unsigned long)m_node->CurrentSize() - m_offset); + target.Put(m_node->buf + m_node->m_head + m_offset, len); + m_position += len; + bytesLeft -= len; + + if (!bytesLeft) + { + m_offset += len; + break; + } + + m_node = m_node->next; + m_offset = 0; + } + + unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); + if (len) + { + target.Put(m_lazyString, len); + m_lazyString += len; + m_lazyLength -= len; + bytesLeft -= len; + } + return transferMax - bytesLeft; +} + +unsigned long ByteQueue::Walker::Skip(unsigned long skipMax) +{ + return TransferTo(g_bitBucket, skipMax); +} + +unsigned long ByteQueue::Walker::CopyTo(BufferedTransformation &target, unsigned long copyMax) const +{ + return Walker(*this).TransferTo(target, copyMax); +} + +NAMESPACE_END \ No newline at end of file diff --git a/external/ours/library/crypto/src/shared/original-old/queue.h b/external/ours/library/crypto/src/shared/original-old/queue.h new file mode 100755 index 000000000..76cf58d7f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/queue.h @@ -0,0 +1,128 @@ +// specification file for an unlimited queue for storing bytes + +#ifndef CRYPTOPP_QUEUE_H +#define CRYPTOPP_QUEUE_H + +#include "cryptlib.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +/** The queue is implemented as a linked list of arrays, but you don't need to + know about that. So just ignore this next line. :) */ +class ByteQueueNode; + +//! Byte Queue +class ByteQueue : public BufferedTransformation +{ +public: + ByteQueue(unsigned int m_nodeSize=256); + ByteQueue(const ByteQueue ©); + ~ByteQueue(); + + unsigned long MaxRetrievable() const + {return CurrentSize();} + bool AnyRetrievable() const + {return !IsEmpty();} + + void Put(byte inByte); + void Put(const byte *inString, unsigned int length); + + unsigned int Get(byte &outByte); + unsigned int Get(byte *outString, unsigned int getMax); + + unsigned int Peek(byte &outByte) const; + unsigned int Peek(byte *outString, unsigned int peekMax) const; + + unsigned long Skip(unsigned long skipMax=ULONG_MAX); + unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); + unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; + + // these member functions are not inherited + unsigned long CurrentSize() const; + bool IsEmpty() const; + + void Clear(); + + void Unget(byte inByte); + void Unget(const byte *inString, unsigned int length); + + const byte * Spy(unsigned int &contiguousSize) const; + + byte * MakeNewSpace(unsigned int &contiguousSize); + void OccupyNewSpace(unsigned int size); + + void LazyPut(const byte *inString, unsigned int size); + void FinalizeLazyPut(); + + ByteQueue & operator=(const ByteQueue &rhs); + bool operator==(const ByteQueue &rhs) const; + byte operator[](unsigned long i) const; + void swap(ByteQueue &rhs); + + class Walker : public BufferedTransformation + { + public: + Walker(const ByteQueue &queue) + : m_queue(queue), m_node(queue.m_head), m_position(0), m_offset(0) + , m_lazyString(queue.m_lazyString), m_lazyLength(queue.m_lazyLength) {} + + unsigned long MaxRetrievable() const + {return m_queue.CurrentSize() - m_position;} + + void Put(byte inByte) {} + void Put(const byte *inString, unsigned int length) {} + + unsigned int Get(byte &outByte); + unsigned int Get(byte *outString, unsigned int getMax); + + unsigned int Peek(byte &outByte) const; + unsigned int Peek(byte *outString, unsigned int peekMax) const; + + unsigned long Skip(unsigned long skipMax=ULONG_MAX); + unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); + unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; + + private: + const ByteQueue &m_queue; + const ByteQueueNode *m_node; + unsigned int m_position, m_offset; + const byte *m_lazyString; + unsigned int m_lazyLength; + }; + + friend class Walker; + +private: + void CleanupUsedNodes(); + void CopyFrom(const ByteQueue ©); + void Destroy(); + + unsigned int m_nodeSize; + ByteQueueNode *m_head, *m_tail; + const byte *m_lazyString; + unsigned int m_lazyLength; +}; + +//! use this to make sure LazyPut is finalized in event of exception +class LazyPutter +{ +public: + LazyPutter(ByteQueue &bq, const byte *inString, unsigned int size) + : m_bq(bq) {bq.LazyPut(inString, size);} + ~LazyPutter() + {try {m_bq.FinalizeLazyPut();} catch(...) {}} +private: + ByteQueue &m_bq; +}; + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/smartptr.h b/external/ours/library/crypto/src/shared/original-old/smartptr.h new file mode 100755 index 000000000..f5c0b41bd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/smartptr.h @@ -0,0 +1,195 @@ +#ifndef CRYPTOPP_SMARTPTR_H +#define CRYPTOPP_SMARTPTR_H + +#include "config.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +template class member_ptr +{ +public: + explicit member_ptr(T *p = nullptr) : m_p(p) {} + + ~member_ptr(); + + const T& operator*() const { return *m_p; } + T& operator*() { return *m_p; } + + const T* operator->() const { return m_p; } + T* operator->() { return m_p; } + + const T* get() const { return m_p; } + T* get() { return m_p; } + + T* release() + { + T *old_p = m_p; + m_p = 0; + return old_p; + } + + void reset(T *p = 0); + +protected: + member_ptr(const member_ptr& rhs); // copy not allowed + void operator=(const member_ptr& rhs); // assignment not allowed + + T *m_p; +}; + +template member_ptr::~member_ptr() {delete m_p;} +template void member_ptr::reset(T *p) {delete m_p; m_p = p;} + +// ******************************************************** + +template class value_ptr : public member_ptr +{ +public: + value_ptr(const T &obj) : member_ptr(new T(obj)) {} + value_ptr(T *p = nullptr) : member_ptr(p) {} + value_ptr(const value_ptr& rhs) + : member_ptr(rhs.m_p ? new T(*rhs.m_p) : nullptr) {} + + value_ptr& operator=(const value_ptr& rhs); + bool operator==(const value_ptr& rhs) + { + return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); + } +}; + +template value_ptr& value_ptr::operator=(const value_ptr& rhs) +{ + T *old_p = this->m_p; + this->m_p = rhs.m_p ? new T(*rhs.m_p) : nullptr; + delete old_p; + return *this; +} + +// ******************************************************** + +template class clonable_ptr : public member_ptr +{ +public: + clonable_ptr(const T &obj) : member_ptr(obj.Clone()) {} + clonable_ptr(T *p = nullptr) : member_ptr(p) {} + clonable_ptr(const clonable_ptr& rhs) + : member_ptr(rhs.m_p ? rhs.m_p->Clone() : nullptr) {} + + clonable_ptr& operator=(const clonable_ptr& rhs); +}; + +template clonable_ptr& clonable_ptr::operator=(const clonable_ptr& rhs) +{ + T *old_p = this->m_p; + this->m_p = rhs.m_p ? rhs.m_p->Clone() : nullptr; + delete old_p; + return *this; +} + +// ******************************************************** + +template class counted_ptr +{ +public: + explicit counted_ptr(T *p = 0); + counted_ptr(const counted_ptr& rhs); + + ~counted_ptr(); + + const T& operator*() const { return *m_p; } + T& operator*() { return *m_p; } + + const T* operator->() const { return m_p; } + T* operator->() { return m_p; } + + const T* get() const { return m_p; } + T* get() { return m_p; } + + counted_ptr & operator=(const counted_ptr& rhs); + +private: + T *m_p; +}; + +template counted_ptr::counted_ptr(T *p) + : m_p(p) +{ + if (m_p) + m_p->m_referenceCount = 1; +} + +template counted_ptr::counted_ptr(const counted_ptr& rhs) + : m_p(rhs.m_p) +{ + if (m_p) + m_p->m_referenceCount++; +} + +template counted_ptr::~counted_ptr() +{ + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; +} + +template counted_ptr & counted_ptr::operator=(const counted_ptr& rhs) +{ + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; + m_p = rhs.m_p; + if (m_p) + m_p->m_referenceCount++; + return *this; +} + +// ******************************************************** + +template class vector_member_ptrs +{ +public: + vector_member_ptrs(unsigned int size=0) + : _size(size) {ptr = new member_ptr[_size];} + ~vector_member_ptrs() + {delete [] ptr;} + + member_ptr& operator[](unsigned int index) + {assert(index<_size); return ptr[index];} + const member_ptr& operator[](unsigned int index) const + {assert(index<_size); return ptr[index];} + + unsigned int size() const {return _size;} + void resize(unsigned int newSize) + { + member_ptr *newPtr = new member_ptr[newSize]; + for (unsigned int i=0; i &c); // copy not allowed + void operator=(const vector_member_ptrs &x); // assignment not allowed + + unsigned int _size; + member_ptr *ptr; +}; + +// ******************************************************** + +// derive from this class for a temporary variable +// that can be used during base/member initialization +template +class ConstructorTemp +{ +protected: + ConstructorTemp(const ConstructorTemp ©) : m_temp(nullptr) {} + ConstructorTemp(T *t = nullptr) : m_temp(t) {} + ConstructorTemp(const T &t) : m_temp(new T(t)) {} + member_ptr m_temp; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/tftables.cpp b/external/ours/library/crypto/src/shared/original-old/tftables.cpp new file mode 100755 index 000000000..22fde97c5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/tftables.cpp @@ -0,0 +1,317 @@ +// Twofish tables + +#include "FirstCrypto.h" +#include "twofish.h" + +NAMESPACE_BEGIN(CryptoPP) + +const byte Twofish::q[2][256] = { + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0, + + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 +}; + +const word32 Twofish::mds[4][256] = { + 0xbcbc3275, 0xecec21f3, 0x202043c6, 0xb3b3c9f4, + 0xdada03db, 0x02028b7b, 0xe2e22bfb, 0x9e9efac8, + 0xc9c9ec4a, 0xd4d409d3, 0x18186be6, 0x1e1e9f6b, + 0x98980e45, 0xb2b2387d, 0xa6a6d2e8, 0x2626b74b, + 0x3c3c57d6, 0x93938a32, 0x8282eed8, 0x525298fd, + 0x7b7bd437, 0xbbbb3771, 0x5b5b97f1, 0x474783e1, + 0x24243c30, 0x5151e20f, 0xbabac6f8, 0x4a4af31b, + 0xbfbf4887, 0x0d0d70fa, 0xb0b0b306, 0x7575de3f, + 0xd2d2fd5e, 0x7d7d20ba, 0x666631ae, 0x3a3aa35b, + 0x59591c8a, 0x00000000, 0xcdcd93bc, 0x1a1ae09d, + 0xaeae2c6d, 0x7f7fabc1, 0x2b2bc7b1, 0xbebeb90e, + 0xe0e0a080, 0x8a8a105d, 0x3b3b52d2, 0x6464bad5, + 0xd8d888a0, 0xe7e7a584, 0x5f5fe807, 0x1b1b1114, + 0x2c2cc2b5, 0xfcfcb490, 0x3131272c, 0x808065a3, + 0x73732ab2, 0x0c0c8173, 0x79795f4c, 0x6b6b4154, + 0x4b4b0292, 0x53536974, 0x94948f36, 0x83831f51, + 0x2a2a3638, 0xc4c49cb0, 0x2222c8bd, 0xd5d5f85a, + 0xbdbdc3fc, 0x48487860, 0xffffce62, 0x4c4c0796, + 0x4141776c, 0xc7c7e642, 0xebeb24f7, 0x1c1c1410, + 0x5d5d637c, 0x36362228, 0x6767c027, 0xe9e9af8c, + 0x4444f913, 0x1414ea95, 0xf5f5bb9c, 0xcfcf18c7, + 0x3f3f2d24, 0xc0c0e346, 0x7272db3b, 0x54546c70, + 0x29294cca, 0xf0f035e3, 0x0808fe85, 0xc6c617cb, + 0xf3f34f11, 0x8c8ce4d0, 0xa4a45993, 0xcaca96b8, + 0x68683ba6, 0xb8b84d83, 0x38382820, 0xe5e52eff, + 0xadad569f, 0x0b0b8477, 0xc8c81dc3, 0x9999ffcc, + 0x5858ed03, 0x19199a6f, 0x0e0e0a08, 0x95957ebf, + 0x70705040, 0xf7f730e7, 0x6e6ecf2b, 0x1f1f6ee2, + 0xb5b53d79, 0x09090f0c, 0x616134aa, 0x57571682, + 0x9f9f0b41, 0x9d9d803a, 0x111164ea, 0x2525cdb9, + 0xafafdde4, 0x4545089a, 0xdfdf8da4, 0xa3a35c97, + 0xeaead57e, 0x353558da, 0xededd07a, 0x4343fc17, + 0xf8f8cb66, 0xfbfbb194, 0x3737d3a1, 0xfafa401d, + 0xc2c2683d, 0xb4b4ccf0, 0x32325dde, 0x9c9c71b3, + 0x5656e70b, 0xe3e3da72, 0x878760a7, 0x15151b1c, + 0xf9f93aef, 0x6363bfd1, 0x3434a953, 0x9a9a853e, + 0xb1b1428f, 0x7c7cd133, 0x88889b26, 0x3d3da65f, + 0xa1a1d7ec, 0xe4e4df76, 0x8181942a, 0x91910149, + 0x0f0ffb81, 0xeeeeaa88, 0x161661ee, 0xd7d77321, + 0x9797f5c4, 0xa5a5a81a, 0xfefe3feb, 0x6d6db5d9, + 0x7878aec5, 0xc5c56d39, 0x1d1de599, 0x7676a4cd, + 0x3e3edcad, 0xcbcb6731, 0xb6b6478b, 0xefef5b01, + 0x12121e18, 0x6060c523, 0x6a6ab0dd, 0x4d4df61f, + 0xcecee94e, 0xdede7c2d, 0x55559df9, 0x7e7e5a48, + 0x2121b24f, 0x03037af2, 0xa0a02665, 0x5e5e198e, + 0x5a5a6678, 0x65654b5c, 0x62624e58, 0xfdfd4519, + 0x0606f48d, 0x404086e5, 0xf2f2be98, 0x3333ac57, + 0x17179067, 0x05058e7f, 0xe8e85e05, 0x4f4f7d64, + 0x89896aaf, 0x10109563, 0x74742fb6, 0x0a0a75fe, + 0x5c5c92f5, 0x9b9b74b7, 0x2d2d333c, 0x3030d6a5, + 0x2e2e49ce, 0x494989e9, 0x46467268, 0x77775544, + 0xa8a8d8e0, 0x9696044d, 0x2828bd43, 0xa9a92969, + 0xd9d97929, 0x8686912e, 0xd1d187ac, 0xf4f44a15, + 0x8d8d1559, 0xd6d682a8, 0xb9b9bc0a, 0x42420d9e, + 0xf6f6c16e, 0x2f2fb847, 0xdddd06df, 0x23233934, + 0xcccc6235, 0xf1f1c46a, 0xc1c112cf, 0x8585ebdc, + 0x8f8f9e22, 0x7171a1c9, 0x9090f0c0, 0xaaaa539b, + 0x0101f189, 0x8b8be1d4, 0x4e4e8ced, 0x8e8e6fab, + 0xababa212, 0x6f6f3ea2, 0xe6e6540d, 0xdbdbf252, + 0x92927bbb, 0xb7b7b602, 0x6969ca2f, 0x3939d9a9, + 0xd3d30cd7, 0xa7a72361, 0xa2a2ad1e, 0xc3c399b4, + 0x6c6c4450, 0x07070504, 0x04047ff6, 0x272746c2, + 0xacaca716, 0xd0d07625, 0x50501386, 0xdcdcf756, + 0x84841a55, 0xe1e15109, 0x7a7a25be, 0x1313ef91, + + 0xa9d93939, 0x67901717, 0xb3719c9c, 0xe8d2a6a6, + 0x04050707, 0xfd985252, 0xa3658080, 0x76dfe4e4, + 0x9a084545, 0x92024b4b, 0x80a0e0e0, 0x78665a5a, + 0xe4ddafaf, 0xddb06a6a, 0xd1bf6363, 0x38362a2a, + 0x0d54e6e6, 0xc6432020, 0x3562cccc, 0x98bef2f2, + 0x181e1212, 0xf724ebeb, 0xecd7a1a1, 0x6c774141, + 0x43bd2828, 0x7532bcbc, 0x37d47b7b, 0x269b8888, + 0xfa700d0d, 0x13f94444, 0x94b1fbfb, 0x485a7e7e, + 0xf27a0303, 0xd0e48c8c, 0x8b47b6b6, 0x303c2424, + 0x84a5e7e7, 0x54416b6b, 0xdf06dddd, 0x23c56060, + 0x1945fdfd, 0x5ba33a3a, 0x3d68c2c2, 0x59158d8d, + 0xf321ecec, 0xae316666, 0xa23e6f6f, 0x82165757, + 0x63951010, 0x015befef, 0x834db8b8, 0x2e918686, + 0xd9b56d6d, 0x511f8383, 0x9b53aaaa, 0x7c635d5d, + 0xa63b6868, 0xeb3ffefe, 0xa5d63030, 0xbe257a7a, + 0x16a7acac, 0x0c0f0909, 0xe335f0f0, 0x6123a7a7, + 0xc0f09090, 0x8cafe9e9, 0x3a809d9d, 0xf5925c5c, + 0x73810c0c, 0x2c273131, 0x2576d0d0, 0x0be75656, + 0xbb7b9292, 0x4ee9cece, 0x89f10101, 0x6b9f1e1e, + 0x53a93434, 0x6ac4f1f1, 0xb499c3c3, 0xf1975b5b, + 0xe1834747, 0xe66b1818, 0xbdc82222, 0x450e9898, + 0xe26e1f1f, 0xf4c9b3b3, 0xb62f7474, 0x66cbf8f8, + 0xccff9999, 0x95ea1414, 0x03ed5858, 0x56f7dcdc, + 0xd4e18b8b, 0x1c1b1515, 0x1eada2a2, 0xd70cd3d3, + 0xfb2be2e2, 0xc31dc8c8, 0x8e195e5e, 0xb5c22c2c, + 0xe9894949, 0xcf12c1c1, 0xbf7e9595, 0xba207d7d, + 0xea641111, 0x77840b0b, 0x396dc5c5, 0xaf6a8989, + 0x33d17c7c, 0xc9a17171, 0x62ceffff, 0x7137bbbb, + 0x81fb0f0f, 0x793db5b5, 0x0951e1e1, 0xaddc3e3e, + 0x242d3f3f, 0xcda47676, 0xf99d5555, 0xd8ee8282, + 0xe5864040, 0xc5ae7878, 0xb9cd2525, 0x4d049696, + 0x44557777, 0x080a0e0e, 0x86135050, 0xe730f7f7, + 0xa1d33737, 0x1d40fafa, 0xaa346161, 0xed8c4e4e, + 0x06b3b0b0, 0x706c5454, 0xb22a7373, 0xd2523b3b, + 0x410b9f9f, 0x7b8b0202, 0xa088d8d8, 0x114ff3f3, + 0x3167cbcb, 0xc2462727, 0x27c06767, 0x90b4fcfc, + 0x20283838, 0xf67f0404, 0x60784848, 0xff2ee5e5, + 0x96074c4c, 0x5c4b6565, 0xb1c72b2b, 0xab6f8e8e, + 0x9e0d4242, 0x9cbbf5f5, 0x52f2dbdb, 0x1bf34a4a, + 0x5fa63d3d, 0x9359a4a4, 0x0abcb9b9, 0xef3af9f9, + 0x91ef1313, 0x85fe0808, 0x49019191, 0xee611616, + 0x2d7cdede, 0x4fb22121, 0x8f42b1b1, 0x3bdb7272, + 0x47b82f2f, 0x8748bfbf, 0x6d2caeae, 0x46e3c0c0, + 0xd6573c3c, 0x3e859a9a, 0x6929a9a9, 0x647d4f4f, + 0x2a948181, 0xce492e2e, 0xcb17c6c6, 0x2fca6969, + 0xfcc3bdbd, 0x975ca3a3, 0x055ee8e8, 0x7ad0eded, + 0xac87d1d1, 0x7f8e0505, 0xd5ba6464, 0x1aa8a5a5, + 0x4bb72626, 0x0eb9bebe, 0xa7608787, 0x5af8d5d5, + 0x28223636, 0x14111b1b, 0x3fde7575, 0x2979d9d9, + 0x88aaeeee, 0x3c332d2d, 0x4c5f7979, 0x02b6b7b7, + 0xb896caca, 0xda583535, 0xb09cc4c4, 0x17fc4343, + 0x551a8484, 0x1ff64d4d, 0x8a1c5959, 0x7d38b2b2, + 0x57ac3333, 0xc718cfcf, 0x8df40606, 0x74695353, + 0xb7749b9b, 0xc4f59797, 0x9f56adad, 0x72dae3e3, + 0x7ed5eaea, 0x154af4f4, 0x229e8f8f, 0x12a2abab, + 0x584e6262, 0x07e85f5f, 0x99e51d1d, 0x34392323, + 0x6ec1f6f6, 0x50446c6c, 0xde5d3232, 0x68724646, + 0x6526a0a0, 0xbc93cdcd, 0xdb03dada, 0xf8c6baba, + 0xc8fa9e9e, 0xa882d6d6, 0x2bcf6e6e, 0x40507070, + 0xdceb8585, 0xfe750a0a, 0x328a9393, 0xa48ddfdf, + 0xca4c2929, 0x10141c1c, 0x2173d7d7, 0xf0ccb4b4, + 0xd309d4d4, 0x5d108a8a, 0x0fe25151, 0x00000000, + 0x6f9a1919, 0x9de01a1a, 0x368f9494, 0x42e6c7c7, + 0x4aecc9c9, 0x5efdd2d2, 0xc1ab7f7f, 0xe0d8a8a8, + + 0xbc75bc32, 0xecf3ec21, 0x20c62043, 0xb3f4b3c9, + 0xdadbda03, 0x027b028b, 0xe2fbe22b, 0x9ec89efa, + 0xc94ac9ec, 0xd4d3d409, 0x18e6186b, 0x1e6b1e9f, + 0x9845980e, 0xb27db238, 0xa6e8a6d2, 0x264b26b7, + 0x3cd63c57, 0x9332938a, 0x82d882ee, 0x52fd5298, + 0x7b377bd4, 0xbb71bb37, 0x5bf15b97, 0x47e14783, + 0x2430243c, 0x510f51e2, 0xbaf8bac6, 0x4a1b4af3, + 0xbf87bf48, 0x0dfa0d70, 0xb006b0b3, 0x753f75de, + 0xd25ed2fd, 0x7dba7d20, 0x66ae6631, 0x3a5b3aa3, + 0x598a591c, 0x00000000, 0xcdbccd93, 0x1a9d1ae0, + 0xae6dae2c, 0x7fc17fab, 0x2bb12bc7, 0xbe0ebeb9, + 0xe080e0a0, 0x8a5d8a10, 0x3bd23b52, 0x64d564ba, + 0xd8a0d888, 0xe784e7a5, 0x5f075fe8, 0x1b141b11, + 0x2cb52cc2, 0xfc90fcb4, 0x312c3127, 0x80a38065, + 0x73b2732a, 0x0c730c81, 0x794c795f, 0x6b546b41, + 0x4b924b02, 0x53745369, 0x9436948f, 0x8351831f, + 0x2a382a36, 0xc4b0c49c, 0x22bd22c8, 0xd55ad5f8, + 0xbdfcbdc3, 0x48604878, 0xff62ffce, 0x4c964c07, + 0x416c4177, 0xc742c7e6, 0xebf7eb24, 0x1c101c14, + 0x5d7c5d63, 0x36283622, 0x672767c0, 0xe98ce9af, + 0x441344f9, 0x149514ea, 0xf59cf5bb, 0xcfc7cf18, + 0x3f243f2d, 0xc046c0e3, 0x723b72db, 0x5470546c, + 0x29ca294c, 0xf0e3f035, 0x088508fe, 0xc6cbc617, + 0xf311f34f, 0x8cd08ce4, 0xa493a459, 0xcab8ca96, + 0x68a6683b, 0xb883b84d, 0x38203828, 0xe5ffe52e, + 0xad9fad56, 0x0b770b84, 0xc8c3c81d, 0x99cc99ff, + 0x580358ed, 0x196f199a, 0x0e080e0a, 0x95bf957e, + 0x70407050, 0xf7e7f730, 0x6e2b6ecf, 0x1fe21f6e, + 0xb579b53d, 0x090c090f, 0x61aa6134, 0x57825716, + 0x9f419f0b, 0x9d3a9d80, 0x11ea1164, 0x25b925cd, + 0xafe4afdd, 0x459a4508, 0xdfa4df8d, 0xa397a35c, + 0xea7eead5, 0x35da3558, 0xed7aedd0, 0x431743fc, + 0xf866f8cb, 0xfb94fbb1, 0x37a137d3, 0xfa1dfa40, + 0xc23dc268, 0xb4f0b4cc, 0x32de325d, 0x9cb39c71, + 0x560b56e7, 0xe372e3da, 0x87a78760, 0x151c151b, + 0xf9eff93a, 0x63d163bf, 0x345334a9, 0x9a3e9a85, + 0xb18fb142, 0x7c337cd1, 0x8826889b, 0x3d5f3da6, + 0xa1eca1d7, 0xe476e4df, 0x812a8194, 0x91499101, + 0x0f810ffb, 0xee88eeaa, 0x16ee1661, 0xd721d773, + 0x97c497f5, 0xa51aa5a8, 0xfeebfe3f, 0x6dd96db5, + 0x78c578ae, 0xc539c56d, 0x1d991de5, 0x76cd76a4, + 0x3ead3edc, 0xcb31cb67, 0xb68bb647, 0xef01ef5b, + 0x1218121e, 0x602360c5, 0x6add6ab0, 0x4d1f4df6, + 0xce4ecee9, 0xde2dde7c, 0x55f9559d, 0x7e487e5a, + 0x214f21b2, 0x03f2037a, 0xa065a026, 0x5e8e5e19, + 0x5a785a66, 0x655c654b, 0x6258624e, 0xfd19fd45, + 0x068d06f4, 0x40e54086, 0xf298f2be, 0x335733ac, + 0x17671790, 0x057f058e, 0xe805e85e, 0x4f644f7d, + 0x89af896a, 0x10631095, 0x74b6742f, 0x0afe0a75, + 0x5cf55c92, 0x9bb79b74, 0x2d3c2d33, 0x30a530d6, + 0x2ece2e49, 0x49e94989, 0x46684672, 0x77447755, + 0xa8e0a8d8, 0x964d9604, 0x284328bd, 0xa969a929, + 0xd929d979, 0x862e8691, 0xd1acd187, 0xf415f44a, + 0x8d598d15, 0xd6a8d682, 0xb90ab9bc, 0x429e420d, + 0xf66ef6c1, 0x2f472fb8, 0xdddfdd06, 0x23342339, + 0xcc35cc62, 0xf16af1c4, 0xc1cfc112, 0x85dc85eb, + 0x8f228f9e, 0x71c971a1, 0x90c090f0, 0xaa9baa53, + 0x018901f1, 0x8bd48be1, 0x4eed4e8c, 0x8eab8e6f, + 0xab12aba2, 0x6fa26f3e, 0xe60de654, 0xdb52dbf2, + 0x92bb927b, 0xb702b7b6, 0x692f69ca, 0x39a939d9, + 0xd3d7d30c, 0xa761a723, 0xa21ea2ad, 0xc3b4c399, + 0x6c506c44, 0x07040705, 0x04f6047f, 0x27c22746, + 0xac16aca7, 0xd025d076, 0x50865013, 0xdc56dcf7, + 0x8455841a, 0xe109e151, 0x7abe7a25, 0x139113ef, + + 0xd939a9d9, 0x90176790, 0x719cb371, 0xd2a6e8d2, + 0x05070405, 0x9852fd98, 0x6580a365, 0xdfe476df, + 0x08459a08, 0x024b9202, 0xa0e080a0, 0x665a7866, + 0xddafe4dd, 0xb06addb0, 0xbf63d1bf, 0x362a3836, + 0x54e60d54, 0x4320c643, 0x62cc3562, 0xbef298be, + 0x1e12181e, 0x24ebf724, 0xd7a1ecd7, 0x77416c77, + 0xbd2843bd, 0x32bc7532, 0xd47b37d4, 0x9b88269b, + 0x700dfa70, 0xf94413f9, 0xb1fb94b1, 0x5a7e485a, + 0x7a03f27a, 0xe48cd0e4, 0x47b68b47, 0x3c24303c, + 0xa5e784a5, 0x416b5441, 0x06dddf06, 0xc56023c5, + 0x45fd1945, 0xa33a5ba3, 0x68c23d68, 0x158d5915, + 0x21ecf321, 0x3166ae31, 0x3e6fa23e, 0x16578216, + 0x95106395, 0x5bef015b, 0x4db8834d, 0x91862e91, + 0xb56dd9b5, 0x1f83511f, 0x53aa9b53, 0x635d7c63, + 0x3b68a63b, 0x3ffeeb3f, 0xd630a5d6, 0x257abe25, + 0xa7ac16a7, 0x0f090c0f, 0x35f0e335, 0x23a76123, + 0xf090c0f0, 0xafe98caf, 0x809d3a80, 0x925cf592, + 0x810c7381, 0x27312c27, 0x76d02576, 0xe7560be7, + 0x7b92bb7b, 0xe9ce4ee9, 0xf10189f1, 0x9f1e6b9f, + 0xa93453a9, 0xc4f16ac4, 0x99c3b499, 0x975bf197, + 0x8347e183, 0x6b18e66b, 0xc822bdc8, 0x0e98450e, + 0x6e1fe26e, 0xc9b3f4c9, 0x2f74b62f, 0xcbf866cb, + 0xff99ccff, 0xea1495ea, 0xed5803ed, 0xf7dc56f7, + 0xe18bd4e1, 0x1b151c1b, 0xada21ead, 0x0cd3d70c, + 0x2be2fb2b, 0x1dc8c31d, 0x195e8e19, 0xc22cb5c2, + 0x8949e989, 0x12c1cf12, 0x7e95bf7e, 0x207dba20, + 0x6411ea64, 0x840b7784, 0x6dc5396d, 0x6a89af6a, + 0xd17c33d1, 0xa171c9a1, 0xceff62ce, 0x37bb7137, + 0xfb0f81fb, 0x3db5793d, 0x51e10951, 0xdc3eaddc, + 0x2d3f242d, 0xa476cda4, 0x9d55f99d, 0xee82d8ee, + 0x8640e586, 0xae78c5ae, 0xcd25b9cd, 0x04964d04, + 0x55774455, 0x0a0e080a, 0x13508613, 0x30f7e730, + 0xd337a1d3, 0x40fa1d40, 0x3461aa34, 0x8c4eed8c, + 0xb3b006b3, 0x6c54706c, 0x2a73b22a, 0x523bd252, + 0x0b9f410b, 0x8b027b8b, 0x88d8a088, 0x4ff3114f, + 0x67cb3167, 0x4627c246, 0xc06727c0, 0xb4fc90b4, + 0x28382028, 0x7f04f67f, 0x78486078, 0x2ee5ff2e, + 0x074c9607, 0x4b655c4b, 0xc72bb1c7, 0x6f8eab6f, + 0x0d429e0d, 0xbbf59cbb, 0xf2db52f2, 0xf34a1bf3, + 0xa63d5fa6, 0x59a49359, 0xbcb90abc, 0x3af9ef3a, + 0xef1391ef, 0xfe0885fe, 0x01914901, 0x6116ee61, + 0x7cde2d7c, 0xb2214fb2, 0x42b18f42, 0xdb723bdb, + 0xb82f47b8, 0x48bf8748, 0x2cae6d2c, 0xe3c046e3, + 0x573cd657, 0x859a3e85, 0x29a96929, 0x7d4f647d, + 0x94812a94, 0x492ece49, 0x17c6cb17, 0xca692fca, + 0xc3bdfcc3, 0x5ca3975c, 0x5ee8055e, 0xd0ed7ad0, + 0x87d1ac87, 0x8e057f8e, 0xba64d5ba, 0xa8a51aa8, + 0xb7264bb7, 0xb9be0eb9, 0x6087a760, 0xf8d55af8, + 0x22362822, 0x111b1411, 0xde753fde, 0x79d92979, + 0xaaee88aa, 0x332d3c33, 0x5f794c5f, 0xb6b702b6, + 0x96cab896, 0x5835da58, 0x9cc4b09c, 0xfc4317fc, + 0x1a84551a, 0xf64d1ff6, 0x1c598a1c, 0x38b27d38, + 0xac3357ac, 0x18cfc718, 0xf4068df4, 0x69537469, + 0x749bb774, 0xf597c4f5, 0x56ad9f56, 0xdae372da, + 0xd5ea7ed5, 0x4af4154a, 0x9e8f229e, 0xa2ab12a2, + 0x4e62584e, 0xe85f07e8, 0xe51d99e5, 0x39233439, + 0xc1f66ec1, 0x446c5044, 0x5d32de5d, 0x72466872, + 0x26a06526, 0x93cdbc93, 0x03dadb03, 0xc6baf8c6, + 0xfa9ec8fa, 0x82d6a882, 0xcf6e2bcf, 0x50704050, + 0xeb85dceb, 0x750afe75, 0x8a93328a, 0x8ddfa48d, + 0x4c29ca4c, 0x141c1014, 0x73d72173, 0xccb4f0cc, + 0x09d4d309, 0x108a5d10, 0xe2510fe2, 0x00000000, + 0x9a196f9a, 0xe01a9de0, 0x8f94368f, 0xe6c742e6, + 0xecc94aec, 0xfdd25efd, 0xab7fc1ab, 0xd8a8e0d8}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/twofish.cpp b/external/ours/library/crypto/src/shared/original-old/twofish.cpp new file mode 100755 index 000000000..55ba2c493 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/twofish.cpp @@ -0,0 +1,166 @@ +// twofish.cpp - modified by Wei Dai from Matthew Skala's twofish.c +// The original code and all modifications are in the public domain. + +#include "FirstCrypto.h" +#include "twofish.h" + +NAMESPACE_BEGIN(CryptoPP) + +// compute (c * x^4) mod (x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1) +// over GF(256) +static inline unsigned int Mod(unsigned int c) +{ + static const unsigned int modulus = 0x14d; + unsigned int c2 = (c<<1) ^ ((c & 0x80) ? modulus : 0); + unsigned int c1 = c2 ^ (c>>1) ^ ((c & 1) ? (modulus>>1) : 0); + return c | (c1 << 8) | (c2 << 16) | (c1 << 24); +} + +// compute RS(12,8) code with the above polynomial as generator +// this is equivalent to multiplying by the RS matrix +static word32 ReedSolomon(word32 high, word32 low) +{ + for (unsigned int i=0; i<8; i++) + { + high = Mod(high>>24) ^ (high<<8) ^ (low>>24); + low <<= 8; + } + return high; +} + +inline word32 Twofish::h0(word32 x, const word32 *key, unsigned int kLen) +{ + x = x | (x<<8) | (x<<16) | (x<<24); + switch(kLen) + { +#define Q(a, b, c, d, t) q[a][GETBYTE(t,0)] ^ (q[b][GETBYTE(t,1)] << 8) ^ (q[c][GETBYTE(t,2)] << 16) ^ (q[d][GETBYTE(t,3)] << 24) + case 4: x = Q(1, 0, 0, 1, x) ^ key[6]; + case 3: x = Q(1, 1, 0, 0, x) ^ key[4]; + case 2: x = Q(0, 1, 0, 1, x) ^ key[2]; + x = Q(0, 0, 1, 1, x) ^ key[0]; + } + return x; +} + +inline word32 Twofish::h(word32 x, const word32 *key, unsigned int kLen) +{ + x = h0(x, key, kLen); + return mds[0][GETBYTE(x,0)] ^ mds[1][GETBYTE(x,1)] ^ mds[2][GETBYTE(x,2)] ^ mds[3][GETBYTE(x,3)]; +} + +Twofish::Twofish(const byte *userKey, unsigned int keylength) + : m_k(40), m_s(4) +{ + assert(keylength == KeyLength(keylength)); + + unsigned int len = (keylength <= 16 ? 2 : (keylength <= 24 ? 3 : 4)); + SecBlock key(len*2); + GetUserKeyLittleEndian(key.ptr, len*2, userKey, keylength); + + unsigned int i; + for (i=0; i<40; i+=2) + { + word32 a = h(i, key, len); + word32 b = rotlFixed(h(i+1, key+1u, len), 8); + m_k[i] = a+b; + m_k[i+1] = rotlFixed(a+2*b, 9); + } + + SecBlock svec(2*len); + for (i=0; i, public VariableKeyLength<16, 0, 32> +{ +protected: + Twofish(const byte *userKey, unsigned int keylength); + static word32 h0(word32 x, const word32 *key, unsigned int kLen); + static word32 h(word32 x, const word32 *key, unsigned int kLen); + + static const byte q[2][256]; + static const word32 mds[4][256]; + + SecBlock m_k; + SecBlock m_s; +}; + +/// Twofish +class TwofishEncryption : public Twofish +{ +public: + TwofishEncryption(const byte *userKey, unsigned int keylength=DEFAULT_KEYLENGTH) + : Twofish(userKey, keylength) {} + + void ProcessBlock(const byte *inBlock, byte * outBlock) const; + void ProcessBlock(byte * inoutBlock) const + {TwofishEncryption::ProcessBlock(inoutBlock, inoutBlock);} +}; + +/// Twofish +class TwofishDecryption : public Twofish +{ +public: + TwofishDecryption(const byte *userKey, unsigned int keylength=DEFAULT_KEYLENGTH) + : Twofish(userKey, keylength) {} + + void ProcessBlock(const byte *inBlock, byte * outBlock) const; + void ProcessBlock(byte * inoutBlock) const + {TwofishDecryption::ProcessBlock(inoutBlock, inoutBlock);} +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original-old/words.h b/external/ours/library/crypto/src/shared/original-old/words.h new file mode 100755 index 000000000..8849b6107 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original-old/words.h @@ -0,0 +1,103 @@ +#ifndef CRYPTOPP_WORDS_H +#define CRYPTOPP_WORDS_H + +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +inline unsigned int CountWords(const word *X, unsigned int N) +{ + while (N && X[N-1]==0) + N--; + return N; +} + +inline void SetWords(word *r, word a, unsigned int n) +{ + for (unsigned int i=0; i> (WORD_BITS-shiftBits); + } + return carry; +} + +inline word ShiftWordsRightByBits(word *r, unsigned int n, unsigned int shiftBits) +{ + assert (shiftBits=0; i--) + { + u = r[i]; + r[i] = (u >> shiftBits) | carry; + carry = u << (WORD_BITS-shiftBits); + } + return carry; +} + +inline void ShiftWordsLeftByWords(word *r, unsigned int n, unsigned int shiftWords) +{ + shiftWords = STDMIN(shiftWords, n); + if (shiftWords) + { + for (unsigned int i=n-1; i>=shiftWords; i--) + r[i] = r[i-shiftWords]; + SetWords(r, 0, shiftWords); + } +} + +inline void ShiftWordsRightByWords(word *r, unsigned int n, unsigned int shiftWords) +{ + shiftWords = STDMIN(shiftWords, n); + if (shiftWords) + { + for (unsigned int i=0; i+shiftWords> 1) | ((a & 0x55555555) << 1); + a = ((a & 0xCCCCCCCC) >> 2) | ((a & 0x33333333) << 2); + return ((a & 0xF0F0F0F0) >> 4) | ((a & 0x0F0F0F0F) << 4); +} + +#define mu(a0, a1, a2) \ +{ \ + a1 = reverseBits(a1); \ + word32 t = reverseBits(a0); \ + a0 = reverseBits(a2); \ + a2 = t; \ +} + +#define pi_gamma_pi(a0, a1, a2) \ +{ \ + word32 b0, b2; \ + b2 = rotlConstant<1>(a2); \ + b0 = rotlConstant<22>(a0); \ + a0 = rotlConstant<1>(b0 ^ (a1|(~b2))); \ + a2 = rotlConstant<22>(b2 ^ (b0|(~a1))); \ + a1 ^= (b2|(~b0)); \ +} + +// thanks to Paulo Barreto for this optimized theta() +#define theta(a0, a1, a2) \ +{ \ + word32 b0, b1, c; \ + c = a0 ^ a1 ^ a2; \ + c = rotlConstant<16>(c) ^ rotlConstant<8>(c); \ + b0 = (a0 << 24) ^ (a2 >> 8) ^ (a1 << 8) ^ (a0 >> 24); \ + b1 = (a1 << 24) ^ (a0 >> 8) ^ (a2 << 8) ^ (a1 >> 24); \ + a0 ^= c ^ b0; \ + a1 ^= c ^ b1; \ + a2 ^= c ^ (b0 >> 16) ^ (b1 << 16); \ +} + +#define rho(a0, a1, a2) \ +{ \ + theta(a0, a1, a2); \ + pi_gamma_pi(a0, a1, a2); \ +} + +void ThreeWay::Base::UncheckedSetKey(const byte *uk, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + m_rounds = GetRoundsAndThrowIfInvalid(params, this); + + for (unsigned int i=0; i<3; i++) + m_k[i] = (word32)uk[4*i+3] | ((word32)uk[4*i+2]<<8) | ((word32)uk[4*i+1]<<16) | ((word32)uk[4*i]<<24); + + if (!IsForwardTransformation()) + { + theta(m_k[0], m_k[1], m_k[2]); + mu(m_k[0], m_k[1], m_k[2]); + m_k[0] = ByteReverse(m_k[0]); + m_k[1] = ByteReverse(m_k[1]); + m_k[2] = ByteReverse(m_k[2]); + } +} + +void ThreeWay::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + typedef BlockGetAndPut Block; + + word32 a0, a1, a2; + Block::Get(inBlock)(a0)(a1)(a2); + + word32 rc = START_E; + + for(unsigned i=0; i Block; + + word32 a0, a1, a2; + Block::Get(inBlock)(a0)(a1)(a2); + + word32 rc = START_D; + + mu(a0, a1, a2); + for(unsigned i=0; i, public FixedKeyLength<12>, public VariableRounds<11> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "3-Way";} +}; + +/// \brief ThreeWay block cipher +/// \sa 3-Way +class ThreeWay : public ThreeWay_Info, public BlockCipherDocumentation +{ + /// \brief Class specific implementation and overrides used to operate the cipher. + /// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + + protected: + unsigned int m_rounds; + FixedSizeSecBlock m_k; + }; + + /// \brief Class specific methods used to operate the cipher in the forward direction. + /// \details Implementations and overrides in \p Enc apply to \p ENCRYPTION. + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Class specific methods used to operate the cipher in the reverse direction. + /// \details Implementations and overrides in \p Dec apply to \p DECRYPTION. + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef ThreeWay::Encryption ThreeWayEncryption; +typedef ThreeWay::Decryption ThreeWayDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/GNUmakefile b/external/ours/library/crypto/src/shared/original/GNUmakefile new file mode 100755 index 000000000..6f6307106 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/GNUmakefile @@ -0,0 +1,1795 @@ + +########################################################### +##### System Attributes and Programs ##### +########################################################### + +# https://www.gnu.org/software/make/manual/make.html#Makefile-Conventions +# and https://www.gnu.org/prep/standards/standards.html + +SHELL = /bin/sh + +# If needed +TMPDIR ?= /tmp +# Used for feature tests +TOUT ?= a.out +TOUT := $(strip $(TOUT)) + +# Allow override for the cryptest.exe recipe. Change to +# ./libcryptopp.so or ./libcryptopp.dylib to suit your +# taste. https://github.com/weidai11/cryptopp/issues/866 +LINK_LIBRARY ?= libcryptopp.a +LINK_LIBRARY_PATH ?= ./ + +# Command and arguments +AR ?= ar +ARFLAGS ?= -cr # ar needs the dash on OpenBSD +RANLIB ?= ranlib + +CP ?= cp +MV ?= mv +RM ?= rm -f +GREP ?= grep +SED ?= sed +CHMOD ?= chmod +MKDIR ?= mkdir -p + +LN ?= ln -sf +LDCONF ?= /sbin/ldconfig -n + +# Solaris provides a non-Posix sed and grep at /usr/bin +# Solaris 10 is missing AR in /usr/bin +ifneq ($(wildcard /usr/xpg4/bin/grep),) + GREP := /usr/xpg4/bin/grep +endif +ifneq ($(wildcard /usr/xpg4/bin/sed),) + SED := /usr/xpg4/bin/sed +endif +ifneq ($(wildcard /usr/xpg4/bin/ar),) + AR := /usr/xpg4/bin/ar +endif + +# Clang is reporting armv8l-unknown-linux-gnueabihf +# for ARMv7 images on Aarch64 hardware. +MACHINEX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null) +HOSTX := $(shell echo $(MACHINEX) | cut -f 1 -d '-') +ifeq ($(HOSTX),) + HOSTX := $(shell uname -m 2>/dev/null) +endif + +IS_X86 := $(shell echo "$(HOSTX)" | $(GREP) -v "64" | $(GREP) -i -c -E 'i.86|x86|i86') +IS_X64 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E '_64|d64') +IS_PPC32 := $(shell echo "$(HOSTX)" | $(GREP) -v "64" | $(GREP) -i -c -E 'ppc|power') +IS_PPC64 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'ppc64|powerpc64|power64') +IS_SPARC32 := $(shell echo "$(HOSTX)" | $(GREP) -v "64" | $(GREP) -i -c -E 'sun|sparc') +IS_SPARC64 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'sun|sparc64') +IS_ARM32 := $(shell echo "$(HOSTX)" | $(GREP) -v "64" | $(GREP) -i -c -E 'arm|armhf|armv7|eabihf|armv8') +IS_ARMV8 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'aarch32|aarch64|arm64') + +# Attempt to determine platform +SYSTEMX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null) +ifeq ($(SYSTEMX),) + SYSTEMX := $(shell uname -s 2>/dev/null) +endif + +IS_LINUX := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c "Linux") +IS_HURD := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c -E "GNU|Hurd") +IS_MINGW := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c "MinGW") +IS_CYGWIN := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c "Cygwin") +IS_DARWIN := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c "Darwin") +IS_NETBSD := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c "NetBSD") +IS_AIX := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c "aix") +IS_SUN := $(shell echo "$(SYSTEMX)" | $(GREP) -i -c -E "SunOS|Solaris") + +SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(GREP) -i -c -E 'CC: (Sun|Studio)') +GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -v -E '(llvm|clang)' | $(GREP) -i -c -E '(gcc|g\+\+)') +XLC_COMPILER := $(shell $(CXX) -qversion 2>/dev/null |$(GREP) -i -c "IBM XL") +CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -i -c -E '(llvm|clang)') +INTEL_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -i -c '\(icc\)') + +# Enable shared object versioning for Linux and Solaris +HAS_SOLIB_VERSION ?= 0 +ifneq ($(IS_LINUX)$(IS_HURD)$(IS_SUN),000) + HAS_SOLIB_VERSION := 1 +endif + +# Formerly adhoc.cpp was created from adhoc.cpp.proto when needed. +ifeq ($(wildcard adhoc.cpp),) +$(shell cp adhoc.cpp.proto adhoc.cpp) +endif + +# Hack to skip CPU feature tests for some recipes +DETECT_FEATURES ?= 1 +ifeq ($(findstring -DCRYPTOPP_DISABLE_ASM,$(CXXFLAGS)),-DCRYPTOPP_DISABLE_ASM) + DETECT_FEATURES := 0 +else ifeq ($(findstring clean,$(MAKECMDGOALS)),clean) + DETECT_FEATURES := 0 +else ifeq ($(findstring distclean,$(MAKECMDGOALS)),distclean) + DETECT_FEATURES := 0 +else ifeq ($(findstring trim,$(MAKECMDGOALS)),trim) + DETECT_FEATURES := 0 +else ifeq ($(findstring zip,$(MAKECMDGOALS)),zip) + DETECT_FEATURES := 0 +endif + +# Strip out -Wall, -Wextra and friends for feature testing. FORTIFY_SOURCE is removed +# because it requires -O1 or higher, but we use -O0 to tame the optimizer. +# Always print testing flags since some tests always happen, like 64-bit. +TCXXFLAGS := $(filter-out -D_FORTIFY_SOURCE=% -M -MM -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CPPFLAGS) $(CXXFLAGS)) +ifneq ($(strip $(TCXXFLAGS)),) + $(info Using testing flags: $(TCXXFLAGS)) +endif + +# TCOMMAND is used for just about all tests. Make will lazy-evaluate +# the variables when executed by $(shell $(TCOMMAND) ...). +TCOMMAND = $(CXX) $(TCXXFLAGS) $(TEXTRA) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) + +# Fixup AIX +ifeq ($(IS_AIX),1) + TPROG = TestPrograms/test_64bit.cpp + TOPT = + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + IS_PPC64=1 + else + IS_PPC32=1 + endif +endif + +# Uncomment for debugging +# $(info Here's what we found... IS_X86: $(IS_X86), IS_X64: $(IS_X64), IS_ARM32: $(IS_ARM32), IS_ARMV8: $(IS_ARMV8)) + +########################################################### +##### General Variables ##### +########################################################### + +# Base CXXFLAGS used if the user did not specify them +ifeq ($(CXXFLAGS),) + ifeq ($(SUN_COMPILER),1) + CRYPTOPP_CXXFLAGS += -DNDEBUG -g -xO3 + ZOPT = -xO0 + else + CRYPTOPP_CXXFLAGS += -DNDEBUG -g2 -O3 + ZOPT = -O0 + endif +endif + +# Fix CXX on Cygwin 1.1.4 +ifeq ($(CXX),gcc) +CXX := g++ +endif + +# On ARM we may compile aes_armv4.S though the CC compiler +ifeq ($(GCC_COMPILER),1) + CC=gcc +else ifeq ($(CLANG_COMPILER),1) + CC=clang +endif + +# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html +ifeq ($(PREFIX),) + PREFIX = /usr/local + PC_PREFIX = /usr/local +else + PC_PREFIX = $(PREFIX) +endif +ifeq ($(LIBDIR),) + LIBDIR := $(PREFIX)/lib + PC_LIBDIR = $${prefix}/lib +else + PC_LIBDIR = $(LIBDIR) +endif +ifeq ($(DATADIR),) + DATADIR := $(PREFIX)/share + PC_DATADIR = $${prefix}/share +else + PC_DATADIR = $(DATADIR) +endif +ifeq ($(INCLUDEDIR),) + INCLUDEDIR := $(PREFIX)/include + PC_INCLUDEDIR = $${prefix}/include +else + PC_INCLUDEDIR = $(INCLUDEDIR) +endif +ifeq ($(BINDIR),) + BINDIR := $(PREFIX)/bin +endif + +# We honor ARFLAGS, but the "v" option used by default causes a noisy make +ifeq ($(ARFLAGS),rv) +ARFLAGS = r +endif + +# Original MinGW targets Win2k by default, but lacks proper Win2k support +# if target Windows version is not specified, use Windows XP instead +ifeq ($(IS_MINGW),1) +ifeq ($(findstring -D_WIN32_WINNT,$(CXXFLAGS)),) +ifeq ($(findstring -D_WIN32_WINDOWS,$(CXXFLAGS)),) +ifeq ($(findstring -DWINVER,$(CXXFLAGS)),) +ifeq ($(findstring -DNTDDI_VERSION,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -D_WIN32_WINNT=0x0501 +endif # NTDDI_VERSION +endif # WINVER +endif # _WIN32_WINDOWS +endif # _WIN32_WINNT +endif # IS_MINGW + +# Newlib needs _XOPEN_SOURCE=600 for signals +TPROG = TestPrograms/test_newlib.cpp +TOPT = +HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) +ifeq ($(strip $(HAVE_OPT)),0) + ifeq ($(findstring -D_XOPEN_SOURCE,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -D_XOPEN_SOURCE=600 + endif +endif + +########################################################### +##### X86/X32/X64 Options ##### +########################################################### + +ifneq ($(IS_X86)$(IS_X64)$(IS_MINGW),000) +ifeq ($(DETECT_FEATURES),1) + + ifeq ($(SUN_COMPILER),1) + SSE2_FLAG = -xarch=sse2 + SSE3_FLAG = -xarch=sse3 + SSSE3_FLAG = -xarch=ssse3 + SSE41_FLAG = -xarch=sse4_1 + SSE42_FLAG = -xarch=sse4_2 + CLMUL_FLAG = -xarch=aes + AESNI_FLAG = -xarch=aes + AVX_FLAG = -xarch=avx + AVX2_FLAG = -xarch=avx2 + SHANI_FLAG = -xarch=sha + else + SSE2_FLAG = -msse2 + SSE3_FLAG = -msse3 + SSSE3_FLAG = -mssse3 + SSE41_FLAG = -msse4.1 + SSE42_FLAG = -msse4.2 + CLMUL_FLAG = -mpclmul + AESNI_FLAG = -maes + AVX_FLAG = -mavx + AVX2_FLAG = -mavx2 + SHANI_FLAG = -msha + endif + + # Tell MacPorts and Homebrew GCC to use Clang integrated assembler + # Intel-based Macs. http://github.com/weidai11/cryptopp/issues/190 + ifneq ($(IS_DARWIN),0) + ifeq ($(findstring -Wa,-q,$(CXXFLAGS)),) + TPROG = TestPrograms/test_cxx.cpp + TOPT = -Wa,-q + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -Wa,-q + CRYPTOPP_CXXFLAGS += -Wa,-q + endif + endif + endif + + TPROG = TestPrograms/test_x86_sse2.cpp + TOPT = $(SSE2_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CHACHA_FLAG = $(SSE2_FLAG) + SUN_LDFLAGS += $(SSE2_FLAG) + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + SSE2_FLAG = + endif + + ifeq ($(SSE2_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif + + # Need SSE2 or higher for these tests + ifneq ($(SSE2_FLAG),) + + TPROG = TestPrograms/test_x86_ssse3.cpp + TOPT = $(SSSE3_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + ARIA_FLAG = $(SSSE3_FLAG) + CHAM_FLAG = $(SSSE3_FLAG) + KECCAK_FLAG = $(SSSE3_FLAG) + LEA_FLAG = $(SSSE3_FLAG) + LSH256_FLAG = $(SSSE3_FLAG) + LSH512_FLAG = $(SSSE3_FLAG) + SIMON128_FLAG = $(SSSE3_FLAG) + SPECK128_FLAG = $(SSSE3_FLAG) + SUN_LDFLAGS += $(SSSE3_FLAG) + else + SSSE3_FLAG = + endif + + # The first Apple MacBooks were Core2's with SSE4.1 + ifneq ($(IS_DARWIN),0) + # Add SSE2 algo's here as required + # They get a free upgrade + endif + + TPROG = TestPrograms/test_x86_sse41.cpp + TOPT = $(SSE41_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + BLAKE2B_FLAG = $(SSE41_FLAG) + BLAKE2S_FLAG = $(SSE41_FLAG) + SUN_LDFLAGS += $(SSE41_FLAG) + else + SSE41_FLAG = + endif + + TPROG = TestPrograms/test_x86_sse42.cpp + TOPT = $(SSE42_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRC_FLAG = $(SSE42_FLAG) + SUN_LDFLAGS += $(SSE42_FLAG) + else + SSE42_FLAG = + endif + + TPROG = TestPrograms/test_x86_clmul.cpp + TOPT = $(CLMUL_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + GCM_FLAG = $(SSSE3_FLAG) $(CLMUL_FLAG) + GF2N_FLAG = $(CLMUL_FLAG) + SUN_LDFLAGS += $(CLMUL_FLAG) + else + CLMUL_FLAG = + endif + + TPROG = TestPrograms/test_x86_aes.cpp + TOPT = $(AESNI_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + AES_FLAG = $(SSE41_FLAG) $(AESNI_FLAG) + SM4_FLAG = $(SSSE3_FLAG) $(AESNI_FLAG) + SUN_LDFLAGS += $(AESNI_FLAG) + else + AESNI_FLAG = + endif + + TPROG = TestPrograms/test_x86_avx.cpp + TOPT = $(AVX_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + # XXX_FLAG = $(AVX_FLAG) + SUN_LDFLAGS += $(AVX_FLAG) + else + AVX_FLAG = + endif + + TPROG = TestPrograms/test_x86_avx2.cpp + TOPT = $(AVX2_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CHACHA_AVX2_FLAG = $(AVX2_FLAG) + LSH256_AVX2_FLAG = $(AVX2_FLAG) + LSH512_AVX2_FLAG = $(AVX2_FLAG) + SUN_LDFLAGS += $(AVX2_FLAG) + else + AVX2_FLAG = + endif + + TPROG = TestPrograms/test_x86_sha.cpp + TOPT = $(SHANI_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA_FLAG = $(SSE42_FLAG) $(SHANI_FLAG) + SUN_LDFLAGS += $(SHANI_FLAG) + else + SHANI_FLAG = + endif + + ifeq ($(SUN_COMPILER),1) + CRYPTOPP_LDFLAGS += $(SUN_LDFLAGS) + endif + + ifeq ($(SSE3_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_SSE3 + else ifeq ($(SSSE3_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_SSSE3 + else ifeq ($(SSE41_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_SSE4 + else ifeq ($(SSE42_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_SSE4 + endif + + ifneq ($(SSE42_FLAG),) + # Unusual GCC/Clang on Macports. It assembles AES, but not CLMUL. + # test_x86_clmul.s:15: no such instruction: 'pclmulqdq $0, %xmm1,%xmm0' + ifeq ($(CLMUL_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_CLMUL + endif + ifeq ($(AESNI_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_AESNI + endif + + ifeq ($(AVX_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_AVX + else ifeq ($(AVX2_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_AVX2 + endif + # SHANI independent of AVX per GH #1045 + ifeq ($(SHANI_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_SHANI + endif + endif + + # Drop to SSE2 if available + ifeq ($(GCM_FLAG),) + GCM_FLAG = $(SSE2_FLAG) + endif + + # Most Clang cannot handle mixed asm with positional arguments, where the + # body is Intel style with no prefix and the templates are AT&T style. + # Also see https://bugs.llvm.org/show_bug.cgi?id=39895 . + + # CRYPTOPP_DISABLE_MIXED_ASM is now being added in config_asm.h for all + # Clang compilers. This test will need to be re-enabled if Clang fixes it. + #TPROG = TestPrograms/test_asm_mixed.cpp + #TOPT = + #HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + #ifneq ($(strip $(HAVE_OPT)),0) + # CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_MIXED_ASM + #endif + + # SSE2_FLAGS + endif +# DETECT_FEATURES +endif + +ifneq ($(INTEL_COMPILER),0) + CRYPTOPP_CXXFLAGS += -wd68 -wd186 -wd279 -wd327 -wd161 -wd3180 + + ICC111_OR_LATER := $(shell $(CXX) --version 2>&1 | $(GREP) -c -E "\(ICC\) ([2-9][0-9]|1[2-9]|11\.[1-9])") + ifeq ($(ICC111_OR_LATER),0) + # "internal error: backend signals" occurs on some x86 inline assembly with ICC 9 and + # some x64 inline assembly with ICC 11.0. If you want to use Crypto++'s assembly code + # with ICC, try enabling it on individual files + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif +endif + +# Allow use of "/" operator for GNU Assembler. +# http://sourceware.org/bugzilla/show_bug.cgi?id=4572 +ifeq ($(findstring -DCRYPTOPP_DISABLE_ASM,$(CXXFLAGS)),) + ifeq ($(IS_SUN)$(GCC_COMPILER),11) + CRYPTOPP_CXXFLAGS += -Wa,--divide + endif +endif + +# IS_X86, IS_X32 and IS_X64 +endif + +########################################################### +##### ARM A-32 and NEON ##### +########################################################### + +ifneq ($(IS_ARM32),0) +ifeq ($(DETECT_FEATURES),1) + + # Clang needs an option to include + TPROG = TestPrograms/test_arm_neon_header.cpp + TOPT = -DCRYPTOPP_ARM_NEON_HEADER=1 -march=armv7-a -mfpu=neon + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -DCRYPTOPP_ARM_NEON_HEADER=1 + endif + + TPROG = TestPrograms/test_arm_neon.cpp + TOPT = -march=armv7-a -mfpu=neon + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + NEON_FLAG = -march=armv7-a -mfpu=neon + ARIA_FLAG = -march=armv7-a -mfpu=neon + GCM_FLAG = -march=armv7-a -mfpu=neon + BLAKE2B_FLAG = -march=armv7-a -mfpu=neon + BLAKE2S_FLAG = -march=armv7-a -mfpu=neon + CHACHA_FLAG = -march=armv7-a -mfpu=neon + CHAM_FLAG = -march=armv7-a -mfpu=neon + LEA_FLAG = -march=armv7-a -mfpu=neon + SIMON128_FLAG = -march=armv7-a -mfpu=neon + SPECK128_FLAG = -march=armv7-a -mfpu=neon + SM4_FLAG = -march=armv7-a -mfpu=neon + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + NEON_FLAG = + endif + + ifeq ($(NEON_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif + +# DETECT_FEATURES +endif +# IS_ARM32 +endif + +########################################################### +##### Aach32 and Aarch64 ##### +########################################################### + +ifneq ($(IS_ARMV8),0) +ifeq ($(DETECT_FEATURES),1) + + TPROG = TestPrograms/test_arm_neon_header.cpp + TOPT = -DCRYPTOPP_ARM_NEON_HEADER=1 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -DCRYPTOPP_ARM_NEON_HEADER=1 + endif + + TPROG = TestPrograms/test_arm_acle_header.cpp + TOPT = -DCRYPTOPP_ARM_ACLE_HEADER=1 -march=armv8-a + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -DCRYPTOPP_ARM_ACLE_HEADER=1 + endif + + TPROG = TestPrograms/test_arm_asimd.cpp + TOPT = -march=armv8-a + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + ASIMD_FLAG = -march=armv8-a + ARIA_FLAG = -march=armv8-a + BLAKE2B_FLAG = -march=armv8-a + BLAKE2S_FLAG = -march=armv8-a + CHACHA_FLAG = -march=armv8-a + CHAM_FLAG = -march=armv8-a + LEA_FLAG = -march=armv8-a + NEON_FLAG = -march=armv8-a + SIMON128_FLAG = -march=armv8-a + SPECK128_FLAG = -march=armv8-a + SM4_FLAG = -march=armv8-a + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + ASIMD_FLAG = + endif + + ifeq ($(ASIMD_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif + + ifneq ($(ASIMD_FLAG),) + TPROG = TestPrograms/test_arm_crc.cpp + TOPT = -march=armv8-a+crc + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRC_FLAG = -march=armv8-a+crc + else + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_CRC32 + endif + + TPROG = TestPrograms/test_arm_aes.cpp + TOPT = -march=armv8-a+crypto + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + AES_FLAG = -march=armv8-a+crypto + else + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_AES + endif + + TPROG = TestPrograms/test_arm_pmull.cpp + TOPT = -march=armv8-a+crypto + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + GCM_FLAG = -march=armv8-a+crypto + GF2N_FLAG = -march=armv8-a+crypto + else + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_PMULL + endif + + TPROG = TestPrograms/test_arm_sha1.cpp + TOPT = -march=armv8-a+crypto + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA_FLAG = -march=armv8-a+crypto + else + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA1 + endif + + TPROG = TestPrograms/test_arm_sha256.cpp + TOPT = -march=armv8-a+crypto + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA_FLAG = -march=armv8-a+crypto + else + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA2 + endif + + TPROG = TestPrograms/test_arm_sm3.cpp + TOPT = -march=armv8.4-a+sm3 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SM3_FLAG = -march=armv8.4-a+sm3 + SM4_FLAG = -march=armv8.4-a+sm3 + else + #CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SM3 + #CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SM4 + endif + + TPROG = TestPrograms/test_arm_sha3.cpp + TOPT = -march=armv8.4-a+sha3 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA3_FLAG = -march=armv8.4-a+sha3 + else + #CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA3 + endif + + TPROG = TestPrograms/test_arm_sha512.cpp + TOPT = -march=armv8.4-a+sha512 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA512_FLAG = -march=armv8.4-a+sha512 + else + #CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA512 + endif + + # ASIMD_FLAG + endif + +# DETECT_FEATURES +endif +# IS_ARMV8 +endif + +########################################################### +##### PowerPC ##### +########################################################### + +# PowerPC and PowerPC64. Altivec is available with POWER4 with GCC and +# POWER6 with XLC. The tests below are crafted for IBM XLC and the LLVM +# front-end. XLC/LLVM only supplies POWER8 so we have to set the flags for +# XLC/LLVM to POWER8. I've got a feeling LLVM is going to cause trouble. + +ifneq ($(IS_PPC32)$(IS_PPC64),00) +ifeq ($(DETECT_FEATURES),1) + + # IBM XL C/C++ has the -qaltivec flag really screwed up. We can't seem + # to get it enabled without an -qarch= option. And -qarch= produces an + # error on later versions of the compiler. The only thing that seems + # to work consistently is -qarch=auto. -qarch=auto is equivalent to + # GCC's -march=native, which we don't really want. + + # XLC requires -qaltivec in addition to Arch or CPU option + ifeq ($(XLC_COMPILER),1) + # POWER9_FLAG = -qarch=pwr9 -qaltivec + POWER8_FLAG = -qarch=pwr8 -qaltivec + POWER7_VSX_FLAG = -qarch=pwr7 -qvsx -qaltivec + POWER7_PWR_FLAG = -qarch=pwr7 -qaltivec + ALTIVEC_FLAG = -qarch=auto -qaltivec + else + # POWER9_FLAG = -mcpu=power9 + POWER8_FLAG = -mcpu=power8 + POWER7_VSX_FLAG = -mcpu=power7 -mvsx + POWER7_PWR_FLAG = -mcpu=power7 + ALTIVEC_FLAG = -maltivec + endif + + # GCC 10 is giving us trouble in CPU_ProbePower9() and + # CPU_ProbeDARN(). GCC is generating POWER9 instructions + # on POWER8 for ppc_power9.cpp. The compiler folks did + # not think through the consequences of requiring us to + # use -mcpu=power9 to unlock the ISA. Epic fail. + # https:#github.com/weidai11/cryptopp/issues/986 + POWER9_FLAG = + + # XLC with LLVM front-ends failed to define XLC defines. + #ifeq ($(findstring -qxlcompatmacros,$(CXXFLAGS)),) + # TPROG = TestPrograms/test_ppc_altivec.cpp + # TOPT = -qxlcompatmacros + # HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + # ifeq ($(strip $(HAVE_OPT)),0) + # CRYPTOPP_CXXFLAGS += -qxlcompatmacros + # endif + #endif + + ##################################################################### + # Looking for a POWER9 option + + #TPROG = TestPrograms/test_ppc_power9.cpp + #TOPT = $(POWER9_FLAG) + #HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + #ifeq ($(strip $(HAVE_OPT)),0) + # DARN_FLAG = $(POWER9_FLAG) + #else + # POWER9_FLAG = + #endif + + ##################################################################### + # Looking for a POWER8 option + + TPROG = TestPrograms/test_ppc_power8.cpp + TOPT = $(POWER8_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + AES_FLAG = $(POWER8_FLAG) + BLAKE2B_FLAG = $(POWER8_FLAG) + CRC_FLAG = $(POWER8_FLAG) + GCM_FLAG = $(POWER8_FLAG) + GF2N_FLAG = $(POWER8_FLAG) + LEA_FLAG = $(POWER8_FLAG) + SHA_FLAG = $(POWER8_FLAG) + SHACAL2_FLAG = $(POWER8_FLAG) + else + POWER8_FLAG = + endif + + ##################################################################### + # Looking for a POWER7 option + + # GCC needs -mvsx for Power7 to enable 64-bit vector elements. + # XLC provides 64-bit vector elements without an option. + + TPROG = TestPrograms/test_ppc_power7.cpp + TOPT = $(POWER7_VSX_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + POWER7_FLAG = $(POWER7_VSX_FLAG) + else + TPROG = TestPrograms/test_ppc_power7.cpp + TOPT = $(POWER7_PWR_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + POWER7_FLAG = $(POWER7_PWR_FLAG) + else + POWER7_FLAG = + endif + endif + + ##################################################################### + # Looking for an Altivec option + + TPROG = TestPrograms/test_ppc_altivec.cpp + TOPT = $(ALTIVEC_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + ALTIVEC_FLAG := $(ALTIVEC_FLAG) + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + ALTIVEC_FLAG = + endif + + ifneq ($(ALTIVEC_FLAG),) + BLAKE2S_FLAG = $(ALTIVEC_FLAG) + CHACHA_FLAG = $(ALTIVEC_FLAG) + SPECK128_FLAG = $(ALTIVEC_FLAG) + SIMON128_FLAG = $(ALTIVEC_FLAG) + endif + + ##################################################################### + # Fixups for algorithms that can drop to a lower ISA, if needed + + # Drop to Altivec if higher Power is not available + ifneq ($(ALTIVEC_FLAG),) + ifeq ($(GCM_FLAG),) + GCM_FLAG = $(ALTIVEC_FLAG) + endif + endif + + ##################################################################### + # Fixups for missing ISAs + + ifeq ($(ALTIVEC_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ALTIVEC + else ifeq ($(POWER7_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_POWER7 + else ifeq ($(POWER8_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_POWER8 + #else ifeq ($(POWER9_FLAG),) + # CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_POWER9 + endif + +# DETECT_FEATURES +endif + +# IBM XL C++ compiler +ifeq ($(XLC_COMPILER),1) + ifeq ($(findstring -qmaxmem,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -qmaxmem=-1 + endif + # http://www-01.ibm.com/support/docview.wss?uid=swg21007500 + ifeq ($(findstring -qrtti,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -qrtti + endif +endif + +# IS_PPC32, IS_PPC64 +endif + +########################################################### +##### Common ##### +########################################################### + +# Add -fPIC for targets *except* X86, X32, Cygwin or MinGW +ifeq ($(IS_X86)$(IS_CYGWIN)$(IS_MINGW),000) + ifeq ($(findstring -fpic,$(CXXFLAGS))$(findstring -fPIC,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -fPIC + endif +endif + +# Use -pthread whenever it is available. See http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf +# http://stackoverflow.com/questions/2127797/gcc-significance-of-pthread-flag-when-compiling +ifeq ($(DETECT_FEATURES),1) + ifeq ($(XLC_COMPILER),1) + ifeq ($(findstring -qthreaded,$(CXXFLAGS)),) + TPROG = TestPrograms/test_pthreads.cpp + TOPT = -qthreaded + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRYPTOPP_CXXFLAGS += -qthreaded + endif # CRYPTOPP_CXXFLAGS + endif # qthreaded + else + ifeq ($(findstring -pthread,$(CXXFLAGS)),) + TPROG = TestPrograms/test_pthreads.cpp + TOPT = -pthread + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRYPTOPP_CXXFLAGS += -pthread + endif # CRYPTOPP_CXXFLAGS + endif # pthread + endif # XLC/GCC and friends +endif # DETECT_FEATURES + +# Remove -fPIC if present. SunCC use -KPIC, and needs the larger GOT table +# https://docs.oracle.com/cd/E19205-01/819-5267/bkbaq/index.html +ifeq ($(SUN_COMPILER),1) + CRYPTOPP_CXXFLAGS := $(subst -fPIC,-KPIC,$(CRYPTOPP_CXXFLAGS)) + CRYPTOPP_CXXFLAGS := $(subst -fpic,-KPIC,$(CRYPTOPP_CXXFLAGS)) +endif + +# Remove -fPIC if present. IBM XL C++ uses -qpic +ifeq ($(XLC_COMPILER),1) + CRYPTOPP_CXXFLAGS := $(subst -fPIC,-qpic,$(CRYPTOPP_CXXFLAGS)) + CRYPTOPP_CXXFLAGS := $(subst -fpic,-qpic,$(CRYPTOPP_CXXFLAGS)) +endif + +# Disable IBM XL C++ "1500-036: (I) The NOSTRICT option (default at OPT(3)) +# has the potential to alter the semantics of a program." +ifeq ($(XLC_COMPILER),1) + TPROG = TestPrograms/test_cxx.cpp + TOPT = -qsuppress=1500-036 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRYPTOPP_CXXFLAGS += -qsuppress=1500-036 + endif # -qsuppress +endif # IBM XL C++ compiler + +# libc++ is LLVM's standard C++ library. If we add libc++ +# here then all user programs must use it too. The open +# question is, which choice is easier on users? +ifneq ($(IS_DARWIN),0) + CXX ?= c++ + # CRYPTOPP_CXXFLAGS += -stdlib=libc++ + ifeq ($(findstring -fno-common,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -fno-common + endif + IS_APPLE_LIBTOOL=$(shell libtool -V 2>&1 | $(GREP) -i -c 'Apple') + ifeq ($(IS_APPLE_LIBTOOL),1) + AR = libtool + else + AR = /usr/bin/libtool + endif + ARFLAGS = -static -o +endif + +# Add -xregs=no%appl SPARC. SunCC should not use certain registers in library code. +# https://docs.oracle.com/cd/E18659_01/html/821-1383/bkamt.html +ifneq ($(IS_SPARC32)$(IS_SPARC64),00) + ifeq ($(SUN_COMPILER),1) + ifeq ($(findstring -xregs=no%appl,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -xregs=no%appl + endif # -xregs + endif # SunCC + ifeq ($(GCC_COMPILER),1) + ifeq ($(findstring -mno-app-regs,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -mno-app-regs + endif # no-app-regs + endif # GCC +endif # Sparc + +# Add -pipe for everything except IBM XL C++, SunCC and ARM. +# Allow ARM-64 because they seems to have >1 GB of memory +ifeq ($(XLC_COMPILER)$(SUN_COMPILER)$(IS_ARM32),000) + ifeq ($(findstring -save-temps,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -pipe + endif +endif + +# For SunOS, create a Mapfile that allows our object files +# to contain additional bits (like SSE4 and AES on old Xeon) +# http://www.oracle.com/technetwork/server-storage/solaris/hwcap-modification-139536.html +ifeq ($(IS_SUN)$(SUN_COMPILER),11) + ifneq ($(IS_X86)$(IS_X64),00) + ifeq ($(findstring -DCRYPTOPP_DISABLE_ASM,$(CRYPTOPP_CXXFLAGS) $(CXXFLAGS)),) + CRYPTOPP_LDFLAGS += -M cryptopp.mapfile + endif # No CRYPTOPP_DISABLE_ASM + endif # X86/X32/X64 +endif # SunOS + +ifneq ($(IS_LINUX)$(IS_HURD),00) + ifeq ($(findstring -fopenmp,$(CXXFLAGS)),-fopenmp) + ifeq ($(findstring -lgomp,$(LDLIBS)),) + LDLIBS += -lgomp + endif # LDLIBS + endif # OpenMP +endif # IS_LINUX or IS_HURD + +# Add -errtags=yes to get the name for a warning suppression +ifneq ($(SUN_COMPILER),0) # override flags for CC Sun C++ compiler +# Add to all Solaris +CRYPTOPP_CXXFLAGS += -template=no%extdef +SUN_CC10_BUGGY := $(shell $(CXX) -V 2>&1 | $(GREP) -c -E "CC: Sun .* 5\.10 .* (2009|2010/0[1-4])") +ifneq ($(SUN_CC10_BUGGY),0) +# -DCRYPTOPP_INCLUDE_VECTOR_CC is needed for Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 +# and was fixed in May 2010. Remove it if you get "already had a body defined" errors in vector.cc +CRYPTOPP_CXXFLAGS += -DCRYPTOPP_INCLUDE_VECTOR_CC +endif +AR = $(CXX) +ARFLAGS = -xar -o +RANLIB = true +endif + +# No ASM for Travis testing +ifeq ($(findstring no-asm,$(MAKECMDGOALS)),no-asm) + ifeq ($(findstring -DCRYPTOPP_DISABLE_ASM,$(CRYPTOPP_CXXFLAGS) $(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif # CRYPTOPP_CXXFLAGS +endif # No ASM + +# Native build testing. Issue 'make native'. +ifeq ($(findstring native,$(MAKECMDGOALS)),native) + NATIVE_OPT = + + # Try GCC and compatibles first + TPROG = TestPrograms/test_cxx.cpp + TOPT = -march=native + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + NATIVE_OPT = -march=native + endif # NATIVE_OPT + + # And tune + ifeq ($(NATIVE_OPT),) + TOPT = -mtune=native + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + NATIVE_OPT = -mtune=native + endif # NATIVE_OPT + endif + + # Try SunCC next + ifeq ($(NATIVE_OPT),) + TOPT = -native + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + NATIVE_OPT = -native + endif # NATIVE_OPT + endif + + ifneq ($(NATIVE_OPT),) + CRYPTOPP_CXXFLAGS += $(NATIVE_OPT) + endif + +endif # Native + +# Undefined Behavior Sanitizer (UBsan) testing. Issue 'make ubsan'. +ifeq ($(findstring ubsan,$(MAKECMDGOALS)),ubsan) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-g%=-g3) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-O%=-O1) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-xO%=-xO1) + ifeq ($(findstring -fsanitize=undefined,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -fsanitize=undefined + endif # CRYPTOPP_CXXFLAGS + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # CRYPTOPP_CXXFLAGS +endif # UBsan + +# Address Sanitizer (Asan) testing. Issue 'make asan'. +ifeq ($(findstring asan,$(MAKECMDGOALS)),asan) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-g%=-g3) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-O%=-O1) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-xO%=-xO1) + ifeq ($(findstring -fsanitize=address,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -fsanitize=address + endif # CRYPTOPP_CXXFLAGS + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # CRYPTOPP_CXXFLAGS + ifeq ($(findstring -fno-omit-frame-pointer,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -fno-omit-frame-pointer + endif # CRYPTOPP_CXXFLAGS +endif # Asan + +# LD gold linker testing. Triggered by 'LD=ld.gold'. +ifeq ($(findstring ld.gold,$(LD)),ld.gold) + ifeq ($(findstring -fuse-ld=gold,$(CXXFLAGS)),) + LD_GOLD = $(shell command -v ld.gold) + ELF_FORMAT := $(shell file $(LD_GOLD) 2>&1 | cut -d":" -f 2 | $(GREP) -i -c "elf") + ifneq ($(ELF_FORMAT),0) + CRYPTOPP_LDFLAGS += -fuse-ld=gold + endif # ELF/ELF64 + endif # CXXFLAGS +endif # Gold + +# lcov code coverage. Issue 'make coverage'. +ifneq ($(filter lcov coverage,$(MAKECMDGOALS)),) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-g%=-g3) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-O%=-O1) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-xO%=-xO1) + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # CRYPTOPP_COVERAGE + ifeq ($(findstring -coverage,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -coverage + endif # -coverage +endif # GCC code coverage + +# gcov code coverage for Travis. Issue 'make codecov'. +ifneq ($(filter gcov codecov,$(MAKECMDGOALS)),) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-g%=-g3) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-O%=-O1) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-xO%=-xO1) + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # CRYPTOPP_COVERAGE + ifeq ($(findstring -coverage,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -coverage + endif # -coverage +endif # GCC code coverage + +# Valgrind testing. Issue 'make valgrind'. +ifneq ($(filter valgrind,$(MAKECMDGOALS)),) + # Tune flags; see http://valgrind.org/docs/manual/quick-start.html + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-g%=-g3) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-O%=-O1) + CRYPTOPP_CXXFLAGS := $(CRYPTOPP_CXXFLAGS:-xO%=-xO1) + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # -DCRYPTOPP_COVERAGE +endif # Valgrind + +# Debug testing on GNU systems. Triggered by -DDEBUG. +# Newlib test due to http://sourceware.org/bugzilla/show_bug.cgi?id=20268 +ifneq ($(filter -DDEBUG -DDEBUG=1,$(CXXFLAGS)),) + TPROG = TestPrograms/test_cxx.cpp + TOPT = + USING_GLIBCXX := $(shell $(CXX)$(CXXFLAGS) -E $(TPROG) -c 2>&1 | $(GREP) -i -c "__GLIBCXX__") + ifneq ($(USING_GLIBCXX),0) + ifeq ($(HAS_NEWLIB),0) + ifeq ($(findstring -D_GLIBCXX_DEBUG,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -D_GLIBCXX_DEBUG + endif # CRYPTOPP_CXXFLAGS + endif # HAS_NEWLIB + endif # USING_GLIBCXX + + ifeq ($(XLC_COMPILER),1) + TPROG = TestPrograms/test_cxx.cpp + TOPT = -qheapdebug -qro + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRYPTOPP_CXXFLAGS += -qheapdebug -qro + endif # CRYPTOPP_CXXFLAGS + endif # XLC_COMPILER +endif # Debug build + +# Dead code stripping. Issue 'make lean'. +ifeq ($(findstring lean,$(MAKECMDGOALS)),lean) + ifeq ($(findstring -ffunction-sections,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -ffunction-sections + endif # CRYPTOPP_CXXFLAGS + ifeq ($(findstring -fdata-sections,$(CXXFLAGS)),) + CRYPTOPP_CXXFLAGS += -fdata-sections + endif # CRYPTOPP_CXXFLAGS + ifneq ($(IS_DARWIN),0) + ifeq ($(findstring -Wl,-dead_strip,$(LDFLAGS)),) + CRYPTOPP_LDFLAGS += -Wl,-dead_strip + endif # CRYPTOPP_CXXFLAGS + else # BSD, Linux and Unix + ifeq ($(findstring -Wl,--gc-sections,$(LDFLAGS)),) + CRYPTOPP_LDFLAGS += -Wl,--gc-sections + endif # LDFLAGS + endif # MAKECMDGOALS +endif # Dead code stripping + +# For Shared Objects, Diff, Dist/Zip rules +LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config_ver.h | cut -d" " -f 3) +LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1) +LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2) +LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3) + +ifeq ($(strip $(LIB_PATCH)),) + LIB_PATCH := 0 +endif + +ifeq ($(HAS_SOLIB_VERSION),1) +# Different patchlevels and minors are compatible since 6.1 +SOLIB_COMPAT_SUFFIX=.$(LIB_MAJOR) +# Linux uses -Wl,-soname +ifneq ($(IS_LINUX)$(IS_HURD),00) +# Linux uses full version suffix for shared library +SOLIB_VERSION_SUFFIX=.$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH) +SOLIB_FLAGS=-Wl,-soname,libcryptopp.so$(SOLIB_COMPAT_SUFFIX) +endif +# Solaris uses -Wl,-h +ifeq ($(IS_SUN),1) +# Solaris uses major version suffix for shared library, but we use major.minor +# The minor version allows previous version to remain and not overwritten. +# https://blogs.oracle.com/solaris/how-to-name-a-solaris-shared-object-v2 +SOLIB_VERSION_SUFFIX=.$(LIB_MAJOR).$(LIB_MINOR) +SOLIB_FLAGS=-Wl,-h,libcryptopp.so$(SOLIB_COMPAT_SUFFIX) +endif +endif # HAS_SOLIB_VERSION + +########################################################### +##### Temp file cleanup ##### +########################################################### + +# After this point no more test programs should be run. +# https://github.com/weidai11/cryptopp/issues/738 +ifeq ($(findstring /dev/null,$(TOUT)),) + # $(info TOUT is not /dev/null, cleaning $(TOUT)) + ifeq ($(wildcard $(TOUT)),$(TOUT)) + UNUSED := $(shell $(RM) $(TOUT) 2>/dev/null) + endif + ifeq ($(wildcard $(TOUT).dSYM/),$(TOUT).dSYM/) + UNUSED := $(shell $(RM) -r $(TOUT).dSYM/ 2>/dev/null) + endif +endif + +########################################################### +##### Source and object files ##### +########################################################### + +# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems. +SRCS := cryptlib.cpp cpu.cpp integer.cpp $(filter-out cryptlib.cpp cpu.cpp integer.cpp pch.cpp simple.cpp,$(sort $(wildcard *.cpp))) +# For Makefile.am; resource.h is Windows +INCL := $(filter-out resource.h,$(sort $(wildcard *.h))) + +ifneq ($(IS_MINGW),0) +INCL += resource.h +endif + +# Cryptogams source files. We couple to ARMv7. +# Limit to Linux. The source files target the GNU assembler. +# Also see https://www.cryptopp.com/wiki/Cryptogams. +ifeq ($(IS_ARM32)$(IS_LINUX),11) + ifeq ($(CLANG_COMPILER),1) + CRYPTOGAMS_ARMV4_FLAG = -march=armv7-a -Wa,--noexecstack + CRYPTOGAMS_ARMV4_THUMB_FLAG = -march=armv7-a -mthumb -Wa,--noexecstack + else + CRYPTOGAMS_ARMV4_FLAG = -march=armv7-a -Wa,--noexecstack + CRYPTOGAMS_ARMV4_THUMB_FLAG = -march=armv7-a -Wa,--noexecstack + endif + SRCS += aes_armv4.S sha1_armv4.S sha256_armv4.S sha512_armv4.S +endif + +# Remove unneeded arch specific files to speed build time. +ifeq ($(IS_PPC32)$(IS_PPC64),00) + SRCS := $(filter-out ppc_%,$(SRCS)) +endif +ifeq ($(IS_ARM32)$(IS_ARMV8),00) + SRCS := $(filter-out arm_%,$(SRCS)) + SRCS := $(filter-out neon_%,$(SRCS)) +endif +ifeq ($(IS_X86)$(IS_X32)$(IS_X64),000) + SRCS := $(filter-out sse_%,$(SRCS)) +endif + +# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems. +OBJS := $(SRCS:.cpp=.o) +OBJS := $(OBJS:.S=.o) + +# List test.cpp first to tame C++ static initialization problems. +TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp dlltest.cpp fipsalgt.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp validat5.cpp validat6.cpp validat7.cpp validat8.cpp validat9.cpp validat10.cpp regtest1.cpp regtest2.cpp regtest3.cpp regtest4.cpp +TESTINCL := bench.h factory.h validate.h + +# Test objects +TESTOBJS := $(TESTSRCS:.cpp=.o) +LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS)) + +# In Crypto++ 5.6.2 these were the source and object files for the FIPS DLL. +# Since the library is on the Historical Validation List we add all files. +# The 5.6.2 list is at https://github.com/weidai11/cryptopp/blob/789f81f048c9. +DLLSRCS := $(SRCS) +DLLOBJS := $(DLLSRCS:.cpp=.export.o) +DLLOBJS := $(DLLOBJS:.S=.export.o) + +# Import lib testing +LIBIMPORTOBJS := $(LIBOBJS:.o=.import.o) +TESTIMPORTOBJS := $(TESTOBJS:.o=.import.o) +DLLTESTOBJS := dlltest.dllonly.o + +# Clean recipe, Issue 998. Don't filter-out some artifacts from the list of objects +# The *.S is a hack. It makes the ASM appear like C++ so the object files make the CLEAN_OBJS list +CLEAN_SRCS := $(wildcard *.cpp) $(patsubst %.S,%.cpp,$(wildcard *.S)) +CLEAN_OBJS := $(CLEAN_SRCS:.cpp=.o) $(CLEAN_SRCS:.cpp=.import.o) $(CLEAN_SRCS:.cpp=.export.o) + +########################################################### +##### Add our flags to user flags ##### +########################################################### + +# This ensures we don't add flags when the user forbids +# use of customary library flags, like -fPIC. Make will +# ignore this assignment when CXXFLAGS is passed as an +# argument to the make program: make CXXFLAGS="..." +CPPFLAGS := $(strip $(CRYPTOPP_CPPFLAGS) $(CPPFLAGS)) +CXXFLAGS := $(strip $(CRYPTOPP_CXXFLAGS) $(CXXFLAGS)) +LDFLAGS := $(strip $(CRYPTOPP_LDFLAGS) $(LDFLAGS)) + +########################################################### +##### Targets and Recipes ##### +########################################################### + +# Default builds program with static library only +.PHONY: default +default: cryptest.exe + +.PHONY: all static dynamic +all: static dynamic cryptest.exe + +ifneq ($(IS_DARWIN),0) +static: libcryptopp.a +shared dynamic dylib: libcryptopp.dylib +else +static: libcryptopp.a +shared dynamic: libcryptopp.so$(SOLIB_VERSION_SUFFIX) +endif + +# CXXFLAGS are tuned earlier. +.PHONY: native no-asm asan ubsan +native no-asm asan ubsan: cryptest.exe + +# CXXFLAGS are tuned earlier. Applications must use linker flags +# -Wl,--gc-sections (Linux and Unix) or -Wl,-dead_strip (OS X) +.PHONY: lean +lean: static dynamic cryptest.exe + +# May want to export CXXFLAGS="-g3 -O1" +.PHONY: lcov coverage +lcov coverage: cryptest.exe + @-$(RM) -r ./TestCoverage/ + lcov --base-directory . --directory . --zerocounters -q + ./cryptest.exe v + ./cryptest.exe tv all + ./cryptest.exe b 0.25 + lcov --base-directory . --directory . -c -o cryptest.info + lcov --remove cryptest.info "adhoc.*" -o cryptest.info + lcov --remove cryptest.info "fips140.*" -o cryptest.info + lcov --remove cryptest.info "*test.*" -o cryptest.info + lcov --remove cryptest.info "/usr/*" -o cryptest.info + genhtml -o ./TestCoverage/ -t "Crypto++ test coverage" --num-spaces 4 cryptest.info + +# Travis CI and CodeCov rule +.PHONY: gcov codecov +gcov codecov: cryptest.exe + @-$(RM) -r ./TestCoverage/ + ./cryptest.exe v + ./cryptest.exe tv all + gcov -r $(SRCS) + +# Should use CXXFLAGS="-g3 -O1" +.PHONY: valgrind +valgrind: cryptest.exe + valgrind --track-origins=yes --suppressions=cryptopp.supp ./cryptest.exe v + +.PHONY: test check +test check: cryptest.exe + ./cryptest.exe v + +# Used to generate list of source files for Autotools, CMakeList, Android.mk, etc +.PHONY: sources +sources: adhoc.cpp + $(info ***** Library sources *****) + $(info $(filter-out $(TESTSRCS),$(SRCS))) + $(info ) + $(info ***** Library headers *****) + $(info $(filter-out $(TESTINCL),$(INCL))) + $(info ) + $(info ***** Test sources *****) + $(info $(TESTSRCS)) + $(info ) + $(info ***** Test headers *****) + $(info $(TESTINCL)) + +# Directory we want (can't specify on Doygen command line) +DOCUMENT_DIRECTORY := ref$(LIB_VER) +# Directory Doxygen uses (specified in Doygen config file) +ifeq ($(wildcard Doxyfile),Doxyfile) +DOXYGEN_DIRECTORY := $(strip $(shell $(GREP) "OUTPUT_DIRECTORY" Doxyfile | $(GREP) -v "\#" | cut -d "=" -f 2)) +endif +# Default directory (in case its missing in the config file) +ifeq ($(strip $(DOXYGEN_DIRECTORY)),) +DOXYGEN_DIRECTORY := html-docs +endif + +# Builds the documentation. Directory name is ref563, ref570, etc. +.PHONY: docs html +docs html: + @-$(RM) -r $(DOXYGEN_DIRECTORY)/ $(DOCUMENT_DIRECTORY)/ html-docs/ + @-$(RM) CryptoPPRef.zip + doxygen Doxyfile -d CRYPTOPP_DOXYGEN_PROCESSING + $(MV) $(DOXYGEN_DIRECTORY)/ $(DOCUMENT_DIRECTORY)/ + zip -9 CryptoPPRef.zip -x ".*" -x "*/.*" -r $(DOCUMENT_DIRECTORY)/ + +.PHONY: clean +clean: + -$(RM) adhoc.cpp.o adhoc.cpp.proto.o $(CLEAN_OBJS) rdrand-*.o + @-$(RM) libcryptopp.a libcryptopp.dylib cryptopp.dll libcryptopp.dll.a libcryptopp.import.a + @-$(RM) libcryptopp.so libcryptopp.so$(SOLIB_COMPAT_SUFFIX) libcryptopp.so$(SOLIB_VERSION_SUFFIX) + @-$(RM) cryptest.exe dlltest.exe cryptest.import.exe cryptest.dat ct et + @-$(RM) *.la *.lo *.gcov *.gcno *.gcda *.stackdump core core-* + @-$(RM) /tmp/adhoc.exe + @-$(RM) -r /tmp/cryptopp_test/ + @-$(RM) -r *.exe.dSYM/ *.dylib.dSYM/ + @-$(RM) -r cov-int/ + +.PHONY: autotools-clean +autotools-clean: + @-$(RM) -f configure.ac configure configure.in Makefile.am Makefile.in Makefile + @-$(RM) -f config.guess config.status config.sub config.h.in compile depcomp + @-$(RM) -f install-sh stamp-h1 ar-lib *.lo *.la *.m4 local.* lt*.sh missing + @-$(RM) -f cryptest cryptestcwd libtool* libcryptopp.la libcryptopp.pc* + @-$(RM) -rf build-aux/ m4/ auto*.cache/ .deps/ .libs/ + +.PHONY: cmake-clean +cmake-clean: + @-$(RM) -f cryptopp-config.cmake CMakeLists.txt + @-$(RM) -rf cmake_build/ + +.PHONY: android-clean +android-clean: + @-$(RM) -f $(patsubst %_simd.cpp,%_simd.cpp.neon,$(wildcard *_simd.cpp)) + @-$(RM) -rf obj/ + +.PHONY: distclean +distclean: clean autotools-clean cmake-clean android-clean + -$(RM) adhoc.cpp adhoc.cpp.copied GNUmakefile.deps benchmarks.html cryptest.txt + -$(RM) cryptest_all.info cryptest_debug.info cryptest_noasm.info cryptest_base.info cryptest.info cryptest_release.info + @-$(RM) cryptest-*.txt cryptopp.tgz libcryptopp.pc *.o *.bc *.ii *~ + @-$(RM) -r cryptlib.lib cryptest.exe *.suo *.sdf *.pdb Win32/ x64/ ipch/ + @-$(RM) -r $(LIBOBJS:.o=.obj) $(TESTOBJS:.o=.obj) + @-$(RM) -r $(LIBOBJS:.o=.lst) $(TESTOBJS:.o=.lst) + @-$(RM) -r TestCoverage/ ref*/ + @-$(RM) cryptopp$(LIB_VER)\.* CryptoPPRef.zip + +# Install cryptest.exe, libcryptopp.a, libcryptopp.so and libcryptopp.pc. +# The library install was broken-out into its own recipe at GH #653. +.PHONY: install +install: cryptest.exe install-lib + @-$(MKDIR) $(DESTDIR)$(BINDIR) + $(CP) cryptest.exe $(DESTDIR)$(BINDIR) + $(CHMOD) u=rwx,go=rx $(DESTDIR)$(BINDIR)/cryptest.exe + @-$(MKDIR) $(DESTDIR)$(DATADIR)/cryptopp/TestData + @-$(MKDIR) $(DESTDIR)$(DATADIR)/cryptopp/TestVectors + $(CP) TestData/*.dat $(DESTDIR)$(DATADIR)/cryptopp/TestData + $(CHMOD) u=rw,go=r $(DESTDIR)$(DATADIR)/cryptopp/TestData/*.dat + $(CP) TestVectors/*.txt $(DESTDIR)$(DATADIR)/cryptopp/TestVectors + $(CHMOD) u=rw,go=r $(DESTDIR)$(DATADIR)/cryptopp/TestVectors/*.txt + +# A recipe to install only the library, and not cryptest.exe. Also +# see https://github.com/weidai11/cryptopp/issues/653. Some users +# already have a libcryptopp.pc. Install the *.pc file if the file +# is present. If you want one, then issue 'make libcryptopp.pc'. +.PHONY: install-lib +install-lib: + @-$(MKDIR) $(DESTDIR)$(INCLUDEDIR)/cryptopp + $(CP) *.h $(DESTDIR)$(INCLUDEDIR)/cryptopp + $(CHMOD) u=rw,go=r $(DESTDIR)$(INCLUDEDIR)/cryptopp/*.h +ifneq ($(wildcard libcryptopp.a),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR) + $(CP) libcryptopp.a $(DESTDIR)$(LIBDIR) + $(CHMOD) u=rw,go=r $(DESTDIR)$(LIBDIR)/libcryptopp.a +endif +ifneq ($(wildcard libcryptopp.dylib),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR) + $(CP) libcryptopp.dylib $(DESTDIR)$(LIBDIR) + $(CHMOD) u=rwx,go=rx $(DESTDIR)$(LIBDIR)/libcryptopp.dylib + -install_name_tool -id $(DESTDIR)$(LIBDIR)/libcryptopp.dylib $(DESTDIR)$(LIBDIR)/libcryptopp.dylib +endif +ifneq ($(wildcard libcryptopp.so$(SOLIB_VERSION_SUFFIX)),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR) + $(CP) libcryptopp.so$(SOLIB_VERSION_SUFFIX) $(DESTDIR)$(LIBDIR) + $(CHMOD) u=rwx,go=rx $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX) +ifeq ($(HAS_SOLIB_VERSION),1) + -$(LN) libcryptopp.so$(SOLIB_VERSION_SUFFIX) $(DESTDIR)$(LIBDIR)/libcryptopp.so + $(LDCONF) $(DESTDIR)$(LIBDIR) +endif +endif +ifneq ($(wildcard libcryptopp.pc),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR)/pkgconfig + $(CP) libcryptopp.pc $(DESTDIR)$(LIBDIR)/pkgconfig + $(CHMOD) u=rw,go=r $(DESTDIR)$(LIBDIR)/pkgconfig/libcryptopp.pc +endif + +.PHONY: remove uninstall +remove uninstall: + -$(RM) -r $(DESTDIR)$(INCLUDEDIR)/cryptopp + -$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.a + -$(RM) $(DESTDIR)$(BINDIR)/cryptest.exe +ifneq ($(wildcard $(DESTDIR)$(LIBDIR)/libcryptopp.dylib),) + -$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.dylib +endif +ifneq ($(wildcard $(DESTDIR)$(LIBDIR)/libcryptopp.so),) + -$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so +endif + @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX) + @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_COMPAT_SUFFIX) + @-$(RM) $(DESTDIR)$(LIBDIR)/pkgconfig/libcryptopp.pc + @-$(RM) -r $(DESTDIR)$(DATADIR)/cryptopp + +libcryptopp.a: $(LIBOBJS) | osx_warning + $(AR) $(ARFLAGS) $@ $(LIBOBJS) +ifeq ($(IS_SUN),0) + $(RANLIB) $@ +endif + +ifeq ($(HAS_SOLIB_VERSION),1) +.PHONY: libcryptopp.so +libcryptopp.so: libcryptopp.so$(SOLIB_VERSION_SUFFIX) | so_warning +endif + +libcryptopp.so$(SOLIB_VERSION_SUFFIX): $(LIBOBJS) +ifeq ($(XLC_COMPILER),1) + $(CXX) -qmkshrobj $(SOLIB_FLAGS) -o $@ $(CXXFLAGS) $(LDFLAGS) $(LIBOBJS) $(LDLIBS) +else + $(CXX) -shared $(SOLIB_FLAGS) -o $@ $(CXXFLAGS) $(LDFLAGS) $(LIBOBJS) $(LDLIBS) +endif +ifeq ($(HAS_SOLIB_VERSION),1) + -$(LN) libcryptopp.so$(SOLIB_VERSION_SUFFIX) libcryptopp.so + -$(LN) libcryptopp.so$(SOLIB_VERSION_SUFFIX) libcryptopp.so$(SOLIB_COMPAT_SUFFIX) +endif + +libcryptopp.dylib: $(LIBOBJS) | osx_warning + $(CXX) -dynamiclib -o $@ $(CXXFLAGS) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS) + +cryptest.exe: $(LINK_LIBRARY) $(TESTOBJS) | osx_warning + $(CXX) -o $@ $(CXXFLAGS) $(TESTOBJS) $(LINK_LIBRARY_PATH)$(LINK_LIBRARY) $(LDFLAGS) $(LDLIBS) + +# Makes it faster to test changes +nolib: $(OBJS) + $(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS) + +dll: cryptest.import.exe dlltest.exe + +cryptopp.dll: $(DLLOBJS) + $(CXX) -shared -o $@ $(CXXFLAGS) $(DLLOBJS) $(LDFLAGS) $(LDLIBS) -Wl,--out-implib=libcryptopp.dll.a + +libcryptopp.import.a: $(LIBIMPORTOBJS) + $(AR) $(ARFLAGS) $@ $(LIBIMPORTOBJS) +ifeq ($(IS_SUN),0) + $(RANLIB) $@ +endif + +cryptest.import.exe: cryptopp.dll libcryptopp.import.a $(TESTIMPORTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(TESTIMPORTOBJS) -L. -lcryptopp.dll -lcryptopp.import $(LDFLAGS) $(LDLIBS) + +dlltest.exe: cryptopp.dll $(DLLTESTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(DLLTESTOBJS) -L. -lcryptopp.dll $(LDFLAGS) $(LDLIBS) + +# Some users already have a libcryptopp.pc. We install it if the file +# is present. If you want one, then issue 'make libcryptopp.pc'. Be sure +# to use/verify PREFIX and LIBDIR below after writing the file. +cryptopp.pc libcryptopp.pc: + @echo '# Crypto++ package configuration file' > libcryptopp.pc + @echo '' >> libcryptopp.pc + @echo 'prefix=$(PC_PREFIX)' >> libcryptopp.pc + @echo 'libdir=$(PC_LIBDIR)' >> libcryptopp.pc + @echo 'includedir=$(PC_INCLUDEDIR)' >> libcryptopp.pc + @echo 'datadir=$(PC_DATADIR)' >> libcryptopp.pc + @echo '' >> libcryptopp.pc + @echo 'Name: Crypto++' >> libcryptopp.pc + @echo 'Description: Crypto++ cryptographic library' >> libcryptopp.pc + @echo 'Version: 8.6' >> libcryptopp.pc + @echo 'URL: https://cryptopp.com/' >> libcryptopp.pc + @echo '' >> libcryptopp.pc + @echo 'Cflags: -I$${includedir}' >> libcryptopp.pc + @echo 'Libs: -L$${libdir} -lcryptopp' >> libcryptopp.pc + +# This recipe prepares the distro files +TEXT_FILES := *.h *.cpp *.S GNUmakefile GNUmakefile-cross License.txt Readme.txt Install.txt Filelist.txt Doxyfile cryptest* cryptlib* dlltest* cryptdll* *.sln *.vcxproj *.filters cryptopp.rc TestVectors/*.txt TestData/*.dat TestPrograms/*.cpp +EXEC_FILES := TestScripts/*.sh TestScripts/*.cmd +EXEC_DIRS := TestData/ TestVectors/ TestScripts/ TestPrograms/ + +ifeq ($(wildcard Filelist.txt),Filelist.txt) +DIST_FILES := $(shell cat Filelist.txt) +endif + +.PHONY: trim +trim: +ifneq ($(IS_DARWIN),0) + $(SED) -i '' -e's/[[:space:]]*$$//' *.supp *.txt .*.yml *.h *.cpp *.asm *.S + $(SED) -i '' -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross + $(SED) -i '' -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cpp TestScripts/*.* + make convert +else + $(SED) -i -e's/[[:space:]]*$$//' *.supp *.txt .*.yml *.h *.cpp *.asm *.S + $(SED) -i -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross + $(SED) -i -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cpp TestScripts/*.* + make convert +endif + +.PHONY: convert +convert: + @-$(CHMOD) u=rwx,go=rx $(EXEC_DIRS) + @-$(CHMOD) u=rw,go=r $(TEXT_FILES) *.supp .*.yml *.asm *.zip TestVectors/*.txt TestData/*.dat TestPrograms/*.cpp + @-$(CHMOD) u=rwx,go=rx $(EXEC_FILES) *.sh + -unix2dos --keepdate --quiet $(TEXT_FILES) .*.yml *.asm TestScripts/*.cmd TestScripts/*.txt TestScripts/*.cpp + -dos2unix --keepdate --quiet GNUmakefile GNUmakefile-cross *.sh *.S *.supp *.mapfile TestScripts/*.sh +ifneq ($(IS_DARWIN),0) + @-xattr -c * +endif + +# Build the ZIP file with source files. No documentation. +.PHONY: zip dist +zip dist: | distclean convert + zip -q -9 cryptopp$(LIB_VER).zip $(DIST_FILES) + +# Build the ISO to transfer the ZIP to old distros via CDROM +.PHONY: iso +iso: | zip +ifneq ($(IS_DARWIN),0) + $(MKDIR) $(PWD)/cryptopp$(LIB_VER) + $(CP) cryptopp$(LIB_VER).zip $(PWD)/cryptopp$(LIB_VER) + hdiutil makehybrid -iso -joliet -o cryptopp$(LIB_VER).iso $(PWD)/cryptopp$(LIB_VER) + @-$(RM) -r $(PWD)/cryptopp$(LIB_VER) +else ifneq ($(IS_LINUX)$(IS_HURD),00) + $(MKDIR) $(PWD)/cryptopp$(LIB_VER) + $(CP) cryptopp$(LIB_VER).zip $(PWD)/cryptopp$(LIB_VER) + genisoimage -q -o cryptopp$(LIB_VER).iso $(PWD)/cryptopp$(LIB_VER) + @-$(RM) -r $(PWD)/cryptopp$(LIB_VER) +endif + +# CRYPTOPP_CPU_FREQ in GHz +CRYPTOPP_CPU_FREQ ?= 0.0 +.PHONY: bench benchmark benchmarks +bench benchmark benchmarks: cryptest.exe + @-$(RM) -f benchmarks.html + ./cryptest.exe b 2 $(CRYPTOPP_CPU_FREQ) + +adhoc.cpp: adhoc.cpp.proto +ifeq ($(wildcard adhoc.cpp),) + cp adhoc.cpp.proto adhoc.cpp +else + touch adhoc.cpp +endif + +# Include dependencies, if present. You must issue `make deps` to create them. +ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps) +-include GNUmakefile.deps +endif # Dependencies + +# A few recipes trigger warnings for -std=c++11 and -stdlib=c++ +NOSTD_CXXFLAGS=$(filter-out -stdlib=%,$(filter-out -std=%,$(CXXFLAGS))) + +# Cryptogams ARM asm implementation. AES needs -mthumb for Clang +aes_armv4.o : aes_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_THUMB_FLAG) -c) $< + +# SSSE3 or NEON available +aria_simd.o : aria_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(ARIA_FLAG) -c) $< + +# SSE, NEON or POWER7 available +blake2s_simd.o : blake2s_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(BLAKE2S_FLAG) -c) $< + +# SSE, NEON or POWER8 available +blake2b_simd.o : blake2b_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(BLAKE2B_FLAG) -c) $< + +# SSE2 or NEON available +chacha_simd.o : chacha_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CHACHA_FLAG) -c) $< + +# AVX2 available +chacha_avx.o : chacha_avx.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CHACHA_AVX2_FLAG) -c) $< + +# SSSE3 available +cham_simd.o : cham_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CHAM_FLAG) -c) $< + +# SSE4.2 or ARMv8a available +crc_simd.o : crc_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CRC_FLAG) -c) $< + +# Power9 available +darn.o : darn.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(DARN_FLAG) -c) $< + +# SSE2 on i686 +donna_sse.o : donna_sse.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SSE2_FLAG) -c) $< + +# Carryless multiply +gcm_simd.o : gcm_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(GCM_FLAG) -c) $< + +# Carryless multiply +gf2n_simd.o : gf2n_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(GF2N_FLAG) -c) $< + +# SSSE3 available +keccak_simd.o : keccak_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(KECCAK_FLAG) -c) $< + +# SSSE3 available +lea_simd.o : lea_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LEA_FLAG) -c) $< + +# SSSE3 available +lsh256_sse.o : lsh256_sse.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH256_FLAG) -c) $< + +# AVX2 available +lsh256_avx.o : lsh256_avx.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH256_AVX2_FLAG) -c) $< + +# SSSE3 available +lsh512_sse.o : lsh512_sse.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH512_FLAG) -c) $< + +# AVX2 available +lsh512_avx.o : lsh512_avx.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH512_AVX2_FLAG) -c) $< + +# NEON available +neon_simd.o : neon_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(NEON_FLAG) -c) $< + +# AltiVec available +ppc_simd.o : ppc_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(ALTIVEC_FLAG) -c) $< + +# Power7 available +ppc_power7.o : ppc_power7.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(POWER7_FLAG) -c) $< + +# Power8 available +ppc_power8.o : ppc_power8.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(POWER8_FLAG) -c) $< + +# Power9 available +ppc_power9.o : ppc_power9.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(POWER9_FLAG) -c) $< + +# AESNI or ARMv7a/ARMv8a available +rijndael_simd.o : rijndael_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(AES_FLAG) -c) $< + +# SSE4.2/SHA-NI or ARMv8a available +sha_simd.o : sha_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SHA_FLAG) -c) $< + +# Cryptogams SHA1 asm implementation. +sha1_armv4.o : sha1_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_FLAG) -c) $< + +# Cryptogams SHA256 asm implementation. +sha256_armv4.o : sha256_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_FLAG) -c) $< + +# Cryptogams SHA512 asm implementation. +sha512_armv4.o : sha512_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_FLAG) -c) $< + +sha3_simd.o : sha3_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SHA3_FLAG) -c) $< + +# SSE4.2/SHA-NI or ARMv8a available +shacal2_simd.o : shacal2_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SHA_FLAG) -c) $< + +# SSSE3, NEON or POWER8 available +simon128_simd.o : simon128_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SIMON128_FLAG) -c) $< + +# SSSE3, NEON or POWER8 available +speck128_simd.o : speck128_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SPECK128_FLAG) -c) $< + +# ARMv8.4 available +sm3_simd.o : sm3_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SM3_FLAG) -c) $< + +# AESNI available +sm4_simd.o : sm4_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SM4_FLAG) -c) $< + +# IBM XLC -O3 optimization bug +ifeq ($(XLC_COMPILER),1) +sm3.o : sm3.cpp + $(CXX) $(strip $(CPPFLAGS) $(subst -O3,-O2,$(CXXFLAGS)) -c) $< +donna_32.o : donna_32.cpp + $(CXX) $(strip $(CPPFLAGS) $(subst -O3,-O2,$(CXXFLAGS)) -c) $< +donna_64.o : donna_64.cpp + $(CXX) $(strip $(CPPFLAGS) $(subst -O3,-O2,$(CXXFLAGS)) -c) $< +endif + +# SSE2 on i686 +sse_simd.o : sse_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SSE2_FLAG) -c) $< + +# Don't build Rijndael with UBsan. Too much noise due to unaligned data accesses. +ifneq ($(findstring -fsanitize=undefined,$(CXXFLAGS)),) +rijndael.o : rijndael.cpp + $(CXX) $(strip $(subst -fsanitize=undefined,,$(CXXFLAGS)) -c) $< +endif + +# Only use CRYPTOPP_DATA_DIR if its not set in CXXFLAGS +ifeq ($(findstring -DCRYPTOPP_DATA_DIR, $(CXXFLAGS)),) +ifneq ($(strip $(CRYPTOPP_DATA_DIR)),) +validat%.o : validat%.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_DATA_DIR=\"$(CRYPTOPP_DATA_DIR)\" -c) $< +bench%.o : bench%.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_DATA_DIR=\"$(CRYPTOPP_DATA_DIR)\" -c) $< +datatest.o : datatest.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_DATA_DIR=\"$(CRYPTOPP_DATA_DIR)\" -c) $< +test.o : test.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_DATA_DIR=\"$(CRYPTOPP_DATA_DIR)\" -c) $< +endif +endif + +validat1.o : validat1.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(ALTIVEC_FLAG) -c) $< + +%.dllonly.o : %.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_DLL_ONLY -c) $< -o $@ + +%.import.o : %.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_IMPORTS -c) $< -o $@ + +%.export.o : %.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -DCRYPTOPP_EXPORTS -c) $< -o $@ + +%.bc : %.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -c) $< + +%.o : %.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -c) $< + +.PHONY: so_warning +so_warning: +ifeq ($(HAS_SOLIB_VERSION),1) + $(info ) + $(info WARNING: Only the symlinks to the shared-object library have been updated.) + $(info WARNING: If the library is installed in a system directory you will need) + $(info WARNING: to run 'ldconfig' to update the shared-object library cache.) + $(info ) +endif + +.PHONY: osx_warning +osx_warning: +ifeq ($(IS_DARWIN)$(CLANG_COMPILER),11) + ifeq ($(findstring -stdlib=libc++,$(CRYPTOPP_CXXFLAGS)$(CXXFLAGS)),) + $(info ) + $(info INFO: Crypto++ was built without LLVM's libc++. If you are using the library) + $(info INFO: with modern Xcode, then you should add -stdlib=libc++ to CXXFLAGS. It is) + $(info INFO: already present in the makefile, and you only need to uncomment it.) + $(info ) + endif +endif + +.PHONY: dep deps depend +dep deps depend GNUmakefile.deps: + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS)) -MM *.cpp > GNUmakefile.deps diff --git a/external/ours/library/crypto/src/shared/original/GNUmakefile-cross b/external/ours/library/crypto/src/shared/original/GNUmakefile-cross new file mode 100755 index 000000000..9847f04bf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/GNUmakefile-cross @@ -0,0 +1,1060 @@ +# https://www.gnu.org/software/make/manual/make.html#Makefile-Conventions +# and https://www.gnu.org/prep/standards/standards.html + +SHELL = /bin/sh + +# If needed +TMPDIR ?= /tmp +# Used for feature tests +TOUT ?= a.out +TOUT := $(strip $(TOUT)) + +# Allow override for the cryptest.exe recipe. Change to +# ./libcryptopp.so or ./libcryptopp.dylib to suit your +# taste. https://github.com/weidai11/cryptopp/issues/866 +LINK_LIBRARY ?= libcryptopp.a +LINK_LIBRARY_PATH ?= ./ + +# Default FLAGS if none were provided +CPPFLAGS ?= -DNDEBUG +CXXFLAGS ?= -g2 -O3 -fPIC -pipe + +AR ?= ar +ARFLAGS ?= cr +RANLIB ?= ranlib +CP ?= cp +MV ?= mv +CHMOD ?= chmod +MKDIR ?= mkdir -p +GREP ?= grep +SED ?= sed + +LN ?= ln -sf +LDCONF ?= /sbin/ldconfig -n + +IS_IOS ?= 0 +IS_ANDROID ?= 0 +IS_ARM_EMBEDDED ?= 0 + +# Clang is reporting armv8l-unknown-linux-gnueabihf +# for ARMv7 images on Aarch64 hardware. +MACHINEX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null) +HOSTX := $(shell echo $(MACHINEX) | cut -f 1 -d '-') +ifeq ($(HOSTX),) + HOSTX := $(shell uname -m 2>/dev/null) +endif + +IS_LINUX := $(shell echo $(MACHINEX) | $(GREP) -i -c "Linux") + +# Can be used by Android and Embedded cross-compiles. Disable by default because +# Android and embedded users typically don't run this configuration. +HAS_SOLIB_VERSION ?= 0 + +# Formerly adhoc.cpp was created from adhoc.cpp.proto when needed. +# This is now needed because ISA tests are performed using adhoc.cpp. +ifeq ($(wildcard adhoc.cpp),) +$(shell cp adhoc.cpp.proto adhoc.cpp) +endif + +########################################################### +##### General Variables ##### +########################################################### + +# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html +ifeq ($(PREFIX),) + PREFIX = /usr/local +endif +ifeq ($(LIBDIR),) + LIBDIR := $(PREFIX)/lib +endif +ifeq ($(DATADIR),) + DATADIR := $(PREFIX)/share +endif +ifeq ($(INCLUDEDIR),) + INCLUDEDIR := $(PREFIX)/include +endif +ifeq ($(BINDIR),) + BINDIR := $(PREFIX)/bin +endif + +# We honor ARFLAGS, but the "v" option used by default causes a noisy make +ifeq ($(ARFLAGS),rv) + ARFLAGS = r +endif + +########################################################### +##### MacOS ##### +########################################################### + +# MacOS cross-compile configuration. +# See http://www.cryptopp.com/wiki/MacOS_(Command_Line). +ifeq ($(IS_MACOS),1) + # setenv-macos.sh sets CPPFLAGS, CXXFLAGS and LDFLAGS + IS_APPLE_LIBTOOL=$(shell libtool -V 2>&1 | $(GREP) -i -c 'Apple') + ifeq ($(IS_APPLE_LIBTOOL),1) + AR = libtool + else + AR = /usr/bin/libtool + endif + ARFLAGS = -static -o +endif + +########################################################### +##### iOS ##### +########################################################### + +# iOS cross-compile configuration. +# See http://www.cryptopp.com/wiki/iOS_(Command_Line). +ifeq ($(IS_IOS),1) + # setenv-ios.sh sets CPPFLAGS, CXXFLAGS and LDFLAGS + AR = libtool + ARFLAGS = -static -o +endif + +########################################################### +##### Android ##### +########################################################### + +# Android cross-compile configuration. +# See http://www.cryptopp.com/wiki/Android_(Command_Line). +ifeq ($(IS_ANDROID),1) + # setenv-android.sh sets CPPFLAGS, CXXFLAGS and LDFLAGS + + # Source files copied into PWD for Android cpu-features + # setenv-android.sh does the copying. Its a dirty compile. + ANDROID_CPU_OBJ = cpu-features.o +endif + +########################################################### +##### Embedded ##### +########################################################### + +# ARM embedded cross-compile configuration. +# See http://www.cryptopp.com/wiki/ARM_Embedded_(Command_Line) +# and http://www.cryptopp.com/wiki/ARM_Embedded_(Bare Metal). +ifeq ($(IS_ARM_EMBEDDED),1) + # setenv-android.sh sets CPPFLAGS, CXXFLAGS and LDFLAGS +endif + +########################################################### +##### Compiler and Platform ##### +########################################################### + +# Wait until CXXFLAGS have been set by setenv scripts. + +GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -v -E 'llvm|clang' | $(GREP) -i -c -E '(gcc|g\+\+)') +CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -i -c -E 'llvm|clang') + +HOSTX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | cut -f 1 -d '-') +ifeq ($(HOSTX),) + HOSTX := $(shell uname -m 2>/dev/null) +endif + +# This dance is because Clang reports the host architecture instead +# of the target architecture for -dumpmachine. Running Clang on an +# x86_64 machine with -arch arm64 yields x86_64 instead of arm64. + +ifeq ($(CLANG_COMPILER),1) + # The compiler is either GCC or Clang + IS_X86 := $(shell echo $(CXXFLAGS) | $(GREP) -v 64 | $(GREP) -i -c -E 'i.86') + IS_X64 := $(shell echo $(CXXFLAGS) | $(GREP) -i -c -E 'x86_64|amd64') + IS_ARM32 := $(shell echo $(CXXFLAGS) | $(GREP) -v 64 | $(GREP) -i -c -E 'arm|armhf|arm7l|armeabihf') + IS_ARMV8 := $(shell echo $(CXXFLAGS) | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8') +else + IS_X86 := $(shell echo $(HOSTX) | $(GREP) -v 64 | $(GREP) -i -c -E 'i.86') + IS_X64 := $(shell echo $(HOSTX) | $(GREP) -i -c -E 'x86_64|amd64') + IS_ARM32 := $(shell echo $(HOSTX) | $(GREP) -v 64 | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf') + IS_ARMV8 := $(shell echo $(HOSTX) | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8') +endif + +ifeq ($(IS_ARMV8),1) + IS_ARM32 = 0 +endif + +IS_X32 := 0 +IS_PPC32 := 0 +IS_PPC64 := 0 + +# Uncomment for debugging +# $(info Here's what we found... IS_X86: $(IS_X86), IS_X64: $(IS_X64), IS_ARM32: $(IS_ARM32), IS_ARMV8: $(IS_ARMV8)) + +########################################################### +##### Test Program ##### +########################################################### + +# Hack to skip CPU feature tests for some recipes +DETECT_FEATURES ?= 1 +ifeq ($(findstring -DCRYPTOPP_DISABLE_ASM,$(CXXFLAGS)),-DCRYPTOPP_DISABLE_ASM) + DETECT_FEATURES := 0 +else ifeq ($(findstring clean,$(MAKECMDGOALS)),clean) + DETECT_FEATURES := 0 +else ifeq ($(findstring distclean,$(MAKECMDGOALS)),distclean) + DETECT_FEATURES := 0 +else ifeq ($(findstring trim,$(MAKECMDGOALS)),trim) + DETECT_FEATURES := 0 +else ifeq ($(findstring zip,$(MAKECMDGOALS)),zip) + DETECT_FEATURES := 0 +endif + +# Strip out -Wall, -Wextra and friends for feature testing. FORTIFY_SOURCE is removed +# because it requires -O1 or higher, but we use -O0 to tame the optimizer. +# Always print testing flags since some tests always happen, like 64-bit. +TCXXFLAGS := $(filter-out -D_FORTIFY_SOURCE=% -M -MM -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CPPFLAGS) $(CXXFLAGS)) +ifneq ($(strip $(TCXXFLAGS)),) + $(info Using testing flags: $(TCXXFLAGS)) +endif + +# TCOMMAND is used for just about all tests. Make will lazy-evaluate +# the variables when executed by $(shell $(TCOMMAND) ...). +TCOMMAND = $(CXX) $(TCXXFLAGS) $(TEXTRA) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) + +########################################################### +##### X86/X32/X64 Options ##### +########################################################### + +ifneq ($(IS_X86)$(IS_X64),00) +ifeq ($(DETECT_FEATURES),1) + + SSE2_FLAG = -msse2 + SSE3_FLAG = -msse3 + SSSE3_FLAG = -mssse3 + SSE41_FLAG = -msse4.1 + SSE42_FLAG = -msse4.2 + CLMUL_FLAG = -mpclmul + AESNI_FLAG = -maes + AVX_FLAG = -mavx + AVX2_FLAG = -mavx2 + SHANI_FLAG = -msha + + TPROG = TestPrograms/test_x86_sse2.cpp + TOPT = $(SSE2_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CHACHA_FLAG = $(SSE2_FLAG) + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + SSE2_FLAG = + endif + + ifeq ($(SSE2_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif + + # Need SSE2 or higher for these tests + ifneq ($(SSE2_FLAG),) + TPROG = TestPrograms/test_x86_ssse3.cpp + TOPT = $(SSSE3_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + ARIA_FLAG = $(SSSE3_FLAG) + CHAM_FLAG = $(SSSE3_FLAG) + KECCAK_FLAG = $(SSSE3_FLAG) + LEA_FLAG = $(SSSE3_FLAG) + LSH256_FLAG = $(SSSE3_FLAG) + LSH512_FLAG = $(SSSE3_FLAG) + SIMON128_FLAG = $(SSSE3_FLAG) + SPECK128_FLAG = $(SSSE3_FLAG) + else + SSSE3_FLAG = + endif + + # The first Apple MacBooks were Core2's with SSE4.1 + ifneq ($(IS_DARWIN),0) + # Add SSE2 algo's here as required + # They get a free upgrade + endif + + TPROG = TestPrograms/test_x86_sse41.cpp + TOPT = $(SSE41_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + BLAKE2B_FLAG = $(SSE41_FLAG) + BLAKE2S_FLAG = $(SSE41_FLAG) + else + SSE41_FLAG = + endif + + TPROG = TestPrograms/test_x86_sse42.cpp + TOPT = $(SSE42_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CRC_FLAG = $(SSE42_FLAG) + else + SSE42_FLAG = + endif + + TPROG = TestPrograms/test_x86_clmul.cpp + TOPT = $(CLMUL_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + GCM_FLAG = $(SSSE3_FLAG) $(CLMUL_FLAG) + GF2N_FLAG = $(CLMUL_FLAG) + else + CLMUL_FLAG = + endif + + TPROG = TestPrograms/test_x86_aes.cpp + TOPT = $(AESNI_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + AES_FLAG = $(SSE41_FLAG) $(AESNI_FLAG) + SM4_FLAG = $(SSSE3_FLAG) $(AESNI_FLAG) + else + AESNI_FLAG = + endif + + TPROG = TestPrograms/test_x86_avx.cpp + TOPT = $(AVX_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + # XXX_FLAG = $(AVX_FLAG) + else + AVX_FLAG = + endif + + TPROG = TestPrograms/test_x86_avx2.cpp + TOPT = $(AVX2_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + CHACHA_AVX2_FLAG = $(AVX2_FLAG) + LSH256_AVX2_FLAG = $(AVX2_FLAG) + LSH512_AVX2_FLAG = $(AVX2_FLAG) + else + AVX2_FLAG = + endif + + TPROG = TestPrograms/test_x86_sha.cpp + TOPT = $(SHANI_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA_FLAG = $(SSE42_FLAG) $(SHANI_FLAG) + else + SHANI_FLAG = + endif + + ifeq ($(SSE3_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_SSE3 + else ifeq ($(SSSE3_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_SSSE3 + else ifeq ($(SSE41_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_SSE4 + else ifeq ($(SSE42_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_SSE4 + endif + + ifneq ($(SSE42_FLAG),) + # Unusual GCC/Clang on Macports. It assembles AES, but not CLMUL. + # test_x86_clmul.s:15: no such instruction: 'pclmulqdq $0, %xmm1,%xmm0' + ifeq ($(CLMUL_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_CLMUL + endif + ifeq ($(AESNI_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_AESNI + endif + + ifeq ($(AVX_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_AVX + else ifeq ($(AVX2_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_AVX2 + endif + # SHANI independent of AVX per GH #1045 + ifeq ($(SHANI_FLAG),) + CRYPTOPP_CXXFLAGS += -DCRYPTOPP_DISABLE_SHANI + endif + endif + + # Drop to SSE2 if available + ifeq ($(GCM_FLAG),) + GCM_FLAG = $(SSE2_FLAG) + endif + + # Most Clang cannot handle mixed asm with positional arguments, where the + # body is Intel style with no prefix and the templates are AT&T style. + # Also see https://bugs.llvm.org/show_bug.cgi?id=39895 . + + # CRYPTOPP_DISABLE_MIXED_ASM is now being added in config_asm.h for all + # Clang compilers. This test will need to be re-enabled if Clang fixes it. + #TPROG = TestPrograms/test_asm_mixed.cpp + #TOPT = + #HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + #ifneq ($(strip $(HAVE_OPT)),0) + # CXXFLAGS += -DCRYPTOPP_DISABLE_MIXED_ASM + #endif + + # SSE2_FLAGS + endif + +# DETECT_FEATURES +endif + +# IS_X86, IS_X32 and IS_X64 +endif + +########################################################### +##### ARM A-32 and NEON ##### +########################################################### + +ifneq ($(IS_ARM32),0) +ifeq ($(DETECT_FEATURES),1) + + # Android needs -c compile flag for NEON. Otherwise there's an odd linker message. + ifeq ($(IS_ANDROID),1) + NEON_FLAG = -march=armv7-a -mfpu=vfpv3-d16 -mfpu=neon + else + NEON_FLAG = -march=armv7-a -mfpu=neon + endif + + # Clang needs an option to include + TPROG = TestPrograms/test_arm_neon_header.cpp + TOPT = -DCRYPTOPP_ARM_NEON_HEADER=1 $(NEON_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -DCRYPTOPP_ARM_NEON_HEADER=1 + endif + + TPROG = TestPrograms/test_arm_neon.cpp + TOPT = $(NEON_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + ARIA_FLAG = $(NEON_FLAG) + AES_FLAG = $(NEON_FLAG) + CRC_FLAG = $(NEON_FLAG) + GCM_FLAG = $(NEON_FLAG) + BLAKE2B_FLAG = $(NEON_FLAG) + BLAKE2S_FLAG = $(NEON_FLAG) + CHACHA_FLAG = $(NEON_FLAG) + CHAM_FLAG = $(NEON_FLAG) + LEA_FLAG = $(NEON_FLAG) + SHA_FLAG = $(NEON_FLAG) + SIMON128_FLAG = $(NEON_FLAG) + SPECK128_FLAG = $(NEON_FLAG) + SM4_FLAG = $(NEON_FLAG) + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + NEON_FLAG = + endif + + ifeq ($(NEON_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif + +# DETECT_FEATURES +endif +# IS_ARM32 +endif + +########################################################### +##### Aach32 and Aarch64 ##### +########################################################### + +ifneq ($(IS_ARMV8),0) +ifeq ($(DETECT_FEATURES),1) + + ifeq ($(IS_IOS),1) + ASIMD_FLAG = -arch arm64 + CRC_FLAG = -arch arm64 + AES_FLAG = -arch arm64 + PMUL_FLAG = -arch arm64 + SHA_FLAG = -arch arm64 + else + ASIMD_FLAG = -march=armv8-a + CRC_FLAG = -march=armv8-a+crc + AES_FLAG = -march=armv8-a+crypto + GCM_FLAG = -march=armv8-a+crypto + GF2N_FLAG = -march=armv8-a+crypto + SHA_FLAG = -march=armv8-a+crypto + endif + + TPROG = TestPrograms/test_arm_neon_header.cpp + TOPT = -DCRYPTOPP_ARM_NEON_HEADER=1 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -DCRYPTOPP_ARM_NEON_HEADER=1 + endif + + TPROG = TestPrograms/test_arm_acle_header.cpp + TOPT = -DCRYPTOPP_ARM_ACLE_HEADER=1 $(ASIMD_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + TEXTRA += -DCRYPTOPP_ARM_ACLE_HEADER=1 + endif + + TPROG = TestPrograms/test_arm_asimd.cpp + TOPT = $(ASIMD_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + ARIA_FLAG = $(ASIMD_FLAG) + BLAKE2B_FLAG = $(ASIMD_FLAG) + BLAKE2S_FLAG = $(ASIMD_FLAG) + CHACHA_FLAG = $(ASIMD_FLAG) + CHAM_FLAG = $(ASIMD_FLAG) + LEA_FLAG = $(ASIMD_FLAG) + NEON_FLAG = $(ASIMD_FLAG) + SIMON128_FLAG = $(ASIMD_FLAG) + SPECK128_FLAG = $(ASIMD_FLAG) + SM4_FLAG = $(ASIMD_FLAG) + else + # Make does not have useful debugging facilities. Show the user + # what happened by compiling again without the pipe. + $(info Running make again to see what failed) + $(info $(shell $(TCOMMAND))) + ASIMD_FLAG = + endif + + ifeq ($(ASIMD_FLAG),) + CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif + + ifneq ($(ASIMD_FLAG),) + + TPROG = TestPrograms/test_arm_crc.cpp + TOPT = $(CRC_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifneq ($(strip $(HAVE_OPT)),0) + CRC_FLAG = + CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_CRC32 + endif + + TPROG = TestPrograms/test_arm_aes.cpp + TOPT = $(AES_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifneq ($(strip $(HAVE_OPT)),0) + AES_FLAG = + CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_AES + endif + + TPROG = TestPrograms/test_arm_pmull.cpp + TOPT = $(PMULL_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifneq ($(strip $(HAVE_OPT)),0) + GCM_FLAG = + GF2N_FLAG = + CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_PMULL + endif + + TPROG = TestPrograms/test_arm_sha1.cpp + TOPT = $(SHA_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifneq ($(strip $(HAVE_OPT)),0) + SHA_FLAG = + CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA1 + endif + + TPROG = TestPrograms/test_arm_sha256.cpp + TOPT = $(SHA_FLAG) + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifneq ($(strip $(HAVE_OPT)),0) + SHA_FLAG = + CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA2 + endif + + TPROG = TestPrograms/test_arm_sm3.cpp + TOPT = -march=armv8.4-a+sm3 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SM3_FLAG = -march=armv8.4-a+sm3 + SM4_FLAG = -march=armv8.4-a+sm3 + else + #CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SM3 + #CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SM4 + endif + + TPROG = TestPrograms/test_arm_sha3.cpp + TOPT = -march=armv8.4-a+sha3 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA3_FLAG = -march=armv8.4-a+sha3 + else + #CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA3 + endif + + TPROG = TestPrograms/test_arm_sha512.cpp + TOPT = -march=armv8.4-a+sha512 + HAVE_OPT = $(shell $(TCOMMAND) 2>&1 | wc -w) + ifeq ($(strip $(HAVE_OPT)),0) + SHA512_FLAG = -march=armv8.4-a+sha512 + else + #CXXFLAGS += -DCRYPTOPP_DISABLE_ARM_SHA512 + endif + + # ASIMD_FLAG + endif + +# DETECT_FEATURES +endif +# IS_ARMV8 +endif + +########################################################### +##### Common ##### +########################################################### + +# No ASM for Travis testing +ifeq ($(findstring no-asm,$(MAKECMDGOALS)),no-asm) + ifeq ($(findstring -DCRYPTOPP_DISABLE_ASM,$(CXXFLAGS)),) + CXXFLAGS += -DCRYPTOPP_DISABLE_ASM + endif # CXXFLAGS +endif # No ASM + +# Undefined Behavior Sanitizer (UBsan) testing. Issue 'make ubsan'. +ifeq ($(findstring ubsan,$(MAKECMDGOALS)),ubsan) + ifeq ($(findstring -fsanitize=undefined,$(CXXFLAGS)),) + CXXFLAGS += -fsanitize=undefined + endif # CXXFLAGS + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # CXXFLAGS +endif # UBsan + +# Address Sanitizer (Asan) testing. Issue 'make asan'. +ifeq ($(findstring asan,$(MAKECMDGOALS)),asan) + ifeq ($(findstring -fsanitize=address,$(CXXFLAGS)),) + CXXFLAGS += -fsanitize=address + endif # CXXFLAGS + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # CXXFLAGS + ifeq ($(findstring -fno-omit-frame-pointer,$(CXXFLAGS)),) + CXXFLAGS += -fno-omit-frame-pointer + endif # CXXFLAGS +endif # Asan + +# LD gold linker testing. Triggered by 'LD=ld.gold'. +ifeq ($(findstring ld.gold,$(LD)),ld.gold) + ifeq ($(findstring -fuse-ld=gold,$(CXXFLAGS)),) + ELF_FORMAT := $(shell file `which ld.gold` 2>&1 | cut -d":" -f 2 | $(GREP) -i -c "elf") + ifneq ($(ELF_FORMAT),0) + LDFLAGS += -fuse-ld=gold + endif # ELF/ELF64 + endif # CXXFLAGS +endif # Gold + +# Valgrind testing. Issue 'make valgrind'. +ifneq ($(filter valgrind,$(MAKECMDGOALS)),) + # Tune flags; see http://valgrind.org/docs/manual/quick-start.html + CXXFLAGS := $(CXXFLAGS:-g%=-g3) + CXXFLAGS := $(CXXFLAGS:-O%=-O1) + CXXFLAGS := $(CXXFLAGS:-xO%=-xO1) + ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),) + CXXFLAGS += -DCRYPTOPP_COVERAGE + endif # -DCRYPTOPP_COVERAGE +endif # Valgrind + +# Debug testing on GNU systems. Triggered by -DDEBUG. +# Newlib test due to http://sourceware.org/bugzilla/show_bug.cgi?id=20268 +ifneq ($(filter -DDEBUG -DDEBUG=1,$(CXXFLAGS)),) + USING_GLIBCXX := $(shell $(CXX) $(CXXFLAGS) -E pch.cpp 2>&1 | $(GREP) -i -c "__GLIBCXX__") + ifneq ($(USING_GLIBCXX),0) + ifeq ($(HAS_NEWLIB),0) + ifeq ($(findstring -D_GLIBCXX_DEBUG,$(CXXFLAGS)),) + CXXFLAGS += -D_GLIBCXX_DEBUG + endif # CXXFLAGS + endif # HAS_NEWLIB + endif # USING_GLIBCXX +endif # GNU Debug build + +# Dead code stripping. Issue 'make lean'. +ifeq ($(findstring lean,$(MAKECMDGOALS)),lean) + ifeq ($(findstring -ffunction-sections,$(CXXFLAGS)),) + CXXFLAGS += -ffunction-sections + endif # CXXFLAGS + ifeq ($(findstring -fdata-sections,$(CXXFLAGS)),) + CXXFLAGS += -fdata-sections + endif # CXXFLAGS + ifneq ($(IS_IOS),0) + ifeq ($(findstring -Wl,-dead_strip,$(LDFLAGS)),) + LDFLAGS += -Wl,-dead_strip + endif # CXXFLAGS + else # BSD, Linux and Unix + ifeq ($(findstring -Wl,--gc-sections,$(LDFLAGS)),) + LDFLAGS += -Wl,--gc-sections + endif # LDFLAGS + endif # MAKECMDGOALS +endif # Dead code stripping + +########################################################### +##### Source and object files ##### +########################################################### + +# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems. +SRCS := cryptlib.cpp cpu.cpp integer.cpp $(filter-out cryptlib.cpp cpu.cpp integer.cpp pch.cpp simple.cpp,$(sort $(wildcard *.cpp))) +# For Makefile.am; resource.h is Windows +INCL := $(filter-out resource.h,$(sort $(wildcard *.h))) + +# Cryptogams source files. We couple to ARMv7. +# Limit to Linux. The source files target the GNU assembler. +# Also see https://www.cryptopp.com/wiki/Cryptogams. +ifeq ($(IS_ARM32)$(IS_LINUX),11) + ifeq ($(CLANG_COMPILER),1) + CRYPTOGAMS_ARMV4_FLAG = -march=armv7-a -Wa,--noexecstack + CRYPTOGAMS_ARMV4_THUMB_FLAG = -march=armv7-a -mthumb -Wa,--noexecstack + else + CRYPTOGAMS_ARMV4_FLAG = -march=armv7-a -Wa,--noexecstack + CRYPTOGAMS_ARMV4_THUMB_FLAG = -march=armv7-a -Wa,--noexecstack + endif + SRCS += aes_armv4.S sha1_armv4.S sha256_armv4.S sha512_armv4.S +endif + +# Remove unneeded arch specific files to speed build time. +ifeq ($(IS_PPC32)$(IS_PPC64),00) + SRCS := $(filter-out ppc_%,$(SRCS)) +endif +ifeq ($(IS_ARM32)$(IS_ARMV8),00) + SRCS := $(filter-out arm_%,$(SRCS)) + SRCS := $(filter-out neon_%,$(SRCS)) +endif +ifeq ($(IS_X86)$(IS_X32)$(IS_X64),000) + SRCS := $(filter-out sse_%,$(SRCS)) +endif + +# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems. +OBJS := $(SRCS:.cpp=.o) +OBJS := $(OBJS:.S=.o) + +# List test.cpp first to tame C++ static initialization problems. +TESTSRCS := adhoc.cpp test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp dlltest.cpp fipsalgt.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp validat5.cpp validat6.cpp validat7.cpp validat8.cpp validat9.cpp validat10.cpp regtest1.cpp regtest2.cpp regtest3.cpp regtest4.cpp +TESTINCL := bench.h factory.h validate.h + +# Test objects +TESTOBJS := $(TESTSRCS:.cpp=.o) +LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS)) + +# Clean recipe, Issue 998. Don't filter-out some artifacts from the list of objects +# The *.S is a hack. It makes the ASM appear like C++ so the object files make the CLEAN_OBJS list +CLEAN_SRCS := $(wildcard *.cpp) $(patsubst %.S,%.cpp,$(wildcard *.S)) +CLEAN_OBJS := $(CLEAN_SRCS:.cpp=.o) $(CLEAN_SRCS:.cpp=.import.o) $(CLEAN_SRCS:.cpp=.export.o) + +# For Shared Objects, Diff, Dist/Zip rules +LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config_ver.h | cut -d" " -f 3) +LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1) +LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2) +LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3) + +ifeq ($(strip $(LIB_PATCH)),) +LIB_PATCH := 0 +endif + +ifeq ($(HAS_SOLIB_VERSION),1) +# Full version suffix for shared library +SOLIB_VERSION_SUFFIX=.$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH) +# Different patchlevels and minors are compatible since 6.1 +SOLIB_COMPAT_SUFFIX=.$(LIB_MAJOR) +SOLIB_FLAGS=-Wl,-soname,libcryptopp.so$(SOLIB_COMPAT_SUFFIX) +endif # HAS_SOLIB_VERSION + +########################################################### +##### Targets and Recipes ##### +########################################################### + +# Default builds program with static library only +.PHONY: default +default: cryptest.exe + +.PHONY: all static dynamic +all: static dynamic cryptest.exe + +ifneq ($(IS_IOS),0) +static: libcryptopp.a +shared dynamic dylib: libcryptopp.dylib +else +static: libcryptopp.a +shared dynamic: libcryptopp.so$(SOLIB_VERSION_SUFFIX) +endif + +.PHONY: test check +test check: cryptest.exe + ./cryptest.exe v + +# CXXFLAGS are tuned earlier. Applications must use linker flags +# -Wl,--gc-sections (Linux and Unix) or -Wl,-dead_strip (OS X) +.PHONY: lean +lean: static dynamic cryptest.exe + +.PHONY: clean +clean: + -$(RM) adhoc.cpp.o adhoc.cpp.proto.o $(CLEAN_OBJS) $(ANDROID_CPU_OBJ) rdrand-*.o + @-$(RM) libcryptopp.a libcryptopp.dylib cryptopp.dll libcryptopp.dll.a libcryptopp.import.a + @-$(RM) libcryptopp.so libcryptopp.so$(SOLIB_COMPAT_SUFFIX) libcryptopp.so$(SOLIB_VERSION_SUFFIX) + @-$(RM) cryptest.exe dlltest.exe cryptest.import.exe cryptest.dat ct et + @-$(RM) *.la *.lo *.gcov *.gcno *.gcda *.stackdump core core-* + @-$(RM) /tmp/adhoc.exe + @-$(RM) -r /tmp/cryptopp_test/ + @-$(RM) -r *.exe.dSYM/ + @-$(RM) -r *.dylib.dSYM/ + @-$(RM) -r cov-int/ + +.PHONY: autotools-clean +autotools-clean: + @-$(RM) -f configure.ac configure configure.in Makefile.am Makefile.in Makefile + @-$(RM) -f config.guess config.status config.sub config.h.in compile depcomp + @-$(RM) -f install-sh stamp-h1 ar-lib *.lo *.la *.m4 local.* lt*.sh missing + @-$(RM) -f cryptest cryptestcwd libtool* libcryptopp.la libcryptopp.pc* + @-$(RM) -rf build-aux/ m4/ auto*.cache/ .deps/ .libs/ + +.PHONY: cmake-clean +cmake-clean: + @-$(RM) -f cryptopp-config.cmake CMakeLists.txt + @-$(RM) -rf cmake_build/ + +.PHONY: android-clean +android-clean: + @-$(RM) -f $(patsubst %_simd.cpp,%_simd.cpp.neon,$(wildcard *_simd.cpp)) + @-$(RM) -rf obj/ + +.PHONY: distclean +distclean: clean autotools-clean cmake-clean android-clean + -$(RM) adhoc.cpp adhoc.cpp.copied GNUmakefile.deps benchmarks.html cryptest.txt + -$(RM) cryptest_all.info cryptest_debug.info cryptest_noasm.info cryptest_base.info cryptest.info cryptest_release.info + @-$(RM) cryptest-*.txt cryptopp.tgz libcryptopp.pc *.o *.bc *.ii *~ + @-$(RM) -r cryptlib.lib cryptest.exe *.suo *.sdf *.pdb Win32/ x64/ ipch/ + @-$(RM) -r $(LIBOBJS:.o=.obj) $(TESTOBJS:.o=.obj) + @-$(RM) -r $(LIBOBJS:.o=.lst) $(TESTOBJS:.o=.lst) + @-$(RM) -r TestCoverage/ ref*/ + @-$(RM) cryptopp$(LIB_VER)\.* CryptoPPRef.zip + +# Install cryptest.exe, libcryptopp.a and libcryptopp.so. +# The library install was broken-out into its own recipe at GH #653. +.PHONY: install +install: cryptest.exe install-lib + @-$(MKDIR) $(DESTDIR)$(BINDIR) + $(CP) cryptest.exe $(DESTDIR)$(BINDIR) + $(CHMOD) u=rwx,go=rx $(DESTDIR)$(BINDIR)/cryptest.exe + @-$(MKDIR) $(DESTDIR)$(DATADIR)/cryptopp/TestData + @-$(MKDIR) $(DESTDIR)$(DATADIR)/cryptopp/TestVectors + $(CP) TestData/*.dat $(DESTDIR)$(DATADIR)/cryptopp/TestData + $(CHMOD) u=rw,go=r $(DESTDIR)$(DATADIR)/cryptopp/TestData/*.dat + $(CP) TestVectors/*.txt $(DESTDIR)$(DATADIR)/cryptopp/TestVectors + $(CHMOD) u=rw,go=r $(DESTDIR)$(DATADIR)/cryptopp/TestVectors/*.txt + +# A recipe to install only the library, and not cryptest.exe. Also +# see https://github.com/weidai11/cryptopp/issues/653. +.PHONY: install-lib +install-lib: + @-$(MKDIR) $(DESTDIR)$(INCLUDEDIR)/cryptopp + $(CP) *.h $(DESTDIR)$(INCLUDEDIR)/cryptopp + $(CHMOD) u=rw,go=r $(DESTDIR)$(INCLUDEDIR)/cryptopp/*.h +ifneq ($(wildcard libcryptopp.a),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR) + $(CP) libcryptopp.a $(DESTDIR)$(LIBDIR) + $(CHMOD) u=rw,go=r $(DESTDIR)$(LIBDIR)/libcryptopp.a +endif +ifneq ($(wildcard libcryptopp.dylib),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR) + $(CP) libcryptopp.dylib $(DESTDIR)$(LIBDIR) + $(CHMOD) u=rwx,go=rx $(DESTDIR)$(LIBDIR)/libcryptopp.dylib + -install_name_tool -id $(DESTDIR)$(LIBDIR)/libcryptopp.dylib $(DESTDIR)$(LIBDIR)/libcryptopp.dylib +endif +ifneq ($(wildcard libcryptopp.so$(SOLIB_VERSION_SUFFIX)),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR) + $(CP) libcryptopp.so$(SOLIB_VERSION_SUFFIX) $(DESTDIR)$(LIBDIR) + $(CHMOD) u=rwx,go=rx $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX) +ifeq ($(HAS_SOLIB_VERSION),1) + -$(LN) libcryptopp.so$(SOLIB_VERSION_SUFFIX) $(DESTDIR)$(LIBDIR)/libcryptopp.so + $(LDCONF) $(DESTDIR)$(LIBDIR) +endif +endif +ifneq ($(wildcard libcryptopp.pc),) + @-$(MKDIR) $(DESTDIR)$(LIBDIR)/pkgconfig + $(CP) libcryptopp.pc $(DESTDIR)$(LIBDIR)/pkgconfig + $(CHMOD) u=rw,go=r $(DESTDIR)$(LIBDIR)/pkgconfig/libcryptopp.pc +endif + +.PHONY: remove uninstall +remove uninstall: + -$(RM) -r $(DESTDIR)$(INCLUDEDIR)/cryptopp + -$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.a + -$(RM) $(DESTDIR)$(BINDIR)/cryptest.exe + @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.dylib + @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX) + @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_COMPAT_SUFFIX) + @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so + +libcryptopp.a: $(LIBOBJS) $(ANDROID_CPU_OBJ) + $(AR) $(ARFLAGS) $@ $(LIBOBJS) $(ANDROID_CPU_OBJ) + $(RANLIB) $@ + +ifeq ($(HAS_SOLIB_VERSION),1) +.PHONY: libcryptopp.so +libcryptopp.so: libcryptopp.so$(SOLIB_VERSION_SUFFIX) +endif + +libcryptopp.so$(SOLIB_VERSION_SUFFIX): $(LIBOBJS) $(ANDROID_CPU_OBJ) + $(CXX) -shared $(SOLIB_FLAGS) -o $@ $(strip $(CPPFLAGS) $(CXXFLAGS)) -Wl,--exclude-libs,ALL $(LIBOBJS) $(ANDROID_CPU_OBJ) $(LDFLAGS) $(LDLIBS) +ifeq ($(HAS_SOLIB_VERSION),1) + -$(LN) libcryptopp.so$(SOLIB_VERSION_SUFFIX) libcryptopp.so + -$(LN) libcryptopp.so$(SOLIB_VERSION_SUFFIX) libcryptopp.so$(SOLIB_COMPAT_SUFFIX) +endif + +libcryptopp.dylib: $(LIBOBJS) + $(CXX) -dynamiclib -o $@ $(strip $(CPPFLAGS) $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS) + +cryptest.exe: $(LINK_LIBRARY) $(TESTOBJS) + $(CXX) -o $@ $(strip $(CPPFLAGS) $(CXXFLAGS)) $(TESTOBJS) $(LINK_LIBRARY_PATH)$(LINK_LIBRARY) $(LDFLAGS) $(LDLIBS) + +# Used to generate list of source files for Autotools, CMakeList and Android.mk +.PHONY: sources +sources: + $(info ***** Library sources *****) + $(info $(filter-out $(TESTSRCS),$(SRCS))) + $(info ) + $(info ***** Library headers *****) + $(info $(filter-out $(TESTINCL),$(INCL))) + $(info ) + $(info ***** Test sources *****) + $(info $(TESTSRCS)) + $(info ) + $(info ***** Test headers *****) + $(info $(TESTINCL)) + +adhoc.cpp: adhoc.cpp.proto +ifeq ($(wildcard adhoc.cpp),) + cp adhoc.cpp.proto adhoc.cpp +else + touch adhoc.cpp +endif + +# Include dependencies, if present. You must issue `make deps` to create them. +ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps) +-include GNUmakefile.deps +endif # Dependencies + +# A few recipes trigger warnings for -std=c++11 and -stdlib=c++ +NOSTD_CXXFLAGS=$(filter-out -stdlib=%,$(filter-out -std=%,$(CXXFLAGS))) + +# Cryptogams ARM asm implementation. AES needs -mthumb for Clang +aes_armv4.o : aes_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_THUMB_FLAG) -c) $< + +# Use C++ compiler on C source after patching. +# https://github.com/weidai11/cryptopp/issues/926 +cpu-features.o: cpu-features.h cpu-features.c + $(CXX) -x c $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) -c) cpu-features.c + +# SSSE3 or NEON available +aria_simd.o : aria_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(ARIA_FLAG) -c) $< + +# SSE, NEON or POWER7 available +blake2s_simd.o : blake2s_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(BLAKE2S_FLAG) -c) $< + +# SSE, NEON or POWER8 available +blake2b_simd.o : blake2b_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(BLAKE2B_FLAG) -c) $< + +# SSE2 or NEON available +chacha_simd.o : chacha_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CHACHA_FLAG) -c) $< + +# AVX2 available +chacha_avx.o : chacha_avx.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CHACHA_AVX2_FLAG) -c) $< + +# SSSE3 available +cham_simd.o : cham_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CHAM_FLAG) -c) $< + +# Power9 available +darn.o : darn.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(DARN_FLAG) -c) $< + +# SSE2 on i686 +donna_sse.o : donna_sse.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SSE2_FLAG) -c) $< + +# SSE2 on i686 +sse_simd.o : sse_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SSE2_FLAG) -c) $< + +# SSE4.2 or ARMv8a available +crc_simd.o : crc_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(CRC_FLAG) -c) $< + +# PCLMUL or ARMv7a/ARMv8a available +gcm_simd.o : gcm_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(GCM_FLAG) -c) $< + +# Carryless multiply +gf2n_simd.o : gf2n_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(GF2N_FLAG) -c) $< + +# SSSE3 available +keccak_simd.o : keccak_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(KECCAK_FLAG) -c) $< + +# SSSE3 available +lea_simd.o : lea_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LEA_FLAG) -c) $< + +# SSSE3 available +lsh256_sse.o : lsh256_sse.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH256_FLAG) -c) $< + +# AVX2 available +lsh256_avx.o : lsh256_avx.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH256_AVX2_FLAG) -c) $< + +# SSSE3 available +lsh512_sse.o : lsh512_sse.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH512_FLAG) -c) $< + +# AVX2 available +lsh512_avx.o : lsh512_avx.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(LSH512_AVX2_FLAG) -c) $< + +# NEON available +neon_simd.o : neon_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(NEON_FLAG) -c) $< + +# AESNI or ARMv7a/ARMv8a available +rijndael_simd.o : rijndael_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(AES_FLAG) -c) $< + +# SSE4.2/SHA-NI or ARMv8a available +sha_simd.o : sha_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SHA_FLAG) -c) $< + +# Cryptogams SHA1 asm implementation. +sha1_armv4.o : sha1_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_FLAG) -c) $< + +# Cryptogams SHA256 asm implementation. +sha256_armv4.o : sha256_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_FLAG) -c) $< + +# Cryptogams SHA512 asm implementation. +sha512_armv4.o : sha512_armv4.S + $(CXX) $(strip $(CPPFLAGS) $(NOSTD_CXXFLAGS) $(CRYPTOGAMS_ARMV4_FLAG) -c) $< + +# SSE4.2/SHA-NI or ARMv8a available +shacal2_simd.o : shacal2_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SHA_FLAG) -c) $< + +# SSSE3, NEON or POWER8 available +simon128_simd.o : simon128_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SIMON128_FLAG) -c) $< + +# SSSE3, NEON or POWER8 available +speck128_simd.o : speck128_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SPECK128_FLAG) -c) $< + +# ARMv8.4 available +sm3_simd.o : sm3_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SM3_FLAG) -c) $< + +# AESNI available +sm4_simd.o : sm4_simd.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) $(SM4_FLAG) -c) $< + +%.o : %.cpp + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS) -c) $< + +.PHONY: dep deps depend +dep deps depend GNUmakefile.deps: + $(CXX) $(strip $(CPPFLAGS) $(CXXFLAGS)) -MM *.cpp > GNUmakefile.deps diff --git a/external/ours/library/crypto/src/shared/original/adhoc.cpp b/external/ours/library/crypto/src/shared/original/adhoc.cpp new file mode 100755 index 000000000..1fc8c3017 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/adhoc.cpp @@ -0,0 +1,42 @@ +#include "config.h" +#include +#include + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4100 4189 4996) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +#ifndef CRYPTOPP_UNUSED +# define CRYPTOPP_UNUSED(x) (void(x)) +#endif + +// Used for testing the compiler and linker in cryptest.sh +#if defined(CRYPTOPP_ADHOC_MAIN) || defined(ADHOC_MAIN) + +int main(int argc, char *argv[]) +{ + CRYPTOPP_UNUSED(argc), CRYPTOPP_UNUSED(argv); + return 0; +} + +// Classic use of adhoc to setup calling convention +#else + +extern int (*AdhocTest)(int argc, char *argv[]); + +int MyAdhocTest(int argc, char *argv[]) +{ + CRYPTOPP_UNUSED(argc), CRYPTOPP_UNUSED(argv); + return 0; +} + +static int s_i = (AdhocTest = &MyAdhocTest, 0); + +#endif diff --git a/external/ours/library/crypto/src/shared/original/adler32.cpp b/external/ours/library/crypto/src/shared/original/adler32.cpp new file mode 100755 index 000000000..2cfb1f447 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/adler32.cpp @@ -0,0 +1,82 @@ +// adler32.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "adler32.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Adler32::Update(const byte *input, size_t length) +{ + const unsigned long BASE = 65521; + + unsigned long s1 = m_s1; + unsigned long s2 = m_s2; + + if (length % 8 != 0) + { + do + { + s1 += *input++; + s2 += s1; + length--; + } while (length % 8 != 0); + + if (s1 >= BASE) + s1 -= BASE; + s2 %= BASE; + } + + while (length > 0) + { + s1 += input[0]; s2 += s1; + s1 += input[1]; s2 += s1; + s1 += input[2]; s2 += s1; + s1 += input[3]; s2 += s1; + s1 += input[4]; s2 += s1; + s1 += input[5]; s2 += s1; + s1 += input[6]; s2 += s1; + s1 += input[7]; s2 += s1; + + length -= 8; + input += 8; + + if (s1 >= BASE) + s1 -= BASE; + if (length % 0x8000 == 0) + s2 %= BASE; + } + + CRYPTOPP_ASSERT(s1 < BASE); + CRYPTOPP_ASSERT(s2 < BASE); + + m_s1 = (word16)s1; + m_s2 = (word16)s2; +} + +void Adler32::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + switch (size) + { + default: + hash[3] = byte(m_s1); + // fall through + case 3: + hash[2] = byte(m_s1 >> 8); + // fall through + case 2: + hash[1] = byte(m_s2); + // fall through + case 1: + hash[0] = byte(m_s2 >> 8); + // fall through + case 0: + ; + // fall through + } + + Reset(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/adler32.h b/external/ours/library/crypto/src/shared/original/adler32.h new file mode 100755 index 000000000..a50d126e0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/adler32.h @@ -0,0 +1,33 @@ +// adler32.h - originally written and placed in the public domain by Wei Dai + +/// \file adler32.h +/// \brief Class file for ADLER-32 checksum calculations + +#ifndef CRYPTOPP_ADLER32_H +#define CRYPTOPP_ADLER32_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// ADLER-32 checksum calculations +class Adler32 : public HashTransformation +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 4); + Adler32() {Reset();} + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Adler32";} + std::string AlgorithmName() const {return StaticAlgorithmName();} + +private: + void Reset() {m_s1 = 1; m_s2 = 0;} + + word16 m_s1, m_s2; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/adv_simd.h b/external/ours/library/crypto/src/shared/original/adv_simd.h new file mode 100755 index 000000000..0b65691d9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/adv_simd.h @@ -0,0 +1,1281 @@ +// adv_simd.h - written and placed in the public domain by Jeffrey Walton + +/// \file adv_simd.h +/// \brief Template for AdvancedProcessBlocks and SIMD processing + +// The SIMD based implementations for ciphers that use SSE, NEON and Power7 +// have a common pattern. Namely, they have a specialized implementation of +// AdvancedProcessBlocks which processes multiple block using hardware +// acceleration. After several implementations we noticed a lot of copy and +// paste occurring. adv_simd.h provides a template to avoid the copy and paste. +// +// There are 6 templates provided in this file. The number following the +// function name, 128, is the block size in bits. The name following the +// block size is the arrangement and acceleration. For example 4x1_SSE means +// Intel SSE using two encrypt (or decrypt) functions: one that operates on +// 4 SIMD words, and one that operates on 1 SIMD words. +// +// * AdvancedProcessBlocks128_4x1_SSE +// * AdvancedProcessBlocks128_6x2_SSE +// * AdvancedProcessBlocks128_4x1_NEON +// * AdvancedProcessBlocks128_6x1_NEON +// * AdvancedProcessBlocks128_4x1_ALTIVEC +// * AdvancedProcessBlocks128_6x1_ALTIVEC +// +// If an arrangement ends in 2, like 6x2, then the template will handle the +// single block case by padding with 0's and using the two SIMD word +// function. This happens at most one time when processing multiple blocks. +// The extra processing of a zero block is trivial and worth the tradeoff. +// +// The MAYBE_CONST macro present on x86 is a SunCC workaround. Some versions +// of SunCC lose/drop the const-ness in the F1 and F4 functions. It eventually +// results in a failed link due to the const/non-const mismatch. +// +// In July 2020 the library stopped using 64-bit block version of +// AdvancedProcessBlocks. Testing showed unreliable results and failed +// self tests on occasion. Also see Issue 945 and +// https://github.com/weidai11/cryptopp/commit/dd7598e638bb. + +#ifndef CRYPTOPP_ADVANCED_SIMD_TEMPLATES +#define CRYPTOPP_ADVANCED_SIMD_TEMPLATES + +#include "config.h" +#include "misc.h" +#include "stdcpp.h" + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) +# include +# include +#endif + +// SunCC needs CRYPTOPP_SSSE3_AVAILABLE, too +#if (CRYPTOPP_SSSE3_AVAILABLE) +# include +# include +# include +#endif + +#if defined(__ALTIVEC__) +# include "ppc_simd.h" +#endif + +// ************************ All block ciphers *********************** // + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::BlockTransformation; + +CRYPTOPP_CONSTANT(BT_XorInput = BlockTransformation::BT_XorInput); +CRYPTOPP_CONSTANT(BT_AllowParallel = BlockTransformation::BT_AllowParallel); +CRYPTOPP_CONSTANT(BT_InBlockIsCounter = BlockTransformation::BT_InBlockIsCounter); +CRYPTOPP_CONSTANT(BT_ReverseDirection = BlockTransformation::BT_ReverseDirection); +CRYPTOPP_CONSTANT(BT_DontIncrementInOutPointers = BlockTransformation::BT_DontIncrementInOutPointers); + +ANONYMOUS_NAMESPACE_END + +// *************************** ARM NEON ************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) || (CRYPTOPP_ARM_ASIMD_AVAILABLE) || \ + defined(CRYPTOPP_DOXYGEN_PROCESSING) +NAMESPACE_BEGIN(CryptoPP) + +/// \brief AdvancedProcessBlocks for 1 and 6 blocks +/// \tparam F1 function to process 1 128-bit block +/// \tparam F6 function to process 6 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_6x1_NEON processes 6 and 2 NEON SIMD words +/// at a time. +/// \details The subkey type is usually word32 or word64. F1 and F6 must use the +/// same word type. +template +inline size_t AdvancedProcessBlocks128_6x1_NEON(F1 func1, F6 func6, + const W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + + const unsigned int w_one[] = {0, 0<<24, 0, 1<<24}; + const uint32x4_t s_one = vld1q_u32(w_one); + + const size_t blockSize = 16; + // const size_t neonBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 6*blockSize) + { + uint64x2_t block0, block1, block2, block3, block4, block5; + if (flags & BT_InBlockIsCounter) + { + const uint64x2_t one = vreinterpretq_u64_u32(s_one); + block0 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + block1 = vaddq_u64(block0, one); + block2 = vaddq_u64(block1, one); + block3 = vaddq_u64(block2, one); + block4 = vaddq_u64(block3, one); + block5 = vaddq_u64(block4, one); + vst1q_u8(const_cast(inBlocks), + vreinterpretq_u8_u64(vaddq_u64(block5, one))); + } + else + { + block0 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block4 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block5 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = veorq_u64(block0, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u64(block1, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = veorq_u64(block2, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = veorq_u64(block3, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = veorq_u64(block4, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = veorq_u64(block5, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func6(block0, block1, block2, block3, block4, block5, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = veorq_u64(block0, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u64(block1, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = veorq_u64(block2, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = veorq_u64(block3, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = veorq_u64(block4, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = veorq_u64(block5, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block0)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block1)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block2)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block3)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block4)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block5)); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 6*blockSize; + } + } + + while (length >= blockSize) + { + uint64x2_t block; + block = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + + if (xorInput) + block = veorq_u64(block, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func1(block, subKeys, static_cast(rounds)); + + if (xorOutput) + block = veorq_u64(block, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block)); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +/// \brief AdvancedProcessBlocks for 1 and 4 blocks +/// \tparam F1 function to process 1 128-bit block +/// \tparam F4 function to process 4 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_4x1_NEON processes 4 and 1 NEON SIMD words +/// at a time. +/// \details The subkey type is usually word32 or word64. V is the vector type and it is +/// usually uint32x4_t or uint32x4_t. F1, F4, and W must use the same word and +/// vector type. +template +inline size_t AdvancedProcessBlocks128_4x1_NEON(F1 func1, F4 func4, + const W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + + const unsigned int w_one[] = {0, 0<<24, 0, 1<<24}; + const uint32x4_t s_one = vld1q_u32(w_one); + + const size_t blockSize = 16; + // const size_t neonBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 4*blockSize) + { + uint32x4_t block0, block1, block2, block3; + if (flags & BT_InBlockIsCounter) + { + const uint32x4_t one = s_one; + block0 = vreinterpretq_u32_u8(vld1q_u8(inBlocks)); + block1 = vreinterpretq_u32_u64(vaddq_u64(vreinterpretq_u64_u32(block0), vreinterpretq_u64_u32(one))); + block2 = vreinterpretq_u32_u64(vaddq_u64(vreinterpretq_u64_u32(block1), vreinterpretq_u64_u32(one))); + block3 = vreinterpretq_u32_u64(vaddq_u64(vreinterpretq_u64_u32(block2), vreinterpretq_u64_u32(one))); + vst1q_u8(const_cast(inBlocks), vreinterpretq_u8_u64(vaddq_u64( + vreinterpretq_u64_u32(block3), vreinterpretq_u64_u32(one)))); + } + else + { + block0 = vreinterpretq_u32_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = vreinterpretq_u32_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = vreinterpretq_u32_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = vreinterpretq_u32_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = veorq_u32(block0, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u32(block1, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = veorq_u32(block2, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = veorq_u32(block3, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func4(block0, block1, block2, block3, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = veorq_u32(block0, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u32(block1, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = veorq_u32(block2, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = veorq_u32(block3, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + vst1q_u8(outBlocks, vreinterpretq_u8_u32(block0)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u32(block1)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u32(block2)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u32(block3)); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 4*blockSize; + } + } + + while (length >= blockSize) + { + uint32x4_t block = vreinterpretq_u32_u8(vld1q_u8(inBlocks)); + + if (xorInput) + block = veorq_u32(block, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func1(block, subKeys, static_cast(rounds)); + + if (xorOutput) + block = veorq_u32(block, vreinterpretq_u32_u8(vld1q_u8(xorBlocks))); + + vst1q_u8(outBlocks, vreinterpretq_u8_u32(block)); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +/// \brief AdvancedProcessBlocks for 2 and 6 blocks +/// \tparam F2 function to process 2 128-bit blocks +/// \tparam F6 function to process 6 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_6x2_NEON processes 6 and 2 NEON SIMD words +/// at a time. For a single block the template uses F2 with a zero block. +/// \details The subkey type is usually word32 or word64. F2 and F6 must use the +/// same word type. +template +inline size_t AdvancedProcessBlocks128_6x2_NEON(F2 func2, F6 func6, + const W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + + const unsigned int w_one[] = {0, 0<<24, 0, 1<<24}; + const uint32x4_t s_one = vld1q_u32(w_one); + + const size_t blockSize = 16; + // const size_t neonBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 6*blockSize) + { + uint64x2_t block0, block1, block2, block3, block4, block5; + if (flags & BT_InBlockIsCounter) + { + const uint64x2_t one = vreinterpretq_u64_u32(s_one); + block0 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + block1 = vaddq_u64(block0, one); + block2 = vaddq_u64(block1, one); + block3 = vaddq_u64(block2, one); + block4 = vaddq_u64(block3, one); + block5 = vaddq_u64(block4, one); + vst1q_u8(const_cast(inBlocks), + vreinterpretq_u8_u64(vaddq_u64(block5, one))); + } + else + { + block0 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block4 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block5 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = veorq_u64(block0, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u64(block1, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = veorq_u64(block2, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = veorq_u64(block3, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = veorq_u64(block4, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = veorq_u64(block5, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func6(block0, block1, block2, block3, block4, block5, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = veorq_u64(block0, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u64(block1, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = veorq_u64(block2, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = veorq_u64(block3, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = veorq_u64(block4, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = veorq_u64(block5, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block0)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block1)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block2)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block3)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block4)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block5)); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 6*blockSize; + } + + while (length >= 2*blockSize) + { + uint64x2_t block0, block1; + if (flags & BT_InBlockIsCounter) + { + const uint64x2_t one = vreinterpretq_u64_u32(s_one); + block0 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + block1 = vaddq_u64(block0, one); + vst1q_u8(const_cast(inBlocks), + vreinterpretq_u8_u64(vaddq_u64(block1, one))); + } + else + { + block0 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = veorq_u64(block0, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u64(block1, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func2(block0, block1, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = veorq_u64(block0, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = veorq_u64(block1, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block0)); + outBlocks = PtrAdd(outBlocks, outIncrement); + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block1)); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 2*blockSize; + } + } + + while (length >= blockSize) + { + uint64x2_t block, zero = {0,0}; + block = vreinterpretq_u64_u8(vld1q_u8(inBlocks)); + + if (xorInput) + block = veorq_u64(block, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func2(block, zero, subKeys, static_cast(rounds)); + + if (xorOutput) + block = veorq_u64(block, vreinterpretq_u64_u8(vld1q_u8(xorBlocks))); + + vst1q_u8(outBlocks, vreinterpretq_u8_u64(block)); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// *************************** Intel SSE ************************** // + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief SunCC workaround +/// \details SunCC loses the const on AES_Enc_Block and AES_Dec_Block +/// \sa Issue +/// 224, SunCC and failed compile for rijndael.cpp +# define MAYBE_CONST const +/// \brief SunCC workaround +/// \details SunCC loses the const on AES_Enc_Block and AES_Dec_Block +/// \sa Issue +/// 224, SunCC and failed compile for rijndael.cpp +# define MAYBE_UNCONST_CAST(T, x) (x) +#elif (__SUNPRO_CC >= 0x5130) +# define MAYBE_CONST +# define MAYBE_UNCONST_CAST(T, x) const_cast(x) +#else +# define MAYBE_CONST const +# define MAYBE_UNCONST_CAST(T, x) (x) +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Clang workaround +/// \details Clang issues spurious alignment warnings +/// \sa Issue +/// 20670, _mm_loadu_si128 parameter has wrong type +# define M128_CAST(x) ((__m128i *)(void *)(x)) +/// \brief Clang workaround +/// \details Clang issues spurious alignment warnings +/// \sa Issue +/// 20670, _mm_loadu_si128 parameter has wrong type +# define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) +#else +# ifndef M128_CAST +# define M128_CAST(x) ((__m128i *)(void *)(x)) +# endif +# ifndef CONST_M128_CAST +# define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) +# endif +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief AdvancedProcessBlocks for 2 and 6 blocks +/// \tparam F2 function to process 2 128-bit blocks +/// \tparam F6 function to process 6 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_6x2_SSE processes 6 and 2 SSE SIMD words +/// at a time. For a single block the template uses F2 with a zero block. +/// \details The subkey type is usually word32 or word64. F2 and F6 must use the +/// same word type. +template +inline size_t AdvancedProcessBlocks128_6x2_SSE(F2 func2, F6 func6, + MAYBE_CONST W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + + const size_t blockSize = 16; + // const size_t xmmBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 6*blockSize) + { + __m128i block0, block1, block2, block3, block4, block5; + if (flags & BT_InBlockIsCounter) + { + // Increment of 1 in big-endian compatible with the ctr byte array. + const __m128i s_one = _mm_set_epi32(1<<24, 0, 0, 0); + block0 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + block1 = _mm_add_epi32(block0, s_one); + block2 = _mm_add_epi32(block1, s_one); + block3 = _mm_add_epi32(block2, s_one); + block4 = _mm_add_epi32(block3, s_one); + block5 = _mm_add_epi32(block4, s_one); + _mm_storeu_si128(M128_CAST(inBlocks), _mm_add_epi32(block5, s_one)); + } + else + { + block0 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block4 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block5 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = _mm_xor_si128(block0, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = _mm_xor_si128(block1, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = _mm_xor_si128(block2, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = _mm_xor_si128(block3, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = _mm_xor_si128(block4, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = _mm_xor_si128(block5, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func6(block0, block1, block2, block3, block4, block5, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = _mm_xor_si128(block0, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = _mm_xor_si128(block1, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = _mm_xor_si128(block2, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = _mm_xor_si128(block3, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = _mm_xor_si128(block4, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = _mm_xor_si128(block5, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + _mm_storeu_si128(M128_CAST(outBlocks), block0); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block1); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block2); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block3); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block4); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block5); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 6*blockSize; + } + + while (length >= 2*blockSize) + { + __m128i block0, block1; + if (flags & BT_InBlockIsCounter) + { + // Increment of 1 in big-endian compatible with the ctr byte array. + const __m128i s_one = _mm_set_epi32(1<<24, 0, 0, 0); + block0 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + block1 = _mm_add_epi32(block0, s_one); + _mm_storeu_si128(M128_CAST(inBlocks), _mm_add_epi32(block1, s_one)); + } + else + { + block0 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = _mm_xor_si128(block0, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = _mm_xor_si128(block1, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func2(block0, block1, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = _mm_xor_si128(block0, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = _mm_xor_si128(block1, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + _mm_storeu_si128(M128_CAST(outBlocks), block0); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block1); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 2*blockSize; + } + } + + while (length >= blockSize) + { + __m128i block, zero = _mm_setzero_si128(); + block = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + + if (xorInput) + block = _mm_xor_si128(block, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func2(block, zero, subKeys, static_cast(rounds)); + + if (xorOutput) + block = _mm_xor_si128(block, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + + _mm_storeu_si128(M128_CAST(outBlocks), block); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +/// \brief AdvancedProcessBlocks for 1 and 4 blocks +/// \tparam F1 function to process 1 128-bit block +/// \tparam F4 function to process 4 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_4x1_SSE processes 4 and 1 SSE SIMD words +/// at a time. +/// \details The subkey type is usually word32 or word64. F1 and F4 must use the +/// same word type. +template +inline size_t AdvancedProcessBlocks128_4x1_SSE(F1 func1, F4 func4, + MAYBE_CONST W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + + const size_t blockSize = 16; + // const size_t xmmBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 4*blockSize) + { + __m128i block0, block1, block2, block3; + if (flags & BT_InBlockIsCounter) + { + // Increment of 1 in big-endian compatible with the ctr byte array. + const __m128i s_one = _mm_set_epi32(1<<24, 0, 0, 0); + block0 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + block1 = _mm_add_epi32(block0, s_one); + block2 = _mm_add_epi32(block1, s_one); + block3 = _mm_add_epi32(block2, s_one); + _mm_storeu_si128(M128_CAST(inBlocks), _mm_add_epi32(block3, s_one)); + } + else + { + block0 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = _mm_xor_si128(block0, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = _mm_xor_si128(block1, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = _mm_xor_si128(block2, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = _mm_xor_si128(block3, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func4(block0, block1, block2, block3, subKeys, static_cast(rounds)); + + if (xorOutput) + { + block0 = _mm_xor_si128(block0, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = _mm_xor_si128(block1, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = _mm_xor_si128(block2, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = _mm_xor_si128(block3, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + _mm_storeu_si128(M128_CAST(outBlocks), block0); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block1); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block2); + outBlocks = PtrAdd(outBlocks, outIncrement); + _mm_storeu_si128(M128_CAST(outBlocks), block3); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 4*blockSize; + } + } + + while (length >= blockSize) + { + __m128i block = _mm_loadu_si128(CONST_M128_CAST(inBlocks)); + + if (xorInput) + block = _mm_xor_si128(block, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func1(block, subKeys, static_cast(rounds)); + + if (xorOutput) + block = _mm_xor_si128(block, _mm_loadu_si128(CONST_M128_CAST(xorBlocks))); + + _mm_storeu_si128(M128_CAST(outBlocks), block); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// ************************** Altivec/Power 4 ************************** // + +#if defined(__ALTIVEC__) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief AdvancedProcessBlocks for 1 and 4 blocks +/// \tparam F1 function to process 1 128-bit block +/// \tparam F4 function to process 4 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_4x1_ALTIVEC processes 4 and 1 Altivec SIMD words +/// at a time. +/// \details The subkey type is usually word32 or word64. F1 and F4 must use the +/// same word type. +template +inline size_t AdvancedProcessBlocks128_4x1_ALTIVEC(F1 func1, F4 func4, + const W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + +#if (CRYPTOPP_LITTLE_ENDIAN) + const uint32x4_p s_one = {1,0,0,0}; +#else + const uint32x4_p s_one = {0,0,0,1}; +#endif + + const size_t blockSize = 16; + // const size_t simdBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 4*blockSize) + { + uint32x4_p block0, block1, block2, block3; + + if (flags & BT_InBlockIsCounter) + { + block0 = VecLoadBE(inBlocks); + block1 = VecAdd(block0, s_one); + block2 = VecAdd(block1, s_one); + block3 = VecAdd(block2, s_one); + + // Hack due to big-endian loads used by POWER8 (and maybe ARM-BE). + // CTR_ModePolicy::OperateKeystream is wired such that after + // returning from this function CTR_ModePolicy will detect wrap on + // on the last counter byte and increment the next to last byte. + // The problem is, with a big-endian load, inBlocks[15] is really + // located at index 15. The vector addition using a 32-bit element + // generates a carry into inBlocks[14] and then CTR_ModePolicy + // increments inBlocks[14] too. + const_cast(inBlocks)[15] += 6; + } + else + { + block0 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = VecXor(block0, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = VecXor(block1, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = VecXor(block2, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = VecXor(block3, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func4(block0, block1, block2, block3, subKeys, rounds); + + if (xorOutput) + { + block0 = VecXor(block0, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = VecXor(block1, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = VecXor(block2, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = VecXor(block3, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + VecStoreBE(block0, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block1, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block2, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block3, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 4*blockSize; + } + } + + while (length >= blockSize) + { + uint32x4_p block = VecLoadBE(inBlocks); + + if (xorInput) + block = VecXor(block, VecLoadBE(xorBlocks)); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func1(block, subKeys, rounds); + + if (xorOutput) + block = VecXor(block, VecLoadBE(xorBlocks)); + + VecStoreBE(block, outBlocks); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +/// \brief AdvancedProcessBlocks for 1 and 6 blocks +/// \tparam F1 function to process 1 128-bit block +/// \tparam F6 function to process 6 128-bit blocks +/// \tparam W word type of the subkey table +/// \details AdvancedProcessBlocks128_6x1_ALTIVEC processes 6 and 1 Altivec SIMD words +/// at a time. +/// \details The subkey type is usually word32 or word64. F1 and F6 must use the +/// same word type. +template +inline size_t AdvancedProcessBlocks128_6x1_ALTIVEC(F1 func1, F6 func6, + const W *subKeys, size_t rounds, const byte *inBlocks, + const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length >= 16); + +#if (CRYPTOPP_LITTLE_ENDIAN) + const uint32x4_p s_one = {1,0,0,0}; +#else + const uint32x4_p s_one = {0,0,0,1}; +#endif + + const size_t blockSize = 16; + // const size_t simdBlockSize = 16; + + size_t inIncrement = (flags & (EnumToInt(BT_InBlockIsCounter)|EnumToInt(BT_DontIncrementInOutPointers))) ? 0 : blockSize; + size_t xorIncrement = (xorBlocks != NULLPTR) ? blockSize : 0; + size_t outIncrement = (flags & EnumToInt(BT_DontIncrementInOutPointers)) ? 0 : blockSize; + + // Clang and Coverity are generating findings using xorBlocks as a flag. + const bool xorInput = (xorBlocks != NULLPTR) && (flags & EnumToInt(BT_XorInput)); + const bool xorOutput = (xorBlocks != NULLPTR) && !(flags & EnumToInt(BT_XorInput)); + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + if (flags & BT_AllowParallel) + { + while (length >= 6*blockSize) + { + uint32x4_p block0, block1, block2, block3, block4, block5; + + if (flags & BT_InBlockIsCounter) + { + block0 = VecLoadBE(inBlocks); + block1 = VecAdd(block0, s_one); + block2 = VecAdd(block1, s_one); + block3 = VecAdd(block2, s_one); + block4 = VecAdd(block3, s_one); + block5 = VecAdd(block4, s_one); + + // Hack due to big-endian loads used by POWER8 (and maybe ARM-BE). + // CTR_ModePolicy::OperateKeystream is wired such that after + // returning from this function CTR_ModePolicy will detect wrap on + // on the last counter byte and increment the next to last byte. + // The problem is, with a big-endian load, inBlocks[15] is really + // located at index 15. The vector addition using a 32-bit element + // generates a carry into inBlocks[14] and then CTR_ModePolicy + // increments inBlocks[14] too. + // + // To find this bug we needed a test case with a ctr of 0xNN...FA. + // The last octet is 0xFA and adding 6 creates the wrap to trigger + // the issue. If the last octet was 0xFC then 4 would trigger it. + // We dumb-lucked into the test with SPECK-128. The test case of + // interest is the one with IV 348ECA9766C09F04 826520DE47A212FA. + uint8x16_p temp = VecAdd((uint8x16_p)block5, (uint8x16_p)s_one); + VecStoreBE(temp, const_cast(inBlocks)); + } + else + { + block0 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block1 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block2 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block3 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block4 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + block5 = VecLoadBE(inBlocks); + inBlocks = PtrAdd(inBlocks, inIncrement); + } + + if (xorInput) + { + block0 = VecXor(block0, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = VecXor(block1, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = VecXor(block2, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = VecXor(block3, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = VecXor(block4, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = VecXor(block5, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + func6(block0, block1, block2, block3, block4, block5, subKeys, rounds); + + if (xorOutput) + { + block0 = VecXor(block0, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block1 = VecXor(block1, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block2 = VecXor(block2, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block3 = VecXor(block3, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block4 = VecXor(block4, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + block5 = VecXor(block5, VecLoadBE(xorBlocks)); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + } + + VecStoreBE(block0, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block1, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block2, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block3, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block4, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + VecStoreBE(block5, outBlocks); + outBlocks = PtrAdd(outBlocks, outIncrement); + + length -= 6*blockSize; + } + } + + while (length >= blockSize) + { + uint32x4_p block = VecLoadBE(inBlocks); + + if (xorInput) + block = VecXor(block, VecLoadBE(xorBlocks)); + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[15]++; + + func1(block, subKeys, rounds); + + if (xorOutput) + block = VecXor(block, VecLoadBE(xorBlocks)); + + VecStoreBE(block, outBlocks); + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +NAMESPACE_END // CryptoPP + +#endif // __ALTIVEC__ + +#endif // CRYPTOPP_ADVANCED_SIMD_TEMPLATES diff --git a/external/ours/library/crypto/src/shared/original/aes.h b/external/ours/library/crypto/src/shared/original/aes.h new file mode 100755 index 000000000..72ff2ccca --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/aes.h @@ -0,0 +1,30 @@ +// aes.h - originally written and placed in the public domain by Wei Dai + +/// \file +/// \brief Class file for the AES cipher (Rijndael) +/// \details AES is a typdef for Rijndael classes. All key sizes are supported. +/// The library only provides Rijndael with 128-bit blocks, and not 192-bit or 256-bit blocks +/// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, +/// Power8 AES since Crypto++ 6.0 + +#ifndef CRYPTOPP_AES_H +#define CRYPTOPP_AES_H + +#include "rijndael.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief AES block cipher (Rijndael) +/// \details AES is a typdef for Rijndael classes. All key sizes are supported. +/// The library only provides Rijndael with 128-bit blocks, and not 192-bit or 256-bit blocks +/// \sa AES winner, announced on 10/2/2000 +/// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, +/// Power8 AES since Crypto++ 6.0 +DOCUMENTED_TYPEDEF(Rijndael, AES); + +typedef RijndaelEncryption AESEncryption; +typedef RijndaelDecryption AESDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/aes_armv4.h b/external/ours/library/crypto/src/shared/original/aes_armv4.h new file mode 100755 index 000000000..2c2eec72c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/aes_armv4.h @@ -0,0 +1,30 @@ +/* Header file for use with Cryptogam's ARMv4 AES. */ +/* Also see http://www.openssl.org/~appro/cryptogams/ and */ +/* https://wiki.openssl.org/index.php?title=Cryptogams_AES */ + +#ifndef CRYPTOGAMS_AES_ARMV4_H +#define CRYPTOGAMS_AES_ARMV4_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define AES_MAXNR 14 +//typedef struct AES_KEY_st { +// unsigned int rd_key[4 * (AES_MAXNR + 1)]; +// int rounds; +//} AES_KEY; + +// Instead of AES_KEY we use a 'word32 rkey[4*15+4]'. It has space for +// both the AES_MAXNR round keys and the number of rounds in the tail. + +int cryptogams_AES_set_encrypt_key(const unsigned char *userKey, const int bits, unsigned int *rkey); +int cryptogams_AES_set_decrypt_key(const unsigned char *userKey, const int bits, unsigned int *rkey); +void cryptogams_AES_encrypt_block(const unsigned char *in, unsigned char *out, const unsigned int *rkey); +void cryptogams_AES_decrypt_block(const unsigned char *in, unsigned char *out, const unsigned int *rkey); + +#ifdef __cplusplus +} +#endif + +#endif /* CRYPTOGAMS_AES_ARMV4_H */ diff --git a/external/ours/library/crypto/src/shared/original/algebra.cpp b/external/ours/library/crypto/src/shared/original/algebra.cpp new file mode 100755 index 000000000..c3b3fdc1e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/algebra.cpp @@ -0,0 +1,341 @@ +// algebra.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_ALGEBRA_CPP // SunCC workaround: compiler could cause this file to be included twice +#define CRYPTOPP_ALGEBRA_CPP + +#include "algebra.h" +#include "integer.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +template const T& AbstractGroup::Double(const Element &a) const +{ + return this->Add(a, a); +} + +template const T& AbstractGroup::Subtract(const Element &a, const Element &b) const +{ + // make copy of a in case Inverse() overwrites it + Element a1(a); + return this->Add(a1, Inverse(b)); +} + +template T& AbstractGroup::Accumulate(Element &a, const Element &b) const +{ + return a = this->Add(a, b); +} + +template T& AbstractGroup::Reduce(Element &a, const Element &b) const +{ + return a = this->Subtract(a, b); +} + +template const T& AbstractRing::Square(const Element &a) const +{ + return this->Multiply(a, a); +} + +template const T& AbstractRing::Divide(const Element &a, const Element &b) const +{ + // make copy of a in case MultiplicativeInverse() overwrites it + Element a1(a); + return this->Multiply(a1, this->MultiplicativeInverse(b)); +} + +template const T& AbstractEuclideanDomain::Mod(const Element &a, const Element &b) const +{ + Element q; + this->DivisionAlgorithm(result, q, a, b); + return result; +} + +template const T& AbstractEuclideanDomain::Gcd(const Element &a, const Element &b) const +{ + Element g[3]={b, a}; + unsigned int i0=0, i1=1, i2=2; + + while (!this->Equal(g[i1], this->Identity())) + { + g[i2] = this->Mod(g[i0], g[i1]); + unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; + } + + return result = g[i0]; +} + +template const typename QuotientRing::Element& QuotientRing::MultiplicativeInverse(const Element &a) const +{ + Element g[3]={m_modulus, a}; + Element v[3]={m_domain.Identity(), m_domain.MultiplicativeIdentity()}; + Element y; + unsigned int i0=0, i1=1, i2=2; + + while (!this->Equal(g[i1], this->Identity())) + { + // y = g[i0] / g[i1]; + // g[i2] = g[i0] % g[i1]; + m_domain.DivisionAlgorithm(g[i2], y, g[i0], g[i1]); + // v[i2] = v[i0] - (v[i1] * y); + v[i2] = m_domain.Subtract(v[i0], m_domain.Multiply(v[i1], y)); + unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; + } + + return m_domain.IsUnit(g[i0]) ? m_domain.Divide(v[i0], g[i0]) : m_domain.Identity(); +} + +template T AbstractGroup::ScalarMultiply(const Element &base, const Integer &exponent) const +{ + Element result; + this->SimultaneousMultiply(&result, base, &exponent, 1); + return result; +} + +template T AbstractGroup::CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const +{ + const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount()); + if (expLen==0) + return this->Identity(); + + const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3)); + const unsigned tableSize = 1< powerTable(tableSize << w); + + powerTable[1] = x; + powerTable[tableSize] = y; + if (w==1) + powerTable[3] = this->Add(x,y); + else + { + powerTable[2] = this->Double(x); + powerTable[2*tableSize] = this->Double(y); + + unsigned i, j; + + for (i=3; i=0; i--) + { + power1 = 2*power1 + e1.GetBit(i); + power2 = 2*power2 + e2.GetBit(i); + + if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize) + { + unsigned squaresBefore = prevPosition-i; + unsigned squaresAfter = 0; + prevPosition = i; + while ((power1 || power2) && power1%2 == 0 && power2%2==0) + { + power1 /= 2; + power2 /= 2; + squaresBefore--; + squaresAfter++; + } + if (firstTime) + { + result = powerTable[(power2<Double(result); + if (power1 || power2) + Accumulate(result, powerTable[(power2<Double(result); + power1 = power2 = 0; + } + } + return result; +} + +template Element GeneralCascadeMultiplication(const AbstractGroup &group, Iterator begin, Iterator end) +{ + if (end-begin == 1) + return group.ScalarMultiply(begin->base, begin->exponent); + else if (end-begin == 2) + return group.CascadeScalarMultiply(begin->base, begin->exponent, (begin+1)->base, (begin+1)->exponent); + else + { + Integer q, t; + Iterator last = end; + --last; + + std::make_heap(begin, end); + std::pop_heap(begin, end); + + while (!!begin->exponent) + { + // last->exponent is largest exponent, begin->exponent is next largest + t = last->exponent; + Integer::Divide(last->exponent, q, t, begin->exponent); + + if (q == Integer::One()) + group.Accumulate(begin->base, last->base); // avoid overhead of ScalarMultiply() + else + group.Accumulate(begin->base, group.ScalarMultiply(last->base, q)); + + std::push_heap(begin, end); + std::pop_heap(begin, end); + } + + return group.ScalarMultiply(last->base, last->exponent); + } +} + +struct WindowSlider +{ + WindowSlider(const Integer &expIn, bool fastNegate, unsigned int windowSizeIn=0) + : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), expWindow(0) + , fastNegate(fastNegate), negateNext(false), firstTime(true), finished(false) + { + if (windowSize == 0) + { + unsigned int expLen = exp.BitCount(); + windowSize = expLen <= 17 ? 1 : (expLen <= 24 ? 2 : (expLen <= 70 ? 3 : (expLen <= 197 ? 4 : (expLen <= 539 ? 5 : (expLen <= 1434 ? 6 : 7))))); + } + windowModulus <<= windowSize; + } + + void FindNextWindow() + { + unsigned int expLen = exp.WordCount() * WORD_BITS; + unsigned int skipCount = firstTime ? 0 : windowSize; + firstTime = false; + while (!exp.GetBit(skipCount)) + { + if (skipCount >= expLen) + { + finished = true; + return; + } + skipCount++; + } + + exp >>= skipCount; + windowBegin += skipCount; + expWindow = word32(exp % (word(1) << windowSize)); + + if (fastNegate && exp.GetBit(windowSize)) + { + negateNext = true; + expWindow = (word32(1) << windowSize) - expWindow; + exp += windowModulus; + } + else + negateNext = false; + } + + Integer exp, windowModulus; + unsigned int windowSize, windowBegin; + word32 expWindow; + bool fastNegate, negateNext, firstTime, finished; +}; + +template +void AbstractGroup::SimultaneousMultiply(T *results, const T &base, const Integer *expBegin, unsigned int expCount) const +{ + std::vector > buckets(expCount); + std::vector exponents; + exponents.reserve(expCount); + unsigned int i; + + for (i=0; expBegin && iNotNegative()); + exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 0)); + exponents[i].FindNextWindow(); + buckets[i].resize(((size_t) 1) << (exponents[i].windowSize-1), Identity()); + } + + unsigned int expBitPosition = 0; + Element g = base; + bool notDone = true; + + while (notDone) + { + notDone = false; + for (i=0; i 1) + { + for (int j = (int)buckets[i].size()-2; j >= 1; j--) + { + Accumulate(buckets[i][j], buckets[i][j+1]); + Accumulate(r, buckets[i][j]); + } + Accumulate(buckets[i][0], buckets[i][1]); + r = Add(Double(r), buckets[i][0]); + } + } +} + +template T AbstractRing::Exponentiate(const Element &base, const Integer &exponent) const +{ + Element result; + SimultaneousExponentiate(&result, base, &exponent, 1); + return result; +} + +template T AbstractRing::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const +{ + return MultiplicativeGroup().AbstractGroup::CascadeScalarMultiply(x, e1, y, e2); +} + +template Element GeneralCascadeExponentiation(const AbstractRing &ring, Iterator begin, Iterator end) +{ + return GeneralCascadeMultiplication(ring.MultiplicativeGroup(), begin, end); +} + +template +void AbstractRing::SimultaneousExponentiate(T *results, const T &base, const Integer *exponents, unsigned int expCount) const +{ + MultiplicativeGroup().AbstractGroup::SimultaneousMultiply(results, base, exponents, expCount); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/algebra.h b/external/ours/library/crypto/src/shared/original/algebra.h new file mode 100755 index 000000000..9326ec6fc --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/algebra.h @@ -0,0 +1,453 @@ +// algebra.h - originally written and placed in the public domain by Wei Dai + +/// \file algebra.h +/// \brief Classes for performing mathematics over different fields + +#ifndef CRYPTOPP_ALGEBRA_H +#define CRYPTOPP_ALGEBRA_H + +#include "config.h" +#include "integer.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +class Integer; + +/// \brief Abstract group +/// \tparam T element class or type +/// \details const Element& returned by member functions are references +/// to internal data members. Since each object may have only +/// one such data member for holding results, the following code +/// will produce incorrect results: +///

    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// But this should be fine: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+template class CRYPTOPP_NO_VTABLE AbstractGroup +{ +public: + typedef T Element; + + virtual ~AbstractGroup() {} + + /// \brief Compare two elements for equality + /// \param a first element + /// \param b second element + /// \return true if the elements are equal, false otherwise + /// \details Equal() tests the elements for equality using a==b + virtual bool Equal(const Element &a, const Element &b) const =0; + + /// \brief Provides the Identity element + /// \return the Identity element + virtual const Element& Identity() const =0; + + /// \brief Adds elements in the group + /// \param a first element + /// \param b second element + /// \return the sum of a and b + virtual const Element& Add(const Element &a, const Element &b) const =0; + + /// \brief Inverts the element in the group + /// \param a first element + /// \return the inverse of the element + virtual const Element& Inverse(const Element &a) const =0; + + /// \brief Determine if inversion is fast + /// \return true if inversion is fast, false otherwise + virtual bool InversionIsFast() const {return false;} + + /// \brief Doubles an element in the group + /// \param a the element + /// \return the element doubled + virtual const Element& Double(const Element &a) const; + + /// \brief Subtracts elements in the group + /// \param a first element + /// \param b second element + /// \return the difference of a and b. The element a must provide a Subtract member function. + virtual const Element& Subtract(const Element &a, const Element &b) const; + + /// \brief TODO + /// \param a first element + /// \param b second element + /// \return TODO + virtual Element& Accumulate(Element &a, const Element &b) const; + + /// \brief Reduces an element in the congruence class + /// \param a element to reduce + /// \param b the congruence class + /// \return the reduced element + virtual Element& Reduce(Element &a, const Element &b) const; + + /// \brief Performs a scalar multiplication + /// \param a multiplicand + /// \param e multiplier + /// \return the product + virtual Element ScalarMultiply(const Element &a, const Integer &e) const; + + /// \brief TODO + /// \param x first multiplicand + /// \param e1 the first multiplier + /// \param y second multiplicand + /// \param e2 the second multiplier + /// \return TODO + virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const; + + /// \brief Multiplies a base to multiple exponents in a group + /// \param results an array of Elements + /// \param base the base to raise to the exponents + /// \param exponents an array of exponents + /// \param exponentsCount the number of exponents in the array + /// \details SimultaneousMultiply() multiplies the base to each exponent in the exponents array and stores the + /// result at the respective position in the results array. + /// \details SimultaneousMultiply() must be implemented in a derived class. + /// \pre COUNTOF(results) == exponentsCount + /// \pre COUNTOF(exponents) == exponentsCount + virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; +}; + +/// \brief Abstract ring +/// \tparam T element class or type +/// \details const Element& returned by member functions are references +/// to internal data members. Since each object may have only +/// one such data member for holding results, the following code +/// will produce incorrect results: +///
    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// But this should be fine: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+template class CRYPTOPP_NO_VTABLE AbstractRing : public AbstractGroup +{ +public: + typedef T Element; + + /// \brief Construct an AbstractRing + AbstractRing() {m_mg.m_pRing = this;} + + /// \brief Copy construct an AbstractRing + /// \param source other AbstractRing + AbstractRing(const AbstractRing &source) + {CRYPTOPP_UNUSED(source); m_mg.m_pRing = this;} + + /// \brief Assign an AbstractRing + /// \param source other AbstractRing + AbstractRing& operator=(const AbstractRing &source) + {CRYPTOPP_UNUSED(source); return *this;} + + /// \brief Determines whether an element is a unit in the group + /// \param a the element + /// \return true if the element is a unit after reduction, false otherwise. + virtual bool IsUnit(const Element &a) const =0; + + /// \brief Retrieves the multiplicative identity + /// \return the multiplicative identity + virtual const Element& MultiplicativeIdentity() const =0; + + /// \brief Multiplies elements in the group + /// \param a the multiplicand + /// \param b the multiplier + /// \return the product of a and b + virtual const Element& Multiply(const Element &a, const Element &b) const =0; + + /// \brief Calculate the multiplicative inverse of an element in the group + /// \param a the element + virtual const Element& MultiplicativeInverse(const Element &a) const =0; + + /// \brief Square an element in the group + /// \param a the element + /// \return the element squared + virtual const Element& Square(const Element &a) const; + + /// \brief Divides elements in the group + /// \param a the dividend + /// \param b the divisor + /// \return the quotient + virtual const Element& Divide(const Element &a, const Element &b) const; + + /// \brief Raises a base to an exponent in the group + /// \param a the base + /// \param e the exponent + /// \return the exponentiation + virtual Element Exponentiate(const Element &a, const Integer &e) const; + + /// \brief TODO + /// \param x first element + /// \param e1 first exponent + /// \param y second element + /// \param e2 second exponent + /// \return TODO + virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const; + + /// \brief Exponentiates a base to multiple exponents in the Ring + /// \param results an array of Elements + /// \param base the base to raise to the exponents + /// \param exponents an array of exponents + /// \param exponentsCount the number of exponents in the array + /// \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the + /// result at the respective position in the results array. + /// \details SimultaneousExponentiate() must be implemented in a derived class. + /// \pre COUNTOF(results) == exponentsCount + /// \pre COUNTOF(exponents) == exponentsCount + virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + + /// \brief Retrieves the multiplicative group + /// \return the multiplicative group + virtual const AbstractGroup& MultiplicativeGroup() const + {return m_mg;} + +private: + class MultiplicativeGroupT : public AbstractGroup + { + public: + const AbstractRing& GetRing() const + {return *m_pRing;} + + bool Equal(const Element &a, const Element &b) const + {return GetRing().Equal(a, b);} + + const Element& Identity() const + {return GetRing().MultiplicativeIdentity();} + + const Element& Add(const Element &a, const Element &b) const + {return GetRing().Multiply(a, b);} + + Element& Accumulate(Element &a, const Element &b) const + {return a = GetRing().Multiply(a, b);} + + const Element& Inverse(const Element &a) const + {return GetRing().MultiplicativeInverse(a);} + + const Element& Subtract(const Element &a, const Element &b) const + {return GetRing().Divide(a, b);} + + Element& Reduce(Element &a, const Element &b) const + {return a = GetRing().Divide(a, b);} + + const Element& Double(const Element &a) const + {return GetRing().Square(a);} + + Element ScalarMultiply(const Element &a, const Integer &e) const + {return GetRing().Exponentiate(a, e);} + + Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const + {return GetRing().CascadeExponentiate(x, e1, y, e2);} + + void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const + {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);} + + const AbstractRing *m_pRing; + }; + + MultiplicativeGroupT m_mg; +}; + +// ******************************************************** + +/// \brief Base and exponent +/// \tparam T base class or type +/// \tparam E exponent class or type +template +struct BaseAndExponent +{ +public: + BaseAndExponent() {} + BaseAndExponent(const T &base, const E &exponent) : base(base), exponent(exponent) {} + bool operator<(const BaseAndExponent &rhs) const {return exponent < rhs.exponent;} + T base; + E exponent; +}; + +// VC60 workaround: incomplete member template support +template + Element GeneralCascadeMultiplication(const AbstractGroup &group, Iterator begin, Iterator end); +template + Element GeneralCascadeExponentiation(const AbstractRing &ring, Iterator begin, Iterator end); + +// ******************************************************** + +/// \brief Abstract Euclidean domain +/// \tparam T element class or type +/// \details const Element& returned by member functions are references +/// to internal data members. Since each object may have only +/// one such data member for holding results, the following code +/// will produce incorrect results: +///
    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// But this should be fine: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+template class CRYPTOPP_NO_VTABLE AbstractEuclideanDomain : public AbstractRing +{ +public: + typedef T Element; + + /// \brief Performs the division algorithm on two elements in the ring + /// \param r the remainder + /// \param q the quotient + /// \param a the dividend + /// \param d the divisor + virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0; + + /// \brief Performs a modular reduction in the ring + /// \param a the element + /// \param b the modulus + /// \return the result of a%b. + virtual const Element& Mod(const Element &a, const Element &b) const =0; + + /// \brief Calculates the greatest common denominator in the ring + /// \param a the first element + /// \param b the second element + /// \return the greatest common denominator of a and b. + virtual const Element& Gcd(const Element &a, const Element &b) const; + +protected: + mutable Element result; +}; + +// ******************************************************** + +/// \brief Euclidean domain +/// \tparam T element class or type +/// \details const Element& returned by member functions are references +/// to internal data members. Since each object may have only +/// one such data member for holding results, the following code +/// will produce incorrect results: +///
    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// But this should be fine: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+template class EuclideanDomainOf : public AbstractEuclideanDomain +{ +public: + typedef T Element; + + EuclideanDomainOf() {} + + bool Equal(const Element &a, const Element &b) const + {return a==b;} + + const Element& Identity() const + {return Element::Zero();} + + const Element& Add(const Element &a, const Element &b) const + {return result = a+b;} + + Element& Accumulate(Element &a, const Element &b) const + {return a+=b;} + + const Element& Inverse(const Element &a) const + {return result = -a;} + + const Element& Subtract(const Element &a, const Element &b) const + {return result = a-b;} + + Element& Reduce(Element &a, const Element &b) const + {return a-=b;} + + const Element& Double(const Element &a) const + {return result = a.Doubled();} + + const Element& MultiplicativeIdentity() const + {return Element::One();} + + const Element& Multiply(const Element &a, const Element &b) const + {return result = a*b;} + + const Element& Square(const Element &a) const + {return result = a.Squared();} + + bool IsUnit(const Element &a) const + {return a.IsUnit();} + + const Element& MultiplicativeInverse(const Element &a) const + {return result = a.MultiplicativeInverse();} + + const Element& Divide(const Element &a, const Element &b) const + {return result = a/b;} + + const Element& Mod(const Element &a, const Element &b) const + {return result = a%b;} + + void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const + {Element::Divide(r, q, a, d);} + + bool operator==(const EuclideanDomainOf &rhs) const + {CRYPTOPP_UNUSED(rhs); return true;} + +private: + mutable Element result; +}; + +/// \brief Quotient ring +/// \tparam T element class or type +/// \details const Element& returned by member functions are references +/// to internal data members. Since each object may have only +/// one such data member for holding results, the following code +/// will produce incorrect results: +///
    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// But this should be fine: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+template class QuotientRing : public AbstractRing +{ +public: + typedef T EuclideanDomain; + typedef typename T::Element Element; + + QuotientRing(const EuclideanDomain &domain, const Element &modulus) + : m_domain(domain), m_modulus(modulus) {} + + const EuclideanDomain & GetDomain() const + {return m_domain;} + + const Element& GetModulus() const + {return m_modulus;} + + bool Equal(const Element &a, const Element &b) const + {return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Identity());} + + const Element& Identity() const + {return m_domain.Identity();} + + const Element& Add(const Element &a, const Element &b) const + {return m_domain.Add(a, b);} + + Element& Accumulate(Element &a, const Element &b) const + {return m_domain.Accumulate(a, b);} + + const Element& Inverse(const Element &a) const + {return m_domain.Inverse(a);} + + const Element& Subtract(const Element &a, const Element &b) const + {return m_domain.Subtract(a, b);} + + Element& Reduce(Element &a, const Element &b) const + {return m_domain.Reduce(a, b);} + + const Element& Double(const Element &a) const + {return m_domain.Double(a);} + + bool IsUnit(const Element &a) const + {return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));} + + const Element& MultiplicativeIdentity() const + {return m_domain.MultiplicativeIdentity();} + + const Element& Multiply(const Element &a, const Element &b) const + {return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);} + + const Element& Square(const Element &a) const + {return m_domain.Mod(m_domain.Square(a), m_modulus);} + + const Element& MultiplicativeInverse(const Element &a) const; + + bool operator==(const QuotientRing &rhs) const + {return m_domain == rhs.m_domain && m_modulus == rhs.m_modulus;} + +protected: + EuclideanDomain m_domain; + Element m_modulus; +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "algebra.cpp" +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/algparam.cpp b/external/ours/library/crypto/src/shared/original/algparam.cpp new file mode 100755 index 000000000..ff394f212 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/algparam.cpp @@ -0,0 +1,75 @@ +// algparam.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "algparam.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +bool CombinedNameValuePairs::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (strcmp(name, "ValueNames") == 0) + return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue); + else + return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue); +} + +void AlgorithmParametersBase::operator=(const AlgorithmParametersBase &rhs) +{ + CRYPTOPP_UNUSED(rhs); + CRYPTOPP_ASSERT(false); +} + +bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (strcmp(name, "ValueNames") == 0) + { + NameValuePairs::ThrowIfTypeMismatch(name, typeid(std::string), valueType); + if (m_next.get()) + m_next->GetVoidValue(name, valueType, pValue); + (*reinterpret_cast(pValue) += m_name) += ";"; + return true; + } + else if (strcmp(name, m_name) == 0) + { + AssignValue(name, valueType, pValue); + m_used = true; + return true; + } + else if (m_next.get()) + return m_next->GetVoidValue(name, valueType, pValue); + else + return false; +} + +AlgorithmParameters::AlgorithmParameters() + : m_defaultThrowIfNotUsed(true) +{ +} + +AlgorithmParameters::AlgorithmParameters(const AlgorithmParameters &x) + : m_defaultThrowIfNotUsed(x.m_defaultThrowIfNotUsed) +{ + m_next.reset(const_cast(x).m_next.release()); +} + +AlgorithmParameters & AlgorithmParameters::operator=(const AlgorithmParameters &x) +{ + m_next.reset(const_cast(x).m_next.release()); + return *this; +} + +bool AlgorithmParameters::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (m_next.get()) + return m_next->GetVoidValue(name, valueType, pValue); + else + return false; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/algparam.h b/external/ours/library/crypto/src/shared/original/algparam.h new file mode 100755 index 000000000..f904c4f93 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/algparam.h @@ -0,0 +1,520 @@ +// algparam.h - originally written and placed in the public domain by Wei Dai + +/// \file algparam.h +/// \brief Classes for working with NameValuePairs + +#ifndef CRYPTOPP_ALGPARAM_H +#define CRYPTOPP_ALGPARAM_H + +#include "config.h" +#include "cryptlib.h" + +#include "smartptr.h" +#include "secblock.h" +#include "integer.h" +#include "misc.h" + +#include +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Used to pass byte array input as part of a NameValuePairs object +class ConstByteArrayParameter +{ +public: + /// \brief Construct a ConstByteArrayParameter + /// \param data a C-String + /// \param deepCopy flag indicating whether the data should be copied + /// \details The deepCopy option is used when the NameValuePairs object can't + /// keep a copy of the data available + ConstByteArrayParameter(const char *data = NULLPTR, bool deepCopy = false) + : m_deepCopy(false), m_data(NULLPTR), m_size(0) + { + Assign(reinterpret_cast(data), data ? strlen(data) : 0, deepCopy); + } + + /// \brief Construct a ConstByteArrayParameter + /// \param data a memory buffer + /// \param size the length of the memory buffer + /// \param deepCopy flag indicating whether the data should be copied + /// \details The deepCopy option is used when the NameValuePairs object can't + /// keep a copy of the data available + ConstByteArrayParameter(const byte *data, size_t size, bool deepCopy = false) + : m_deepCopy(false), m_data(NULLPTR), m_size(0) + { + Assign(data, size, deepCopy); + } + + /// \brief Construct a ConstByteArrayParameter + /// \tparam T a std::basic_string or std::vector class + /// \param string a std::basic_string or std::vector object + /// \param deepCopy flag indicating whether the data should be copied + /// \details The deepCopy option is used when the NameValuePairs object can't + /// keep a copy of the data available + template ConstByteArrayParameter(const T &string, bool deepCopy = false) + : m_deepCopy(false), m_data(NULLPTR), m_size(0) + { + CRYPTOPP_COMPILE_ASSERT(sizeof(typename T::value_type) == 1); + Assign(reinterpret_cast(&string[0]), string.size(), deepCopy); + } + + /// \brief Assign contents from a memory buffer + /// \param data a memory buffer + /// \param size the length of the memory buffer + /// \param deepCopy flag indicating whether the data should be copied + /// \details The deepCopy option is used when the NameValuePairs object can't + /// keep a copy of the data available + void Assign(const byte *data, size_t size, bool deepCopy) + { + // This fires, which means: no data with a size, or data with no size. + // CRYPTOPP_ASSERT((data && size) || !(data || size)); + if (deepCopy) + m_block.Assign(data, size); + else + { + m_data = data; + m_size = size; + } + m_deepCopy = deepCopy; + } + + /// \brief Pointer to the first byte in the memory block + const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;} + /// \brief Pointer beyond the last byte in the memory block + const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;} + /// \brief Length of the memory block + size_t size() const {return m_deepCopy ? m_block.size() : m_size;} + +private: + bool m_deepCopy; + const byte *m_data; + size_t m_size; + SecByteBlock m_block; +}; + +/// \brief Used to pass byte array input as part of a NameValuePairs object +class ByteArrayParameter +{ +public: + /// \brief Construct a ByteArrayParameter + /// \param data a memory buffer + /// \param size the length of the memory buffer + ByteArrayParameter(byte *data = NULLPTR, unsigned int size = 0) + : m_data(data), m_size(size) {} + + /// \brief Construct a ByteArrayParameter + /// \param block a SecByteBlock + ByteArrayParameter(SecByteBlock &block) + : m_data(block.begin()), m_size(block.size()) {} + + /// \brief Pointer to the first byte in the memory block + byte *begin() const {return m_data;} + /// \brief Pointer beyond the last byte in the memory block + byte *end() const {return m_data + m_size;} + /// \brief Length of the memory block + size_t size() const {return m_size;} + +private: + byte *m_data; + size_t m_size; +}; + +/// \brief Combines two sets of NameValuePairs +/// \details CombinedNameValuePairs allows you to provide two sets of of NameValuePairs. +/// If a name is not found in the first set, then the second set is searched for the +/// name and value pair. The second set of NameValuePairs often provides default values. +class CRYPTOPP_DLL CombinedNameValuePairs : public NameValuePairs +{ +public: + /// \brief Construct a CombinedNameValuePairs + /// \param pairs1 reference to the first set of NameValuePairs + /// \param pairs2 reference to the second set of NameValuePairs + CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2) + : m_pairs1(pairs1), m_pairs2(pairs2) {} + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + +private: + const NameValuePairs &m_pairs1, &m_pairs2; +}; + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +template +class GetValueHelperClass +{ +public: + GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst) + : m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false) + { + if (strcmp(m_name, "ValueNames") == 0) + { + m_found = m_getValueNames = true; + NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType); + if (searchFirst) + searchFirst->GetVoidValue(m_name, valueType, pValue); + if (typeid(T) != typeid(BASE)) + pObject->BASE::GetVoidValue(m_name, valueType, pValue); + ((*reinterpret_cast(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';'; + } + + if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0) + { + NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType); + *reinterpret_cast(pValue) = pObject; + m_found = true; + return; + } + + if (!m_found && searchFirst) + m_found = searchFirst->GetVoidValue(m_name, valueType, pValue); + + if (!m_found && typeid(T) != typeid(BASE)) + m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue); + } + + operator bool() const {return m_found;} + + template + GetValueHelperClass & operator()(const char *name, const R & (T::*pm)() const) + { + if (m_getValueNames) + (*reinterpret_cast(m_pValue) += name) += ";"; + if (!m_found && strcmp(name, m_name) == 0) + { + NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType); + *reinterpret_cast(m_pValue) = (m_pObject->*pm)(); + m_found = true; + } + return *this; + } + + GetValueHelperClass &Assignable() + { +#ifndef __INTEL_COMPILER // ICL 9.1 workaround: Intel compiler copies the vTable pointer for some reason + if (m_getValueNames) + ((*reinterpret_cast(m_pValue) += "ThisObject:") += typeid(T).name()) += ';'; + if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0) + { + NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType); + *reinterpret_cast(m_pValue) = *m_pObject; + m_found = true; + } +#endif + return *this; + } + +private: + const T *m_pObject; + const char *m_name; + const std::type_info *m_valueType; + void *m_pValue; + bool m_found, m_getValueNames; +}; + +template +GetValueHelperClass GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULLPTR) +{ + return GetValueHelperClass(pObject, name, valueType, pValue, searchFirst); +} + +template +GetValueHelperClass GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULLPTR) +{ + return GetValueHelperClass(pObject, name, valueType, pValue, searchFirst); +} + +// ******************************************************** + +template +class AssignFromHelperClass +{ +public: + AssignFromHelperClass(T *pObject, const NameValuePairs &source) + : m_pObject(pObject), m_source(source), m_done(false) + { + if (source.GetThisObject(*pObject)) + m_done = true; + else if (typeid(BASE) != typeid(T)) + pObject->BASE::AssignFrom(source); + } + + template + AssignFromHelperClass & operator()(const char *name, void (T::*pm)(const R&)) + { + if (!m_done) + { + R value; + if (!m_source.GetValue(name, value)) + throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'"); + (m_pObject->*pm)(value); + } + return *this; + } + + template + AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(const R&, const S&)) + { + if (!m_done) + { + R value1; + if (!m_source.GetValue(name1, value1)) + throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'"); + S value2; + if (!m_source.GetValue(name2, value2)) + throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'"); + (m_pObject->*pm)(value1, value2); + } + return *this; + } + +private: + T *m_pObject; + const NameValuePairs &m_source; + bool m_done; +}; + +template +AssignFromHelperClass AssignFromHelper(T *pObject, const NameValuePairs &source) +{ + return AssignFromHelperClass(pObject, source); +} + +template +AssignFromHelperClass AssignFromHelper(T *pObject, const NameValuePairs &source) +{ + return AssignFromHelperClass(pObject, source); +} + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +// ******************************************************** + +#ifndef CRYPTOPP_NO_ASSIGN_TO_INTEGER +// Allow the linker to discard Integer code if not needed. +// Also see http://github.com/weidai11/cryptopp/issues/389. +CRYPTOPP_DLL bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt); +#endif + +CRYPTOPP_DLL const std::type_info & CRYPTOPP_API IntegerTypeId(); + +/// \brief Base class for AlgorithmParameters +class CRYPTOPP_DLL AlgorithmParametersBase +{ +public: + /// \brief Exception thrown when an AlgorithmParameter is unused + class ParameterNotUsed : public Exception + { + public: + ParameterNotUsed(const char *name) : Exception(OTHER_ERROR, std::string("AlgorithmParametersBase: parameter \"") + name + "\" not used") {} + }; + + virtual ~AlgorithmParametersBase() CRYPTOPP_THROW + { + +#if defined(CRYPTOPP_CXX17_UNCAUGHT_EXCEPTIONS) + if (std::uncaught_exceptions() == 0) +#elif defined(CRYPTOPP_CXX98_UNCAUGHT_EXCEPTION) + if (std::uncaught_exception() == false) +#else + try +#endif + { + if (m_throwIfNotUsed && !m_used) + throw ParameterNotUsed(m_name); + } +#if !defined(CRYPTOPP_CXX98_UNCAUGHT_EXCEPTION) +# if !defined(CRYPTOPP_CXX17_UNCAUGHT_EXCEPTIONS) + catch(const Exception&) + { + } +# endif +#endif + } + + // this is actually a move, not a copy + AlgorithmParametersBase(const AlgorithmParametersBase &x) + : m_name(x.m_name), m_throwIfNotUsed(x.m_throwIfNotUsed), m_used(x.m_used) + { + m_next.reset(const_cast(x).m_next.release()); + x.m_used = true; + } + + /// \brief Construct a AlgorithmParametersBase + /// \param name the parameter name + /// \param throwIfNotUsed flags indicating whether an exception should be thrown + /// \details If throwIfNotUsed is true, then a ParameterNotUsed exception + /// will be thrown in the destructor if the parameter is not not retrieved. + AlgorithmParametersBase(const char *name, bool throwIfNotUsed) + : m_name(name), m_throwIfNotUsed(throwIfNotUsed), m_used(false) {} + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + +protected: + friend class AlgorithmParameters; + void operator=(const AlgorithmParametersBase& rhs); // assignment not allowed, declare this for VC60 + + virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0; + virtual void MoveInto(void *p) const =0; // not really const + + const char *m_name; + bool m_throwIfNotUsed; + mutable bool m_used; + member_ptr m_next; +}; + +/// \brief Template base class for AlgorithmParameters +/// \tparam T the class or type +template +class AlgorithmParametersTemplate : public AlgorithmParametersBase +{ +public: + /// \brief Construct an AlgorithmParametersTemplate + /// \param name the name of the value + /// \param value a reference to the value + /// \param throwIfNotUsed flags indicating whether an exception should be thrown + /// \details If throwIfNotUsed is true, then a ParameterNotUsed exception + /// will be thrown in the destructor if the parameter is not not retrieved. + AlgorithmParametersTemplate(const char *name, const T &value, bool throwIfNotUsed) + : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) + { + } + + void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const + { +#ifndef CRYPTOPP_NO_ASSIGN_TO_INTEGER + // Special case for retrieving an Integer parameter when an int was passed in + if (!(typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value))) +#endif + { + NameValuePairs::ThrowIfTypeMismatch(name, typeid(T), valueType); + *reinterpret_cast(pValue) = m_value; + } + } + +#if defined(DEBUG_NEW) && (_MSC_VER >= 1300) +# pragma push_macro("new") +# undef new +#endif + + void MoveInto(void *buffer) const + { + AlgorithmParametersTemplate* p = new(buffer) AlgorithmParametersTemplate(*this); + CRYPTOPP_UNUSED(p); // silence warning + } + +#if defined(DEBUG_NEW) && (_MSC_VER >= 1300) +# pragma pop_macro("new") +#endif + +protected: + T m_value; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate; +CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate; +CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate; + +/// \brief An object that implements NameValuePairs +/// \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by +/// repeatedly using operator() on the object returned by MakeParameters, for example: +///
+///     AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
+///   
+class CRYPTOPP_DLL AlgorithmParameters : public NameValuePairs +{ +public: + /// \brief Construct a AlgorithmParameters + /// \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by + /// repeatedly using operator() on the object returned by MakeParameters, for example: + ///
+	///     AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
+	///   
+ AlgorithmParameters(); + +#ifdef __BORLANDC__ + /// \brief Construct a AlgorithmParameters + /// \tparam T the class or type + /// \param name the name of the object or value to retrieve + /// \param value reference to a variable that receives the value + /// \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed + /// \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(), + /// such as MSVC 7.0 and earlier. + /// \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by + /// repeatedly using operator() on the object returned by MakeParameters, for example: + ///
+	///     AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
+	///   
+ template + AlgorithmParameters(const char *name, const T &value, bool throwIfNotUsed=true) + : m_next(new AlgorithmParametersTemplate(name, value, throwIfNotUsed)) + , m_defaultThrowIfNotUsed(throwIfNotUsed) + { + } +#endif + + AlgorithmParameters(const AlgorithmParameters &x); + + AlgorithmParameters & operator=(const AlgorithmParameters &x); + + /// \tparam T the class or type + /// \param name the name of the object or value to retrieve + /// \param value reference to a variable that receives the value + /// \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed + template + AlgorithmParameters & operator()(const char *name, const T &value, bool throwIfNotUsed) + { + member_ptr p(new AlgorithmParametersTemplate(name, value, throwIfNotUsed)); + p->m_next.reset(m_next.release()); + m_next.reset(p.release()); + m_defaultThrowIfNotUsed = throwIfNotUsed; + return *this; + } + + /// \brief Appends a NameValuePair to a collection of NameValuePairs + /// \tparam T the class or type + /// \param name the name of the object or value to retrieve + /// \param value reference to a variable that receives the value + template + AlgorithmParameters & operator()(const char *name, const T &value) + { + return operator()(name, value, m_defaultThrowIfNotUsed); + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + +protected: + member_ptr m_next; + bool m_defaultThrowIfNotUsed; +}; + +/// \brief Create an object that implements NameValuePairs +/// \tparam T the class or type +/// \param name the name of the object or value to retrieve +/// \param value reference to a variable that receives the value +/// \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed +/// \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(), +/// such as MSVC 7.0 and earlier. +/// \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by +/// repeatedly using \p operator() on the object returned by \p MakeParameters, for example: +///
+///     AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3);
+///   
+#ifdef __BORLANDC__ +typedef AlgorithmParameters MakeParameters; +#else +template +AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true) +{ + return AlgorithmParameters()(name, value, throwIfNotUsed); +} +#endif + +#define CRYPTOPP_GET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Get##name) +#define CRYPTOPP_SET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Set##name) +#define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2) (Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2) + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/allocate.cpp b/external/ours/library/crypto/src/shared/original/allocate.cpp new file mode 100755 index 000000000..745eb7811 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/allocate.cpp @@ -0,0 +1,107 @@ +// allocate.cpp - written and placed in the public domain by Jeffrey Walton + +// The functions in allocate.h and allocate.cpp were originally in misc.h +// and misc.cpp. They were extracted in September 2019 to sidestep a circular +// dependency with misc.h and secblock.h. + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "allocate.h" +#include "stdcpp.h" +#include "misc.h" +#include "trap.h" + +// for memalign +#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX) +# include +#endif +// for posix_memalign +#if defined(CRYPTOPP_POSIX_MEMALIGN_AVAILABLE) +# include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +void CallNewHandler() +{ + using std::new_handler; + using std::set_new_handler; + + new_handler newHandler = set_new_handler(NULLPTR); + if (newHandler) + set_new_handler(newHandler); + + if (newHandler) + newHandler(); + else + throw std::bad_alloc(); +} + +void * AlignedAllocate(size_t size) +{ + byte *p; +#if defined(CRYPTOPP_MM_MALLOC_AVAILABLE) + while ((p = (byte *)_mm_malloc(size, 16)) == NULLPTR) +#elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) + while ((p = (byte *)memalign(16, size)) == NULLPTR) +#elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) + while ((p = (byte *)malloc(size)) == NULLPTR) +#elif defined(CRYPTOPP_POSIX_MEMALIGN_AVAILABLE) + while (posix_memalign(reinterpret_cast(&p), 16, size) != 0) +#else + while ((p = (byte *)malloc(size + 16)) == NULLPTR) +#endif + CallNewHandler(); + +#ifdef CRYPTOPP_NO_ALIGNED_ALLOC + size_t adjustment = 16-((size_t)p%16); + CRYPTOPP_ASSERT(adjustment > 0); + p += adjustment; + p[-1] = (byte)adjustment; +#endif + + // If this assert fires then there are problems that need + // to be fixed. Please open a bug report. + CRYPTOPP_ASSERT(IsAlignedOn(p, 16)); + return p; +} + +void AlignedDeallocate(void *p) +{ + // Guard pointer due to crash on AIX when CRYPTOPP_NO_ALIGNED_ALLOC + // is in effect. The guard was previously in place in SecBlock, + // but it was removed at f4d68353ca7c as part of GH #875. + CRYPTOPP_ASSERT(p); + + if (p != NULLPTR) + { +#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE + _mm_free(p); +#elif defined(CRYPTOPP_NO_ALIGNED_ALLOC) + p = (byte *)p - ((byte *)p)[-1]; + free(p); +#else + free(p); +#endif + } +} + +void * UnalignedAllocate(size_t size) +{ + void *p; + while ((p = malloc(size)) == NULLPTR) + CallNewHandler(); + return p; +} + +void UnalignedDeallocate(void *p) +{ + free(p); +} + +NAMESPACE_END + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/allocate.h b/external/ours/library/crypto/src/shared/original/allocate.h new file mode 100755 index 000000000..64e1ac79f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/allocate.h @@ -0,0 +1,74 @@ +// allocate.h - written and placed in the public domain by Jeffrey Walton + +// The functions in allocate.h and allocate.cpp were originally in misc.h +// and misc.cpp. They were extracted in September 2019 to sidestep a circular +// dependency with misc.h and secblock.h. + +/// \file allocate.h +/// \brief Functions for allocating aligned buffers + +#ifndef CRYPTOPP_ALLOCATE_H +#define CRYPTOPP_ALLOCATE_H + +#include "config.h" +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Attempts to reclaim unused memory +/// \throw bad_alloc +/// \details In the normal course of running a program, a request for memory +/// normally succeeds. If a call to AlignedAllocate or UnalignedAllocate fails, +/// then CallNewHandler is called in n effort to recover. Internally, +/// CallNewHandler calls set_new_handler(nullptr) in an effort to free memory. +/// There is no guarantee CallNewHandler will be able to obtain more memory so +/// an allocation succeeds. If the call to set_new_handler fails, then CallNewHandler +/// throws a bad_alloc exception. +/// \throw bad_alloc on failure +/// \since Crypto++ 5.0 +/// \sa AlignedAllocate, AlignedDeallocate, UnalignedAllocate, UnalignedDeallocate +CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler(); + +/// \brief Allocates a buffer on 16-byte boundary +/// \param size the size of the buffer +/// \details AlignedAllocate is primarily used when the data will be +/// processed by SSE, NEON, ARMv8 or PowerPC instructions. The assembly +/// language routines rely on the alignment. If the alignment is not +/// respected, then a SIGBUS could be generated on Unix and Linux, and an +/// EXCEPTION_DATATYPE_MISALIGNMENT could be generated on Windows. +/// \details Formerly, AlignedAllocate and AlignedDeallocate were only +/// available on certain platforms when CRYTPOPP_DISABLE_ASM was not in +/// effect. However, Android and iOS debug simulator builds got into a +/// state where the aligned allocator was not available and caused link +/// failures. +/// \since AlignedAllocate for SIMD since Crypto++ 1.0, AlignedAllocate +/// for all builds since Crypto++ 8.1 +/// \sa AlignedDeallocate, UnalignedAllocate, UnalignedDeallocate, CallNewHandler, +/// Issue 779 +CRYPTOPP_DLL void* CRYPTOPP_API AlignedAllocate(size_t size); + +/// \brief Frees a buffer allocated with AlignedAllocate +/// \param ptr the buffer to free +/// \since AlignedDeallocate for SIMD since Crypto++ 1.0, AlignedAllocate +/// for all builds since Crypto++ 8.1 +/// \sa AlignedAllocate, UnalignedAllocate, UnalignedDeallocate, CallNewHandler, +/// Issue 779 +CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *ptr); + +/// \brief Allocates a buffer +/// \param size the size of the buffer +/// \since Crypto++ 1.0 +/// \sa AlignedAllocate, AlignedDeallocate, UnalignedDeallocate, CallNewHandler, +/// Issue 779 +CRYPTOPP_DLL void * CRYPTOPP_API UnalignedAllocate(size_t size); + +/// \brief Frees a buffer allocated with UnalignedAllocate +/// \param ptr the buffer to free +/// \since Crypto++ 1.0 +/// \sa AlignedAllocate, AlignedDeallocate, UnalignedAllocate, CallNewHandler, +/// Issue 779 +CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *ptr); + +NAMESPACE_END + +#endif // CRYPTOPP_ALLOCATE_H diff --git a/external/ours/library/crypto/src/shared/original/arc4.cpp b/external/ours/library/crypto/src/shared/original/arc4.cpp new file mode 100755 index 000000000..2bc2dd1fd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/arc4.cpp @@ -0,0 +1,122 @@ +// arc4.cpp - originally written and placed in the public domain by Wei Dai + +// The ARC4 algorithm was first revealed in an anonymous email to the +// cypherpunks mailing list. This file originally contained some +// code copied from this email. The code has since been rewritten in order +// to clarify the copyright status of this file. It should now be +// completely in the public domain. + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "arc4.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void ARC4_TestInstantiations() +{ + ARC4 x; +} +#endif + +ARC4_Base::~ARC4_Base() +{ + m_x = m_y = 0; +} + +void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + m_x = 1; + m_y = 0; + + unsigned int i; + for (i=0; i<256; i++) + m_state[i] = byte(i); + + unsigned int keyIndex = 0, stateIndex = 0; + for (i=0; i<256; i++) + { + unsigned int a = m_state[i]; + stateIndex += key[keyIndex] + a; + stateIndex &= 0xff; + m_state[i] = m_state[stateIndex]; + m_state[stateIndex] = byte(a); + if (++keyIndex >= length) + keyIndex = 0; + } + + int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes()); + DiscardBytes(discardBytes); +} + +template +static inline unsigned int MakeByte(T &x, T &y, byte *s) +{ + unsigned int a = s[x]; + y = byte((y+a) & 0xff); + unsigned int b = s[y]; + s[x] = byte(b); + s[y] = byte(a); + x = byte((x+1) & 0xff); + return s[(a+b) & 0xff]; +} + +void ARC4_Base::GenerateBlock(byte *output, size_t size) +{ + while (size--) + *output++ = static_cast(MakeByte(m_x, m_y, m_state)); +} + +void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length) +{ + if (length == 0) + return; + + byte *const s = m_state; + unsigned int x = m_x; + unsigned int y = m_y; + + if (inString == outString) + { + do + { + *outString++ ^= MakeByte(x, y, s); + } while (--length); + } + else + { + do + { + *outString++ = *inString++ ^ byte(MakeByte(x, y, s)); + } + while(--length); + } + + m_x = byte(x); + m_y = byte(y); +} + +void ARC4_Base::DiscardBytes(size_t n) +{ + if (n == 0) + return; + + byte *const s = m_state; + unsigned int x = m_x; + unsigned int y = m_y; + + do + { + MakeByte(x, y, s); + } + while(--n); + + m_x = byte(x); + m_y = byte(y); +} + +} +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/arc4.h b/external/ours/library/crypto/src/shared/original/arc4.h new file mode 100755 index 000000000..baed9e767 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/arc4.h @@ -0,0 +1,89 @@ +// arc4.h - originally written and placed in the public domain by Wei Dai + +/// \file arc4.h +/// \brief Classes for ARC4 cipher +/// \since Crypto++ 3.1 + +#ifndef CRYPTOPP_ARC4_H +#define CRYPTOPP_ARC4_H + +#include "cryptlib.h" +#include "strciphr.h" +#include "secblock.h" +#include "smartptr.h" + +NAMESPACE_BEGIN(CryptoPP) + +namespace Weak1 { + +/// \brief ARC4 base class +/// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions +/// \since Crypto++ 3.1 +class CRYPTOPP_NO_VTABLE ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher, public SymmetricCipherDocumentation +{ +public: + ~ARC4_Base(); + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ARC4";} + + void GenerateBlock(byte *output, size_t size); + void DiscardBytes(size_t n); + + void ProcessData(byte *outString, const byte *inString, size_t length); + + bool IsRandomAccess() const {return false;} + bool IsSelfInverting() const {return true;} + bool IsForwardTransformation() const {return true;} + + typedef SymmetricCipherFinal Encryption; + typedef SymmetricCipherFinal Decryption; + +protected: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + virtual unsigned int GetDefaultDiscardBytes() const {return 0;} + + FixedSizeSecBlock m_state; + byte m_x, m_y; +}; + +/// \brief Alleged RC4 +/// \sa Alleged RC4 +/// \since Crypto++ 3.1 +DOCUMENTED_TYPEDEF(SymmetricCipherFinal, ARC4); + +/// \brief MARC4 base class +/// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions +/// \details MARC4 discards the first 256 bytes of keystream, which may be weaker than the rest +/// \since Crypto++ 3.1 +class CRYPTOPP_NO_VTABLE MARC4_Base : public ARC4_Base +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "MARC4";} + + typedef SymmetricCipherFinal Encryption; + typedef SymmetricCipherFinal Decryption; + +protected: + unsigned int GetDefaultDiscardBytes() const {return 256;} +}; + +/// \brief Modified Alleged RC4 +/// \sa Alleged RC4 +/// \since Crypto++ 3.1 +DOCUMENTED_TYPEDEF(SymmetricCipherFinal, MARC4); + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/argnames.h b/external/ours/library/crypto/src/shared/original/argnames.h new file mode 100755 index 000000000..3d2859a8e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/argnames.h @@ -0,0 +1,99 @@ +// argnames.h - originally written and placed in the public domain by Wei Dai + +/// \file argnames.h +/// \brief Standard names for retrieving values by name when working with \p NameValuePairs + +#ifndef CRYPTOPP_ARGNAMES_H +#define CRYPTOPP_ARGNAMES_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +DOCUMENTED_NAMESPACE_BEGIN(Name) + +#define CRYPTOPP_DEFINE_NAME_STRING(name) inline const char *name() {return #name;} + +CRYPTOPP_DEFINE_NAME_STRING(ValueNames) ///< string, a list of value names with a semicolon (';') after each name +CRYPTOPP_DEFINE_NAME_STRING(Version) ///< int +CRYPTOPP_DEFINE_NAME_STRING(Seed) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Key) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(IV) ///< ConstByteArrayParameter, also accepts const byte * for backwards compatibility +CRYPTOPP_DEFINE_NAME_STRING(StolenIV) ///< byte * +CRYPTOPP_DEFINE_NAME_STRING(Nonce) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Rounds) ///< int +CRYPTOPP_DEFINE_NAME_STRING(FeedbackSize) ///< int +CRYPTOPP_DEFINE_NAME_STRING(WordSize) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(BlockSize) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(EffectiveKeyLength) ///< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(KeySize) ///< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(ModulusSize) ///< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrderSize) ///< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(PrivateExponentSize)///< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(Modulus) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(PublicExponent) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(PrivateExponent) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(PublicElement) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrder) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(Cofactor) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(SubgroupGenerator) ///< Integer, ECP::Point, or EC2N::Point +CRYPTOPP_DEFINE_NAME_STRING(Curve) ///< ECP or EC2N +CRYPTOPP_DEFINE_NAME_STRING(GroupOID) ///< OID +CRYPTOPP_DEFINE_NAME_STRING(PointerToPrimeSelector) ///< const PrimeSelector * +CRYPTOPP_DEFINE_NAME_STRING(Prime1) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(Prime2) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(ModPrime1PrivateExponent) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(ModPrime2PrivateExponent) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(MultiplicativeInverseOfPrime2ModPrime1) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime1) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime2) ///< Integer +CRYPTOPP_DEFINE_NAME_STRING(PutMessage) ///< bool +CRYPTOPP_DEFINE_NAME_STRING(TruncatedDigestSize) ///< int +CRYPTOPP_DEFINE_NAME_STRING(BlockPaddingScheme) ///< StreamTransformationFilter::BlockPaddingScheme +CRYPTOPP_DEFINE_NAME_STRING(HashVerificationFilterFlags) ///< word32 +CRYPTOPP_DEFINE_NAME_STRING(AuthenticatedDecryptionFilterFlags) ///< word32 +CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) ///< word32 +CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) ///< ByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(InputFileName) ///< const char * +CRYPTOPP_DEFINE_NAME_STRING(InputFileNameWide) ///< const wchar_t * +CRYPTOPP_DEFINE_NAME_STRING(InputStreamPointer) ///< std::istream * +CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode) ///< bool +CRYPTOPP_DEFINE_NAME_STRING(OutputFileName) ///< const char * +CRYPTOPP_DEFINE_NAME_STRING(OutputFileNameWide) ///< const wchar_t * +CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer) ///< std::ostream * +CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode) ///< bool +CRYPTOPP_DEFINE_NAME_STRING(EncodingParameters) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(KeyDerivationParameters) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Separator) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Terminator) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Uppercase) ///< bool +CRYPTOPP_DEFINE_NAME_STRING(GroupSize) ///< int +CRYPTOPP_DEFINE_NAME_STRING(Pad) ///< bool +CRYPTOPP_DEFINE_NAME_STRING(PaddingByte) ///< byte +CRYPTOPP_DEFINE_NAME_STRING(Log2Base) ///< int +CRYPTOPP_DEFINE_NAME_STRING(EncodingLookupArray) ///< const byte * +CRYPTOPP_DEFINE_NAME_STRING(DecodingLookupArray) ///< const byte * +CRYPTOPP_DEFINE_NAME_STRING(InsertLineBreaks) ///< bool +CRYPTOPP_DEFINE_NAME_STRING(MaxLineLength) ///< int +CRYPTOPP_DEFINE_NAME_STRING(DigestSize) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(TableSize) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(Blinding) ///< bool, timing attack mitigations, ON by default +CRYPTOPP_DEFINE_NAME_STRING(DerivedKey) ///< ByteArrayParameter, key derivation, derived key +CRYPTOPP_DEFINE_NAME_STRING(DerivedKeyLength) ///< int, key derivation, derived key length in bytes +CRYPTOPP_DEFINE_NAME_STRING(Personalization) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(PersonalizationSize) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(Salt) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Tweak) ///< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(SaltSize) ///< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(TreeMode) ///< byte +CRYPTOPP_DEFINE_NAME_STRING(FileName) ///< const char * +CRYPTOPP_DEFINE_NAME_STRING(FileTime) ///< int +CRYPTOPP_DEFINE_NAME_STRING(Comment) ///< const char * +CRYPTOPP_DEFINE_NAME_STRING(Identity) ///< ConstByteArrayParameter +DOCUMENTED_NAMESPACE_END + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/aria.cpp b/external/ours/library/crypto/src/shared/original/aria.cpp new file mode 100755 index 000000000..bc7509fdf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/aria.cpp @@ -0,0 +1,343 @@ +// aria.cpp - written and placed in the public domain by Jeffrey Walton + +#include "pch.h" +#include "config.h" + +#include "aria.h" +#include "misc.h" +#include "cpu.h" + +#if CRYPTOPP_SSE2_INTRIN_AVAILABLE +# define CRYPTOPP_ENABLE_ARIA_SSE2_INTRINSICS 1 +#endif + +#if CRYPTOPP_SSSE3_AVAILABLE +# define CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS 1 +#endif + +// GCC cast warning. Note: this is used on round key table, +// which is word32 and naturally aligned. +#define UINT32_CAST(x) ((word32 *)(void *)(x)) + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(ARIATab) + +extern const word32 S1[256]; +extern const word32 S2[256]; +extern const word32 X1[256]; +extern const word32 X2[256]; +extern const word32 KRK[3][4]; + +NAMESPACE_END +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +using CryptoPP::ARIATab::S1; +using CryptoPP::ARIATab::S2; +using CryptoPP::ARIATab::X1; +using CryptoPP::ARIATab::X2; +using CryptoPP::ARIATab::KRK; + +inline byte ARIA_BRF(const word32 x, const int y) { + return static_cast(GETBYTE(x, y)); +} + +// Key XOR Layer +#define ARIA_KXL { \ + typedef BlockGetAndPut NativeBlock; \ + NativeBlock::Put(rk, t)(t[0])(t[1])(t[2])(t[3]); \ + } + +// S-Box Layer 1 + M +#define SBL1_M(T0,T1,T2,T3) { \ + T0=S1[ARIA_BRF(T0,3)]^S2[ARIA_BRF(T0,2)]^X1[ARIA_BRF(T0,1)]^X2[ARIA_BRF(T0,0)]; \ + T1=S1[ARIA_BRF(T1,3)]^S2[ARIA_BRF(T1,2)]^X1[ARIA_BRF(T1,1)]^X2[ARIA_BRF(T1,0)]; \ + T2=S1[ARIA_BRF(T2,3)]^S2[ARIA_BRF(T2,2)]^X1[ARIA_BRF(T2,1)]^X2[ARIA_BRF(T2,0)]; \ + T3=S1[ARIA_BRF(T3,3)]^S2[ARIA_BRF(T3,2)]^X1[ARIA_BRF(T3,1)]^X2[ARIA_BRF(T3,0)]; \ + } + +// S-Box Layer 2 + M +#define SBL2_M(T0,T1,T2,T3) { \ + T0=X1[ARIA_BRF(T0,3)]^X2[ARIA_BRF(T0,2)]^S1[ARIA_BRF(T0,1)]^S2[ARIA_BRF(T0,0)]; \ + T1=X1[ARIA_BRF(T1,3)]^X2[ARIA_BRF(T1,2)]^S1[ARIA_BRF(T1,1)]^S2[ARIA_BRF(T1,0)]; \ + T2=X1[ARIA_BRF(T2,3)]^X2[ARIA_BRF(T2,2)]^S1[ARIA_BRF(T2,1)]^S2[ARIA_BRF(T2,0)]; \ + T3=X1[ARIA_BRF(T3,3)]^X2[ARIA_BRF(T3,2)]^S1[ARIA_BRF(T3,1)]^S2[ARIA_BRF(T3,0)]; \ + } + +#define ARIA_P(T0,T1,T2,T3) { \ + (T1) = (((T1)<< 8)&0xff00ff00) ^ (((T1)>> 8)&0x00ff00ff); \ + (T2) = rotrConstant<16>(T2); \ + (T3) = ByteReverse((T3)); \ + } + +#define ARIA_M(X,Y) { \ + Y=(X)<<8 ^ (X)>>8 ^ (X)<<16 ^ (X)>>16 ^ (X)<<24 ^ (X)>>24; \ + } + +#define ARIA_MM(T0,T1,T2,T3) { \ + (T1)^=(T2); (T2)^=(T3); (T0)^=(T1); \ + (T3)^=(T1); (T2)^=(T0); (T1)^=(T2); \ + } + +#define ARIA_FO {SBL1_M(t[0],t[1],t[2],t[3]) ARIA_MM(t[0],t[1],t[2],t[3]) ARIA_P(t[0],t[1],t[2],t[3]) ARIA_MM(t[0],t[1],t[2],t[3])} +#define ARIA_FE {SBL2_M(t[0],t[1],t[2],t[3]) ARIA_MM(t[0],t[1],t[2],t[3]) ARIA_P(t[2],t[3],t[0],t[1]) ARIA_MM(t[0],t[1],t[2],t[3])} + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) +extern void ARIA_UncheckedSetKey_Schedule_NEON(byte* rk, word32* ws, unsigned int keylen); +extern void ARIA_ProcessAndXorBlock_NEON(const byte* xorBlock, byte* outblock, const byte *rk, word32 *t); +#endif + +#if (CRYPTOPP_SSSE3_AVAILABLE) +extern void ARIA_ProcessAndXorBlock_SSSE3(const byte* xorBlock, byte* outBlock, const byte *rk, word32 *t); +#endif + +// n-bit right shift of Y XORed to X +template +inline void ARIA_GSRK(const word32 X[4], const word32 Y[4], byte RK[16]) +{ + // MSVC is not generating a "rotate immediate". Constify to help it along. + static const unsigned int Q = 4-(N/32); + static const unsigned int R = N % 32; + UINT32_CAST(RK)[0] = (X[0]) ^ ((Y[(Q )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R)); + UINT32_CAST(RK)[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q )%4])<<(32-R)); + UINT32_CAST(RK)[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R)); + UINT32_CAST(RK)[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R)); +} + +void ARIA::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + + m_rk.New(16*17); // round keys + m_w.New(4*7); // w0, w1, w2, w3, t and u + + byte *rk = m_rk.data(); + int Q, q, R, r; + + switch (keylen) + { + case 16: + R = r = m_rounds = 12; + Q = q = 0; + break; + case 32: + R = r = m_rounds = 16; + Q = q = 2; + break; + case 24: + R = r = m_rounds = 14; + Q = q = 1; + break; + default: + Q = q = R = r = m_rounds = 0; + CRYPTOPP_ASSERT(0); + } + + // w0 has room for 32 bytes. w1-w3 each has room for 16 bytes. t and u are 16 byte temp areas. + word32 *w0 = m_w.data(), *w1 = m_w.data()+8, *w2 = m_w.data()+12, *w3 = m_w.data()+16, *t = m_w.data()+20; + + GetBlockblock(key); + block(w0[0])(w0[1])(w0[2])(w0[3]); + + t[0]=w0[0]^KRK[q][0]; t[1]=w0[1]^KRK[q][1]; + t[2]=w0[2]^KRK[q][2]; t[3]=w0[3]^KRK[q][3]; + + ARIA_FO; + + if (keylen == 32) + { + block(w1[0])(w1[1])(w1[2])(w1[3]); + } + else if (keylen == 24) + { + block(w1[0])(w1[1]); w1[2] = w1[3] = 0; + } + else + { + w1[0]=w1[1]=w1[2]=w1[3]=0; + } + + w1[0]^=t[0]; w1[1]^=t[1]; w1[2]^=t[2]; w1[3]^=t[3]; + ::memcpy(t, w1, 16); + + q = (q==2) ? 0 : (q+1); + t[0]^=KRK[q][0]; t[1]^=KRK[q][1]; t[2]^=KRK[q][2]; t[3]^=KRK[q][3]; + + ARIA_FE; + + t[0]^=w0[0]; t[1]^=w0[1]; t[2]^=w0[2]; t[3]^=w0[3]; + ::memcpy(w2, t, 16); + + q = (q==2) ? 0 : (q+1); + t[0]^=KRK[q][0]; t[1]^=KRK[q][1]; t[2]^=KRK[q][2]; t[3]^=KRK[q][3]; + + ARIA_FO; + + w3[0]=t[0]^w1[0]; w3[1]=t[1]^w1[1]; w3[2]=t[2]^w1[2]; w3[3]=t[3]^w1[3]; + +#if CRYPTOPP_ARM_NEON_AVAILABLE + if (HasNEON()) + { + ARIA_UncheckedSetKey_Schedule_NEON(rk, m_w, keylen); + } + else +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + { + ARIA_GSRK<19>(w0, w1, rk + 0); + ARIA_GSRK<19>(w1, w2, rk + 16); + ARIA_GSRK<19>(w2, w3, rk + 32); + ARIA_GSRK<19>(w3, w0, rk + 48); + ARIA_GSRK<31>(w0, w1, rk + 64); + ARIA_GSRK<31>(w1, w2, rk + 80); + ARIA_GSRK<31>(w2, w3, rk + 96); + ARIA_GSRK<31>(w3, w0, rk + 112); + ARIA_GSRK<67>(w0, w1, rk + 128); + ARIA_GSRK<67>(w1, w2, rk + 144); + ARIA_GSRK<67>(w2, w3, rk + 160); + ARIA_GSRK<67>(w3, w0, rk + 176); + ARIA_GSRK<97>(w0, w1, rk + 192); + + if (keylen > 16) + { + ARIA_GSRK<97>(w1, w2, rk + 208); + ARIA_GSRK<97>(w2, w3, rk + 224); + + if (keylen > 24) + { + ARIA_GSRK< 97>(w3, w0, rk + 240); + ARIA_GSRK<109>(w0, w1, rk + 256); + } + } + } + + // Decryption operation + if (!IsForwardTransformation()) + { + word32 *a, *z, *s; + rk = m_rk.data(); + r = R; q = Q; + + a=UINT32_CAST(rk); s=m_w.data()+24; z=a+r*4; + ::memcpy(t, a, 16); ::memcpy(a, z, 16); ::memcpy(z, t, 16); + + a+=4; z-=4; + for (; a(m_rk.data()); + word32 *t = const_cast(m_w.data()+20); + + // Timing attack countermeasure. See comments in Rijndael for more details. + // We used Yun's 32-bit implementation, so we use words rather than bytes. + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + volatile word32 _u = 0; + word32 u = _u; + + for (i=0; iblock(inBlock); + block(t[0])(t[1])(t[2])(t[3]); + + if (m_rounds > 12) { + ARIA_KXL; rk+= 16; ARIA_FO; + ARIA_KXL; rk+= 16; ARIA_FE; + } + + if (m_rounds > 14) { + ARIA_KXL; rk+= 16; ARIA_FO; + ARIA_KXL; rk+= 16; ARIA_FE; + } + + ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; ARIA_FE; + ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; ARIA_FE; + ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; ARIA_FE; + ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; ARIA_FE; + ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; ARIA_FE; + ARIA_KXL; rk+= 16; ARIA_FO; ARIA_KXL; rk+= 16; + +#if CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS + if (HasSSSE3()) + { + ARIA_ProcessAndXorBlock_SSSE3(xorBlock, outBlock, rk, t); + return; + } + else +#endif // CRYPTOPP_ENABLE_ARIA_SSSE3_INTRINSICS +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + { + ARIA_ProcessAndXorBlock_NEON(xorBlock, outBlock, rk, t); + return; + } + else +#endif // CRYPTOPP_ARM_NEON_AVAILABLE +#if (CRYPTOPP_LITTLE_ENDIAN) + { + outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ) ^ rk[ 3]; + outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8) ^ rk[ 2]; + outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ) ^ rk[ 1]; + outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ) ^ rk[ 0]; + outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ) ^ rk[ 7]; + outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8) ^ rk[ 6]; + outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ) ^ rk[ 5]; + outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ) ^ rk[ 4]; + outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ) ^ rk[11]; + outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8) ^ rk[10]; + outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ) ^ rk[ 9]; + outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ) ^ rk[ 8]; + outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ) ^ rk[15]; + outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8) ^ rk[14]; + outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ) ^ rk[13]; + outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ) ^ rk[12]; + } +#else + { + outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ) ^ rk[ 0]; + outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8) ^ rk[ 1]; + outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ) ^ rk[ 2]; + outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ) ^ rk[ 3]; + outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ) ^ rk[ 4]; + outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8) ^ rk[ 5]; + outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ) ^ rk[ 6]; + outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ) ^ rk[ 7]; + outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ) ^ rk[ 8]; + outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8) ^ rk[ 9]; + outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ) ^ rk[10]; + outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ) ^ rk[11]; + outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ) ^ rk[12]; + outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8) ^ rk[13]; + outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ) ^ rk[14]; + outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ) ^ rk[15]; + } +#endif // CRYPTOPP_LITTLE_ENDIAN + + if (xorBlock != NULLPTR) + for (unsigned int n=0; nRFC 5794, A Description of the ARIA Encryption Algorithm, +/// Korea +/// Internet & Security Agency homepage + +#ifndef CRYPTOPP_ARIA_H +#define CRYPTOPP_ARIA_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief ARIA block cipher information +/// \since Crypto++ 6.0 +struct ARIA_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ARIA";} +}; + +/// \brief ARIA block cipher +/// \details The Crypto++ ARIA implementation is based on the 32-bit implementation by Aaram Yun +/// from the National Security Research Institute, KOREA. Aaram Yun's implementation is based on +/// the 8-bit implementation by Jin Hong. The source files are available in ARIA.zip from the Korea +/// Internet & Security Agency website. +/// \sa RFC 5794, A Description of the ARIA Encryption Algorithm, +/// Korea +/// Internet & Security Agency homepage +/// \sa ARIA +/// \since Crypto++ 6.0 +class ARIA : public ARIA_Info, public BlockCipherDocumentation +{ +public: + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + Base() : m_rounds(0) {} + + protected: + void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + private: + // Reference implementation allocates a table of 17 round keys. + typedef SecBlock > AlignedByteBlock; + typedef SecBlock > AlignedWordBlock; + + AlignedByteBlock m_rk; // round keys + AlignedWordBlock m_w; // w0, w1, w2, w3, t and u + unsigned int m_rounds; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef ARIA::Encryption ARIAEncryption; +typedef ARIA::Decryption ARIADecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/aria_simd.cpp b/external/ours/library/crypto/src/shared/original/aria_simd.cpp new file mode 100755 index 000000000..56265e0e1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/aria_simd.cpp @@ -0,0 +1,194 @@ +// aria_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics to gain access to ARMv7a and +// ARMv8a NEON instructions. A separate source file is needed +// because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "misc.h" + +#if (CRYPTOPP_SSSE3_AVAILABLE) +# include +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char ARIA_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(ARIATab) + +extern const word32 S1[256]; +extern const word32 S2[256]; +extern const word32 X1[256]; +extern const word32 X2[256]; +extern const word32 KRK[3][4]; + +NAMESPACE_END +NAMESPACE_END + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; + +inline byte ARIA_BRF(const word32 x, const int y) { + return static_cast(GETBYTE(x, y)); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +using CryptoPP::ARIATab::S1; +using CryptoPP::ARIATab::S2; +using CryptoPP::ARIATab::X1; +using CryptoPP::ARIATab::X2; +using CryptoPP::ARIATab::KRK; + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +template +inline void ARIA_GSRK_NEON(const uint32x4_t X, const uint32x4_t Y, byte RK[16]) +{ + enum { Q1 = (4-(N/32)) % 4, + Q2 = (3-(N/32)) % 4, + R = N % 32 + }; + + vst1q_u8(RK, vreinterpretq_u8_u32( + veorq_u32(X, veorq_u32( + vshrq_n_u32(vextq_u32(Y, Y, Q1), R), + vshlq_n_u32(vextq_u32(Y, Y, Q2), 32-R))))); +} + +void ARIA_UncheckedSetKey_Schedule_NEON(byte* rk, word32* ws, unsigned int keylen) +{ + const uint32x4_t w0 = vld1q_u32(ws+ 0); + const uint32x4_t w1 = vld1q_u32(ws+ 8); + const uint32x4_t w2 = vld1q_u32(ws+12); + const uint32x4_t w3 = vld1q_u32(ws+16); + + ARIA_GSRK_NEON<19>(w0, w1, rk + 0); + ARIA_GSRK_NEON<19>(w1, w2, rk + 16); + ARIA_GSRK_NEON<19>(w2, w3, rk + 32); + ARIA_GSRK_NEON<19>(w3, w0, rk + 48); + ARIA_GSRK_NEON<31>(w0, w1, rk + 64); + ARIA_GSRK_NEON<31>(w1, w2, rk + 80); + ARIA_GSRK_NEON<31>(w2, w3, rk + 96); + ARIA_GSRK_NEON<31>(w3, w0, rk + 112); + ARIA_GSRK_NEON<67>(w0, w1, rk + 128); + ARIA_GSRK_NEON<67>(w1, w2, rk + 144); + ARIA_GSRK_NEON<67>(w2, w3, rk + 160); + ARIA_GSRK_NEON<67>(w3, w0, rk + 176); + ARIA_GSRK_NEON<97>(w0, w1, rk + 192); + + if (keylen > 16) + { + ARIA_GSRK_NEON<97>(w1, w2, rk + 208); + ARIA_GSRK_NEON<97>(w2, w3, rk + 224); + + if (keylen > 24) + { + ARIA_GSRK_NEON< 97>(w3, w0, rk + 240); + ARIA_GSRK_NEON<109>(w0, w1, rk + 256); + } + } +} + +void ARIA_ProcessAndXorBlock_NEON(const byte* xorBlock, byte* outBlock, const byte *rk, word32 *t) +{ + outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ); + outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8); + outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ); + outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ); + outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ); + outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8); + outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ); + outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ); + outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ); + outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8); + outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ); + outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ); + outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ); + outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8); + outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ); + outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ); + + // 'outBlock' and 'xorBlock' may be unaligned. + if (xorBlock != NULLPTR) + { + vst1q_u8(outBlock, + veorq_u8( + vld1q_u8(xorBlock), + veorq_u8( + vld1q_u8(outBlock), + vrev32q_u8(vld1q_u8((rk)))))); + } + else + { + vst1q_u8(outBlock, + veorq_u8( + vld1q_u8(outBlock), + vrev32q_u8(vld1q_u8(rk)))); + } +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_SSSE3_AVAILABLE) + +void ARIA_ProcessAndXorBlock_SSSE3(const byte* xorBlock, byte* outBlock, const byte *rk, word32 *t) +{ + const __m128i MASK = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); + + outBlock[ 0] = (byte)(X1[ARIA_BRF(t[0],3)] ); + outBlock[ 1] = (byte)(X2[ARIA_BRF(t[0],2)]>>8); + outBlock[ 2] = (byte)(S1[ARIA_BRF(t[0],1)] ); + outBlock[ 3] = (byte)(S2[ARIA_BRF(t[0],0)] ); + outBlock[ 4] = (byte)(X1[ARIA_BRF(t[1],3)] ); + outBlock[ 5] = (byte)(X2[ARIA_BRF(t[1],2)]>>8); + outBlock[ 6] = (byte)(S1[ARIA_BRF(t[1],1)] ); + outBlock[ 7] = (byte)(S2[ARIA_BRF(t[1],0)] ); + outBlock[ 8] = (byte)(X1[ARIA_BRF(t[2],3)] ); + outBlock[ 9] = (byte)(X2[ARIA_BRF(t[2],2)]>>8); + outBlock[10] = (byte)(S1[ARIA_BRF(t[2],1)] ); + outBlock[11] = (byte)(S2[ARIA_BRF(t[2],0)] ); + outBlock[12] = (byte)(X1[ARIA_BRF(t[3],3)] ); + outBlock[13] = (byte)(X2[ARIA_BRF(t[3],2)]>>8); + outBlock[14] = (byte)(S1[ARIA_BRF(t[3],1)] ); + outBlock[15] = (byte)(S2[ARIA_BRF(t[3],0)] ); + + // 'outBlock' and 'xorBlock' may be unaligned. + if (xorBlock != NULLPTR) + { + _mm_storeu_si128(M128_CAST(outBlock), + _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(xorBlock)), + _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(outBlock)), + _mm_shuffle_epi8(_mm_load_si128(CONST_M128_CAST(rk)), MASK))) + ); + } + else + { + _mm_storeu_si128(M128_CAST(outBlock), + _mm_xor_si128(_mm_loadu_si128(CONST_M128_CAST(outBlock)), + _mm_shuffle_epi8(_mm_load_si128(CONST_M128_CAST(rk)), MASK))); + } +} + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ariatab.cpp b/external/ours/library/crypto/src/shared/original/ariatab.cpp new file mode 100755 index 000000000..6c8a15667 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ariatab.cpp @@ -0,0 +1,166 @@ +// ariatab.cpp - written and placed in the public domain by Jeffrey Walton + +#include "pch.h" +#include "config.h" + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(ARIATab) + +CRYPTOPP_ALIGN_DATA(16) +CRYPTOPP_TABLE +const word32 S1[256]={ + 0x00636363,0x007c7c7c,0x00777777,0x007b7b7b,0x00f2f2f2,0x006b6b6b,0x006f6f6f,0x00c5c5c5, + 0x00303030,0x00010101,0x00676767,0x002b2b2b,0x00fefefe,0x00d7d7d7,0x00ababab,0x00767676, + 0x00cacaca,0x00828282,0x00c9c9c9,0x007d7d7d,0x00fafafa,0x00595959,0x00474747,0x00f0f0f0, + 0x00adadad,0x00d4d4d4,0x00a2a2a2,0x00afafaf,0x009c9c9c,0x00a4a4a4,0x00727272,0x00c0c0c0, + 0x00b7b7b7,0x00fdfdfd,0x00939393,0x00262626,0x00363636,0x003f3f3f,0x00f7f7f7,0x00cccccc, + 0x00343434,0x00a5a5a5,0x00e5e5e5,0x00f1f1f1,0x00717171,0x00d8d8d8,0x00313131,0x00151515, + 0x00040404,0x00c7c7c7,0x00232323,0x00c3c3c3,0x00181818,0x00969696,0x00050505,0x009a9a9a, + 0x00070707,0x00121212,0x00808080,0x00e2e2e2,0x00ebebeb,0x00272727,0x00b2b2b2,0x00757575, + 0x00090909,0x00838383,0x002c2c2c,0x001a1a1a,0x001b1b1b,0x006e6e6e,0x005a5a5a,0x00a0a0a0, + 0x00525252,0x003b3b3b,0x00d6d6d6,0x00b3b3b3,0x00292929,0x00e3e3e3,0x002f2f2f,0x00848484, + 0x00535353,0x00d1d1d1,0x00000000,0x00ededed,0x00202020,0x00fcfcfc,0x00b1b1b1,0x005b5b5b, + 0x006a6a6a,0x00cbcbcb,0x00bebebe,0x00393939,0x004a4a4a,0x004c4c4c,0x00585858,0x00cfcfcf, + 0x00d0d0d0,0x00efefef,0x00aaaaaa,0x00fbfbfb,0x00434343,0x004d4d4d,0x00333333,0x00858585, + 0x00454545,0x00f9f9f9,0x00020202,0x007f7f7f,0x00505050,0x003c3c3c,0x009f9f9f,0x00a8a8a8, + 0x00515151,0x00a3a3a3,0x00404040,0x008f8f8f,0x00929292,0x009d9d9d,0x00383838,0x00f5f5f5, + 0x00bcbcbc,0x00b6b6b6,0x00dadada,0x00212121,0x00101010,0x00ffffff,0x00f3f3f3,0x00d2d2d2, + 0x00cdcdcd,0x000c0c0c,0x00131313,0x00ececec,0x005f5f5f,0x00979797,0x00444444,0x00171717, + 0x00c4c4c4,0x00a7a7a7,0x007e7e7e,0x003d3d3d,0x00646464,0x005d5d5d,0x00191919,0x00737373, + 0x00606060,0x00818181,0x004f4f4f,0x00dcdcdc,0x00222222,0x002a2a2a,0x00909090,0x00888888, + 0x00464646,0x00eeeeee,0x00b8b8b8,0x00141414,0x00dedede,0x005e5e5e,0x000b0b0b,0x00dbdbdb, + 0x00e0e0e0,0x00323232,0x003a3a3a,0x000a0a0a,0x00494949,0x00060606,0x00242424,0x005c5c5c, + 0x00c2c2c2,0x00d3d3d3,0x00acacac,0x00626262,0x00919191,0x00959595,0x00e4e4e4,0x00797979, + 0x00e7e7e7,0x00c8c8c8,0x00373737,0x006d6d6d,0x008d8d8d,0x00d5d5d5,0x004e4e4e,0x00a9a9a9, + 0x006c6c6c,0x00565656,0x00f4f4f4,0x00eaeaea,0x00656565,0x007a7a7a,0x00aeaeae,0x00080808, + 0x00bababa,0x00787878,0x00252525,0x002e2e2e,0x001c1c1c,0x00a6a6a6,0x00b4b4b4,0x00c6c6c6, + 0x00e8e8e8,0x00dddddd,0x00747474,0x001f1f1f,0x004b4b4b,0x00bdbdbd,0x008b8b8b,0x008a8a8a, + 0x00707070,0x003e3e3e,0x00b5b5b5,0x00666666,0x00484848,0x00030303,0x00f6f6f6,0x000e0e0e, + 0x00616161,0x00353535,0x00575757,0x00b9b9b9,0x00868686,0x00c1c1c1,0x001d1d1d,0x009e9e9e, + 0x00e1e1e1,0x00f8f8f8,0x00989898,0x00111111,0x00696969,0x00d9d9d9,0x008e8e8e,0x00949494, + 0x009b9b9b,0x001e1e1e,0x00878787,0x00e9e9e9,0x00cecece,0x00555555,0x00282828,0x00dfdfdf, + 0x008c8c8c,0x00a1a1a1,0x00898989,0x000d0d0d,0x00bfbfbf,0x00e6e6e6,0x00424242,0x00686868, + 0x00414141,0x00999999,0x002d2d2d,0x000f0f0f,0x00b0b0b0,0x00545454,0x00bbbbbb,0x00161616 +}; + +CRYPTOPP_ALIGN_DATA(16) +CRYPTOPP_TABLE +const word32 S2[256]={ + 0xe200e2e2,0x4e004e4e,0x54005454,0xfc00fcfc,0x94009494,0xc200c2c2,0x4a004a4a,0xcc00cccc, + 0x62006262,0x0d000d0d,0x6a006a6a,0x46004646,0x3c003c3c,0x4d004d4d,0x8b008b8b,0xd100d1d1, + 0x5e005e5e,0xfa00fafa,0x64006464,0xcb00cbcb,0xb400b4b4,0x97009797,0xbe00bebe,0x2b002b2b, + 0xbc00bcbc,0x77007777,0x2e002e2e,0x03000303,0xd300d3d3,0x19001919,0x59005959,0xc100c1c1, + 0x1d001d1d,0x06000606,0x41004141,0x6b006b6b,0x55005555,0xf000f0f0,0x99009999,0x69006969, + 0xea00eaea,0x9c009c9c,0x18001818,0xae00aeae,0x63006363,0xdf00dfdf,0xe700e7e7,0xbb00bbbb, + 0x00000000,0x73007373,0x66006666,0xfb00fbfb,0x96009696,0x4c004c4c,0x85008585,0xe400e4e4, + 0x3a003a3a,0x09000909,0x45004545,0xaa00aaaa,0x0f000f0f,0xee00eeee,0x10001010,0xeb00ebeb, + 0x2d002d2d,0x7f007f7f,0xf400f4f4,0x29002929,0xac00acac,0xcf00cfcf,0xad00adad,0x91009191, + 0x8d008d8d,0x78007878,0xc800c8c8,0x95009595,0xf900f9f9,0x2f002f2f,0xce00cece,0xcd00cdcd, + 0x08000808,0x7a007a7a,0x88008888,0x38003838,0x5c005c5c,0x83008383,0x2a002a2a,0x28002828, + 0x47004747,0xdb00dbdb,0xb800b8b8,0xc700c7c7,0x93009393,0xa400a4a4,0x12001212,0x53005353, + 0xff00ffff,0x87008787,0x0e000e0e,0x31003131,0x36003636,0x21002121,0x58005858,0x48004848, + 0x01000101,0x8e008e8e,0x37003737,0x74007474,0x32003232,0xca00caca,0xe900e9e9,0xb100b1b1, + 0xb700b7b7,0xab00abab,0x0c000c0c,0xd700d7d7,0xc400c4c4,0x56005656,0x42004242,0x26002626, + 0x07000707,0x98009898,0x60006060,0xd900d9d9,0xb600b6b6,0xb900b9b9,0x11001111,0x40004040, + 0xec00ecec,0x20002020,0x8c008c8c,0xbd00bdbd,0xa000a0a0,0xc900c9c9,0x84008484,0x04000404, + 0x49004949,0x23002323,0xf100f1f1,0x4f004f4f,0x50005050,0x1f001f1f,0x13001313,0xdc00dcdc, + 0xd800d8d8,0xc000c0c0,0x9e009e9e,0x57005757,0xe300e3e3,0xc300c3c3,0x7b007b7b,0x65006565, + 0x3b003b3b,0x02000202,0x8f008f8f,0x3e003e3e,0xe800e8e8,0x25002525,0x92009292,0xe500e5e5, + 0x15001515,0xdd00dddd,0xfd00fdfd,0x17001717,0xa900a9a9,0xbf00bfbf,0xd400d4d4,0x9a009a9a, + 0x7e007e7e,0xc500c5c5,0x39003939,0x67006767,0xfe00fefe,0x76007676,0x9d009d9d,0x43004343, + 0xa700a7a7,0xe100e1e1,0xd000d0d0,0xf500f5f5,0x68006868,0xf200f2f2,0x1b001b1b,0x34003434, + 0x70007070,0x05000505,0xa300a3a3,0x8a008a8a,0xd500d5d5,0x79007979,0x86008686,0xa800a8a8, + 0x30003030,0xc600c6c6,0x51005151,0x4b004b4b,0x1e001e1e,0xa600a6a6,0x27002727,0xf600f6f6, + 0x35003535,0xd200d2d2,0x6e006e6e,0x24002424,0x16001616,0x82008282,0x5f005f5f,0xda00dada, + 0xe600e6e6,0x75007575,0xa200a2a2,0xef00efef,0x2c002c2c,0xb200b2b2,0x1c001c1c,0x9f009f9f, + 0x5d005d5d,0x6f006f6f,0x80008080,0x0a000a0a,0x72007272,0x44004444,0x9b009b9b,0x6c006c6c, + 0x90009090,0x0b000b0b,0x5b005b5b,0x33003333,0x7d007d7d,0x5a005a5a,0x52005252,0xf300f3f3, + 0x61006161,0xa100a1a1,0xf700f7f7,0xb000b0b0,0xd600d6d6,0x3f003f3f,0x7c007c7c,0x6d006d6d, + 0xed00eded,0x14001414,0xe000e0e0,0xa500a5a5,0x3d003d3d,0x22002222,0xb300b3b3,0xf800f8f8, + 0x89008989,0xde00dede,0x71007171,0x1a001a1a,0xaf00afaf,0xba00baba,0xb500b5b5,0x81008181 +}; + +CRYPTOPP_ALIGN_DATA(16) +CRYPTOPP_TABLE +const word32 X1[256]={ + 0x52520052,0x09090009,0x6a6a006a,0xd5d500d5,0x30300030,0x36360036,0xa5a500a5,0x38380038, + 0xbfbf00bf,0x40400040,0xa3a300a3,0x9e9e009e,0x81810081,0xf3f300f3,0xd7d700d7,0xfbfb00fb, + 0x7c7c007c,0xe3e300e3,0x39390039,0x82820082,0x9b9b009b,0x2f2f002f,0xffff00ff,0x87870087, + 0x34340034,0x8e8e008e,0x43430043,0x44440044,0xc4c400c4,0xdede00de,0xe9e900e9,0xcbcb00cb, + 0x54540054,0x7b7b007b,0x94940094,0x32320032,0xa6a600a6,0xc2c200c2,0x23230023,0x3d3d003d, + 0xeeee00ee,0x4c4c004c,0x95950095,0x0b0b000b,0x42420042,0xfafa00fa,0xc3c300c3,0x4e4e004e, + 0x08080008,0x2e2e002e,0xa1a100a1,0x66660066,0x28280028,0xd9d900d9,0x24240024,0xb2b200b2, + 0x76760076,0x5b5b005b,0xa2a200a2,0x49490049,0x6d6d006d,0x8b8b008b,0xd1d100d1,0x25250025, + 0x72720072,0xf8f800f8,0xf6f600f6,0x64640064,0x86860086,0x68680068,0x98980098,0x16160016, + 0xd4d400d4,0xa4a400a4,0x5c5c005c,0xcccc00cc,0x5d5d005d,0x65650065,0xb6b600b6,0x92920092, + 0x6c6c006c,0x70700070,0x48480048,0x50500050,0xfdfd00fd,0xeded00ed,0xb9b900b9,0xdada00da, + 0x5e5e005e,0x15150015,0x46460046,0x57570057,0xa7a700a7,0x8d8d008d,0x9d9d009d,0x84840084, + 0x90900090,0xd8d800d8,0xabab00ab,0x00000000,0x8c8c008c,0xbcbc00bc,0xd3d300d3,0x0a0a000a, + 0xf7f700f7,0xe4e400e4,0x58580058,0x05050005,0xb8b800b8,0xb3b300b3,0x45450045,0x06060006, + 0xd0d000d0,0x2c2c002c,0x1e1e001e,0x8f8f008f,0xcaca00ca,0x3f3f003f,0x0f0f000f,0x02020002, + 0xc1c100c1,0xafaf00af,0xbdbd00bd,0x03030003,0x01010001,0x13130013,0x8a8a008a,0x6b6b006b, + 0x3a3a003a,0x91910091,0x11110011,0x41410041,0x4f4f004f,0x67670067,0xdcdc00dc,0xeaea00ea, + 0x97970097,0xf2f200f2,0xcfcf00cf,0xcece00ce,0xf0f000f0,0xb4b400b4,0xe6e600e6,0x73730073, + 0x96960096,0xacac00ac,0x74740074,0x22220022,0xe7e700e7,0xadad00ad,0x35350035,0x85850085, + 0xe2e200e2,0xf9f900f9,0x37370037,0xe8e800e8,0x1c1c001c,0x75750075,0xdfdf00df,0x6e6e006e, + 0x47470047,0xf1f100f1,0x1a1a001a,0x71710071,0x1d1d001d,0x29290029,0xc5c500c5,0x89890089, + 0x6f6f006f,0xb7b700b7,0x62620062,0x0e0e000e,0xaaaa00aa,0x18180018,0xbebe00be,0x1b1b001b, + 0xfcfc00fc,0x56560056,0x3e3e003e,0x4b4b004b,0xc6c600c6,0xd2d200d2,0x79790079,0x20200020, + 0x9a9a009a,0xdbdb00db,0xc0c000c0,0xfefe00fe,0x78780078,0xcdcd00cd,0x5a5a005a,0xf4f400f4, + 0x1f1f001f,0xdddd00dd,0xa8a800a8,0x33330033,0x88880088,0x07070007,0xc7c700c7,0x31310031, + 0xb1b100b1,0x12120012,0x10100010,0x59590059,0x27270027,0x80800080,0xecec00ec,0x5f5f005f, + 0x60600060,0x51510051,0x7f7f007f,0xa9a900a9,0x19190019,0xb5b500b5,0x4a4a004a,0x0d0d000d, + 0x2d2d002d,0xe5e500e5,0x7a7a007a,0x9f9f009f,0x93930093,0xc9c900c9,0x9c9c009c,0xefef00ef, + 0xa0a000a0,0xe0e000e0,0x3b3b003b,0x4d4d004d,0xaeae00ae,0x2a2a002a,0xf5f500f5,0xb0b000b0, + 0xc8c800c8,0xebeb00eb,0xbbbb00bb,0x3c3c003c,0x83830083,0x53530053,0x99990099,0x61610061, + 0x17170017,0x2b2b002b,0x04040004,0x7e7e007e,0xbaba00ba,0x77770077,0xd6d600d6,0x26260026, + 0xe1e100e1,0x69690069,0x14140014,0x63630063,0x55550055,0x21210021,0x0c0c000c,0x7d7d007d +}; + +CRYPTOPP_ALIGN_DATA(16) +CRYPTOPP_TABLE +const word32 X2[256]={ + 0x30303000,0x68686800,0x99999900,0x1b1b1b00,0x87878700,0xb9b9b900,0x21212100,0x78787800, + 0x50505000,0x39393900,0xdbdbdb00,0xe1e1e100,0x72727200,0x09090900,0x62626200,0x3c3c3c00, + 0x3e3e3e00,0x7e7e7e00,0x5e5e5e00,0x8e8e8e00,0xf1f1f100,0xa0a0a000,0xcccccc00,0xa3a3a300, + 0x2a2a2a00,0x1d1d1d00,0xfbfbfb00,0xb6b6b600,0xd6d6d600,0x20202000,0xc4c4c400,0x8d8d8d00, + 0x81818100,0x65656500,0xf5f5f500,0x89898900,0xcbcbcb00,0x9d9d9d00,0x77777700,0xc6c6c600, + 0x57575700,0x43434300,0x56565600,0x17171700,0xd4d4d400,0x40404000,0x1a1a1a00,0x4d4d4d00, + 0xc0c0c000,0x63636300,0x6c6c6c00,0xe3e3e300,0xb7b7b700,0xc8c8c800,0x64646400,0x6a6a6a00, + 0x53535300,0xaaaaaa00,0x38383800,0x98989800,0x0c0c0c00,0xf4f4f400,0x9b9b9b00,0xededed00, + 0x7f7f7f00,0x22222200,0x76767600,0xafafaf00,0xdddddd00,0x3a3a3a00,0x0b0b0b00,0x58585800, + 0x67676700,0x88888800,0x06060600,0xc3c3c300,0x35353500,0x0d0d0d00,0x01010100,0x8b8b8b00, + 0x8c8c8c00,0xc2c2c200,0xe6e6e600,0x5f5f5f00,0x02020200,0x24242400,0x75757500,0x93939300, + 0x66666600,0x1e1e1e00,0xe5e5e500,0xe2e2e200,0x54545400,0xd8d8d800,0x10101000,0xcecece00, + 0x7a7a7a00,0xe8e8e800,0x08080800,0x2c2c2c00,0x12121200,0x97979700,0x32323200,0xababab00, + 0xb4b4b400,0x27272700,0x0a0a0a00,0x23232300,0xdfdfdf00,0xefefef00,0xcacaca00,0xd9d9d900, + 0xb8b8b800,0xfafafa00,0xdcdcdc00,0x31313100,0x6b6b6b00,0xd1d1d100,0xadadad00,0x19191900, + 0x49494900,0xbdbdbd00,0x51515100,0x96969600,0xeeeeee00,0xe4e4e400,0xa8a8a800,0x41414100, + 0xdadada00,0xffffff00,0xcdcdcd00,0x55555500,0x86868600,0x36363600,0xbebebe00,0x61616100, + 0x52525200,0xf8f8f800,0xbbbbbb00,0x0e0e0e00,0x82828200,0x48484800,0x69696900,0x9a9a9a00, + 0xe0e0e000,0x47474700,0x9e9e9e00,0x5c5c5c00,0x04040400,0x4b4b4b00,0x34343400,0x15151500, + 0x79797900,0x26262600,0xa7a7a700,0xdedede00,0x29292900,0xaeaeae00,0x92929200,0xd7d7d700, + 0x84848400,0xe9e9e900,0xd2d2d200,0xbababa00,0x5d5d5d00,0xf3f3f300,0xc5c5c500,0xb0b0b000, + 0xbfbfbf00,0xa4a4a400,0x3b3b3b00,0x71717100,0x44444400,0x46464600,0x2b2b2b00,0xfcfcfc00, + 0xebebeb00,0x6f6f6f00,0xd5d5d500,0xf6f6f600,0x14141400,0xfefefe00,0x7c7c7c00,0x70707000, + 0x5a5a5a00,0x7d7d7d00,0xfdfdfd00,0x2f2f2f00,0x18181800,0x83838300,0x16161600,0xa5a5a500, + 0x91919100,0x1f1f1f00,0x05050500,0x95959500,0x74747400,0xa9a9a900,0xc1c1c100,0x5b5b5b00, + 0x4a4a4a00,0x85858500,0x6d6d6d00,0x13131300,0x07070700,0x4f4f4f00,0x4e4e4e00,0x45454500, + 0xb2b2b200,0x0f0f0f00,0xc9c9c900,0x1c1c1c00,0xa6a6a600,0xbcbcbc00,0xececec00,0x73737300, + 0x90909000,0x7b7b7b00,0xcfcfcf00,0x59595900,0x8f8f8f00,0xa1a1a100,0xf9f9f900,0x2d2d2d00, + 0xf2f2f200,0xb1b1b100,0x00000000,0x94949400,0x37373700,0x9f9f9f00,0xd0d0d000,0x2e2e2e00, + 0x9c9c9c00,0x6e6e6e00,0x28282800,0x3f3f3f00,0x80808000,0xf0f0f000,0x3d3d3d00,0xd3d3d300, + 0x25252500,0x8a8a8a00,0xb5b5b500,0xe7e7e700,0x42424200,0xb3b3b300,0xc7c7c700,0xeaeaea00, + 0xf7f7f700,0x4c4c4c00,0x11111100,0x33333300,0x03030300,0xa2a2a200,0xacacac00,0x60606000 +}; + +CRYPTOPP_ALIGN_DATA(16) +CRYPTOPP_TABLE +const word32 KRK[3][4] = { + {0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0}, + {0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0}, + {0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e} +}; + +NAMESPACE_END +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/arm_simd.h b/external/ours/library/crypto/src/shared/original/arm_simd.h new file mode 100755 index 000000000..84298b9a5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/arm_simd.h @@ -0,0 +1,449 @@ +// arm_simd.h - written and placed in public domain by Jeffrey Walton + +/// \file arm_simd.h +/// \brief Support functions for ARM and vector operations + +#ifndef CRYPTOPP_ARM_SIMD_H +#define CRYPTOPP_ARM_SIMD_H + +#include "config.h" + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if (CRYPTOPP_ARM_CRC32_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \name CRC32 checksum +//@{ + +/// \brief CRC32 checksum +/// \param crc the starting crc value +/// \param val the value to checksum +/// \return CRC32 value +/// \since Crypto++ 8.6 +inline uint32_t CRC32B (uint32_t crc, uint8_t val) +{ +#if defined(_MSC_VER) + return __crc32b(crc, val); +#else + __asm__ ("crc32b %w0, %w0, %w1 \n\t" + :"+r" (crc) : "r" (val) ); + return crc; +#endif +} + +/// \brief CRC32 checksum +/// \param crc the starting crc value +/// \param val the value to checksum +/// \return CRC32 value +/// \since Crypto++ 8.6 +inline uint32_t CRC32W (uint32_t crc, uint32_t val) +{ +#if defined(_MSC_VER) + return __crc32w(crc, val); +#else + __asm__ ("crc32w %w0, %w0, %w1 \n\t" + :"+r" (crc) : "r" (val) ); + return crc; +#endif +} + +/// \brief CRC32 checksum +/// \param crc the starting crc value +/// \param vals the values to checksum +/// \return CRC32 value +/// \since Crypto++ 8.6 +inline uint32_t CRC32Wx4 (uint32_t crc, const uint32_t vals[4]) +{ +#if defined(_MSC_VER) + return __crc32w(__crc32w(__crc32w(__crc32w( + crc, vals[0]), vals[1]), vals[2]), vals[3]); +#else + __asm__ ("crc32w %w0, %w0, %w1 \n\t" + "crc32w %w0, %w0, %w2 \n\t" + "crc32w %w0, %w0, %w3 \n\t" + "crc32w %w0, %w0, %w4 \n\t" + :"+r" (crc) : "r" (vals[0]), "r" (vals[1]), + "r" (vals[2]), "r" (vals[3])); + return crc; +#endif +} + +//@} +/// \name CRC32-C checksum + +/// \brief CRC32-C checksum +/// \param crc the starting crc value +/// \param val the value to checksum +/// \return CRC32-C value +/// \since Crypto++ 8.6 +inline uint32_t CRC32CB (uint32_t crc, uint8_t val) +{ +#if defined(_MSC_VER) + return __crc32cb(crc, val); +#else + __asm__ ("crc32cb %w0, %w0, %w1 \n\t" + :"+r" (crc) : "r" (val) ); + return crc; +#endif +} + +/// \brief CRC32-C checksum +/// \param crc the starting crc value +/// \param val the value to checksum +/// \return CRC32-C value +/// \since Crypto++ 8.6 +inline uint32_t CRC32CW (uint32_t crc, uint32_t val) +{ +#if defined(_MSC_VER) + return __crc32cw(crc, val); +#else + __asm__ ("crc32cw %w0, %w0, %w1 \n\t" + :"+r" (crc) : "r" (val) ); + return crc; +#endif +} + +/// \brief CRC32-C checksum +/// \param crc the starting crc value +/// \param vals the values to checksum +/// \return CRC32-C value +/// \since Crypto++ 8.6 +inline uint32_t CRC32CWx4 (uint32_t crc, const uint32_t vals[4]) +{ +#if defined(_MSC_VER) + return __crc32cw(__crc32cw(__crc32cw(__crc32cw( + crc, vals[0]), vals[1]), vals[2]), vals[3]); +#else + __asm__ ("crc32cw %w0, %w0, %w1 \n\t" + "crc32cw %w0, %w0, %w2 \n\t" + "crc32cw %w0, %w0, %w3 \n\t" + "crc32cw %w0, %w0, %w4 \n\t" + :"+r" (crc) : "r" (vals[0]), "r" (vals[1]), + "r" (vals[2]), "r" (vals[3])); + return crc; +#endif +} +//@} +#endif // CRYPTOPP_ARM_CRC32_AVAILABLE + +#if (CRYPTOPP_ARM_PMULL_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \name Polynomial multiplication +//@{ + +/// \brief Polynomial multiplication +/// \param a the first value +/// \param b the second value +/// \return vector product +/// \details PMULL_00() performs polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x00). +/// The 0x00 indicates the low 64-bits of a and b +/// are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and +/// numbered 0. +/// \since Crypto++ 8.0 +inline uint64x2_t PMULL_00(const uint64x2_t a, const uint64x2_t b) +{ +#if defined(_MSC_VER) + const __n64 x = { vgetq_lane_u64(a, 0) }; + const __n64 y = { vgetq_lane_u64(b, 0) }; + return vmull_p64(x, y); +#elif defined(__GNUC__) + uint64x2_t r; + __asm__ ("pmull %0.1q, %1.1d, %2.1d \n\t" + :"=w" (r) : "w" (a), "w" (b) ); + return r; +#else + return (uint64x2_t)(vmull_p64( + vgetq_lane_u64(vreinterpretq_u64_u8(a),0), + vgetq_lane_u64(vreinterpretq_u64_u8(b),0))); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first value +/// \param b the second value +/// \return vector product +/// \details PMULL_01 performs() polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x01). +/// The 0x01 indicates the low 64-bits of a and high +/// 64-bits of b are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and +/// numbered 0. +/// \since Crypto++ 8.0 +inline uint64x2_t PMULL_01(const uint64x2_t a, const uint64x2_t b) +{ +#if defined(_MSC_VER) + const __n64 x = { vgetq_lane_u64(a, 0) }; + const __n64 y = { vgetq_lane_u64(b, 1) }; + return vmull_p64(x, y); +#elif defined(__GNUC__) + uint64x2_t r; + __asm__ ("pmull %0.1q, %1.1d, %2.1d \n\t" + :"=w" (r) : "w" (a), "w" (vget_high_u64(b)) ); + return r; +#else + return (uint64x2_t)(vmull_p64( + vgetq_lane_u64(vreinterpretq_u64_u8(a),0), + vgetq_lane_u64(vreinterpretq_u64_u8(b),1))); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first value +/// \param b the second value +/// \return vector product +/// \details PMULL_10() performs polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x10). +/// The 0x10 indicates the high 64-bits of a and low +/// 64-bits of b are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and +/// numbered 0. +/// \since Crypto++ 8.0 +inline uint64x2_t PMULL_10(const uint64x2_t a, const uint64x2_t b) +{ +#if defined(_MSC_VER) + const __n64 x = { vgetq_lane_u64(a, 1) }; + const __n64 y = { vgetq_lane_u64(b, 0) }; + return vmull_p64(x, y); +#elif defined(__GNUC__) + uint64x2_t r; + __asm__ ("pmull %0.1q, %1.1d, %2.1d \n\t" + :"=w" (r) : "w" (vget_high_u64(a)), "w" (b) ); + return r; +#else + return (uint64x2_t)(vmull_p64( + vgetq_lane_u64(vreinterpretq_u64_u8(a),1), + vgetq_lane_u64(vreinterpretq_u64_u8(b),0))); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first value +/// \param b the second value +/// \return vector product +/// \details PMULL_11() performs polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x11). +/// The 0x11 indicates the high 64-bits of a and b +/// are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and +/// numbered 0. +/// \since Crypto++ 8.0 +inline uint64x2_t PMULL_11(const uint64x2_t a, const uint64x2_t b) +{ +#if defined(_MSC_VER) + const __n64 x = { vgetq_lane_u64(a, 1) }; + const __n64 y = { vgetq_lane_u64(b, 1) }; + return vmull_p64(x, y); +#elif defined(__GNUC__) + uint64x2_t r; + __asm__ ("pmull2 %0.1q, %1.2d, %2.2d \n\t" + :"=w" (r) : "w" (a), "w" (b) ); + return r; +#else + return (uint64x2_t)(vmull_p64( + vgetq_lane_u64(vreinterpretq_u64_u8(a),1), + vgetq_lane_u64(vreinterpretq_u64_u8(b),1))); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first value +/// \param b the second value +/// \return vector product +/// \details PMULL() performs vmull_p64(). PMULL is provided as +/// GCC inline assembly due to Clang and lack of support for the intrinsic. +/// \since Crypto++ 8.0 +inline uint64x2_t PMULL(const uint64x2_t a, const uint64x2_t b) +{ +#if defined(_MSC_VER) + const __n64 x = { vgetq_lane_u64(a, 0) }; + const __n64 y = { vgetq_lane_u64(b, 0) }; + return vmull_p64(x, y); +#elif defined(__GNUC__) + uint64x2_t r; + __asm__ ("pmull %0.1q, %1.1d, %2.1d \n\t" + :"=w" (r) : "w" (a), "w" (b) ); + return r; +#else + return (uint64x2_t)(vmull_p64( + vgetq_lane_u64(vreinterpretq_u64_u8(a),0), + vgetq_lane_u64(vreinterpretq_u64_u8(b),0))); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first value +/// \param b the second value +/// \return vector product +/// \details PMULL_HIGH() performs vmull_high_p64(). PMULL_HIGH is provided as +/// GCC inline assembly due to Clang and lack of support for the intrinsic. +/// \since Crypto++ 8.0 +inline uint64x2_t PMULL_HIGH(const uint64x2_t a, const uint64x2_t b) +{ +#if defined(_MSC_VER) + const __n64 x = { vgetq_lane_u64(a, 1) }; + const __n64 y = { vgetq_lane_u64(b, 1) }; + return vmull_p64(x, y); +#elif defined(__GNUC__) + uint64x2_t r; + __asm__ ("pmull2 %0.1q, %1.2d, %2.2d \n\t" + :"=w" (r) : "w" (a), "w" (b) ); + return r; +#else + return (uint64x2_t)(vmull_p64( + vgetq_lane_u64(vreinterpretq_u64_u8(a),1), + vgetq_lane_u64(vreinterpretq_u64_u8(b),1)))); +#endif +} + +/// \brief Vector extraction +/// \param a the first value +/// \param b the second value +/// \param c the byte count +/// \return vector +/// \details VEXT_U8() extracts the first c bytes of vector +/// a and the remaining bytes in b. VEXT_U8 is provided +/// as GCC inline assembly due to Clang and lack of support for the intrinsic. +/// \since Crypto++ 8.0 +inline uint64x2_t VEXT_U8(uint64x2_t a, uint64x2_t b, unsigned int c) +{ +#if defined(_MSC_VER) + return vreinterpretq_u64_u8(vextq_u8( + vreinterpretq_u8_u64(a), vreinterpretq_u8_u64(b), c)); +#else + uint64x2_t r; + __asm__ ("ext %0.16b, %1.16b, %2.16b, %3 \n\t" + :"=w" (r) : "w" (a), "w" (b), "I" (c) ); + return r; +#endif +} + +/// \brief Vector extraction +/// \tparam C the byte count +/// \param a the first value +/// \param b the second value +/// \return vector +/// \details VEXT_U8() extracts the first C bytes of vector +/// a and the remaining bytes in b. VEXT_U8 is provided +/// as GCC inline assembly due to Clang and lack of support for the intrinsic. +/// \since Crypto++ 8.0 +template +inline uint64x2_t VEXT_U8(uint64x2_t a, uint64x2_t b) +{ + // https://github.com/weidai11/cryptopp/issues/366 +#if defined(_MSC_VER) + return vreinterpretq_u64_u8(vextq_u8( + vreinterpretq_u8_u64(a), vreinterpretq_u8_u64(b), C)); +#else + uint64x2_t r; + __asm__ ("ext %0.16b, %1.16b, %2.16b, %3 \n\t" + :"=w" (r) : "w" (a), "w" (b), "I" (C) ); + return r; +#endif +//@} +} + +#endif // CRYPTOPP_ARM_PMULL_AVAILABLE + +#if CRYPTOPP_ARM_SHA3_AVAILABLE || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \name ARMv8.2 operations +//@{ + +/// \brief Three-way XOR +/// \param a the first value +/// \param b the second value +/// \param c the third value +/// \return three-way exclusive OR of the values +/// \details VEOR3() performs veor3q_u64(). VEOR3 is provided as GCC inline assembly due +/// to Clang and lack of support for the intrinsic. +/// \details VEOR3 requires ARMv8.2. +/// \since Crypto++ 8.6 +inline uint64x2_t VEOR3(uint64x2_t a, uint64x2_t b, uint64x2_t c) +{ +#if defined(_MSC_VER) + return veor3q_u64(a, b, c); +#else + uint64x2_t r; + __asm__ ("eor3 %0.16b, %1.16b, %2.16b, %3.16b \n\t" + :"=w" (r) : "w" (a), "w" (b), "w" (c)); + return r; +#endif +} + +/// \brief XOR and rotate +/// \param a the first value +/// \param b the second value +/// \param c the third value +/// \return two-way exclusive OR of the values, then rotated by imm6 +/// \details VXARQ() performs vxarq_u64(). VXARQ is provided as GCC inline assembly due +/// to Clang and lack of support for the intrinsic. +/// \details VXARQ requires ARMv8.2. +/// \since Crypto++ 8.6 +inline uint64x2_t VXAR(uint64x2_t a, uint64x2_t b, const int imm6) +{ +#if defined(_MSC_VER) + return vxarq_u64(a, b, imm6); +#else + uint64x2_t r; + __asm__ ("xar %0.2d, %1.2d, %2.2d, %3 \n\t" + :"=w" (r) : "w" (a), "w" (b), "I" (imm6)); + return r; +#endif +} + +/// \brief XOR and rotate +/// \tparam C the rotate amount +/// \param a the first value +/// \param b the second value +/// \return two-way exclusive OR of the values, then rotated by C +/// \details VXARQ() performs vxarq_u64(). VXARQ is provided as GCC inline assembly due +/// to Clang and lack of support for the intrinsic. +/// \details VXARQ requires ARMv8.2. +/// \since Crypto++ 8.6 +template +inline uint64x2_t VXAR(uint64x2_t a, uint64x2_t b) +{ +#if defined(_MSC_VER) + return vxarq_u64(a, b, C); +#else + uint64x2_t r; + __asm__ ("xar %0.2d, %1.2d, %2.2d, %3 \n\t" + :"=w" (r) : "w" (a), "w" (b), "I" (C)); + return r; +#endif +} + +/// \brief XOR and rotate +/// \param a the first value +/// \param b the second value +/// \return two-way exclusive OR of the values, then rotated 1-bit +/// \details VRAX1() performs vrax1q_u64(). VRAX1 is provided as GCC inline assembly due +/// to Clang and lack of support for the intrinsic. +/// \details VRAX1 requires ARMv8.2. +/// \since Crypto++ 8.6 +inline uint64x2_t VRAX1(uint64x2_t a, uint64x2_t b) +{ +#if defined(_MSC_VER) + return vrax1q_u64(a, b); +#else + uint64x2_t r; + __asm__ ("rax1 %0.2d, %1.2d, %2.2d \n\t" + :"=w" (r) : "w" (a), "w" (b)); + return r; +#endif +} +//@} +#endif // CRYPTOPP_ARM_SHA3_AVAILABLE + +#endif // CRYPTOPP_ARM_SIMD_H diff --git a/external/ours/library/crypto/src/shared/original/asn.cpp b/external/ours/library/crypto/src/shared/original/asn.cpp new file mode 100755 index 000000000..d3ceef9dd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/asn.cpp @@ -0,0 +1,717 @@ +// asn.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cryptlib.h" +#include "asn.h" +#include "misc.h" + +#include +#include +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +size_t DERLengthEncode(BufferedTransformation &bt, lword length) +{ + size_t i=0; + if (length <= 0x7f) + { + bt.Put(byte(length)); + i++; + } + else + { + bt.Put(byte(BytePrecision(length) | 0x80)); + i++; + for (int j=BytePrecision(length); j; --j) + { + bt.Put(byte(length >> (j-1)*8)); + i++; + } + } + return i; +} + +bool BERLengthDecode(BufferedTransformation &bt, lword &length, bool &definiteLength) +{ + byte b; + + if (!bt.Get(b)) + return false; + + if (!(b & 0x80)) + { + definiteLength = true; + length = b; + } + else + { + unsigned int lengthBytes = b & 0x7f; + + if (lengthBytes == 0) + { + definiteLength = false; + return true; + } + + definiteLength = true; + length = 0; + while (lengthBytes--) + { + if (length >> (8*(sizeof(length)-1))) + BERDecodeError(); // length about to overflow + + if (!bt.Get(b)) + return false; + + length = (length << 8) | b; + } + } + return true; +} + +bool BERLengthDecode(BufferedTransformation &bt, size_t &length) +{ + lword lw = 0; + bool definiteLength = false; + if (!BERLengthDecode(bt, lw, definiteLength)) + BERDecodeError(); + if (!SafeConvert(lw, length)) + BERDecodeError(); + return definiteLength; +} + +void DEREncodeNull(BufferedTransformation &out) +{ + out.Put(TAG_NULL); + out.Put(0); +} + +void BERDecodeNull(BufferedTransformation &in) +{ + byte b; + if (!in.Get(b) || b != TAG_NULL) + BERDecodeError(); + size_t length; + if (!BERLengthDecode(in, length) || length != 0) + BERDecodeError(); +} + +/// ASN Strings +size_t DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen) +{ + bt.Put(OCTET_STRING); + size_t lengthBytes = DERLengthEncode(bt, strLen); + bt.Put(str, strLen); + return 1+lengthBytes+strLen; +} + +size_t DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str) +{ + return DEREncodeOctetString(bt, ConstBytePtr(str), BytePtrSize(str)); +} + +size_t BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str) +{ + byte b; + if (!bt.Get(b) || b != OCTET_STRING) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + if (bc > bt.MaxRetrievable()) // Issue 346 + BERDecodeError(); + + str.New(bc); + if (bc != bt.Get(BytePtr(str), bc)) + BERDecodeError(); + return bc; +} + +size_t BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str) +{ + byte b; + if (!bt.Get(b) || b != OCTET_STRING) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + if (bc > bt.MaxRetrievable()) // Issue 346 + BERDecodeError(); + + bt.TransferTo(str, bc); + return bc; +} + +size_t DEREncodeTextString(BufferedTransformation &bt, const byte* str, size_t strLen, byte asnTag) +{ + bt.Put(asnTag); + size_t lengthBytes = DERLengthEncode(bt, strLen); + bt.Put(str, strLen); + return 1+lengthBytes+strLen; +} + +size_t DEREncodeTextString(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag) +{ + return DEREncodeTextString(bt, ConstBytePtr(str), BytePtrSize(str), asnTag); +} + +size_t DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag) +{ + return DEREncodeTextString(bt, ConstBytePtr(str), BytePtrSize(str), asnTag); +} + +size_t BERDecodeTextString(BufferedTransformation &bt, SecByteBlock &str, byte asnTag) +{ + byte b; + if (!bt.Get(b) || b != asnTag) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + if (bc > bt.MaxRetrievable()) // Issue 346 + BERDecodeError(); + + str.resize(bc); + if (bc != bt.Get(BytePtr(str), BytePtrSize(str))) + BERDecodeError(); + + return bc; +} + +size_t BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag) +{ + byte b; + if (!bt.Get(b) || b != asnTag) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + if (bc > bt.MaxRetrievable()) // Issue 346 + BERDecodeError(); + + str.resize(bc); + if (bc != bt.Get(BytePtr(str), BytePtrSize(str))) + BERDecodeError(); + + return bc; +} + +size_t DEREncodeDate(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag) +{ + bt.Put(asnTag); + size_t lengthBytes = DERLengthEncode(bt, str.size()); + bt.Put(ConstBytePtr(str), BytePtrSize(str)); + return 1+lengthBytes+str.size(); +} + +size_t BERDecodeDate(BufferedTransformation &bt, SecByteBlock &str, byte asnTag) +{ + byte b; + if (!bt.Get(b) || b != asnTag) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + if (bc > bt.MaxRetrievable()) // Issue 346 + BERDecodeError(); + + str.resize(bc); + if (bc != bt.Get(BytePtr(str), BytePtrSize(str))) + BERDecodeError(); + + return bc; +} + +size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits) +{ + bt.Put(BIT_STRING); + size_t lengthBytes = DERLengthEncode(bt, strLen+1); + bt.Put((byte)unusedBits); + bt.Put(str, strLen); + return 2+lengthBytes+strLen; +} + +size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits) +{ + byte b; + if (!bt.Get(b) || b != BIT_STRING) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + if (bc == 0) + BERDecodeError(); + if (bc > bt.MaxRetrievable()) // Issue 346 + BERDecodeError(); + + // X.690, 8.6.2.2: "The number [of unused bits] shall be in the range zero to seven" + byte unused; + if (!bt.Get(unused) || unused > 7) + BERDecodeError(); + unusedBits = unused; + str.resize(bc-1); + if ((bc-1) != bt.Get(BytePtr(str), bc-1)) + BERDecodeError(); + return bc-1; +} + +void DERReencode(BufferedTransformation &source, BufferedTransformation &dest) +{ + byte tag; + source.Peek(tag); + BERGeneralDecoder decoder(source, tag); + DERGeneralEncoder encoder(dest, tag); + if (decoder.IsDefiniteLength()) + decoder.TransferTo(encoder, decoder.RemainingLength()); + else + { + while (!decoder.EndReached()) + DERReencode(decoder, encoder); + } + decoder.MessageEnd(); + encoder.MessageEnd(); +} + +size_t BERDecodePeekLength(const BufferedTransformation &bt) +{ + lword count = (std::min)(bt.MaxRetrievable(), static_cast(16)); + if (count == 0) return 0; + + ByteQueue tagAndLength; + bt.CopyTo(tagAndLength, count); + + // Skip tag + tagAndLength.Skip(1); + + // BERLengthDecode fails for indefinite length. + size_t length; + if (!BERLengthDecode(tagAndLength, length)) + return 0; + + return length; +} + +void OID::EncodeValue(BufferedTransformation &bt, word32 v) +{ + for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) + bt.Put((byte)(0x80 | ((v >> i) & 0x7f))); + bt.Put((byte)(v & 0x7f)); +} + +size_t OID::DecodeValue(BufferedTransformation &bt, word32 &v) +{ + byte b; + size_t i=0; + v = 0; + while (true) + { + if (!bt.Get(b)) + BERDecodeError(); + i++; + if (v >> (8*sizeof(v)-7)) // v about to overflow + BERDecodeError(); + v <<= 7; + v += b & 0x7f; + if (!(b & 0x80)) + return i; + } +} + +void OID::DEREncode(BufferedTransformation &bt) const +{ + CRYPTOPP_ASSERT(m_values.size() >= 2); + ByteQueue temp; + temp.Put(byte(m_values[0] * 40 + m_values[1])); + for (size_t i=2; i 0) + { + word32 v; + size_t valueLen = DecodeValue(bt, v); + if (valueLen > length) + BERDecodeError(); + m_values.push_back(v); + length -= valueLen; + } +} + +void OID::BERDecodeAndCheck(BufferedTransformation &bt) const +{ + OID oid(bt); + if (*this != oid) + BERDecodeError(); +} + +std::ostream& OID::Print(std::ostream& out) const +{ + std::ostringstream oss; + for (size_t i = 0; i < m_values.size(); ++i) + { + oss << m_values[i]; + if (i+1 < m_values.size()) + oss << "."; + } + return out << oss.str(); +} + +inline BufferedTransformation & EncodedObjectFilter::CurrentTarget() +{ + if (m_flags & PUT_OBJECTS) + return *AttachedTransformation(); + else + return TheBitBucket(); +} + +void EncodedObjectFilter::Put(const byte *inString, size_t length) +{ + if (m_nCurrentObject == m_nObjects) + { + AttachedTransformation()->Put(inString, length); + return; + } + + LazyPutter lazyPutter(m_queue, inString, length); + + while (m_queue.AnyRetrievable()) + { + switch (m_state) + { + case IDENTIFIER: + if (!m_queue.Get(m_id)) + return; + m_queue.TransferTo(CurrentTarget(), 1); + m_state = LENGTH; + // fall through + case LENGTH: + { + byte b; + if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0) + { + m_queue.TransferTo(CurrentTarget(), 1); + m_level--; + m_state = IDENTIFIER; + break; + } + ByteQueue::Walker walker(m_queue); + bool definiteLength = false; + if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength)) + return; + m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition()); + if (!((m_id & CONSTRUCTED) || definiteLength)) + BERDecodeError(); + if (!definiteLength) + { + if (!(m_id & CONSTRUCTED)) + BERDecodeError(); + m_level++; + m_state = IDENTIFIER; + break; + } + m_state = BODY; + } + // fall through + case BODY: + m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining); + + if (m_lengthRemaining == 0) + m_state = IDENTIFIER; + // fall through + case TAIL: + case ALL_DONE: + default: ; + } + + if (m_state == IDENTIFIER && m_level == 0) + { + // just finished processing a level 0 object + ++m_nCurrentObject; + + if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT) + AttachedTransformation()->MessageEnd(); + + if (m_nCurrentObject == m_nObjects) + { + if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS) + AttachedTransformation()->MessageEnd(); + + if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS) + AttachedTransformation()->MessageSeriesEnd(); + + m_queue.TransferAllTo(*AttachedTransformation()); + return; + } + } + } +} + +BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue) + : m_inQueue(inQueue), m_length(0), m_finished(false) +{ + Init(DefaultTag); +} + +BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag) + : m_inQueue(inQueue), m_length(0), m_finished(false) +{ + Init(asnTag); +} + +BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) + : m_inQueue(inQueue), m_length(0), m_finished(false) +{ + Init(asnTag); +} + +void BERGeneralDecoder::Init(byte asnTag) +{ + byte b; + if (!m_inQueue.Get(b) || b != asnTag) + BERDecodeError(); + + if (!BERLengthDecode(m_inQueue, m_length, m_definiteLength)) + BERDecodeError(); + + if (!m_definiteLength && !(asnTag & CONSTRUCTED)) + BERDecodeError(); // cannot be primitive and have indefinite length +} + +BERGeneralDecoder::~BERGeneralDecoder() +{ + try // avoid throwing in destructor + { + if (!m_finished) + MessageEnd(); + } + catch (const Exception&) + { + // CRYPTOPP_ASSERT(0); + } +} + +bool BERGeneralDecoder::EndReached() const +{ + if (m_definiteLength) + return m_length == 0; + else + { // check end-of-content octets + word16 i; + return (m_inQueue.PeekWord16(i)==2 && i==0); + } +} + +byte BERGeneralDecoder::PeekByte() const +{ + byte b; + if (!Peek(b)) + BERDecodeError(); + return b; +} + +void BERGeneralDecoder::CheckByte(byte check) +{ + byte b; + if (!Get(b) || b != check) + BERDecodeError(); +} + +void BERGeneralDecoder::MessageEnd() +{ + m_finished = true; + if (m_definiteLength) + { + if (m_length != 0) + BERDecodeError(); + } + else + { // remove end-of-content octets + word16 i; + if (m_inQueue.GetWord16(i) != 2 || i != 0) + BERDecodeError(); + } +} + +size_t BERGeneralDecoder::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (m_definiteLength && transferBytes > m_length) + transferBytes = m_length; + size_t blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking); + ReduceLength(transferBytes); + return blockedBytes; +} + +size_t BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + if (m_definiteLength) + end = STDMIN(m_length, end); + return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking); +} + +lword BERGeneralDecoder::ReduceLength(lword delta) +{ + if (m_definiteLength) + { + if (m_length < delta) + BERDecodeError(); + m_length -= delta; + } + return delta; +} + +DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue) + : m_outQueue(outQueue), m_asnTag(DefaultTag), m_finished(false) +{ +} + +DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag) + : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false) +{ +} + +DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag) + : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false) +{ +} + +DERGeneralEncoder::~DERGeneralEncoder() +{ + try // avoid throwing in constructor + { + if (!m_finished) + MessageEnd(); + } + catch (const Exception&) + { + CRYPTOPP_ASSERT(0); + } +} + +void DERGeneralEncoder::MessageEnd() +{ + m_finished = true; + lword length = CurrentSize(); + m_outQueue.Put(m_asnTag); + DERLengthEncode(m_outQueue, length); + TransferTo(m_outQueue); +} + +// ************************************************************* + +void X509PublicKey::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder subjectPublicKeyInfo(bt); + BERSequenceDecoder algorithm(subjectPublicKeyInfo); + GetAlgorithmID().BERDecodeAndCheck(algorithm); + bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); + subjectPublicKey.CheckByte(0); // unused bits + BERDecodePublicKey(subjectPublicKey, parametersPresent, (size_t)subjectPublicKey.RemainingLength()); + subjectPublicKey.MessageEnd(); + subjectPublicKeyInfo.MessageEnd(); +} + +void X509PublicKey::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder subjectPublicKeyInfo(bt); + + DERSequenceEncoder algorithm(subjectPublicKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + DEREncodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); + subjectPublicKey.Put(0); // unused bits + DEREncodePublicKey(subjectPublicKey); + subjectPublicKey.MessageEnd(); + + subjectPublicKeyInfo.MessageEnd(); +} + +void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder privateKeyInfo(bt); + word32 version; + BERDecodeUnsigned(privateKeyInfo, version, INTEGER, 0, 0); // check version + + BERSequenceDecoder algorithm(privateKeyInfo); + GetAlgorithmID().BERDecodeAndCheck(algorithm); + bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); + BERDecodePrivateKey(octetString, parametersPresent, (size_t)privateKeyInfo.RemainingLength()); + octetString.MessageEnd(); + + if (!privateKeyInfo.EndReached()) + BERDecodeOptionalAttributes(privateKeyInfo); + privateKeyInfo.MessageEnd(); +} + +void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKeyInfo(bt); + DEREncodeUnsigned(privateKeyInfo, 0); // version + + DERSequenceEncoder algorithm(privateKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + DEREncodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING); + DEREncodePrivateKey(octetString); + octetString.MessageEnd(); + + DEREncodeOptionalAttributes(privateKeyInfo); + privateKeyInfo.MessageEnd(); +} + +void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt) +{ + DERReencode(bt, m_optionalAttributes); +} + +void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const +{ + m_optionalAttributes.CopyTo(bt); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/asn.h b/external/ours/library/crypto/src/shared/original/asn.h new file mode 100755 index 000000000..dce819485 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/asn.h @@ -0,0 +1,965 @@ +// asn.h - originally written and placed in the public domain by Wei Dai + +/// \file asn.h +/// \brief Classes and functions for working with ANS.1 objects + +#ifndef CRYPTOPP_ASN_H +#define CRYPTOPP_ASN_H + +#include "cryptlib.h" +#include "filters.h" +#include "smartptr.h" +#include "stdcpp.h" +#include "queue.h" +#include "misc.h" + +#include + +// Issue 340 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief ASN.1 types +/// \note These tags are not complete +enum ASNTag +{ + /// \brief ASN.1 Boolean + BOOLEAN = 0x01, + /// \brief ASN.1 Integer + INTEGER = 0x02, + /// \brief ASN.1 Bit string + BIT_STRING = 0x03, + /// \brief ASN.1 Octet string + OCTET_STRING = 0x04, + /// \brief ASN.1 Null + TAG_NULL = 0x05, + /// \brief ASN.1 Object identifier + OBJECT_IDENTIFIER = 0x06, + /// \brief ASN.1 Object descriptor + OBJECT_DESCRIPTOR = 0x07, + /// \brief ASN.1 External reference + EXTERNAL = 0x08, + /// \brief ASN.1 Real integer + REAL = 0x09, + /// \brief ASN.1 Enumerated value + ENUMERATED = 0x0a, + /// \brief ASN.1 UTF-8 string + UTF8_STRING = 0x0c, + /// \brief ASN.1 Sequence + SEQUENCE = 0x10, + /// \brief ASN.1 Set + SET = 0x11, + /// \brief ASN.1 Numeric string + NUMERIC_STRING = 0x12, + /// \brief ASN.1 Printable string + PRINTABLE_STRING = 0x13, + /// \brief ASN.1 T61 string + T61_STRING = 0x14, + /// \brief ASN.1 Videotext string + VIDEOTEXT_STRING = 0x15, + /// \brief ASN.1 IA5 string + IA5_STRING = 0x16, + /// \brief ASN.1 UTC time + UTC_TIME = 0x17, + /// \brief ASN.1 Generalized time + GENERALIZED_TIME = 0x18, + /// \brief ASN.1 Graphic string + GRAPHIC_STRING = 0x19, + /// \brief ASN.1 Visible string + VISIBLE_STRING = 0x1a, + /// \brief ASN.1 General string + GENERAL_STRING = 0x1b, + /// \brief ASN.1 Universal string + UNIVERSAL_STRING = 0x1c, + /// \brief ASN.1 BMP string + BMP_STRING = 0x1e +}; + +/// \brief ASN.1 flags +/// \note These flags are not complete +enum ASNIdFlag +{ + /// \brief ASN.1 Universal class + UNIVERSAL = 0x00, + // DATA = 0x01, + // HEADER = 0x02, + /// \brief ASN.1 Primitive flag + PRIMITIVE = 0x00, + /// \brief ASN.1 Constructed flag + CONSTRUCTED = 0x20, + /// \brief ASN.1 Application class + APPLICATION = 0x40, + /// \brief ASN.1 Context specific class + CONTEXT_SPECIFIC = 0x80, + /// \brief ASN.1 Private class + PRIVATE = 0xc0 +}; + +/// \brief Raises a BERDecodeErr +inline void BERDecodeError() {throw BERDecodeErr();} + +/// \brief Exception thrown when an unknown object identifier is encountered +class CRYPTOPP_DLL UnknownOID : public BERDecodeErr +{ +public: + /// \brief Construct an UnknownOID + UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {} + /// \brief Construct an UnknownOID + /// \param err error message to use for the execption + UnknownOID(const char *err) : BERDecodeErr(err) {} +}; + +/// \brief DER encode a length +/// \param bt BufferedTransformation object for writing +/// \param length the size to encode +/// \return the number of octets used for the encoding +CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &bt, lword length); + +/// \brief BER decode a length +/// \param bt BufferedTransformation object for reading +/// \param length the decoded size +/// \return true if the value was decoded +/// \throw BERDecodeError if the value fails to decode or is too large for size_t +/// \details BERLengthDecode() returns false if the encoding is indefinite length. +CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &bt, size_t &length); + +/// \brief DER encode NULL +/// \param bt BufferedTransformation object for writing +CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &bt); + +/// \brief BER decode NULL +/// \param bt BufferedTransformation object for reading +CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &bt); + +/// \brief DER encode octet string +/// \param bt BufferedTransformation object for writing +/// \param str the string to encode +/// \param strLen the length of the string +/// \return the number of octets used for the encoding +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen); + +/// \brief DER encode octet string +/// \param bt BufferedTransformation object for reading +/// \param str the string to encode +/// \return the number of octets used for the encoding +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str); + +/// \brief BER decode octet string +/// \param bt BufferedTransformation object for reading +/// \param str the decoded string +/// \return the number of octets used for the encoding +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str); + +/// \brief BER decode octet string +/// \param bt BufferedTransformation object for reading +/// \param str the decoded string +/// \return the number of octets used for the encoding +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str); + +/// \brief DER encode text string +/// \param bt BufferedTransformation object for writing +/// \param str the string to encode +/// \param strLen the length of the string, in bytes +/// \param asnTag the ASN.1 identifier +/// \return the number of octets used for the encoding +/// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING +/// \since Crypto++ 8.3 +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const byte* str, size_t strLen, byte asnTag); + +/// \brief DER encode text string +/// \param bt BufferedTransformation object for writing +/// \param str the string to encode +/// \param asnTag the ASN.1 identifier +/// \return the number of octets used for the encoding +/// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING +/// \since Crypto++ 8.3 +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag); + +/// \brief DER encode text string +/// \param bt BufferedTransformation object for writing +/// \param str the string to encode +/// \param asnTag the ASN.1 identifier +/// \return the number of octets used for the encoding +/// \details DEREncodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING +/// \since Crypto++ 6.0 +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag); + +/// \brief BER decode text string +/// \param bt BufferedTransformation object for reading +/// \param str the string to decode +/// \param asnTag the ASN.1 identifier +/// \details BERDecodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING +/// \since Crypto++ 8.3 +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &bt, SecByteBlock &str, byte asnTag); + +/// \brief BER decode text string +/// \param bt BufferedTransformation object for reading +/// \param str the string to decode +/// \param asnTag the ASN.1 identifier +/// \details BERDecodeTextString() can be used for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING +/// \since Crypto++ 6.0 +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag); + +/// \brief DER encode date +/// \param bt BufferedTransformation object for writing +/// \param str the date to encode +/// \param asnTag the ASN.1 identifier +/// \return the number of octets used for the encoding +/// \details BERDecodeDate() can be used for UTC_TIME and GENERALIZED_TIME +/// \since Crypto++ 8.3 +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeDate(BufferedTransformation &bt, const SecByteBlock &str, byte asnTag); + +/// \brief BER decode date +/// \param bt BufferedTransformation object for reading +/// \param str the date to decode +/// \param asnTag the ASN.1 identifier +/// \details BERDecodeDate() can be used for UTC_TIME and GENERALIZED_TIME +/// \since Crypto++ 8.3 +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeDate(BufferedTransformation &bt, SecByteBlock &str, byte asnTag); + +/// \brief DER encode bit string +/// \param bt BufferedTransformation object for writing +/// \param str the string to encode +/// \param strLen the length of the string +/// \param unusedBits the number of unused bits +/// \return the number of octets used for the encoding +/// \details The caller is responsible for shifting octets if unusedBits is +/// not 0. For example, to DER encode a web server X.509 key usage, the 101b +/// bit mask is often used (digitalSignature and keyEncipherment). In this +/// case str is one octet with a value=0xa0 and unusedBits=5. The +/// value 0xa0 is 101b << 5. +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0); + +/// \brief DER decode bit string +/// \param bt BufferedTransformation object for reading +/// \param str the decoded string +/// \param unusedBits the number of unused bits +/// \details The caller is responsible for shifting octets if unusedBits is +/// not 0. For example, to DER encode a web server X.509 key usage, the 101b +/// bit mask is often used (digitalSignature and keyEncipherment). In this +/// case str is one octet with a value=0xa0 and unusedBits=5. The +/// value 0xa0 is 101b << 5. +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits); + +/// \brief BER decode and DER re-encode +/// \param bt BufferedTransformation object for writing +/// \param dest BufferedTransformation object +CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &bt, BufferedTransformation &dest); + +/// \brief BER decode size +/// \param bt BufferedTransformation object for reading +/// \return the length of the ASN.1 value, in bytes +/// \details BERDecodePeekLength() determines the length of a value without +/// consuming octets in the stream. The stream must use definite length encoding. +/// If indefinite length encoding is used or an error occurs, then 0 is returned. +/// \since Crypto++ 8.3 +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodePeekLength(const BufferedTransformation &bt); + +/// \brief Object Identifier +class CRYPTOPP_DLL OID +{ +public: + virtual ~OID() {} + + /// \brief Construct an OID + OID() {} + + /// \brief Construct an OID + /// \param v value to initialize the OID + OID(word32 v) : m_values(1, v) {} + + /// \brief Construct an OID + /// \param bt BufferedTransformation object + OID(BufferedTransformation &bt) { + BERDecode(bt); + } + + /// \brief Append a value to an OID + /// \param rhs the value to append + inline OID & operator+=(word32 rhs) { + m_values.push_back(rhs); return *this; + } + + /// \brief DER encode this OID + /// \param bt BufferedTransformation object + void DEREncode(BufferedTransformation &bt) const; + + /// \brief BER decode an OID + /// \param bt BufferedTransformation object + void BERDecode(BufferedTransformation &bt); + + /// \brief BER decode an OID + /// \param bt BufferedTransformation object + /// \throw BERDecodeErr() if decoded value doesn't match an expected OID + /// \details BERDecodeAndCheck() can be used to parse an OID and verify it matches an expected. + ///
+	///   BERSequenceDecoder key(bt);
+	///   ...
+	///   BERSequenceDecoder algorithm(key);
+	///   GetAlgorithmID().BERDecodeAndCheck(algorithm);
+	/// 
+ void BERDecodeAndCheck(BufferedTransformation &bt) const; + + /// \brief Determine if OID is empty + /// \return true if OID has 0 elements, false otherwise + /// \since Crypto++ 8.0 + bool Empty() const { + return m_values.empty(); + } + + /// \brief Retrieve OID value array + /// \return OID value vector + /// \since Crypto++ 8.0 + const std::vector& GetValues() const { + return m_values; + } + + /// \brief Print an OID + /// \param out ostream object + /// \return ostream reference + /// \details Print() writes the OID in a customary format, like + /// 1.2.840.113549.1.1.11. The caller is reposnsible to convert the + /// OID to a friendly name, like sha256WithRSAEncryption. + /// \since Crypto++ 8.3 + std::ostream& Print(std::ostream& out) const; + +protected: + friend bool operator==(const OID &lhs, const OID &rhs); + friend bool operator!=(const OID &lhs, const OID &rhs); + friend bool operator<(const OID &lhs, const OID &rhs); + friend bool operator<=(const OID &lhs, const OID &rhs); + friend bool operator>=(const OID &lhs, const OID &rhs); + + std::vector m_values; + +private: + static void EncodeValue(BufferedTransformation &bt, word32 v); + static size_t DecodeValue(BufferedTransformation &bt, word32 &v); +}; + +/// \brief ASN.1 encoded object filter +class EncodedObjectFilter : public Filter +{ +public: + enum Flag {PUT_OBJECTS=1, PUT_MESSANGE_END_AFTER_EACH_OBJECT=2, PUT_MESSANGE_END_AFTER_ALL_OBJECTS=4, PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS=8}; + enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state; + + virtual ~EncodedObjectFilter() {} + + /// \brief Construct an EncodedObjectFilter + /// \param attachment a BufferedTrasformation to attach to this object + /// \param nObjects the number of objects + /// \param flags bitwise OR of EncodedObjectFilter::Flag + EncodedObjectFilter(BufferedTransformation *attachment = NULLPTR, unsigned int nObjects = 1, word32 flags = 0); + + /// \brief Input a byte buffer for processing + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + void Put(const byte *inString, size_t length); + + unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;} + unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];} + +private: + BufferedTransformation & CurrentTarget(); + + ByteQueue m_queue; + std::vector m_positions; + lword m_lengthRemaining; + word32 m_nObjects, m_nCurrentObject, m_level, m_flags; + byte m_id; +}; + +/// \brief BER General Decoder +class CRYPTOPP_DLL BERGeneralDecoder : public Store +{ +public: + /// \brief Default ASN.1 tag + enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)}; + + virtual ~BERGeneralDecoder(); + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \details BERGeneralDecoder uses DefaultTag + explicit BERGeneralDecoder(BufferedTransformation &inQueue); + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \param asnTag ASN.1 tag + explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag); + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \param asnTag ASN.1 tag + explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag); + + /// \brief Determine length encoding + /// \return true if the ASN.1 object is definite length encoded, false otherwise + bool IsDefiniteLength() const { + return m_definiteLength; + } + + /// \brief Determine remaining length + /// \return number of octets that remain to be consumed + /// \details RemainingLength() is only valid if IsDefiniteLength() + /// returns true. + lword RemainingLength() const { + CRYPTOPP_ASSERT(m_definiteLength); + return IsDefiniteLength() ? m_length : 0; + } + + /// \brief Determine end of stream + /// \return true if all octets have been consumed, false otherwise + bool EndReached() const; + + /// \brief Determine next octet + /// \return next octet in the stream + /// \details PeekByte does not consume the octet. + /// \throw BERDecodeError if there are no octets remaining + byte PeekByte() const; + + /// \brief Determine next octet + /// \details CheckByte reads the next byte in the stream and verifies + /// the octet matches b. + /// \throw BERDecodeError if the next octet is not b + void CheckByte(byte b); + + /// \brief Transfer bytes to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param transferBytes the number of bytes to transfer + /// \param channel the channel on which the transfer should occur + /// \param blocking specifies whether the object should block when + /// processing input + /// \return the number of bytes that remain in the transfer block + /// (i.e., bytes not transferred) + /// \details TransferTo2() removes bytes and moves + /// them to the destination. Transfer begins at the index position + /// in the current stream, and not from an absolute position in the + /// stream. + /// \details transferBytes is an \a IN and \a OUT parameter. When + /// the call is made, transferBytes is the requested size of the + /// transfer. When the call returns, transferBytes is the number + /// of bytes that were transferred. + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + + /// \brief Copy bytes to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param begin the 0-based index of the first byte to copy in + /// the stream + /// \param end the 0-based index of the last byte to copy in + /// the stream + /// \param channel the channel on which the transfer should occur + /// \param blocking specifies whether the object should block when + /// processing input + /// \return the number of bytes that remain in the copy block + /// (i.e., bytes not copied) + /// \details CopyRangeTo2 copies bytes to the + /// destination. The bytes are not removed from this object. Copying + /// begins at the index position in the current stream, and not from + /// an absolute position in the stream. + /// \details begin is an \a IN and \a OUT parameter. When the call is + /// made, begin is the starting position of the copy. When the call + /// returns, begin is the position of the first byte that was \a not + /// copied (which may be different than end). begin can be used for + /// subsequent calls to CopyRangeTo2(). + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + + /// \brief Signals the end of messages to the object + /// \details Call this to denote end of sequence + void MessageEnd(); + +protected: + BufferedTransformation &m_inQueue; + lword m_length; + bool m_finished, m_definiteLength; + +private: + void Init(byte asnTag); + void StoreInitialize(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters); CRYPTOPP_ASSERT(false);} + lword ReduceLength(lword delta); +}; + +/// \brief DER General Encoder +class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue +{ +public: + /// \brief Default ASN.1 tag + enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)}; + + virtual ~DERGeneralEncoder(); + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \details DERGeneralEncoder uses DefaultTag + explicit DERGeneralEncoder(BufferedTransformation &outQueue); + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \param asnTag ASN.1 tag + explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag); + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \param asnTag ASN.1 tag + explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag); + + /// \brief Signals the end of messages to the object + /// \details Call this to denote end of sequence + void MessageEnd(); + +private: + BufferedTransformation &m_outQueue; + byte m_asnTag; + bool m_finished; +}; + +/// \brief BER Sequence Decoder +class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder +{ +public: + /// \brief Default ASN.1 tag + enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)}; + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \details BERSequenceDecoder uses DefaultTag + explicit BERSequenceDecoder(BufferedTransformation &inQueue) + : BERGeneralDecoder(inQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \param asnTag ASN.1 tag + explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag) + : BERGeneralDecoder(inQueue, asnTag) {} + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \details BERSequenceDecoder uses DefaultTag + explicit BERSequenceDecoder(BERSequenceDecoder &inQueue) + : BERGeneralDecoder(inQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \param asnTag ASN.1 tag + explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag) + : BERGeneralDecoder(inQueue, asnTag) {} +}; + +/// \brief DER Sequence Encoder +class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder +{ +public: + /// \brief Default ASN.1 tag + enum {DefaultTag = SEQUENCE | EnumToInt(CONSTRUCTED)}; + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \details DERSequenceEncoder uses DefaultTag + explicit DERSequenceEncoder(BufferedTransformation &outQueue) + : DERGeneralEncoder(outQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \param asnTag ASN.1 tag + explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag) + : DERGeneralEncoder(outQueue, asnTag) {} + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \details DERSequenceEncoder uses DefaultTag + explicit DERSequenceEncoder(DERSequenceEncoder &outQueue) + : DERGeneralEncoder(outQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \param asnTag ASN.1 tag + explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag) + : DERGeneralEncoder(outQueue, asnTag) {} +}; + +/// \brief BER Set Decoder +class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder +{ +public: + /// \brief Default ASN.1 tag + enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)}; + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \details BERSetDecoder uses DefaultTag + explicit BERSetDecoder(BufferedTransformation &inQueue) + : BERGeneralDecoder(inQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \param asnTag ASN.1 tag + explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag) + : BERGeneralDecoder(inQueue, asnTag) {} + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \details BERSetDecoder uses DefaultTag + explicit BERSetDecoder(BERSetDecoder &inQueue) + : BERGeneralDecoder(inQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 decoder + /// \param inQueue input byte queue + /// \param asnTag ASN.1 tag + explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag) + : BERGeneralDecoder(inQueue, asnTag) {} +}; + +/// \brief DER Set Encoder +class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder +{ +public: + /// \brief Default ASN.1 tag + enum {DefaultTag = SET | EnumToInt(CONSTRUCTED)}; + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \details DERSetEncoder uses DefaultTag + explicit DERSetEncoder(BufferedTransformation &outQueue) + : DERGeneralEncoder(outQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \param asnTag ASN.1 tag + explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag) + : DERGeneralEncoder(outQueue, asnTag) {} + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \details DERSetEncoder uses DefaultTag + explicit DERSetEncoder(DERSetEncoder &outQueue) + : DERGeneralEncoder(outQueue, DefaultTag) {} + + /// \brief Construct an ASN.1 encoder + /// \param outQueue output byte queue + /// \param asnTag ASN.1 tag + explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag) + : DERGeneralEncoder(outQueue, asnTag) {} +}; + +/// \brief Optional data encoder and decoder +/// \tparam T class or type +template +class ASNOptional : public member_ptr +{ +public: + /// \brief BER decode optional data + /// \param seqDecoder sequence with the optional ASN.1 data + /// \param tag ASN.1 tag to match as optional data + /// \param mask the mask to apply when matching the tag + /// \sa ASNTag and ASNIdFlag + void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED) + { + byte b; + if (seqDecoder.Peek(b) && (b & mask) == tag) + reset(new T(seqDecoder)); + } + + /// \brief DER encode optional data + /// \param out BufferedTransformation object + void DEREncode(BufferedTransformation &out) + { + if (this->get() != NULLPTR) + this->get()->DEREncode(out); + } +}; + +/// \brief Encode and decode ASN.1 objects with additional information +/// \tparam BASE base class or type +/// \details Encodes and decodes public keys, private keys and group +/// parameters with OID identifying the algorithm or scheme. +template +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE +{ +public: + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \details Save() will write the OID associated with algorithm or scheme. + /// In the case of public and private keys, this function writes the + /// subjectPublicKeyInfo and privateKeyInfo parts. + void Save(BufferedTransformation &bt) const + {BEREncode(bt);} + + /// \brief BER decode ASN.1 object + /// \param bt BufferedTransformation object + void Load(BufferedTransformation &bt) + {BERDecode(bt);} +}; + +/// \brief Encodes and decodes subjectPublicKeyInfo +class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial +{ +public: + virtual ~X509PublicKey() {} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + /// \brief Retrieves the OID of the algorithm + /// \return OID of the algorithm + virtual OID GetAlgorithmID() const =0; + + /// \brief Decode algorithm parameters + /// \param bt BufferedTransformation object + /// \sa BERDecodePublicKey, RFC + /// 2459, section 7.3.1 + virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) + {BERDecodeNull(bt); return false;} + + /// \brief Encode algorithm parameters + /// \param bt BufferedTransformation object + /// \sa DEREncodePublicKey, RFC + /// 2459, section 7.3.1 + virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const + {DEREncodeNull(bt); return false;} + + /// \brief Decode subjectPublicKey part of subjectPublicKeyInfo + /// \param bt BufferedTransformation object + /// \param parametersPresent flag indicating if algorithm parameters are present + /// \param size number of octets to read for the parameters, in bytes + /// \details BERDecodePublicKey() the decodes subjectPublicKey part of + /// subjectPublicKeyInfo, without the BIT STRING header. + /// \details When parametersPresent = true then BERDecodePublicKey() calls + /// BERDecodeAlgorithmParameters() to parse algorithm parameters. + /// \sa BERDecodeAlgorithmParameters + virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0; + + /// \brief Encode subjectPublicKey part of subjectPublicKeyInfo + /// \param bt BufferedTransformation object + /// \details DEREncodePublicKey() encodes the subjectPublicKey part of + /// subjectPublicKeyInfo, without the BIT STRING header. + /// \sa DEREncodeAlgorithmParameters + virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0; +}; + +/// \brief Encodes and Decodes privateKeyInfo +class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial +{ +public: + virtual ~PKCS8PrivateKey() {} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + /// \brief Retrieves the OID of the algorithm + /// \return OID of the algorithm + virtual OID GetAlgorithmID() const =0; + + /// \brief Decode optional parameters + /// \param bt BufferedTransformation object + /// \sa BERDecodePrivateKey, RFC + /// 2459, section 7.3.1 + virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) + {BERDecodeNull(bt); return false;} + + /// \brief Encode optional parameters + /// \param bt BufferedTransformation object + /// \sa DEREncodePrivateKey, RFC + /// 2459, section 7.3.1 + virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const + {DEREncodeNull(bt); return false;} + + /// \brief Decode privateKey part of privateKeyInfo + /// \param bt BufferedTransformation object + /// \param parametersPresent flag indicating if algorithm parameters are present + /// \param size number of octets to read for the parameters, in bytes + /// \details BERDecodePrivateKey() the decodes privateKey part of privateKeyInfo, + /// without the OCTET STRING header. + /// \details When parametersPresent = true then BERDecodePrivateKey() calls + /// BERDecodeAlgorithmParameters() to parse algorithm parameters. + /// \sa BERDecodeAlgorithmParameters + virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0; + + /// \brief Encode privateKey part of privateKeyInfo + /// \param bt BufferedTransformation object + /// \details DEREncodePrivateKey() encodes the privateKey part of privateKeyInfo, + /// without the OCTET STRING header. + /// \sa DEREncodeAlgorithmParameters + virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0; + + /// \brief Decode optional attributes + /// \param bt BufferedTransformation object + /// \details BERDecodeOptionalAttributes() decodes optional attributes including + /// context-specific tag. + /// \sa BERDecodeAlgorithmParameters, DEREncodeOptionalAttributes + /// \note default implementation stores attributes to be output using + /// DEREncodeOptionalAttributes + virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt); + + /// \brief Encode optional attributes + /// \param bt BufferedTransformation object + /// \details DEREncodeOptionalAttributes() encodes optional attributes including + /// context-specific tag. + /// \sa BERDecodeAlgorithmParameters + virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const; + +protected: + ByteQueue m_optionalAttributes; +}; + +// ******************************************************** + +/// \brief DER Encode unsigned value +/// \tparam T class or type +/// \param out BufferedTransformation object +/// \param w unsigned value to encode +/// \param asnTag the ASN.1 identifier +/// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM +template +size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER) +{ + byte buf[sizeof(w)+1]; + unsigned int bc; + if (asnTag == BOOLEAN) + { + buf[sizeof(w)] = w ? 0xff : 0; + bc = 1; + } + else + { + buf[0] = 0; + for (unsigned int i=0; i> (sizeof(w)-1-i)*8); + bc = sizeof(w); + while (bc > 1 && buf[sizeof(w)+1-bc] == 0) + --bc; + if (buf[sizeof(w)+1-bc] & 0x80) + ++bc; + } + out.Put(asnTag); + size_t lengthBytes = DERLengthEncode(out, bc); + out.Put(buf+sizeof(w)+1-bc, bc); + return 1+lengthBytes+bc; +} + +/// \brief BER Decode unsigned value +/// \tparam T fundamental C++ type +/// \param in BufferedTransformation object +/// \param w the decoded value +/// \param asnTag the ASN.1 identifier +/// \param minValue the minimum expected value +/// \param maxValue the maximum expected value +/// \throw BERDecodeErr() if the value cannot be parsed or the decoded value is not within range. +/// \details DEREncodeUnsigned() can be used with INTEGER, BOOLEAN, and ENUM +template +void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER, + T minValue = 0, T maxValue = T(0xffffffff)) +{ + byte b; + if (!in.Get(b) || b != asnTag) + BERDecodeError(); + + size_t bc; + bool definite = BERLengthDecode(in, bc); + if (!definite) + BERDecodeError(); + if (bc > in.MaxRetrievable()) // Issue 346 + BERDecodeError(); + if (asnTag == BOOLEAN && bc != 1) // X.690, 8.2.1 + BERDecodeError(); + if ((asnTag == INTEGER || asnTag == ENUMERATED) && bc == 0) // X.690, 8.3.1 and 8.4 + BERDecodeError(); + + SecByteBlock buf(bc); + + if (bc != in.Get(buf, bc)) + BERDecodeError(); + + // This consumes leading 0 octets. According to X.690, 8.3.2, it could be non-conforming behavior. + // X.690, 8.3.2 says "the bits of the first octet and bit 8 of the second octet ... (a) shall + // not all be ones and (b) shall not all be zeros ... These rules ensure that an integer value + // is always encoded in the smallest possible number of octet". + // We invented AER (Alternate Encoding Rules), which is more relaxed than BER, CER, and DER. + const byte *ptr = buf; + while (bc > sizeof(w) && *ptr == 0) + { + bc--; + ptr++; + } + if (bc > sizeof(w)) + BERDecodeError(); + + w = 0; + for (unsigned int i=0; i maxValue) + BERDecodeError(); +} + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING +/// \brief Compare two OIDs for equality +/// \param lhs the first OID +/// \param rhs the second OID +/// \return true if the OIDs are equal, false otherwise +inline bool operator==(const OID &lhs, const OID &rhs); +/// \brief Compare two OIDs for inequality +/// \param lhs the first OID +/// \param rhs the second OID +/// \return true if the OIDs are not equal, false otherwise +inline bool operator!=(const OID &lhs, const OID &rhs); +/// \brief Compare two OIDs for ordering +/// \param lhs the first OID +/// \param rhs the second OID +/// \return true if the first OID is less than the second OID, false otherwise +/// \details operator<() calls std::lexicographical_compare() on each element in the array of values. +inline bool operator<(const OID &lhs, const OID &rhs); +/// \brief Compare two OIDs for ordering +/// \param lhs the first OID +/// \param rhs the second OID +/// \return true if the first OID is less than or equal to the second OID, false otherwise +/// \details operator<=() is implemented in terms of operator==() and operator<(). +/// \since Crypto++ 8.3 +inline bool operator<=(const OID &lhs, const OID &rhs); +/// \brief Compare two OIDs for ordering +/// \param lhs the first OID +/// \param rhs the second OID +/// \return true if the first OID is greater than or equal to the second OID, false otherwise +/// \details operator>=() is implemented in terms of operator<(). +/// \since Crypto++ 8.3 +inline bool operator>=(const OID &lhs, const OID &rhs); +/// \brief Append a value to an OID +/// \param lhs the OID +/// \param rhs the value to append +inline OID operator+(const OID &lhs, unsigned long rhs); +/// \brief Print a OID value +/// \param out the output stream +/// \param oid the OID +inline std::ostream& operator<<(std::ostream& out, const OID &oid) + { return oid.Print(out); } +#else +inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return lhs.m_values == rhs.m_values;} +inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return lhs.m_values != rhs.m_values;} +inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());} +inline bool operator<=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return lhs=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return ! (lhs= blockSize) + { + memcpy(data+num, input, blockSize-num); + AuthenticateBlocks(data, blockSize); + input += (blockSize-num); + len -= (blockSize-num); + num = 0; + // drop through and do the rest + } + else + { + memcpy(data+num, input, len); + num += (unsigned int)len; + return; + } + } + + // now process the input data in blocks of blockSize bytes and save the leftovers to m_data + if (len >= blockSize) + { + size_t leftOver = AuthenticateBlocks(input, len); + input += (len - leftOver); + len = leftOver; + } + + if (data && len) + memcpy(data, input, len); + num = (unsigned int)len; +} + +void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) +{ + m_bufferedDataLength = 0; + m_state = State_Start; + + this->SetKeyWithoutResync(userKey, keylength, params); + m_state = State_KeySet; + + size_t length; + const byte *iv = GetIVAndThrowIfInvalid(params, length); + if (iv) + Resynchronize(iv, (int)length); +} + +void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length) +{ + if (m_state < State_KeySet) + throw BadState(AlgorithmName(), "Resynchronize", "key is set"); + + m_bufferedDataLength = 0; + m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0; + m_state = State_KeySet; + + Resync(iv, this->ThrowIfInvalidIVLength(length)); + m_state = State_IVSet; +} + +void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length) +{ + // Part of original authenc.cpp code. Don't remove it. + if (length == 0) {return;} + + switch (m_state) + { + case State_Start: + case State_KeySet: + throw BadState(AlgorithmName(), "Update", "setting key and IV"); + case State_IVSet: + AuthenticateData(input, length); + m_totalHeaderLength += length; + break; + case State_AuthUntransformed: + case State_AuthTransformed: + AuthenticateLastConfidentialBlock(); + m_bufferedDataLength = 0; + m_state = State_AuthFooter; + // fall through + case State_AuthFooter: + AuthenticateData(input, length); + m_totalFooterLength += length; + break; + default: + CRYPTOPP_ASSERT(false); + } +} + +void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length) +{ + if (m_state >= State_IVSet && length > MaxMessageLength()-m_totalMessageLength) + throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum"); + m_totalMessageLength += length; + +reswitch: + switch (m_state) + { + case State_Start: + case State_KeySet: + throw BadState(AlgorithmName(), "ProcessData", "setting key and IV"); + case State_AuthFooter: + throw BadState(AlgorithmName(), "ProcessData was called after footer input has started"); + case State_IVSet: + AuthenticateLastHeaderBlock(); + m_bufferedDataLength = 0; + m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed; + goto reswitch; + case State_AuthUntransformed: + AuthenticateData(inString, length); + AccessSymmetricCipher().ProcessData(outString, inString, length); + break; + case State_AuthTransformed: + AccessSymmetricCipher().ProcessData(outString, inString, length); + AuthenticateData(outString, length); + break; + default: + CRYPTOPP_ASSERT(false); + } +} + +void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize) +{ + // https://github.com/weidai11/cryptopp/issues/954 + this->ThrowIfInvalidTruncatedSize(macSize); + + if (m_totalHeaderLength > MaxHeaderLength()) + throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength())); + + if (m_totalFooterLength > MaxFooterLength()) + { + if (MaxFooterLength() == 0) + throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted"); + else + throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength())); + } + + switch (m_state) + { + case State_Start: + case State_KeySet: + throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV"); + + case State_IVSet: + AuthenticateLastHeaderBlock(); + m_bufferedDataLength = 0; + // fall through + + case State_AuthUntransformed: + case State_AuthTransformed: + AuthenticateLastConfidentialBlock(); + m_bufferedDataLength = 0; + // fall through + + case State_AuthFooter: + AuthenticateLastFooterBlock(mac, macSize); + m_bufferedDataLength = 0; + break; + + default: + CRYPTOPP_ASSERT(false); + } + + m_state = State_KeySet; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/authenc.h b/external/ours/library/crypto/src/shared/original/authenc.h new file mode 100755 index 000000000..980de0b4e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/authenc.h @@ -0,0 +1,87 @@ +// authenc.h - originally written and placed in the public domain by Wei Dai + +/// \file +/// \brief Classes for authenticated encryption modes of operation +/// \details Authenticated encryption (AE) schemes combine confidentiality and authenticity +/// into a single mode of operation They gained traction in the early 2000's because manually +/// combining them was error prone for the typical developer. Around that time, the desire to +/// authenticate but not ecrypt additional data (AAD) was also identified. When both features +/// are available from a scheme, the system is referred to as an AEAD scheme. +/// \details Crypto++ provides four authenticated encryption modes of operation - CCM, EAX, GCM +/// and OCB mode. All modes derive from AuthenticatedSymmetricCipherBase() and the +/// motivation for the API, like calling AAD a "header", can be found in Bellare, +/// Rogaway and Wagner's The EAX +/// Mode of Operation. The EAX paper suggested a basic API to help standardize AEAD +/// schemes in software and promote adoption of the modes. +/// \sa Authenticated +/// Encryption on the Crypto++ wiki. +/// \since Crypto++ 5.6.0 + +#ifndef CRYPTOPP_AUTHENC_H +#define CRYPTOPP_AUTHENC_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Base class for authenticated encryption modes of operation +/// \details AuthenticatedSymmetricCipherBase() serves as a base implementation for one direction +/// (encryption or decryption) of a stream cipher or block cipher mode with authentication. +/// \details Crypto++ provides four authenticated encryption modes of operation - CCM, EAX, GCM +/// and OCB mode. All modes derive from AuthenticatedSymmetricCipherBase() and the +/// motivation for the API, like calling AAD a "header", can be found in Bellare, +/// Rogaway and Wagner's The EAX +/// Mode of Operation. The EAX paper suggested a basic API to help standardize AEAD +/// schemes in software and promote adoption of the modes. +/// \sa Authenticated +/// Encryption on the Crypto++ wiki. +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipherBase : public AuthenticatedSymmetricCipher +{ +public: + AuthenticatedSymmetricCipherBase() : m_totalHeaderLength(0), m_totalMessageLength(0), + m_totalFooterLength(0), m_bufferedDataLength(0), m_state(State_Start) {} + + // StreamTransformation interface + bool IsRandomAccess() const {return false;} + bool IsSelfInverting() const {return true;} + + void SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); + void Restart() {if (m_state > State_KeySet) m_state = State_KeySet;} + void Resynchronize(const byte *iv, int length=-1); + void Update(const byte *input, size_t length); + void ProcessData(byte *outString, const byte *inString, size_t length); + void TruncatedFinal(byte *mac, size_t macSize); + +protected: + void UncheckedSetKey(const byte * key, unsigned int length,const CryptoPP::NameValuePairs ¶ms) + {CRYPTOPP_UNUSED(key), CRYPTOPP_UNUSED(length), CRYPTOPP_UNUSED(params); CRYPTOPP_ASSERT(false);} + + void AuthenticateData(const byte *data, size_t len); + const SymmetricCipher & GetSymmetricCipher() const + {return const_cast(this)->AccessSymmetricCipher();} + + virtual SymmetricCipher & AccessSymmetricCipher() =0; + virtual bool AuthenticationIsOnPlaintext() const =0; + virtual unsigned int AuthenticationBlockSize() const =0; + virtual void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) =0; + virtual void Resync(const byte *iv, size_t len) =0; + virtual size_t AuthenticateBlocks(const byte *data, size_t len) =0; + virtual void AuthenticateLastHeaderBlock() =0; + virtual void AuthenticateLastConfidentialBlock() {} + virtual void AuthenticateLastFooterBlock(byte *mac, size_t macSize) =0; + + // State_AuthUntransformed: authentication is applied to plain text (Authenticate-then-Encrypt) + // State_AuthTransformed: authentication is applied to cipher text (Encrypt-then-Authenticate) + enum State {State_Start, State_KeySet, State_IVSet, State_AuthUntransformed, State_AuthTransformed, State_AuthFooter}; + + AlignedSecByteBlock m_buffer; + lword m_totalHeaderLength, m_totalMessageLength, m_totalFooterLength; + unsigned int m_bufferedDataLength; + State m_state; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/base32.cpp b/external/ours/library/crypto/src/shared/original/base32.cpp new file mode 100755 index 000000000..2f0c4c7f6 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/base32.cpp @@ -0,0 +1,97 @@ +// base32.cpp - written and placed in the public domain by Frank Palazzolo, based on hex.cpp by Wei Dai +// extended hex alphabet added by JW in November, 2017. + +#include "pch.h" +#include "base32.h" + +NAMESPACE_BEGIN(CryptoPP) +ANONYMOUS_NAMESPACE_BEGIN + +const byte s_stdUpper[] = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789"; +const byte s_stdLower[] = "abcdefghijkmnpqrstuvwxyz23456789"; +const byte s_hexUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; +const byte s_hexLower[] = "0123456789abcdefghijklmnopqrstuv"; + +const int s_array[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, -1, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, -1, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +const int s_hexArray[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +ANONYMOUS_NAMESPACE_END + +void Base32Encoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_stdUpper[0] : &s_stdLower[0], false)(Name::Log2Base(), 5, true))); +} + +void Base32Decoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 5, true))); +} + +// Unrolled initialization, http://github.com/weidai11/cryptopp/issues/376 +const int *Base32Decoder::GetDefaultDecodingLookupArray() +{ + return s_array; +} + +void Base32HexEncoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_hexUpper[0] : &s_hexLower[0], false)(Name::Log2Base(), 5, true))); +} + +void Base32HexDecoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 5, true))); +} + +// Unrolled initialization, http://github.com/weidai11/cryptopp/issues/376 +const int *Base32HexDecoder::GetDefaultDecodingLookupArray() +{ + return s_hexArray; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/base32.h b/external/ours/library/crypto/src/shared/original/base32.h new file mode 100755 index 000000000..4eeae43ce --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/base32.h @@ -0,0 +1,158 @@ +// base32.h - written and placed in the public domain by Frank Palazzolo, based on hex.cpp by Wei Dai +// extended hex alphabet added by JW in November, 2017. + +/// \file base32.h +/// \brief Classes for Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder + +#ifndef CRYPTOPP_BASE32_H +#define CRYPTOPP_BASE32_H + +#include "cryptlib.h" +#include "basecode.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Base32 encodes data using DUDE encoding +/// \details Converts data to base32 using DUDE encoding. The default code is based on Differential Unicode Domain Encoding (DUDE) (draft-ietf-idn-dude-02.txt). +/// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder +class Base32Encoder : public SimpleProxyFilter +{ +public: + /// \brief Construct a Base32Encoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \param uppercase a flag indicating uppercase output + /// \param groupSize the size of the grouping + /// \param separator the separator to use between groups + /// \param terminator the terminator appeand after processing + /// \details Base32Encoder() constructs a default encoder. The constructor lacks fields for padding and + /// line breaks. You must use IsolatedInitialize() to change the default padding character or suppress it. + /// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder + Base32Encoder(BufferedTransformation *attachment = NULLPTR, bool uppercase = true, int groupSize = 0, const std::string &separator = ":", const std::string &terminator = "") + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), groupSize)(Name::Separator(), ConstByteArrayParameter(separator))(Name::Terminator(), ConstByteArrayParameter(terminator))); + } + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + /// \details The following code modifies the padding and line break parameters for an encoder: + ///
+	///     Base32Encoder encoder;
+	///     AlgorithmParameters params = MakeParameters(Pad(), false)(InsertLineBreaks(), false);
+	///     encoder.IsolatedInitialize(params);
+ /// \details You can change the encoding to RFC 4648, Base + /// 32 Encoding with Extended Hex Alphabet by performing the following: + ///
+	///     Base32Encoder encoder;
+	///     const byte ALPHABET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+	///     AlgorithmParameters params = MakeParameters(Name::EncodingLookupArray(),(const byte *)ALPHABET);
+	///     encoder.IsolatedInitialize(params);
+ /// \details If you change the encoding alphabet, then you will need to change the decoding alphabet \a and + /// the decoder's lookup table. + /// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +/// \brief Base32 decodes data using DUDE encoding +/// \details Converts data from base32 using DUDE encoding. The default code is based on Differential Unicode Domain Encoding (DUDE) (draft-ietf-idn-dude-02.txt). +/// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder +class Base32Decoder : public BaseN_Decoder +{ +public: + /// \brief Construct a Base32Decoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \sa IsolatedInitialize() for an example of modifying a Base32Decoder after construction. + Base32Decoder(BufferedTransformation *attachment = NULLPTR) + : BaseN_Decoder(GetDefaultDecodingLookupArray(), 5, attachment) {} + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + /// \details You can change the encoding to RFC 4648, Base + /// 32 Encoding with Extended Hex Alphabet by performing the following: + ///
+	///     int lookup[256];
+	///     const byte ALPHABET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+	///     Base32Decoder::InitializeDecodingLookupArray(lookup, ALPHABET, 32, true /*insensitive*/);
+	///
+	///     Base32Decoder decoder;
+	///     AlgorithmParameters params = MakeParameters(Name::DecodingLookupArray(),(const int *)lookup);
+	///     decoder.IsolatedInitialize(params);
+ /// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + /// \brief Provides the default decoding lookup table + /// \return default decoding lookup table + static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); +}; + +/// \brief Base32 encodes data using extended hex +/// \details Converts data to base32 using extended hex alphabet. The alphabet is different than Base32Encoder. +/// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder, RFC 4648, Base 32 Encoding with Extended Hex Alphabet. +/// \since Crypto++ 6.0 +class Base32HexEncoder : public SimpleProxyFilter +{ +public: + /// \brief Construct a Base32HexEncoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \param uppercase a flag indicating uppercase output + /// \param groupSize the size of the grouping + /// \param separator the separator to use between groups + /// \param terminator the terminator appeand after processing + /// \details Base32HexEncoder() constructs a default encoder. The constructor lacks fields for padding and + /// line breaks. You must use IsolatedInitialize() to change the default padding character or suppress it. + /// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder + Base32HexEncoder(BufferedTransformation *attachment = NULLPTR, bool uppercase = true, int groupSize = 0, const std::string &separator = ":", const std::string &terminator = "") + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), groupSize)(Name::Separator(), ConstByteArrayParameter(separator))(Name::Terminator(), ConstByteArrayParameter(terminator))); + } + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + /// \details The following code modifies the padding and line break parameters for an encoder: + ///
+	///     Base32HexEncoder encoder;
+	///     AlgorithmParameters params = MakeParameters(Pad(), false)(InsertLineBreaks(), false);
+	///     encoder.IsolatedInitialize(params);
+ void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +/// \brief Base32 decodes data using extended hex +/// \details Converts data from base32 using extended hex alphabet. The alphabet is different than Base32Decoder. +/// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder, RFC 4648, Base 32 Encoding with Extended Hex Alphabet. +/// \since Crypto++ 6.0 +class Base32HexDecoder : public BaseN_Decoder +{ +public: + /// \brief Construct a Base32HexDecoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder + Base32HexDecoder(BufferedTransformation *attachment = NULLPTR) + : BaseN_Decoder(GetDefaultDecodingLookupArray(), 5, attachment) {} + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + /// \brief Provides the default decoding lookup table + /// \return default decoding lookup table + static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/base64.cpp b/external/ours/library/crypto/src/shared/original/base64.cpp new file mode 100755 index 000000000..9c899cbc2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/base64.cpp @@ -0,0 +1,111 @@ +// base64.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" +#include "base64.h" + +NAMESPACE_BEGIN(CryptoPP) +ANONYMOUS_NAMESPACE_BEGIN + +const byte s_stdVec[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +const byte s_urlVec[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; +const byte s_padding = '='; +const int s_stdArray[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; +const int s_urlArray[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +ANONYMOUS_NAMESPACE_END + +void Base64Encoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool insertLineBreaks = parameters.GetValueWithDefault(Name::InsertLineBreaks(), true); + int maxLineLength = parameters.GetIntValueWithDefault(Name::MaxLineLength(), 72); + + const char *lineBreak = insertLineBreaks ? "\n" : ""; + + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), &s_stdVec[0], false) + (Name::PaddingByte(), s_padding) + (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0) + (Name::Separator(), ConstByteArrayParameter(lineBreak)) + (Name::Terminator(), ConstByteArrayParameter(lineBreak)) + (Name::Log2Base(), 6, true))); +} + +void Base64URLEncoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool insertLineBreaks = parameters.GetValueWithDefault(Name::InsertLineBreaks(), true); + int maxLineLength = parameters.GetIntValueWithDefault(Name::MaxLineLength(), 72); + + const char *lineBreak = insertLineBreaks ? "\n" : ""; + + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), &s_urlVec[0], false) + (Name::PaddingByte(), s_padding) + (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0) + (Name::Separator(), ConstByteArrayParameter(lineBreak)) + (Name::Terminator(), ConstByteArrayParameter(lineBreak)) + (Name::Log2Base(), 6, true))); +} + +void Base64Decoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDecodingLookupArray(), false)(Name::Log2Base(), 6, true))); +} + +const int *Base64Decoder::GetDecodingLookupArray() +{ + return s_stdArray; +} + +void Base64URLDecoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDecodingLookupArray(), false)(Name::Log2Base(), 6, true))); +} + +// Unrolled initialization, http://github.com/weidai11/cryptopp/issues/376 +const int *Base64URLDecoder::GetDecodingLookupArray() +{ + return s_urlArray; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/base64.h b/external/ours/library/crypto/src/shared/original/base64.h new file mode 100755 index 000000000..5defc3740 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/base64.h @@ -0,0 +1,158 @@ +// base64.h - originally written and placed in the public domain by Wei Dai + +/// \file base64.h +/// \brief Classes for the Base64Encoder, Base64Decoder, Base64URLEncoder and Base64URLDecoder + +#ifndef CRYPTOPP_BASE64_H +#define CRYPTOPP_BASE64_H + +#include "cryptlib.h" +#include "basecode.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Base64 encodes data using DUDE +/// \details Base64 encodes data per RFC 4648, Base 64 Encoding. +class Base64Encoder : public SimpleProxyFilter +{ +public: + /// \brief Construct a Base64Encoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \param insertLineBreaks a BufferedTrasformation to attach to this object + /// \param maxLineLength the length of a line if line breaks are used + /// \details Base64Encoder constructs a default encoder. The constructor lacks a parameter for padding, and you must + /// use IsolatedInitialize() to modify the Base64Encoder after construction. + /// \sa IsolatedInitialize() for an example of modifying an encoder after construction. + Base64Encoder(BufferedTransformation *attachment = NULLPTR, bool insertLineBreaks = true, int maxLineLength = 72) + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), insertLineBreaks)(Name::MaxLineLength(), maxLineLength)); + } + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + /// \details The following code modifies the padding and line break parameters for an encoder: + ///
+	///     Base64Encoder encoder;
+	///     AlgorithmParameters params = MakeParameters(Pad(), false)(InsertLineBreaks(), false);
+	///     encoder.IsolatedInitialize(params);
+ /// \details You can change the encoding to RFC 4648 web safe alphabet by performing the following: + ///
+	///     Base64Encoder encoder;
+	///     const byte ALPHABET[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+	///     AlgorithmParameters params = MakeParameters(Name::EncodingLookupArray(),(const byte *)ALPHABET);
+	///     encoder.IsolatedInitialize(params);
+ /// \details If you change the encoding alphabet, then you will need to change the decoding alphabet \a and + /// the decoder's lookup table. + /// \sa Base64URLEncoder for an encoder that provides the web safe alphabet, and Base64Decoder::IsolatedInitialize() + /// for an example of modifying a decoder's lookup table after construction. + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +/// \brief Base64 decodes data using DUDE +/// \details Base64 encodes data per RFC 4648, Base 64 Encoding. +class Base64Decoder : public BaseN_Decoder +{ +public: + /// \brief Construct a Base64Decoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \sa IsolatedInitialize() for an example of modifying an encoder after construction. + Base64Decoder(BufferedTransformation *attachment = NULLPTR) + : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {} + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + /// \details The default decoding alpahbet is RFC 4868. You can change the to RFC 4868 web safe alphabet + /// by performing the following: + ///
+	///     int lookup[256];
+	///     const byte ALPHABET[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+	///     Base64Decoder::InitializeDecodingLookupArray(lookup, ALPHABET, 64, false);
+	///
+	///     Base64Decoder decoder;
+	///     AlgorithmParameters params = MakeParameters(Name::DecodingLookupArray(),(const int *)lookup);
+	///     decoder.IsolatedInitialize(params);
+ /// \sa Base64URLDecoder for a decoder that provides the web safe alphabet, and Base64Encoder::IsolatedInitialize() + /// for an example of modifying an encoder's alphabet after construction. + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + /// \brief Provides the default decoding lookup table + /// \return default decoding lookup table + static const int * CRYPTOPP_API GetDecodingLookupArray(); +}; + +/// \brief Base64 encodes data using a web safe alphabet +/// \details Base64 encodes data per RFC 4648, Base 64 Encoding +/// with URL and Filename Safe Alphabet. +class Base64URLEncoder : public SimpleProxyFilter +{ +public: + /// \brief Construct a Base64URLEncoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \param insertLineBreaks a BufferedTrasformation to attach to this object + /// \param maxLineLength the length of a line if line breaks are used + /// \details Base64URLEncoder() constructs a default encoder using a web safe alphabet. The constructor ignores + /// insertLineBreaks and maxLineLength because the web and URL safe specifications don't use them. They are + /// present in the constructor for API compatibility with Base64Encoder so it is a drop-in replacement. The + /// constructor also disables padding on the encoder for the same reason. + /// \details If you need line breaks or padding, then you must use IsolatedInitialize() to set them + /// after constructing a Base64URLEncoder. + /// \sa Base64Encoder for an encoder that provides a classic alphabet, and Base64URLEncoder::IsolatedInitialize + /// for an example of modifying an encoder after construction. + Base64URLEncoder(BufferedTransformation *attachment = NULLPTR, bool insertLineBreaks = false, int maxLineLength = -1) + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + CRYPTOPP_UNUSED(insertLineBreaks), CRYPTOPP_UNUSED(maxLineLength); + IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), false)(Name::MaxLineLength(), -1)(Name::Pad(),false)); + } + + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached + /// transformations. If initialization should be propagated, then use the Initialize() function. + /// \details The following code modifies the padding and line break parameters for an encoder: + ///
+	///     Base64URLEncoder encoder;
+	///     AlgorithmParameters params = MakeParameters(Name::Pad(), true)(Name::InsertLineBreaks(), true);
+	///     encoder.IsolatedInitialize(params);
+ /// \sa Base64Encoder for an encoder that provides a classic alphabet. + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +/// \brief Base64 decodes data using a web safe alphabet +/// \details Base64 encodes data per RFC 4648, Base 64 Encoding +/// with URL and Filename Safe Alphabet. +class Base64URLDecoder : public BaseN_Decoder +{ +public: + /// \brief Construct a Base64URLDecoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \details Base64URLDecoder() constructs a default decoder using a web safe alphabet. + /// \sa Base64Decoder for a decoder that provides a classic alphabet. + Base64URLDecoder(BufferedTransformation *attachment = NULLPTR) + : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {} + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs used to initialize this object + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on + /// attached transformations. If initialization should be propagated, then use the Initialize() function. + /// \sa Base64Decoder for a decoder that provides a classic alphabet, and Base64URLEncoder::IsolatedInitialize + /// for an example of modifying an encoder after construction. + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + /// \brief Provides the default decoding lookup table + /// \return default decoding lookup table + static const int * CRYPTOPP_API GetDecodingLookupArray(); +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/basecode.cpp b/external/ours/library/crypto/src/shared/original/basecode.cpp new file mode 100755 index 000000000..a9a278920 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/basecode.cpp @@ -0,0 +1,247 @@ +// basecode.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4100) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wunused-value" +#endif + +#ifndef CRYPTOPP_IMPORTS + +#include "basecode.h" +#include "fltrimpl.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +void BaseN_Encoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet); + + parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar); + if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) + throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive"); + + byte padding; + bool pad; + if (parameters.GetValue(Name::PaddingByte(), padding)) + pad = parameters.GetValueWithDefault(Name::Pad(), true); + else + pad = false; + m_padding = pad ? padding : -1; + + m_bytePos = m_bitPos = 0; + + int i = 8; + while (i%m_bitsPerChar != 0) + i += 8; + m_outputBlockSize = i/m_bitsPerChar; + + m_outBuf.New(m_outputBlockSize); +} + +size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + while (m_inputPosition < length) + { + if (m_bytePos == 0) + memset(m_outBuf, 0, m_outputBlockSize); + + { + unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8; + while (true) + { + CRYPTOPP_ASSERT(m_bitsPerChar-m_bitPos >= 0); + unsigned int bitsLeftInTarget = (unsigned int)(m_bitsPerChar-m_bitPos); + m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget); + if (bitsLeftInSource >= bitsLeftInTarget) + { + m_bitPos = 0; + ++m_bytePos; + bitsLeftInSource -= bitsLeftInTarget; + if (bitsLeftInSource == 0) + break; + b <<= bitsLeftInTarget; + b &= 0xff; + } + else + { + m_bitPos += bitsLeftInSource; + break; + } + } + } + + CRYPTOPP_ASSERT(m_bytePos <= m_outputBlockSize); + if (m_bytePos == m_outputBlockSize) + { + int i; + for (i=0; i 0) + ++m_bytePos; + + int i; + for (i=0; i 0) + { + memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos); + m_bytePos = m_outputBlockSize; + } + FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); + m_bytePos = m_bitPos = 0; + } + FILTER_END_NO_MESSAGE_END; +} + +void BaseN_Decoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup); + + parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar); + if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) + throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive"); + + m_bytePos = m_bitPos = 0; + + int i = m_bitsPerChar; + while (i%8 != 0) + i += m_bitsPerChar; + m_outputBlockSize = i/8; + + m_outBuf.New(m_outputBlockSize); +} + +size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + while (m_inputPosition < length) + { + unsigned int value; + value = m_lookup[begin[m_inputPosition++]]; + if (value >= 256) + continue; + + if (m_bytePos == 0 && m_bitPos == 0) + memset(m_outBuf, 0, m_outputBlockSize); + + { + int newBitPos = m_bitPos + m_bitsPerChar; + if (newBitPos <= 8) + m_outBuf[m_bytePos] |= value << (8-newBitPos); + else + { + m_outBuf[m_bytePos] |= value >> (newBitPos-8); + m_outBuf[m_bytePos+1] |= value << (16-newBitPos); + } + + m_bitPos = newBitPos; + while (m_bitPos >= 8) + { + m_bitPos -= 8; + ++m_bytePos; + } + } + + if (m_bytePos == m_outputBlockSize) + { + FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0); + m_bytePos = m_bitPos = 0; + } + } + if (messageEnd) + { + FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); + m_bytePos = m_bitPos = 0; + } + FILTER_END_NO_MESSAGE_END; +} + +void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive) +{ + std::fill(lookup, lookup+256, -1); + + for (unsigned int i=0; i +{ +public: + /// \brief Construct a BaseN_Encoder + /// \param attachment a BufferedTransformation to attach to this object + BaseN_Encoder(BufferedTransformation *attachment=NULLPTR) + : m_alphabet(NULLPTR), m_padding(0), m_bitsPerChar(0) + , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0) + {Detach(attachment);} + + /// \brief Construct a BaseN_Encoder + /// \param alphabet table of ASCII characters to use as the alphabet + /// \param log2base the log2base + /// \param attachment a BufferedTransformation to attach to this object + /// \param padding the character to use as padding + /// \pre log2base must be between 1 and 7 inclusive + /// \throw InvalidArgument if log2base is not between 1 and 7 + BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULLPTR, int padding=-1) + : m_alphabet(NULLPTR), m_padding(0), m_bitsPerChar(0) + , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0) + { + Detach(attachment); + BaseN_Encoder::IsolatedInitialize( + MakeParameters + (Name::EncodingLookupArray(), alphabet) + (Name::Log2Base(), log2base) + (Name::Pad(), padding != -1) + (Name::PaddingByte(), byte(padding))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +private: + const byte *m_alphabet; + int m_padding, m_bitsPerChar, m_outputBlockSize; + int m_bytePos, m_bitPos; + SecByteBlock m_outBuf; +}; + +/// \brief Decoder for bases that are a power of 2 +class CRYPTOPP_DLL BaseN_Decoder : public Unflushable +{ +public: + /// \brief Construct a BaseN_Decoder + /// \param attachment a BufferedTransformation to attach to this object + /// \details padding is set to -1, which means use default padding. If not + /// required, then the value must be set via IsolatedInitialize(). + BaseN_Decoder(BufferedTransformation *attachment=NULLPTR) + : m_lookup(NULLPTR), m_bitsPerChar(0) + , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0) + {Detach(attachment);} + + /// \brief Construct a BaseN_Decoder + /// \param lookup table of values + /// \param log2base the log2base + /// \param attachment a BufferedTransformation to attach to this object + /// \details log2base is the exponent (like 5 in 25), and not + /// the number of elements (like 32). + /// \details padding is set to -1, which means use default padding. If not + /// required, then the value must be set via IsolatedInitialize(). + BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULLPTR) + : m_lookup(NULLPTR), m_bitsPerChar(0) + , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0) + { + Detach(attachment); + BaseN_Decoder::IsolatedInitialize( + MakeParameters + (Name::DecodingLookupArray(), lookup) + (Name::Log2Base(), log2base)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + + /// \brief Initializes BaseN lookup array + /// \param lookup table of values + /// \param alphabet table of ASCII characters + /// \param base the base for the encoder + /// \param caseInsensitive flag indicating whether the alphabet is case sensitivie + /// \pre COUNTOF(lookup) == 256 + /// \pre COUNTOF(alphabet) == base + /// \details Internally, the function sets the first 256 elements in the lookup table to + /// their value from the alphabet array or -1. base is the number of element (like 32), + /// and not an exponent (like 5 in 25) + static void CRYPTOPP_API InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive); + +private: + const int *m_lookup; + int m_bitsPerChar, m_outputBlockSize; + int m_bytePos, m_bitPos; + SecByteBlock m_outBuf; +}; + +/// \brief Filter that breaks input stream into groups of fixed size +class CRYPTOPP_DLL Grouper : public Bufferless +{ +public: + /// \brief Construct a Grouper + /// \param attachment a BufferedTransformation to attach to this object + Grouper(BufferedTransformation *attachment=NULLPTR) + : m_groupSize(0), m_counter(0) {Detach(attachment);} + + /// \brief Construct a Grouper + /// \param groupSize the size of the grouping + /// \param separator the separator to use between groups + /// \param terminator the terminator appeand after processing + /// \param attachment a BufferedTransformation to attach to this object + Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULLPTR) + : m_groupSize(0), m_counter(0) + { + Detach(attachment); + Grouper::IsolatedInitialize( + MakeParameters + (Name::GroupSize(), groupSize) + (Name::Separator(), ConstByteArrayParameter(separator)) + (Name::Terminator(), ConstByteArrayParameter(terminator))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +private: + SecByteBlock m_separator, m_terminator; + size_t m_groupSize, m_counter; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/bench.h b/external/ours/library/crypto/src/shared/original/bench.h new file mode 100755 index 000000000..2c30e971c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/bench.h @@ -0,0 +1,105 @@ +// bench.h - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#ifndef CRYPTOPP_BENCH_H +#define CRYPTOPP_BENCH_H + +#include "cryptlib.h" + +#include +#include +#include +#include + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +// More granular control over benchmarks +enum TestClass { + /// \brief Random number generators + UnkeyedRNG=(1<<0), + /// \brief Message digests + UnkeyedHash=(1<<1), + /// \brief Other unkeyed algorithms + UnkeyedOther=(1<<2), + + /// \brief Message authentication codes + SharedKeyMAC=(1<<3), + /// \brief Stream ciphers + SharedKeyStream=(1<<4), + /// \brief Block ciphers ciphers + SharedKeyBlock=(1<<5), + /// \brief Other shared key algorithms + SharedKeyOther=(1<<6), + + /// \brief Key agreement algorithms over integers + PublicKeyAgreement=(1<<7), + /// \brief Encryption algorithms over integers + PublicKeyEncryption=(1<<8), + /// \brief Signature algorithms over integers + PublicKeySignature=(1<<9), + /// \brief Other public key algorithms over integers + PublicKeyOther=(1<<10), + + /// \brief Key agreement algorithms over EC + PublicKeyAgreementEC=(1<<11), + /// \brief Encryption algorithms over EC + PublicKeyEncryptionEC=(1<<12), + /// \brief Signature algorithms over EC + PublicKeySignatureEC=(1<<13), + /// \brief Other public key algorithms over EC + PublicKeyOtherEC=(1<<14), + + Unkeyed=UnkeyedRNG|UnkeyedHash|UnkeyedOther, + SharedKey=SharedKeyMAC|SharedKeyStream|SharedKeyBlock|SharedKeyOther, + PublicKey=PublicKeyAgreement|PublicKeyEncryption|PublicKeySignature|PublicKeyOther, + PublicKeyEC=PublicKeyAgreementEC|PublicKeyEncryptionEC|PublicKeySignatureEC|PublicKeyOtherEC, + + All=Unkeyed|SharedKey|PublicKey|PublicKeyEC, + + TestFirst=(0), TestLast=(1<<15) +}; + +extern const double CLOCK_TICKS_PER_SECOND; +extern double g_allocatedTime; +extern double g_hertz; +extern double g_logTotal; +extern unsigned int g_logCount; +extern const byte defaultKey[]; + +// Test book keeping +extern time_t g_testBegin; +extern time_t g_testEnd; + +// Benchmark command handler +void BenchmarkWithCommand(int argc, const char* const argv[]); +// Top level, prints preamble and postamble +void Benchmark(Test::TestClass suites, double t, double hertz); +// Unkeyed systems +void BenchmarkUnkeyedAlgorithms(double t, double hertz); +// Shared key systems +void BenchmarkSharedKeyedAlgorithms(double t, double hertz); +// Public key systems over integers +void BenchmarkPublicKeyAlgorithms(double t, double hertz); +// Public key systems over elliptic curves +void BenchmarkEllipticCurveAlgorithms(double t, double hertz); + +// These are defined in bench1.cpp +extern void OutputResultKeying(double iterations, double timeTaken); +extern void OutputResultBytes(const char *name, const char *provider, double length, double timeTaken); +extern void OutputResultOperations(const char *name, const char *provider, const char *operation, bool pc, unsigned long iterations, double timeTaken); + +// These are defined in bench1.cpp +extern void BenchMark(const char *name, BufferedTransformation &bt, double timeTotal); +extern void BenchMark(const char *name, StreamTransformation &cipher, double timeTotal); +extern void BenchMark(const char *name, HashTransformation &ht, double timeTotal); +extern void BenchMark(const char *name, RandomNumberGenerator &rng, double timeTotal); + +// These are defined in bench2.cpp +extern void BenchMarkKeying(SimpleKeyingInterface &c, size_t keyLength, const NameValuePairs ¶ms); +extern void BenchMark(const char *name, AuthenticatedSymmetricCipher &cipher, double timeTotal); + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP + +#endif diff --git a/external/ours/library/crypto/src/shared/original/bench1.cpp b/external/ours/library/crypto/src/shared/original/bench1.cpp new file mode 100755 index 000000000..e7197ece5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/bench1.cpp @@ -0,0 +1,520 @@ +// bench1.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#include "cryptlib.h" +#include "bench.h" +#include "validate.h" + +#include "cpu.h" +#include "factory.h" +#include "algparam.h" +#include "argnames.h" +#include "smartptr.h" +#include "stdcpp.h" + +#include "osrng.h" +#include "drbg.h" +#include "darn.h" +#include "mersenne.h" +#include "rdrand.h" +#include "padlkrng.h" + +#include +#include +#include + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4355) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +#ifdef CLOCKS_PER_SEC +const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC; +#elif defined(CLK_TCK) +const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK; +#else +const double CLOCK_TICKS_PER_SECOND = 1000000.0; +#endif + +extern const byte defaultKey[] = "0123456789" // 168 + NULL + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "00000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000"; + +double g_allocatedTime = 0.0, g_hertz = 0.0, g_logTotal = 0.0; +unsigned int g_logCount = 0; +time_t g_testBegin, g_testEnd; + +inline std::string HertzToString(double hertz) +{ + std::ostringstream oss; + oss.precision(3); + + if (hertz >= 0.999e+9) + oss << hertz / 1e+9 << " GHz"; + else if (hertz >= 0.999e+6) + oss << hertz / 1e+6 << " MHz"; + else if (hertz >= 0.999e+3) + oss << hertz / 1e+3 << " KHz"; + else + oss << hertz << " Hz"; + + return oss.str(); +} + +void OutputResultBytes(const char *name, const char *provider, double length, double timeTaken) +{ + std::ostringstream oss; + + // Coverity finding + if (length < 0.000001f) length = 0.000001f; + if (timeTaken < 0.000001f) timeTaken = 0.000001f; + + double mbs = length / timeTaken / (1024*1024); + oss << "\n" << name << "" << provider; + oss << std::setiosflags(std::ios::fixed); + oss << "" << std::setprecision(0) << std::setiosflags(std::ios::fixed) << mbs; + if (g_hertz > 1.0f) + { + const double cpb = timeTaken * g_hertz / length; + if (cpb < 24.0f) + oss << "" << std::setprecision(2) << std::setiosflags(std::ios::fixed) << cpb; + else + oss << "" << std::setprecision(1) << std::setiosflags(std::ios::fixed) << cpb; + } + g_logTotal += log(mbs); + g_logCount++; + + std::cout << oss.str(); +} + +void OutputResultKeying(double iterations, double timeTaken) +{ + std::ostringstream oss; + + // Coverity finding + if (iterations < 0.000001f) iterations = 0.000001f; + if (timeTaken < 0.000001f) timeTaken = 0.000001f; + + oss << "" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << (1000*1000*timeTaken/iterations); + + // Coverity finding + if (g_hertz > 1.0f) + oss << "" << std::setprecision(0) << std::setiosflags(std::ios::fixed) << timeTaken * g_hertz / iterations; + + std::cout << oss.str(); +} + +void OutputResultOperations(const char *name, const char *provider, const char *operation, bool pc, unsigned long iterations, double timeTaken) +{ + CRYPTOPP_UNUSED(provider); + std::ostringstream oss; + + // Coverity finding + if (!iterations) iterations++; + if (timeTaken < 0.000001f) timeTaken = 0.000001f; + + oss << "\n" << name << " " << operation << (pc ? " with precomputation" : ""); + //oss << "" << provider; + oss << "" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << (1000*timeTaken/iterations); + + // Coverity finding + if (g_hertz > 1.0f) + { + const double t = timeTaken * g_hertz / iterations / 1000000; + oss << "" << std::setprecision(3) << std::setiosflags(std::ios::fixed) << t; + } + + g_logTotal += log(iterations/timeTaken); + g_logCount++; + + std::cout << oss.str(); +} + +/* +void BenchMark(const char *name, BlockTransformation &cipher, double timeTotal) +{ + const int BUF_SIZE = RoundUpToMultipleOf(2048U, cipher.OptimalNumberOfParallelBlocks() * cipher.BlockSize()); + AlignedSecByteBlock buf(BUF_SIZE); + buf.SetMark(16); + + const int nBlocks = BUF_SIZE / cipher.BlockSize(); + unsigned long i=0, blocks=1; + double timeTaken; + + clock_t start = ::clock(); + do + { + blocks *= 2; + for (; i(&rng); + if (cipher != NULLPTR) + { + const size_t size = cipher->DefaultKeyLength(); + if (cipher->IsResynchronizable()) + cipher->SetKeyWithIV(buf, size, buf+size); + else + cipher->SetKey(buf, size); + } + + unsigned long long blocks = 1; + double timeTaken; + + clock_t start = ::clock(); + do + { + rng.GenerateBlock(buf, buf.size()); + blocks++; + timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND; + } while (timeTaken < timeTotal); + + std::string provider = rng.AlgorithmProvider(); + OutputResultBytes(name, provider.c_str(), double(blocks) * BUF_SIZE, timeTaken); +} + +// Hack, but we probably need a KeyedRandomNumberGenerator interface +// and a few methods to generalize keying a RNG. X917RNG, Hash_DRBG, +// HMAC_DRBG, AES/CFB RNG and a few others could use it. "A few others" +// includes BLAKE2, ChaCha and Poly1305 when used as a RNG. +void BenchMark(const char *name, NIST_DRBG &rng, double timeTotal) +{ + const int BUF_SIZE = 2048U; + AlignedSecByteBlock buf(BUF_SIZE); + Test::GlobalRNG().GenerateBlock(buf, BUF_SIZE); + buf.SetMark(16); + + rng.IncorporateEntropy(buf, rng.MinEntropyLength()); + unsigned long long blocks = 1; + double timeTaken; + + clock_t start = ::clock(); + do + { + rng.GenerateBlock(buf, buf.size()); + blocks++; + timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND; + } while (timeTaken < timeTotal); + + std::string provider = rng.AlgorithmProvider(); + OutputResultBytes(name, provider.c_str(), double(blocks) * BUF_SIZE, timeTaken); +} + +template +void BenchMarkByNameKeyLess(const char *factoryName, const char *displayName = NULLPTR, const NameValuePairs ¶ms = g_nullNameValuePairs) +{ + CRYPTOPP_UNUSED(params); + std::string name = factoryName; + if (displayName) + name = displayName; + + member_ptr obj(ObjectFactoryRegistry::Registry().CreateObject(factoryName)); + BenchMark(name.c_str(), *obj, g_allocatedTime); +} + +void AddHtmlHeader() +{ + std::ostringstream oss; + + // HTML5 + oss << ""; + oss << "\n"; + + oss << "\n"; + oss << "\n"; + oss << "\nSpeed Comparison of Popular Crypto Algorithms"; + oss << "\n"; + oss << "\n"; + + oss << "\n"; + + oss << "\n

Crypto++ " << CRYPTOPP_VERSION / 100; + oss << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << " Benchmarks

"; + + oss << "\n

Here are speed benchmarks for some commonly used cryptographic algorithms.

"; + + if (g_hertz > 1.0f) + oss << "\n

CPU frequency of the test platform is " << HertzToString(g_hertz) << ".

"; + else + oss << "\n

CPU frequency of the test platform was not provided.

" << std::endl; + + std::cout << oss.str(); +} + +void AddHtmlFooter() +{ + std::ostringstream oss; + oss << "\n\n\n"; + std::cout << oss.str(); +} + +void BenchmarkWithCommand(int argc, const char* const argv[]) +{ + std::string command(argv[1]); + float runningTime(argc >= 3 ? Test::StringToValue(argv[2]) : 1.0f); + float cpuFreq(argc >= 4 ? Test::StringToValue(argv[3])*float(1e9) : 0.0f); + std::string algoName(argc >= 5 ? argv[4] : ""); + + // https://github.com/weidai11/cryptopp/issues/983 + if (runningTime > 10.0f) + runningTime = 10.0f; + + if (command == "b") // All benchmarks + Benchmark(Test::All, runningTime, cpuFreq); + else if (command == "b4") // Public key algorithms over EC + Test::Benchmark(Test::PublicKeyEC, runningTime, cpuFreq); + else if (command == "b3") // Public key algorithms + Test::Benchmark(Test::PublicKey, runningTime, cpuFreq); + else if (command == "b2") // Shared key algorithms + Test::Benchmark(Test::SharedKey, runningTime, cpuFreq); + else if (command == "b1") // Unkeyed algorithms + Test::Benchmark(Test::Unkeyed, runningTime, cpuFreq); +} + +void Benchmark(Test::TestClass suites, double t, double hertz) +{ + g_allocatedTime = t; + g_hertz = hertz; + + // Add
in between tables + size_t count_breaks = 0; + + AddHtmlHeader(); + + g_testBegin = ::time(NULLPTR); + + if (static_cast(suites) == 0 || static_cast(suites) > TestLast) + suites = Test::All; + + // Unkeyed algorithms + if (suites & Test::Unkeyed) + { + if (count_breaks) + std::cout << "\n
"; + count_breaks++; + + BenchmarkUnkeyedAlgorithms(t, hertz); + } + + // Shared key algorithms + if (suites & Test::SharedKey) + { + if (count_breaks) + std::cout << "\n
"; + count_breaks++; + + BenchmarkSharedKeyedAlgorithms(t, hertz); + } + + // Public key algorithms + if (suites & Test::PublicKey) + { + if (count_breaks) + std::cout << "\n
"; + count_breaks++; + + BenchmarkPublicKeyAlgorithms(t, hertz); + } + + // Public key algorithms over EC + if (suites & Test::PublicKeyEC) + { + if (count_breaks) + std::cout << "\n
"; + count_breaks++; + + BenchmarkEllipticCurveAlgorithms(t, hertz); + } + + g_testEnd = ::time(NULLPTR); + + std::ostringstream oss; + oss << "\n

Throughput Geometric Average: " << std::setiosflags(std::ios::fixed); + oss << std::exp(g_logTotal/(g_logCount > 0.0f ? g_logCount : 1.0f)) << std::endl; + + oss << "\n

Test started at " << TimeToString(g_testBegin); + oss << "\n
Test ended at " << TimeToString(g_testEnd); + oss << "\n"; + std::cout << oss.str(); + + AddHtmlFooter(); +} + +void BenchmarkUnkeyedAlgorithms(double t, double hertz) +{ + g_allocatedTime = t; + g_hertz = hertz; + + const char *cpb; + if (g_hertz > 1.0f) + cpb = "Cycles/Byte"; + else + cpb = ""; + + std::cout << "\n"; + + std::cout << "\n"; + std::cout << ""; + std::cout << "\n"; + std::cout << "\n"; + { +#ifdef NONBLOCKING_RNG_AVAILABLE + BenchMarkByNameKeyLess("NonblockingRng"); +#endif +#ifdef OS_RNG_AVAILABLE + BenchMarkByNameKeyLess("AutoSeededRandomPool"); + BenchMarkByNameKeyLess("AutoSeededX917RNG(AES)"); +#endif + BenchMarkByNameKeyLess("MT19937"); +#if (CRYPTOPP_BOOL_X86) && !defined(CRYPTOPP_DISABLE_ASM) + if (HasPadlockRNG()) + BenchMarkByNameKeyLess("PadlockRNG"); +#endif +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_ASM) + if (HasRDRAND()) + BenchMarkByNameKeyLess("RDRAND"); + if (HasRDSEED()) + BenchMarkByNameKeyLess("RDSEED"); +#endif +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) && !defined(CRYPTOPP_DISABLE_ASM) + if (HasDARN()) + BenchMarkByNameKeyLess("DARN"); +#endif + BenchMarkByNameKeyLess("AES/OFB RNG"); + BenchMarkByNameKeyLess("Hash_DRBG(SHA1)"); + BenchMarkByNameKeyLess("Hash_DRBG(SHA256)"); + BenchMarkByNameKeyLess("HMAC_DRBG(SHA1)"); + BenchMarkByNameKeyLess("HMAC_DRBG(SHA256)"); + } + + std::cout << "\n"; + { + BenchMarkByNameKeyLess("CRC32"); + BenchMarkByNameKeyLess("CRC32C"); + BenchMarkByNameKeyLess("Adler32"); + BenchMarkByNameKeyLess("MD5"); + BenchMarkByNameKeyLess("SHA-1"); + BenchMarkByNameKeyLess("SHA-256"); + BenchMarkByNameKeyLess("SHA-512"); + BenchMarkByNameKeyLess("SHA3-224"); + BenchMarkByNameKeyLess("SHA3-256"); + BenchMarkByNameKeyLess("SHA3-384"); + BenchMarkByNameKeyLess("SHA3-512"); + BenchMarkByNameKeyLess("Keccak-224"); + BenchMarkByNameKeyLess("Keccak-256"); + BenchMarkByNameKeyLess("Keccak-384"); + BenchMarkByNameKeyLess("Keccak-512"); + BenchMarkByNameKeyLess("Tiger"); + BenchMarkByNameKeyLess("Whirlpool"); + BenchMarkByNameKeyLess("RIPEMD-160"); + BenchMarkByNameKeyLess("RIPEMD-320"); + BenchMarkByNameKeyLess("RIPEMD-128"); + BenchMarkByNameKeyLess("RIPEMD-256"); + BenchMarkByNameKeyLess("SM3"); + BenchMarkByNameKeyLess("BLAKE2s"); + BenchMarkByNameKeyLess("BLAKE2b"); + BenchMarkByNameKeyLess("LSH-256"); + BenchMarkByNameKeyLess("LSH-512"); + } + + std::cout << "\n
AlgorithmProviderMiB/Second" << cpb; + + std::cout << "\n
" << std::endl; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/bench2.cpp b/external/ours/library/crypto/src/shared/original/bench2.cpp new file mode 100755 index 000000000..2cfd62002 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/bench2.cpp @@ -0,0 +1,267 @@ +// bench2.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#include "cryptlib.h" +#include "bench.h" +#include "validate.h" + +#include "cpu.h" +#include "factory.h" +#include "algparam.h" +#include "argnames.h" +#include "smartptr.h" +#include "stdcpp.h" + +#include "vmac.h" +#include "hmac.h" +#include "ttmac.h" +#include "cmac.h" +#include "dmac.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4355) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +void BenchMarkKeying(SimpleKeyingInterface &c, size_t keyLength, const NameValuePairs ¶ms) +{ + unsigned long iterations = 0; + double timeTaken; + + clock_t start = ::clock(); + do + { + for (unsigned int i=0; i<1024; i++) + c.SetKey(defaultKey, keyLength, params); + timeTaken = double(::clock() - start) / CLOCK_TICKS_PER_SECOND; + iterations += 1024; + } + while (timeTaken < g_allocatedTime); + + OutputResultKeying(iterations, timeTaken); +} + +void BenchMark(const char *name, AuthenticatedSymmetricCipher &cipher, double timeTotal) +{ + if (cipher.NeedsPrespecifiedDataLengths()) + cipher.SpecifyDataLengths(0, cipher.MaxMessageLength(), 0); + + BenchMark(name, static_cast(cipher), timeTotal); +} + +template +void BenchMarkByName2(const char *factoryName, size_t keyLength=0, const char *displayName=NULLPTR, const NameValuePairs ¶ms = g_nullNameValuePairs) +{ + std::string name(factoryName ? factoryName : ""); + member_ptr obj(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + + if (keyLength == 0) + keyLength = obj->DefaultKeyLength(); + + if (displayName != NULLPTR) + name = displayName; + else if (keyLength != 0) + name += " (" + IntToString(keyLength * 8) + "-bit key)"; + + obj->SetKey(defaultKey, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, obj->IVSize()), false))); + BenchMark(name.c_str(), *static_cast(obj.get()), g_allocatedTime); + BenchMarkKeying(*obj, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), ConstByteArrayParameter(defaultKey, obj->IVSize()), false))); +} + +template +void BenchMarkByName(const char *factoryName, size_t keyLength=0, const char *displayName=NULLPTR, const NameValuePairs ¶ms = g_nullNameValuePairs) +{ + BenchMarkByName2(factoryName, keyLength, displayName, params); +} + +void BenchmarkSharedKeyedAlgorithms(double t, double hertz) +{ + g_allocatedTime = t; + g_hertz = hertz; + + const char *cpb, *cpk; + if (g_hertz > 1.0f) + { + cpb = "Cycles/Byte"; + cpk = "Cycles to
Setup Key and IV"; + } + else + { + cpb = cpk = ""; + } + + std::cout << "\n"; + std::cout << "\n"; + std::cout << "\n"; + std::cout << "\n"; + { +#if CRYPTOPP_AESNI_AVAILABLE + if (HasCLMUL()) + BenchMarkByName2("AES/GCM", 0, "GMAC(AES)"); + else +#elif CRYPTOPP_ARM_PMULL_AVAILABLE + if (HasPMULL()) + BenchMarkByName2("AES/GCM", 0, "GMAC(AES)"); + else +#elif CRYPTOPP_POWER8_VMULL_AVAILABLE + if (HasPMULL()) + BenchMarkByName2("AES/GCM", 0, "GMAC(AES)"); + else +#endif + { + BenchMarkByName2("AES/GCM", 0, "GMAC(AES) (2K tables)", MakeParameters(Name::TableSize(), 2048)); + BenchMarkByName2("AES/GCM", 0, "GMAC(AES) (64K tables)", MakeParameters(Name::TableSize(), 64 * 1024)); + } + + BenchMarkByName("VMAC(AES)-64"); + BenchMarkByName("VMAC(AES)-128"); + BenchMarkByName("HMAC(SHA-1)"); + BenchMarkByName("HMAC(SHA-256)"); + BenchMarkByName("Two-Track-MAC"); + BenchMarkByName("CMAC(AES)"); + BenchMarkByName("DMAC(AES)"); + BenchMarkByName("Poly1305(AES)"); + BenchMarkByName("Poly1305TLS"); + BenchMarkByName("BLAKE2s"); + BenchMarkByName("BLAKE2b"); + BenchMarkByName("SipHash-2-4"); + BenchMarkByName("SipHash-4-8"); + } + + std::cout << "\n"; + { + BenchMarkByName("Panama-LE"); + BenchMarkByName("Panama-BE"); + BenchMarkByName("Salsa20", 0, "Salsa20"); + BenchMarkByName("Salsa20", 0, "Salsa20/12", MakeParameters(Name::Rounds(), 12)); + BenchMarkByName("Salsa20", 0, "Salsa20/8", MakeParameters(Name::Rounds(), 8)); + BenchMarkByName("ChaCha", 0, "ChaCha20"); + BenchMarkByName("ChaCha", 0, "ChaCha12", MakeParameters(Name::Rounds(), 12)); + BenchMarkByName("ChaCha", 0, "ChaCha8", MakeParameters(Name::Rounds(), 8)); + BenchMarkByName("ChaChaTLS"); + BenchMarkByName("Sosemanuk"); + BenchMarkByName("Rabbit"); + BenchMarkByName("RabbitWithIV"); + BenchMarkByName("HC-128"); + BenchMarkByName("HC-256"); + BenchMarkByName("MARC4"); + BenchMarkByName("SEAL-3.0-LE"); + BenchMarkByName("WAKE-OFB-LE"); + } + + std::cout << "\n"; + { + BenchMarkByName("AES/CTR", 16); + BenchMarkByName("AES/CTR", 24); + BenchMarkByName("AES/CTR", 32); + BenchMarkByName("AES/CBC", 16); + BenchMarkByName("AES/CBC", 24); + BenchMarkByName("AES/CBC", 32); + BenchMarkByName("AES/XTS", 32); + BenchMarkByName("AES/XTS", 48); + BenchMarkByName("AES/XTS", 64); + BenchMarkByName("AES/OFB", 16); + BenchMarkByName("AES/CFB", 16); + BenchMarkByName("AES/ECB", 16); + BenchMarkByName("ARIA/CTR", 16); + BenchMarkByName("ARIA/CTR", 32); + BenchMarkByName("HIGHT/CTR"); + BenchMarkByName("Camellia/CTR", 16); + BenchMarkByName("Camellia/CTR", 32); + BenchMarkByName("Twofish/CTR"); + BenchMarkByName("Threefish-256(256)/CTR", 32); + BenchMarkByName("Threefish-512(512)/CTR", 64); + BenchMarkByName("Threefish-1024(1024)/CTR", 128); + BenchMarkByName("Serpent/CTR"); + BenchMarkByName("CAST-128/CTR"); + BenchMarkByName("CAST-256/CTR", 32); + BenchMarkByName("RC6/CTR"); + BenchMarkByName("MARS/CTR"); + BenchMarkByName("SHACAL-2/CTR", 16); + BenchMarkByName("SHACAL-2/CTR", 64); + BenchMarkByName("DES/CTR"); + BenchMarkByName("DES-XEX3/CTR"); + BenchMarkByName("DES-EDE3/CTR"); + BenchMarkByName("IDEA/CTR"); + BenchMarkByName("RC5/CTR", 0, "RC5 (r=16)"); + BenchMarkByName("Blowfish/CTR"); + BenchMarkByName("SKIPJACK/CTR"); + BenchMarkByName("SEED/CTR", 0, "SEED/CTR (1/2 K table)"); + BenchMarkByName("SM4/CTR"); + + BenchMarkByName("Kalyna-128/CTR", 16, "Kalyna-128(128)/CTR (128-bit key)"); + BenchMarkByName("Kalyna-128/CTR", 32, "Kalyna-128(256)/CTR (256-bit key)"); + BenchMarkByName("Kalyna-256/CTR", 32, "Kalyna-256(256)/CTR (256-bit key)"); + BenchMarkByName("Kalyna-256/CTR", 64, "Kalyna-256(512)/CTR (512-bit key)"); + BenchMarkByName("Kalyna-512/CTR", 64, "Kalyna-512(512)/CTR (512-bit key)"); + } + + std::cout << "\n"; + { + BenchMarkByName("CHAM-64/CTR", 16, "CHAM-64(128)/CTR (128-bit key)"); + BenchMarkByName("CHAM-128/CTR", 16, "CHAM-128(128)/CTR (128-bit key)"); + BenchMarkByName("CHAM-128/CTR", 32, "CHAM-128(256)/CTR (256-bit key)"); + + BenchMarkByName("LEA-128/CTR", 16, "LEA-128(128)/CTR (128-bit key)"); + BenchMarkByName("LEA-128/CTR", 24, "LEA-128(192)/CTR (192-bit key)"); + BenchMarkByName("LEA-128/CTR", 32, "LEA-128(256)/CTR (256-bit key)"); + + BenchMarkByName("SIMECK-32/CTR", 8, "SIMECK-32(64)/CTR (64-bit key)"); + BenchMarkByName("SIMECK-64/CTR", 16, "SIMECK-64(128)/CTR (128-bit key)"); + + BenchMarkByName("SIMON-64/CTR", 12, "SIMON-64(96)/CTR (96-bit key)"); + BenchMarkByName("SIMON-64/CTR", 16, "SIMON-64(128)/CTR (128-bit key)"); + BenchMarkByName("SIMON-128/CTR", 16, "SIMON-128(128)/CTR (128-bit key)"); + BenchMarkByName("SIMON-128/CTR", 24, "SIMON-128(192)/CTR (192-bit key)"); + BenchMarkByName("SIMON-128/CTR", 32, "SIMON-128(256)/CTR (256-bit key)"); + + BenchMarkByName("SPECK-64/CTR", 12, "SPECK-64(96)/CTR (96-bit key)"); + BenchMarkByName("SPECK-64/CTR", 16, "SPECK-64(128)/CTR (128-bit key)"); + BenchMarkByName("SPECK-128/CTR", 16, "SPECK-128(128)/CTR (128-bit key)"); + BenchMarkByName("SPECK-128/CTR", 24, "SPECK-128(192)/CTR (192-bit key)"); + BenchMarkByName("SPECK-128/CTR", 32, "SPECK-128(256)/CTR (256-bit key)"); + + BenchMarkByName("TEA/CTR"); + BenchMarkByName("XTEA/CTR"); + } + + std::cout << "\n"; + { +#if CRYPTOPP_AESNI_AVAILABLE + if (HasCLMUL()) + BenchMarkByName2("AES/GCM", 0, "AES/GCM"); + else +#elif CRYPTOPP_ARM_PMULL_AVAILABLE + if (HasPMULL()) + BenchMarkByName2("AES/GCM", 0, "AES/GCM"); + else +#elif CRYPTOPP_POWER8_VMULL_AVAILABLE + if (HasPMULL()) + BenchMarkByName2("AES/GCM", 0, "AES/GCM"); + else +#endif + { + BenchMarkByName2("AES/GCM", 0, "AES/GCM (2K tables)", MakeParameters(Name::TableSize(), 2048)); + BenchMarkByName2("AES/GCM", 0, "AES/GCM (64K tables)", MakeParameters(Name::TableSize(), 64 * 1024)); + } + BenchMarkByName2("AES/CCM"); + BenchMarkByName2("AES/EAX"); + BenchMarkByName2("ChaCha20/Poly1305"); + BenchMarkByName2("XChaCha20/Poly1305"); + } + + std::cout << "\n
AlgorithmProviderMiB/Second" << cpb; + std::cout << "Microseconds to
Setup Key and IV" << cpk; + + std::cout << "\n
" << std::endl; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/bench3.cpp b/external/ours/library/crypto/src/shared/original/bench3.cpp new file mode 100755 index 000000000..7c98661b5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/bench3.cpp @@ -0,0 +1,480 @@ +// bench3.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#include "cryptlib.h" +#include "bench.h" +#include "validate.h" + +#include "cpu.h" +#include "factory.h" +#include "algparam.h" +#include "argnames.h" +#include "smartptr.h" +#include "stdcpp.h" + +#include "pubkey.h" +#include "gfpcrypt.h" +#include "eccrypto.h" +#include "pkcspad.h" + +#include "files.h" +#include "filters.h" +#include "hex.h" +#include "rsa.h" +#include "nr.h" +#include "dsa.h" +#include "luc.h" +#include "rw.h" +#include "ecp.h" +#include "ec2n.h" +#include "asn.h" +#include "dh.h" +#include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" +#include "xed25519.h" +#include "xtrcrypt.h" +#include "esign.h" +#include "pssr.h" +#include "oids.h" +#include "randpool.h" +#include "stdcpp.h" +#include "hrtimer.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal, bool pc = false) +{ + unsigned int len = 16; + SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len)); + Test::GlobalRNG().GenerateBlock(plaintext, len); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + key.Encrypt(Test::GlobalRNG(), plaintext, len, ciphertext); + ++i; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = key.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Encryption", pc, i, timeTaken); + + if (!pc && key.GetMaterial().SupportsPrecomputation()) + { + key.AccessMaterial().Precompute(16); + BenchMarkEncryption(name, key, timeTotal, true); + } +} + +void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub, double timeTotal) +{ + unsigned int len = 16; + SecByteBlock ciphertext(pub.CiphertextLength(len)); + SecByteBlock plaintext(pub.MaxPlaintextLength(ciphertext.size())); + Test::GlobalRNG().GenerateBlock(plaintext, len); + pub.Encrypt(Test::GlobalRNG(), plaintext, len, ciphertext); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + priv.Decrypt(Test::GlobalRNG(), ciphertext, ciphertext.size(), plaintext); + ++i; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = priv.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Decryption", false, i, timeTaken); +} + +void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool pc=false) +{ + unsigned int len = 16; + AlignedSecByteBlock message(len), signature(key.SignatureLength()); + Test::GlobalRNG().GenerateBlock(message, len); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + (void)key.SignMessage(Test::GlobalRNG(), message, len, signature); + ++i; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = key.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Signature", pc, i, timeTaken); + + if (!pc && key.GetMaterial().SupportsPrecomputation()) + { + key.AccessMaterial().Precompute(16); + BenchMarkSigning(name, key, timeTotal, true); + } +} + +void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier &pub, double timeTotal, bool pc=false) +{ + unsigned int len = 16; + AlignedSecByteBlock message(len), signature(pub.SignatureLength()); + Test::GlobalRNG().GenerateBlock(message, len); + priv.SignMessage(Test::GlobalRNG(), message, len, signature); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + (void)pub.VerifyMessage(message, len, signature, signature.size()); + ++i; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = pub.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Verification", pc, i, timeTaken); + + if (!pc && pub.GetMaterial().SupportsPrecomputation()) + { + pub.AccessMaterial().Precompute(16); + BenchMarkVerification(name, priv, pub, timeTotal, true); + } +} + +void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength()); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + d.GenerateKeyPair(Test::GlobalRNG(), priv, pub); + ++i; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = d.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Key-Pair Generation", pc, i, timeTaken); + + if (!pc && d.GetMaterial().SupportsPrecomputation()) + { + d.AccessMaterial().Precompute(16); + BenchMarkKeyGen(name, d, timeTotal, true); + } +} + +void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength()); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + d.GenerateEphemeralKeyPair(Test::GlobalRNG(), priv, pub); + ++i; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = d.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Key-Pair Generation", pc, i, timeTaken); + + if (!pc && d.GetMaterial().SupportsPrecomputation()) + { + d.AccessMaterial().Precompute(16); + BenchMarkKeyGen(name, d, timeTotal, true); + } +} + +void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength()); + SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength()); + d.GenerateKeyPair(Test::GlobalRNG(), priv1, pub1); + d.GenerateKeyPair(Test::GlobalRNG(), priv2, pub2); + SecByteBlock val(d.AgreedValueLength()); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + d.Agree(val, priv1, pub2); + d.Agree(val, priv2, pub1); + i+=2; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = d.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Key Agreement", pc, i, timeTaken); +} + +void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength()); + SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength()); + SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength()); + SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength()); + d.GenerateStaticKeyPair(Test::GlobalRNG(), spriv1, spub1); + d.GenerateStaticKeyPair(Test::GlobalRNG(), spriv2, spub2); + d.GenerateEphemeralKeyPair(Test::GlobalRNG(), epriv1, epub1); + d.GenerateEphemeralKeyPair(Test::GlobalRNG(), epriv2, epub2); + SecByteBlock val(d.AgreedValueLength()); + + unsigned int i = 0; + double timeTaken; + + ThreadUserTimer timer; + timer.StartTimer(); + + do + { + d.Agree(val, spriv1, epriv1, spub2, epub2); + d.Agree(val, spriv2, epriv2, spub1, epub1); + i+=2; timeTaken = timer.ElapsedTimeAsDouble(); + } + while (timeTaken < timeTotal); + + std::string provider = d.AlgorithmProvider(); + OutputResultOperations(name, provider.c_str(), "Key Agreement", pc, i, timeTaken); +} + +template +void BenchMarkCrypto(const char *filename, const char *name, double timeTotal) +{ + FileSource f(DataDir(filename).c_str(), true, new HexDecoder); + typename SCHEME::Decryptor priv(f); + typename SCHEME::Encryptor pub(priv); + BenchMarkEncryption(name, pub, timeTotal); + BenchMarkDecryption(name, priv, pub, timeTotal); +} + +template +void BenchMarkSignature(const char *filename, const char *name, double timeTotal) +{ + FileSource f(DataDir(filename).c_str(), true, new HexDecoder); + typename SCHEME::Signer priv(f); + typename SCHEME::Verifier pub(priv); + BenchMarkSigning(name, priv, timeTotal); + BenchMarkVerification(name, priv, pub, timeTotal); +} + +template +void BenchMarkKeyAgreement(const char *filename, const char *name, double timeTotal) +{ + FileSource f(DataDir(filename).c_str(), true, new HexDecoder); + D d(f); + BenchMarkKeyGen(name, d, timeTotal); + BenchMarkAgreement(name, d, timeTotal); +} + +void BenchmarkPublicKeyAlgorithms(double t, double hertz) +{ + g_allocatedTime = t; + g_hertz = hertz; + + const char *mco; + if (g_hertz > 1.0f) + mco = "Megacycles/Operation"; + else + mco = ""; + + std::cout << "\n"; + std::cout << "\n"; + std::cout << "\n"; + std::cout << "\n"; + { + BenchMarkCrypto > >("TestData/rsa1024.dat", "RSA 1024", t); + BenchMarkCrypto > >("TestData/luc1024.dat", "LUC 1024", t); + BenchMarkCrypto >("TestData/dlie1024.dat", "DLIES 1024", t); + BenchMarkCrypto >("TestData/lucc512.dat", "LUCELG 512", t); + } + + std::cout << "\n"; + { + BenchMarkCrypto > >("TestData/rsa2048.dat", "RSA 2048", t); + BenchMarkCrypto > >("TestData/luc2048.dat", "LUC 2048", t); + BenchMarkCrypto >("TestData/dlie2048.dat", "DLIES 2048", t); + BenchMarkCrypto >("TestData/lucc1024.dat", "LUCELG 1024", t); + } + + std::cout << "\n"; + { + BenchMarkSignature >("TestData/rsa1024.dat", "RSA 1024", t); + BenchMarkSignature >("TestData/rw1024.dat", "RW 1024", t); + BenchMarkSignature >("TestData/luc1024.dat", "LUC 1024", t); + BenchMarkSignature >("TestData/nr1024.dat", "NR 1024", t); + BenchMarkSignature("TestData/dsa1024.dat", "DSA 1024", t); + BenchMarkSignature >("TestData/lucs512.dat", "LUC-HMP 512", t); + BenchMarkSignature >("TestData/esig1023.dat", "ESIGN 1023", t); + BenchMarkSignature >("TestData/esig1536.dat", "ESIGN 1536", t); + } + + std::cout << "\n"; + { + BenchMarkSignature >("TestData/rsa2048.dat", "RSA 2048", t); + BenchMarkSignature >("TestData/rw2048.dat", "RW 2048", t); + BenchMarkSignature >("TestData/luc2048.dat", "LUC 2048", t); + BenchMarkSignature >("TestData/nr2048.dat", "NR 2048", t); + BenchMarkSignature >("TestData/lucs1024.dat", "LUC-HMP 1024", t); + BenchMarkSignature >("TestData/esig2046.dat", "ESIGN 2046", t); + } + + std::cout << "\n"; + { + BenchMarkKeyAgreement("TestData/xtrdh171.dat", "XTR-DH 171", t); + BenchMarkKeyAgreement("TestData/xtrdh342.dat", "XTR-DH 342", t); + BenchMarkKeyAgreement("TestData/dh1024.dat", "DH 1024", t); + BenchMarkKeyAgreement("TestData/dh2048.dat", "DH 2048", t); + BenchMarkKeyAgreement("TestData/lucd512.dat", "LUCDIF 512", t); + BenchMarkKeyAgreement("TestData/lucd1024.dat", "LUCDIF 1024", t); + BenchMarkKeyAgreement("TestData/mqv1024.dat", "MQV 1024", t); + BenchMarkKeyAgreement("TestData/mqv2048.dat", "MQV 2048", t); + } + + std::cout << "\n
OperationMilliseconds/Operation" << mco; + + std::cout << "\n
" << std::endl; +} + +void BenchmarkEllipticCurveAlgorithms(double t, double hertz) +{ + g_allocatedTime = t; + g_hertz = hertz; + + const char *mco; + if (g_hertz > 1.0f) + mco = "Megacycles/Operation"; + else + mco = ""; + + std::cout << "\n"; + std::cout << "\n"; + std::cout << "\n"; + std::cout << "\n"; + { + ed25519::Signer sign(Test::GlobalRNG()); + ed25519::Verifier verify(sign); + x25519 agree(Test::GlobalRNG()); + + BenchMarkSigning("ed25519", sign, t); + BenchMarkVerification("ed25519", sign, verify, t); + BenchMarkKeyGen("x25519", agree, t); + BenchMarkAgreement("x25519", agree, t); + } + +#if 0 + std::cout << "\n"; + { + BenchMarkKeyAgreement("TestData/mqv160.dat", "MQV P-160", t); + BenchMarkKeyAgreement("TestData/mqv256.dat", "MQV P-256", t); + BenchMarkKeyAgreement("TestData/mqv384.dat", "MQV P-384", t); + BenchMarkKeyAgreement("TestData/mqv512.dat", "MQV P-521", t); + + BenchMarkKeyAgreement("TestData/hmqv160.dat", "HMQV P-160", t); + BenchMarkKeyAgreement("TestData/hmqv256.dat", "HMQV P-256", t); + BenchMarkKeyAgreement("TestData/hmqv384.dat", "HMQV P-384", t); + BenchMarkKeyAgreement("TestData/hmqv512.dat", "HMQV P-521", t); + + BenchMarkKeyAgreement("TestData/fhmqv160.dat", "FHMQV P-160", t); + BenchMarkKeyAgreement("TestData/fhmqv256.dat", "FHMQV P-256", t); + BenchMarkKeyAgreement("TestData/fhmqv384.dat", "FHMQV P-384", t); + BenchMarkKeyAgreement("TestData/fhmqv512.dat", "FHMQV P-521", t); + } +#endif + + std::cout << "\n"; + { + ECIES::Decryptor cpriv(Test::GlobalRNG(), ASN1::secp256k1()); + ECIES::Encryptor cpub(cpriv); + ECDSA::Signer spriv(cpriv); + ECDSA::Verifier spub(spriv); + ECDSA_RFC6979::Signer spriv2(cpriv); + ECDSA_RFC6979::Verifier spub2(spriv2); + ECGDSA::Signer spriv3(Test::GlobalRNG(), ASN1::secp256k1()); + ECGDSA::Verifier spub3(spriv3); + ECDH::Domain ecdhc(ASN1::secp256k1()); + ECMQV::Domain ecmqvc(ASN1::secp256k1()); + + BenchMarkEncryption("ECIES over GF(p) 256", cpub, t); + BenchMarkDecryption("ECIES over GF(p) 256", cpriv, cpub, t); + BenchMarkSigning("ECDSA over GF(p) 256", spriv, t); + BenchMarkVerification("ECDSA over GF(p) 256", spriv, spub, t); + BenchMarkSigning("ECDSA-RFC6979 over GF(p) 256", spriv2, t); + BenchMarkVerification("ECDSA-RFC6979 over GF(p) 256", spriv2, spub2, t); + BenchMarkSigning("ECGDSA over GF(p) 256", spriv3, t); + BenchMarkVerification("ECGDSA over GF(p) 256", spriv3, spub3, t); + BenchMarkKeyGen("ECDHC over GF(p) 256", ecdhc, t); + BenchMarkAgreement("ECDHC over GF(p) 256", ecdhc, t); + BenchMarkKeyGen("ECMQVC over GF(p) 256", ecmqvc, t); + BenchMarkAgreement("ECMQVC over GF(p) 256", ecmqvc, t); + } + + std::cout << "\n"; + { + ECIES::Decryptor cpriv(Test::GlobalRNG(), ASN1::sect233r1()); + ECIES::Encryptor cpub(cpriv); + ECDSA::Signer spriv(cpriv); + ECDSA::Verifier spub(spriv); + ECDSA_RFC6979::Signer spriv2(cpriv); + ECDSA_RFC6979::Verifier spub2(spriv2); + ECGDSA::Signer spriv3(Test::GlobalRNG(), ASN1::sect233r1()); + ECGDSA::Verifier spub3(spriv3); + ECDH::Domain ecdhc(ASN1::sect233r1()); + ECMQV::Domain ecmqvc(ASN1::sect233r1()); + + BenchMarkEncryption("ECIES over GF(2^n) 233", cpub, t); + BenchMarkDecryption("ECIES over GF(2^n) 233", cpriv, cpub, t); + BenchMarkSigning("ECDSA over GF(2^n) 233", spriv, t); + BenchMarkVerification("ECDSA over GF(2^n) 233", spriv, spub, t); + BenchMarkSigning("ECDSA-RFC6979 over GF(2^n) 233", spriv2, t); + BenchMarkVerification("ECDSA-RFC6979 over GF(2^n) 233", spriv2, spub2, t); + BenchMarkSigning("ECGDSA over GF(2^n) 233", spriv3, t); + BenchMarkVerification("ECGDSA over GF(2^n) 233", spriv3, spub3, t); + BenchMarkKeyGen("ECDHC over GF(2^n) 233", ecdhc, t); + BenchMarkAgreement("ECDHC over GF(2^n) 233", ecdhc, t); + BenchMarkKeyGen("ECMQVC over GF(2^n) 233", ecmqvc, t); + BenchMarkAgreement("ECMQVC over GF(2^n) 233", ecmqvc, t); + } + + std::cout << "\n
OperationMilliseconds/Operation" << mco; + + std::cout << "\n
" << std::endl; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/bfinit.cpp b/external/ours/library/crypto/src/shared/original/bfinit.cpp new file mode 100755 index 000000000..06db2096f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/bfinit.cpp @@ -0,0 +1,277 @@ +#include "pch.h" +#include "blowfish.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word32 Blowfish::Base::p_init[Blowfish::ROUNDS+2] = +{ + 608135816U, 2242054355U, 320440878U, 57701188U, + 2752067618U, 698298832U, 137296536U, 3964562569U, + 1160258022U, 953160567U, 3193202383U, 887688300U, + 3232508343U, 3380367581U, 1065670069U, 3041331479U, + 2450970073U, 2306472731U +} ; + +const word32 Blowfish::Base::s_init[4*256] = { + 3509652390U, 2564797868U, 805139163U, 3491422135U, + 3101798381U, 1780907670U, 3128725573U, 4046225305U, + 614570311U, 3012652279U, 134345442U, 2240740374U, + 1667834072U, 1901547113U, 2757295779U, 4103290238U, + 227898511U, 1921955416U, 1904987480U, 2182433518U, + 2069144605U, 3260701109U, 2620446009U, 720527379U, + 3318853667U, 677414384U, 3393288472U, 3101374703U, + 2390351024U, 1614419982U, 1822297739U, 2954791486U, + 3608508353U, 3174124327U, 2024746970U, 1432378464U, + 3864339955U, 2857741204U, 1464375394U, 1676153920U, + 1439316330U, 715854006U, 3033291828U, 289532110U, + 2706671279U, 2087905683U, 3018724369U, 1668267050U, + 732546397U, 1947742710U, 3462151702U, 2609353502U, + 2950085171U, 1814351708U, 2050118529U, 680887927U, + 999245976U, 1800124847U, 3300911131U, 1713906067U, + 1641548236U, 4213287313U, 1216130144U, 1575780402U, + 4018429277U, 3917837745U, 3693486850U, 3949271944U, + 596196993U, 3549867205U, 258830323U, 2213823033U, + 772490370U, 2760122372U, 1774776394U, 2652871518U, + 566650946U, 4142492826U, 1728879713U, 2882767088U, + 1783734482U, 3629395816U, 2517608232U, 2874225571U, + 1861159788U, 326777828U, 3124490320U, 2130389656U, + 2716951837U, 967770486U, 1724537150U, 2185432712U, + 2364442137U, 1164943284U, 2105845187U, 998989502U, + 3765401048U, 2244026483U, 1075463327U, 1455516326U, + 1322494562U, 910128902U, 469688178U, 1117454909U, + 936433444U, 3490320968U, 3675253459U, 1240580251U, + 122909385U, 2157517691U, 634681816U, 4142456567U, + 3825094682U, 3061402683U, 2540495037U, 79693498U, + 3249098678U, 1084186820U, 1583128258U, 426386531U, + 1761308591U, 1047286709U, 322548459U, 995290223U, + 1845252383U, 2603652396U, 3431023940U, 2942221577U, + 3202600964U, 3727903485U, 1712269319U, 422464435U, + 3234572375U, 1170764815U, 3523960633U, 3117677531U, + 1434042557U, 442511882U, 3600875718U, 1076654713U, + 1738483198U, 4213154764U, 2393238008U, 3677496056U, + 1014306527U, 4251020053U, 793779912U, 2902807211U, + 842905082U, 4246964064U, 1395751752U, 1040244610U, + 2656851899U, 3396308128U, 445077038U, 3742853595U, + 3577915638U, 679411651U, 2892444358U, 2354009459U, + 1767581616U, 3150600392U, 3791627101U, 3102740896U, + 284835224U, 4246832056U, 1258075500U, 768725851U, + 2589189241U, 3069724005U, 3532540348U, 1274779536U, + 3789419226U, 2764799539U, 1660621633U, 3471099624U, + 4011903706U, 913787905U, 3497959166U, 737222580U, + 2514213453U, 2928710040U, 3937242737U, 1804850592U, + 3499020752U, 2949064160U, 2386320175U, 2390070455U, + 2415321851U, 4061277028U, 2290661394U, 2416832540U, + 1336762016U, 1754252060U, 3520065937U, 3014181293U, + 791618072U, 3188594551U, 3933548030U, 2332172193U, + 3852520463U, 3043980520U, 413987798U, 3465142937U, + 3030929376U, 4245938359U, 2093235073U, 3534596313U, + 375366246U, 2157278981U, 2479649556U, 555357303U, + 3870105701U, 2008414854U, 3344188149U, 4221384143U, + 3956125452U, 2067696032U, 3594591187U, 2921233993U, + 2428461U, 544322398U, 577241275U, 1471733935U, + 610547355U, 4027169054U, 1432588573U, 1507829418U, + 2025931657U, 3646575487U, 545086370U, 48609733U, + 2200306550U, 1653985193U, 298326376U, 1316178497U, + 3007786442U, 2064951626U, 458293330U, 2589141269U, + 3591329599U, 3164325604U, 727753846U, 2179363840U, + 146436021U, 1461446943U, 4069977195U, 705550613U, + 3059967265U, 3887724982U, 4281599278U, 3313849956U, + 1404054877U, 2845806497U, 146425753U, 1854211946U, + + 1266315497U, 3048417604U, 3681880366U, 3289982499U, + 2909710000U, 1235738493U, 2632868024U, 2414719590U, + 3970600049U, 1771706367U, 1449415276U, 3266420449U, + 422970021U, 1963543593U, 2690192192U, 3826793022U, + 1062508698U, 1531092325U, 1804592342U, 2583117782U, + 2714934279U, 4024971509U, 1294809318U, 4028980673U, + 1289560198U, 2221992742U, 1669523910U, 35572830U, + 157838143U, 1052438473U, 1016535060U, 1802137761U, + 1753167236U, 1386275462U, 3080475397U, 2857371447U, + 1040679964U, 2145300060U, 2390574316U, 1461121720U, + 2956646967U, 4031777805U, 4028374788U, 33600511U, + 2920084762U, 1018524850U, 629373528U, 3691585981U, + 3515945977U, 2091462646U, 2486323059U, 586499841U, + 988145025U, 935516892U, 3367335476U, 2599673255U, + 2839830854U, 265290510U, 3972581182U, 2759138881U, + 3795373465U, 1005194799U, 847297441U, 406762289U, + 1314163512U, 1332590856U, 1866599683U, 4127851711U, + 750260880U, 613907577U, 1450815602U, 3165620655U, + 3734664991U, 3650291728U, 3012275730U, 3704569646U, + 1427272223U, 778793252U, 1343938022U, 2676280711U, + 2052605720U, 1946737175U, 3164576444U, 3914038668U, + 3967478842U, 3682934266U, 1661551462U, 3294938066U, + 4011595847U, 840292616U, 3712170807U, 616741398U, + 312560963U, 711312465U, 1351876610U, 322626781U, + 1910503582U, 271666773U, 2175563734U, 1594956187U, + 70604529U, 3617834859U, 1007753275U, 1495573769U, + 4069517037U, 2549218298U, 2663038764U, 504708206U, + 2263041392U, 3941167025U, 2249088522U, 1514023603U, + 1998579484U, 1312622330U, 694541497U, 2582060303U, + 2151582166U, 1382467621U, 776784248U, 2618340202U, + 3323268794U, 2497899128U, 2784771155U, 503983604U, + 4076293799U, 907881277U, 423175695U, 432175456U, + 1378068232U, 4145222326U, 3954048622U, 3938656102U, + 3820766613U, 2793130115U, 2977904593U, 26017576U, + 3274890735U, 3194772133U, 1700274565U, 1756076034U, + 4006520079U, 3677328699U, 720338349U, 1533947780U, + 354530856U, 688349552U, 3973924725U, 1637815568U, + 332179504U, 3949051286U, 53804574U, 2852348879U, + 3044236432U, 1282449977U, 3583942155U, 3416972820U, + 4006381244U, 1617046695U, 2628476075U, 3002303598U, + 1686838959U, 431878346U, 2686675385U, 1700445008U, + 1080580658U, 1009431731U, 832498133U, 3223435511U, + 2605976345U, 2271191193U, 2516031870U, 1648197032U, + 4164389018U, 2548247927U, 300782431U, 375919233U, + 238389289U, 3353747414U, 2531188641U, 2019080857U, + 1475708069U, 455242339U, 2609103871U, 448939670U, + 3451063019U, 1395535956U, 2413381860U, 1841049896U, + 1491858159U, 885456874U, 4264095073U, 4001119347U, + 1565136089U, 3898914787U, 1108368660U, 540939232U, + 1173283510U, 2745871338U, 3681308437U, 4207628240U, + 3343053890U, 4016749493U, 1699691293U, 1103962373U, + 3625875870U, 2256883143U, 3830138730U, 1031889488U, + 3479347698U, 1535977030U, 4236805024U, 3251091107U, + 2132092099U, 1774941330U, 1199868427U, 1452454533U, + 157007616U, 2904115357U, 342012276U, 595725824U, + 1480756522U, 206960106U, 497939518U, 591360097U, + 863170706U, 2375253569U, 3596610801U, 1814182875U, + 2094937945U, 3421402208U, 1082520231U, 3463918190U, + 2785509508U, 435703966U, 3908032597U, 1641649973U, + 2842273706U, 3305899714U, 1510255612U, 2148256476U, + 2655287854U, 3276092548U, 4258621189U, 236887753U, + 3681803219U, 274041037U, 1734335097U, 3815195456U, + 3317970021U, 1899903192U, 1026095262U, 4050517792U, + 356393447U, 2410691914U, 3873677099U, 3682840055U, + + 3913112168U, 2491498743U, 4132185628U, 2489919796U, + 1091903735U, 1979897079U, 3170134830U, 3567386728U, + 3557303409U, 857797738U, 1136121015U, 1342202287U, + 507115054U, 2535736646U, 337727348U, 3213592640U, + 1301675037U, 2528481711U, 1895095763U, 1721773893U, + 3216771564U, 62756741U, 2142006736U, 835421444U, + 2531993523U, 1442658625U, 3659876326U, 2882144922U, + 676362277U, 1392781812U, 170690266U, 3921047035U, + 1759253602U, 3611846912U, 1745797284U, 664899054U, + 1329594018U, 3901205900U, 3045908486U, 2062866102U, + 2865634940U, 3543621612U, 3464012697U, 1080764994U, + 553557557U, 3656615353U, 3996768171U, 991055499U, + 499776247U, 1265440854U, 648242737U, 3940784050U, + 980351604U, 3713745714U, 1749149687U, 3396870395U, + 4211799374U, 3640570775U, 1161844396U, 3125318951U, + 1431517754U, 545492359U, 4268468663U, 3499529547U, + 1437099964U, 2702547544U, 3433638243U, 2581715763U, + 2787789398U, 1060185593U, 1593081372U, 2418618748U, + 4260947970U, 69676912U, 2159744348U, 86519011U, + 2512459080U, 3838209314U, 1220612927U, 3339683548U, + 133810670U, 1090789135U, 1078426020U, 1569222167U, + 845107691U, 3583754449U, 4072456591U, 1091646820U, + 628848692U, 1613405280U, 3757631651U, 526609435U, + 236106946U, 48312990U, 2942717905U, 3402727701U, + 1797494240U, 859738849U, 992217954U, 4005476642U, + 2243076622U, 3870952857U, 3732016268U, 765654824U, + 3490871365U, 2511836413U, 1685915746U, 3888969200U, + 1414112111U, 2273134842U, 3281911079U, 4080962846U, + 172450625U, 2569994100U, 980381355U, 4109958455U, + 2819808352U, 2716589560U, 2568741196U, 3681446669U, + 3329971472U, 1835478071U, 660984891U, 3704678404U, + 4045999559U, 3422617507U, 3040415634U, 1762651403U, + 1719377915U, 3470491036U, 2693910283U, 3642056355U, + 3138596744U, 1364962596U, 2073328063U, 1983633131U, + 926494387U, 3423689081U, 2150032023U, 4096667949U, + 1749200295U, 3328846651U, 309677260U, 2016342300U, + 1779581495U, 3079819751U, 111262694U, 1274766160U, + 443224088U, 298511866U, 1025883608U, 3806446537U, + 1145181785U, 168956806U, 3641502830U, 3584813610U, + 1689216846U, 3666258015U, 3200248200U, 1692713982U, + 2646376535U, 4042768518U, 1618508792U, 1610833997U, + 3523052358U, 4130873264U, 2001055236U, 3610705100U, + 2202168115U, 4028541809U, 2961195399U, 1006657119U, + 2006996926U, 3186142756U, 1430667929U, 3210227297U, + 1314452623U, 4074634658U, 4101304120U, 2273951170U, + 1399257539U, 3367210612U, 3027628629U, 1190975929U, + 2062231137U, 2333990788U, 2221543033U, 2438960610U, + 1181637006U, 548689776U, 2362791313U, 3372408396U, + 3104550113U, 3145860560U, 296247880U, 1970579870U, + 3078560182U, 3769228297U, 1714227617U, 3291629107U, + 3898220290U, 166772364U, 1251581989U, 493813264U, + 448347421U, 195405023U, 2709975567U, 677966185U, + 3703036547U, 1463355134U, 2715995803U, 1338867538U, + 1343315457U, 2802222074U, 2684532164U, 233230375U, + 2599980071U, 2000651841U, 3277868038U, 1638401717U, + 4028070440U, 3237316320U, 6314154U, 819756386U, + 300326615U, 590932579U, 1405279636U, 3267499572U, + 3150704214U, 2428286686U, 3959192993U, 3461946742U, + 1862657033U, 1266418056U, 963775037U, 2089974820U, + 2263052895U, 1917689273U, 448879540U, 3550394620U, + 3981727096U, 150775221U, 3627908307U, 1303187396U, + 508620638U, 2975983352U, 2726630617U, 1817252668U, + 1876281319U, 1457606340U, 908771278U, 3720792119U, + 3617206836U, 2455994898U, 1729034894U, 1080033504U, + + 976866871U, 3556439503U, 2881648439U, 1522871579U, + 1555064734U, 1336096578U, 3548522304U, 2579274686U, + 3574697629U, 3205460757U, 3593280638U, 3338716283U, + 3079412587U, 564236357U, 2993598910U, 1781952180U, + 1464380207U, 3163844217U, 3332601554U, 1699332808U, + 1393555694U, 1183702653U, 3581086237U, 1288719814U, + 691649499U, 2847557200U, 2895455976U, 3193889540U, + 2717570544U, 1781354906U, 1676643554U, 2592534050U, + 3230253752U, 1126444790U, 2770207658U, 2633158820U, + 2210423226U, 2615765581U, 2414155088U, 3127139286U, + 673620729U, 2805611233U, 1269405062U, 4015350505U, + 3341807571U, 4149409754U, 1057255273U, 2012875353U, + 2162469141U, 2276492801U, 2601117357U, 993977747U, + 3918593370U, 2654263191U, 753973209U, 36408145U, + 2530585658U, 25011837U, 3520020182U, 2088578344U, + 530523599U, 2918365339U, 1524020338U, 1518925132U, + 3760827505U, 3759777254U, 1202760957U, 3985898139U, + 3906192525U, 674977740U, 4174734889U, 2031300136U, + 2019492241U, 3983892565U, 4153806404U, 3822280332U, + 352677332U, 2297720250U, 60907813U, 90501309U, + 3286998549U, 1016092578U, 2535922412U, 2839152426U, + 457141659U, 509813237U, 4120667899U, 652014361U, + 1966332200U, 2975202805U, 55981186U, 2327461051U, + 676427537U, 3255491064U, 2882294119U, 3433927263U, + 1307055953U, 942726286U, 933058658U, 2468411793U, + 3933900994U, 4215176142U, 1361170020U, 2001714738U, + 2830558078U, 3274259782U, 1222529897U, 1679025792U, + 2729314320U, 3714953764U, 1770335741U, 151462246U, + 3013232138U, 1682292957U, 1483529935U, 471910574U, + 1539241949U, 458788160U, 3436315007U, 1807016891U, + 3718408830U, 978976581U, 1043663428U, 3165965781U, + 1927990952U, 4200891579U, 2372276910U, 3208408903U, + 3533431907U, 1412390302U, 2931980059U, 4132332400U, + 1947078029U, 3881505623U, 4168226417U, 2941484381U, + 1077988104U, 1320477388U, 886195818U, 18198404U, + 3786409000U, 2509781533U, 112762804U, 3463356488U, + 1866414978U, 891333506U, 18488651U, 661792760U, + 1628790961U, 3885187036U, 3141171499U, 876946877U, + 2693282273U, 1372485963U, 791857591U, 2686433993U, + 3759982718U, 3167212022U, 3472953795U, 2716379847U, + 445679433U, 3561995674U, 3504004811U, 3574258232U, + 54117162U, 3331405415U, 2381918588U, 3769707343U, + 4154350007U, 1140177722U, 4074052095U, 668550556U, + 3214352940U, 367459370U, 261225585U, 2610173221U, + 4209349473U, 3468074219U, 3265815641U, 314222801U, + 3066103646U, 3808782860U, 282218597U, 3406013506U, + 3773591054U, 379116347U, 1285071038U, 846784868U, + 2669647154U, 3771962079U, 3550491691U, 2305946142U, + 453669953U, 1268987020U, 3317592352U, 3279303384U, + 3744833421U, 2610507566U, 3859509063U, 266596637U, + 3847019092U, 517658769U, 3462560207U, 3443424879U, + 370717030U, 4247526661U, 2224018117U, 4143653529U, + 4112773975U, 2788324899U, 2477274417U, 1456262402U, + 2901442914U, 1517677493U, 1846949527U, 2295493580U, + 3734397586U, 2176403920U, 1280348187U, 1908823572U, + 3871786941U, 846861322U, 1172426758U, 3287448474U, + 3383383037U, 1655181056U, 3139813346U, 901632758U, + 1897031941U, 2986607138U, 3066810236U, 3447102507U, + 1393639104U, 373351379U, 950779232U, 625454576U, + 3124240540U, 4148612726U, 2007998917U, 544563296U, + 2244738638U, 2330496472U, 2058025392U, 1291430526U, + 424198748U, 50039436U, 29584100U, 3605783033U, + 2429876329U, 2791104160U, 1057563949U, 3255363231U, + 3075367218U, 3463963227U, 1469046755U, 985887462U +}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/blake2.cpp b/external/ours/library/crypto/src/shared/original/blake2.cpp new file mode 100755 index 000000000..3504f1319 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blake2.cpp @@ -0,0 +1,797 @@ +// blake2.cpp - written and placed in the public domain by Jeffrey Walton +// and Zooko Wilcox-O'Hearn. Based on Aumasson, Neves, +// Wilcox-O'Hearn and Winnerlein's reference BLAKE2 +// implementation at http://github.com/BLAKE2/BLAKE2. +// +// The BLAKE2b and BLAKE2s numbers are consistent with the BLAKE2 team's +// numbers. However, we have an Altivec implementation of BLAKE2s, +// and a POWER8 implementation of BLAKE2b (BLAKE2 team is missing them). +// Altivec code is about 2x faster than C++ when using GCC 5.0 or +// above. The POWER8 code is about 2.5x faster than C++ when using GCC 5.0 +// or above. If you use GCC 4.0 (PowerMac) or GCC 4.8 (GCC Compile Farm) +// then the PowerPC code will be slower than C++. Be sure to use GCC 5.0 +// or above for PowerPC builds or disable Altivec for BLAKE2b and BLAKE2s +// if using the old compilers. + +#include "pch.h" +#include "config.h" +#include "cryptlib.h" +#include "argnames.h" +#include "algparam.h" +#include "blake2.h" +#include "cpu.h" + +// Uncomment for benchmarking C++ against SSE2 or NEON. +// Do so in both blake2.cpp and blake2_simd.cpp. +// #undef CRYPTOPP_SSE41_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE +// #undef CRYPTOPP_ALTIVEC_AVAILABLE +// #undef CRYPTOPP_POWER8_AVAILABLE + +// Disable NEON/ASIMD for Cortex-A53 and A57. The shifts are too slow and C/C++ is about +// 3 cpb faster than NEON/ASIMD. Also see http://github.com/weidai11/cryptopp/issues/367. +#if (defined(__aarch32__) || defined(__aarch64__)) && defined(CRYPTOPP_SLOW_ARMV8_SHIFT) +# undef CRYPTOPP_ARM_NEON_AVAILABLE +#endif + +// BLAKE2s bug on AIX 7.1 (POWER7) with XLC 12.01 +// https://github.com/weidai11/cryptopp/issues/743 +#if defined(__xlC__) && (__xlC__ < 0x0d01) +# define CRYPTOPP_DISABLE_ALTIVEC 1 +# undef CRYPTOPP_POWER7_AVAILABLE +# undef CRYPTOPP_POWER8_AVAILABLE +# undef CRYPTOPP_ALTIVEC_AVAILABLE +#endif + +// Can't use GetAlignmentOf() because of C++11 and constexpr +// Can use 'const unsigned int' because of MSVC 2013 +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +# define ALIGN_SPEC32 16 +# define ALIGN_SPEC64 16 +#else +# define ALIGN_SPEC32 4 +# define ALIGN_SPEC64 8 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// Export the tables to the SIMD files +extern const word32 BLAKE2S_IV[8]; +extern const word64 BLAKE2B_IV[8]; + +CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32) +const word32 BLAKE2S_IV[8] = { + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +CRYPTOPP_ALIGN_DATA(ALIGN_SPEC64) +const word64 BLAKE2B_IV[8] = { + W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), + W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), + W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), + W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179) +}; + +NAMESPACE_END + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotrConstant; + +CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32) +const byte BLAKE2S_SIGMA[10][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, +}; + +CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32) +const byte BLAKE2B_SIGMA[12][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + +template +inline void BLAKE2B_G(const word64 m[16], word64& a, word64& b, word64& c, word64& d) +{ + a = a + b + m[BLAKE2B_SIGMA[R][2*N+0]]; + d = rotrConstant<32>(d ^ a); + c = c + d; + b = rotrConstant<24>(b ^ c); + a = a + b + m[BLAKE2B_SIGMA[R][2*N+1]]; + d = rotrConstant<16>(d ^ a); + c = c + d; + b = rotrConstant<63>(b ^ c); +} + +template +inline void BLAKE2B_ROUND(const word64 m[16], word64 v[16]) +{ + BLAKE2B_G(m,v[ 0],v[ 4],v[ 8],v[12]); + BLAKE2B_G(m,v[ 1],v[ 5],v[ 9],v[13]); + BLAKE2B_G(m,v[ 2],v[ 6],v[10],v[14]); + BLAKE2B_G(m,v[ 3],v[ 7],v[11],v[15]); + BLAKE2B_G(m,v[ 0],v[ 5],v[10],v[15]); + BLAKE2B_G(m,v[ 1],v[ 6],v[11],v[12]); + BLAKE2B_G(m,v[ 2],v[ 7],v[ 8],v[13]); + BLAKE2B_G(m,v[ 3],v[ 4],v[ 9],v[14]); +} + +template +inline void BLAKE2S_G(const word32 m[16], word32& a, word32& b, word32& c, word32& d) +{ + a = a + b + m[BLAKE2S_SIGMA[R][2*N+0]]; + d = rotrConstant<16>(d ^ a); + c = c + d; + b = rotrConstant<12>(b ^ c); + a = a + b + m[BLAKE2S_SIGMA[R][2*N+1]]; + d = rotrConstant<8>(d ^ a); + c = c + d; + b = rotrConstant<7>(b ^ c); +} + +template +inline void BLAKE2S_ROUND(const word32 m[16], word32 v[]) +{ + BLAKE2S_G(m,v[ 0],v[ 4],v[ 8],v[12]); + BLAKE2S_G(m,v[ 1],v[ 5],v[ 9],v[13]); + BLAKE2S_G(m,v[ 2],v[ 6],v[10],v[14]); + BLAKE2S_G(m,v[ 3],v[ 7],v[11],v[15]); + BLAKE2S_G(m,v[ 0],v[ 5],v[10],v[15]); + BLAKE2S_G(m,v[ 1],v[ 6],v[11],v[12]); + BLAKE2S_G(m,v[ 2],v[ 7],v[ 8],v[13]); + BLAKE2S_G(m,v[ 3],v[ 4],v[ 9],v[14]); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void BLAKE2_Compress32_CXX(const byte* input, BLAKE2s_State& state); +void BLAKE2_Compress64_CXX(const byte* input, BLAKE2b_State& state); + +#if CRYPTOPP_SSE41_AVAILABLE +extern void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2s_State& state); +extern void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2b_State& state); +#endif + +#if CRYPTOPP_ARM_NEON_AVAILABLE +extern void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state); +extern void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state); +#endif + +#if CRYPTOPP_ALTIVEC_AVAILABLE +extern void BLAKE2_Compress32_ALTIVEC(const byte* input, BLAKE2s_State& state); +#endif + +#if CRYPTOPP_POWER8_AVAILABLE +extern void BLAKE2_Compress64_POWER8(const byte* input, BLAKE2b_State& state); +#endif + +unsigned int BLAKE2b::OptimalDataAlignment() const +{ +#if defined(CRYPTOPP_SSE41_AVAILABLE) + if (HasSSE41()) + return 16; // load __m128i + else +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return 8; // load uint64x2_t + else +#endif +#if (CRYPTOPP_POWER8_AVAILABLE) + if (HasPower8()) + return 16; // load vector long long + else +#endif + return GetAlignmentOf(); +} + +std::string BLAKE2b::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_SSE41_AVAILABLE) + if (HasSSE41()) + return "SSE4.1"; + else +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; + else +#endif +#if (CRYPTOPP_POWER8_AVAILABLE) + if (HasPower8()) + return "Power8"; + else +#endif + return "C++"; +} + +unsigned int BLAKE2s::OptimalDataAlignment() const +{ +#if defined(CRYPTOPP_SSE41_AVAILABLE) + if (HasSSE41()) + return 16; // load __m128i + else +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return 4; // load uint32x4_t + else +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return 16; // load vector unsigned int + else +#endif + return GetAlignmentOf(); +} + +std::string BLAKE2s::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_SSE41_AVAILABLE) + if (HasSSE41()) + return "SSE4.1"; + else +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; + else +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return "Altivec"; + else +#endif + return "C++"; +} + +void BLAKE2s_State::Reset() +{ + std::memset(m_hft, 0x00, m_hft.SizeInBytes()); + m_len = 0; +} + +void BLAKE2b_State::Reset() +{ + std::memset(m_hft, 0x00, m_hft.SizeInBytes()); + m_len = 0; +} + +BLAKE2s_ParameterBlock::BLAKE2s_ParameterBlock(size_t digestLen, size_t keyLen, + const byte* saltStr, size_t saltLen, + const byte* personalizationStr, size_t personalizationLen) +{ + Reset(digestLen, keyLen); + + if (saltStr && saltLen) + memcpy_s(salt(), SALTSIZE, saltStr, saltLen); + + if (personalizationStr && personalizationLen) + memcpy_s(personalization(), PERSONALIZATIONSIZE, personalizationStr, personalizationLen); +} + +BLAKE2b_ParameterBlock::BLAKE2b_ParameterBlock(size_t digestLen, size_t keyLen, + const byte* saltStr, size_t saltLen, + const byte* personalizationStr, size_t personalizationLen) +{ + Reset(digestLen, keyLen); + + if (saltStr && saltLen) + memcpy_s(salt(), SALTSIZE, saltStr, saltLen); + + if (personalizationStr && personalizationLen) + memcpy_s(personalization(), PERSONALIZATIONSIZE, personalizationStr, personalizationLen); +} + +void BLAKE2s_ParameterBlock::Reset(size_t digestLen, size_t keyLen) +{ + std::memset(m_data, 0x00, m_data.size()); + m_data[DigestOff] = static_cast(digestLen); + m_data[KeyOff] = static_cast(keyLen); + m_data[FanoutOff] = m_data[DepthOff] = 1; +} + +void BLAKE2b_ParameterBlock::Reset(size_t digestLen, size_t keyLen) +{ + std::memset(m_data, 0x00, m_data.size()); + m_data[DigestOff] = static_cast(digestLen); + m_data[KeyOff] = static_cast(keyLen); + m_data[FanoutOff] = m_data[DepthOff] = 1; +} + +BLAKE2s::BLAKE2s(bool treeMode, unsigned int digestSize) + : m_digestSize(digestSize), m_keyLength(0), m_treeMode(treeMode) +{ + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + + UncheckedSetKey(NULLPTR, 0, MakeParameters + (Name::DigestSize(), (int)digestSize) + (Name::TreeMode(), treeMode)); +} + +BLAKE2b::BLAKE2b(bool treeMode, unsigned int digestSize) + : m_digestSize(digestSize), m_keyLength(0), m_treeMode(treeMode) +{ + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + + UncheckedSetKey(NULLPTR, 0, MakeParameters + (Name::DigestSize(), (int)digestSize) + (Name::TreeMode(), treeMode)); +} + +BLAKE2s::BLAKE2s(unsigned int digestSize) + : m_digestSize(digestSize), m_keyLength(0), m_treeMode(false) +{ + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + + UncheckedSetKey(NULLPTR, 0, MakeParameters + (Name::DigestSize(), (int)digestSize) + (Name::TreeMode(), false)); +} + +BLAKE2b::BLAKE2b(unsigned int digestSize) + : m_digestSize(digestSize), m_keyLength(0), m_treeMode(false) +{ + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + + UncheckedSetKey(NULLPTR, 0, MakeParameters + (Name::DigestSize(), (int)digestSize) + (Name::TreeMode(), false)); +} + +BLAKE2s::BLAKE2s(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize) + : m_digestSize(digestSize), m_keyLength(static_cast(keyLength)), m_treeMode(treeMode) +{ + CRYPTOPP_ASSERT(keyLength <= MAX_KEYLENGTH); + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + CRYPTOPP_ASSERT(saltLength <= SALTSIZE); + CRYPTOPP_ASSERT(personalizationLength <= PERSONALIZATIONSIZE); + + UncheckedSetKey(key, static_cast(keyLength), MakeParameters + (Name::DigestSize(),(int)digestSize) + (Name::TreeMode(),treeMode) + (Name::Salt(), ConstByteArrayParameter(salt, saltLength)) + (Name::Personalization(), ConstByteArrayParameter(personalization, personalizationLength))); +} + +BLAKE2b::BLAKE2b(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize) + : m_digestSize(digestSize), m_keyLength(static_cast(keyLength)), m_treeMode(treeMode) +{ + CRYPTOPP_ASSERT(keyLength <= MAX_KEYLENGTH); + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + CRYPTOPP_ASSERT(saltLength <= SALTSIZE); + CRYPTOPP_ASSERT(personalizationLength <= PERSONALIZATIONSIZE); + + UncheckedSetKey(key, static_cast(keyLength), MakeParameters + (Name::DigestSize(),(int)digestSize) + (Name::TreeMode(),treeMode) + (Name::Salt(), ConstByteArrayParameter(salt, saltLength)) + (Name::Personalization(), ConstByteArrayParameter(personalization, personalizationLength))); +} + +void BLAKE2s::UncheckedSetKey(const byte *key, unsigned int length, const CryptoPP::NameValuePairs& params) +{ + if (key && length) + { + m_key.New(BLOCKSIZE); + std::memcpy(m_key, key, length); + std::memset(m_key + length, 0x00, BLOCKSIZE - length); + m_keyLength = length; + } + else + { + m_key.resize(0); + m_keyLength = 0; + } + + m_digestSize = static_cast(params.GetIntValueWithDefault( + Name::DigestSize(), static_cast(m_digestSize))); + + m_state.Reset(); + m_block.Reset(m_digestSize, m_keyLength); + (void)params.GetValue(Name::TreeMode(), m_treeMode); + + ConstByteArrayParameter t; + if (params.GetValue(Name::Salt(), t) && t.begin() && t.size()) + memcpy_s(m_block.salt(), SALTSIZE, t.begin(), t.size()); + + if (params.GetValue(Name::Personalization(), t) && t.begin() && t.size()) + memcpy_s(m_block.personalization(), PERSONALIZATIONSIZE, t.begin(), t.size()); + + Restart(); +} + +void BLAKE2b::UncheckedSetKey(const byte *key, unsigned int length, const CryptoPP::NameValuePairs& params) +{ + if (key && length) + { + m_key.New(BLOCKSIZE); + std::memcpy(m_key, key, length); + std::memset(m_key + length, 0x00, BLOCKSIZE - length); + m_keyLength = length; + } + else + { + m_key.resize(0); + m_keyLength = 0; + } + + m_digestSize = static_cast(params.GetIntValueWithDefault( + Name::DigestSize(), static_cast(m_digestSize))); + + m_state.Reset(); + m_block.Reset(m_digestSize, m_keyLength); + (void)params.GetValue(Name::TreeMode(), m_treeMode); + + ConstByteArrayParameter t; + if (params.GetValue(Name::Salt(), t) && t.begin() && t.size()) + memcpy_s(m_block.salt(), SALTSIZE, t.begin(), t.size()); + + if (params.GetValue(Name::Personalization(), t) && t.begin() && t.size()) + memcpy_s(m_block.personalization(), PERSONALIZATIONSIZE, t.begin(), t.size()); + + Restart(); +} + +void BLAKE2s::Restart() +{ + static const word32 zero[2] = {0,0}; + Restart(m_block, zero); +} + +void BLAKE2b::Restart() +{ + static const word64 zero[2] = {0,0}; + Restart(m_block, zero); +} + +void BLAKE2s::Restart(const BLAKE2s_ParameterBlock& block, const word32 counter[2]) +{ + // We take a counter as a parameter to allow customized state. + m_state.Reset(); + if (counter != NULLPTR) + { + word32* t = m_state.t(); + t[0] = counter[0]; + t[1] = counter[1]; + } + + // We take a parameter block as a parameter to allow customized state. + // Avoid the copy of the parameter block when we are passing our own block. + if (block.data() != m_block.data()) { + std::memcpy(m_block.data(), block.data(), m_block.size()); + } + + m_block.m_data[BLAKE2s_ParameterBlock::DigestOff] = (byte)m_digestSize; + m_block.m_data[BLAKE2s_ParameterBlock::KeyOff] = (byte)m_keyLength; + + const word32* iv = BLAKE2S_IV; + PutBlock put(m_block.data(), m_state.h()); + put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]); + + // When BLAKE2 is keyed, the input stream is simply {key || 0 || message}. + // The key is padded to a full Blocksize with 0. Key it during Restart to + // avoid FirstPut and friends. Key size == 0 means no key. + if (m_keyLength) + Update(m_key, BLOCKSIZE); +} + +void BLAKE2b::Restart(const BLAKE2b_ParameterBlock& block, const word64 counter[2]) +{ + // We take a counter as a parameter to allow customized state. + m_state.Reset(); + if (counter != NULLPTR) + { + word64* t = m_state.t(); + t[0] = counter[0]; + t[1] = counter[1]; + } + + // We take a parameter block as a parameter to allow customized state. + // Avoid the copy of the parameter block when we are passing our own block. + if (block.data() != m_block.data()) { + std::memcpy(m_block.data(), block.data(), m_block.size()); + } + + m_block.m_data[BLAKE2b_ParameterBlock::DigestOff] = (byte)m_digestSize; + m_block.m_data[BLAKE2b_ParameterBlock::KeyOff] = (byte)m_keyLength; + + const word64* iv = BLAKE2B_IV; + PutBlock put(m_block.data(), m_state.h()); + put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]); + + // When BLAKE2 is keyed, the input stream is simply {key || 0 || message}. + // The key is padded to a full Blocksize with 0. Key it during Restart to + // avoid FirstPut and friends. Key size == 0 means no key. + if (m_keyLength) + Update(m_key, BLOCKSIZE); +} + +void BLAKE2s::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(input != NULLPTR || length == 0); + + if (length > BLOCKSIZE - m_state.m_len) + { + if (m_state.m_len != 0) + { + // Complete current block + const size_t fill = BLOCKSIZE - m_state.m_len; + std::memcpy(m_state.m_buf+m_state.m_len, input, fill); + + IncrementCounter(BLOCKSIZE); + Compress(m_state.m_buf); + m_state.m_len = 0; + + length -= fill, input += fill; + } + + // Compress in-place to avoid copies + while (length > BLOCKSIZE) + { + IncrementCounter(BLOCKSIZE); + Compress(input); + length -= BLOCKSIZE, input += BLOCKSIZE; + } + } + + // Copy tail bytes + if (length) + { + CRYPTOPP_ASSERT(length <= BLOCKSIZE - m_state.m_len); + std::memcpy(m_state.m_buf+m_state.m_len, input, length); + m_state.m_len += static_cast(length); + } +} + +void BLAKE2b::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(input != NULLPTR || length == 0); + + if (length > BLOCKSIZE - m_state.m_len) + { + if (m_state.m_len != 0) + { + // Complete current block + const size_t fill = BLOCKSIZE - m_state.m_len; + std::memcpy(m_state.m_buf+m_state.m_len, input, fill); + + IncrementCounter(BLOCKSIZE); + Compress(m_state.m_buf); + m_state.m_len = 0; + + length -= fill, input += fill; + } + + // Compress in-place to avoid copies + while (length > BLOCKSIZE) + { + CRYPTOPP_ASSERT(m_state.m_len == 0); + IncrementCounter(BLOCKSIZE); + Compress(input); + length -= BLOCKSIZE, input += BLOCKSIZE; + } + } + + // Copy tail bytes + if (length) + { + CRYPTOPP_ASSERT(length <= BLOCKSIZE - m_state.m_len); + std::memcpy(m_state.m_buf + m_state.m_len, input, length); + m_state.m_len += static_cast(length); + } +} + +void BLAKE2s::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + this->ThrowIfInvalidTruncatedSize(size); + word32* f = m_state.f(); + + // Set last block unconditionally + f[0] = ~static_cast(0); + + // Set last node if tree mode + if (m_treeMode) + f[1] = ~static_cast(0); + + // Increment counter for tail bytes only + IncrementCounter(m_state.m_len); + + std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len); + Compress(m_state.m_buf); + + // Copy to caller buffer + std::memcpy(hash, m_state.h(), size); + + Restart(); +} + +void BLAKE2b::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + this->ThrowIfInvalidTruncatedSize(size); + word64* f = m_state.f(); + + // Set last block unconditionally + f[0] = ~static_cast(0); + + // Set last node if tree mode + if (m_treeMode) + f[1] = ~static_cast(0); + + // Increment counter for tail bytes only + IncrementCounter(m_state.m_len); + + std::memset(m_state.m_buf + m_state.m_len, 0x00, BLOCKSIZE - m_state.m_len); + Compress(m_state.m_buf); + + // Copy to caller buffer + std::memcpy(hash, m_state.h(), size); + + Restart(); +} + +void BLAKE2s::IncrementCounter(size_t count) +{ + word32* t = m_state.t(); + t[0] += static_cast(count); + t[1] += !!(t[0] < count); +} + +void BLAKE2b::IncrementCounter(size_t count) +{ + word64* t = m_state.t(); + t[0] += static_cast(count); + t[1] += !!(t[0] < count); +} + +void BLAKE2s::Compress(const byte *input) +{ +#if CRYPTOPP_SSE41_AVAILABLE + if(HasSSE41()) + { + return BLAKE2_Compress32_SSE4(input, m_state); + } +#endif +#if CRYPTOPP_ARM_NEON_AVAILABLE + if(HasNEON()) + { + return BLAKE2_Compress32_NEON(input, m_state); + } +#endif +#if CRYPTOPP_ALTIVEC_AVAILABLE + if(HasAltivec()) + { + return BLAKE2_Compress32_ALTIVEC(input, m_state); + } +#endif + return BLAKE2_Compress32_CXX(input, m_state); +} + +void BLAKE2b::Compress(const byte *input) +{ +#if CRYPTOPP_SSE41_AVAILABLE + if(HasSSE41()) + { + return BLAKE2_Compress64_SSE4(input, m_state); + } +#endif +#if CRYPTOPP_ARM_NEON_AVAILABLE + if(HasNEON()) + { + return BLAKE2_Compress64_NEON(input, m_state); + } +#endif +#if CRYPTOPP_POWER8_AVAILABLE + if(HasPower8()) + { + return BLAKE2_Compress64_POWER8(input, m_state); + } +#endif + return BLAKE2_Compress64_CXX(input, m_state); +} + +void BLAKE2_Compress64_CXX(const byte* input, BLAKE2b_State& state) +{ + word64 m[16], v[16]; + + GetBlock get1(input); + get1(m[0])(m[1])(m[2])(m[3])(m[4])(m[5])(m[6])(m[7])(m[8])(m[9])(m[10])(m[11])(m[12])(m[13])(m[14])(m[15]); + + GetBlock get2(state.h()); + get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]); + + const word64* iv = BLAKE2B_IV; + const word64* tf = state.t(); + v[ 8] = iv[0]; + v[ 9] = iv[1]; + v[10] = iv[2]; + v[11] = iv[3]; + v[12] = tf[0] ^ iv[4]; + v[13] = tf[1] ^ iv[5]; + v[14] = tf[2] ^ iv[6]; + v[15] = tf[3] ^ iv[7]; + + BLAKE2B_ROUND<0>(m, v); + BLAKE2B_ROUND<1>(m, v); + BLAKE2B_ROUND<2>(m, v); + BLAKE2B_ROUND<3>(m, v); + BLAKE2B_ROUND<4>(m, v); + BLAKE2B_ROUND<5>(m, v); + BLAKE2B_ROUND<6>(m, v); + BLAKE2B_ROUND<7>(m, v); + BLAKE2B_ROUND<8>(m, v); + BLAKE2B_ROUND<9>(m, v); + BLAKE2B_ROUND<10>(m, v); + BLAKE2B_ROUND<11>(m, v); + + word64* h = state.h(); + for (unsigned int i = 0; i < 8; ++i) + h[i] = h[i] ^ ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v[i] ^ v[i + 8]); +} + +void BLAKE2_Compress32_CXX(const byte* input, BLAKE2s_State& state) +{ + word32 m[16], v[16]; + + GetBlock get1(input); + get1(m[0])(m[1])(m[2])(m[3])(m[4])(m[5])(m[6])(m[7])(m[8])(m[9])(m[10])(m[11])(m[12])(m[13])(m[14])(m[15]); + + GetBlock get2(state.h()); + get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]); + + const word32* iv = BLAKE2S_IV; + const word32* tf = state.t(); + v[ 8] = iv[0]; + v[ 9] = iv[1]; + v[10] = iv[2]; + v[11] = iv[3]; + v[12] = tf[0] ^ iv[4]; + v[13] = tf[1] ^ iv[5]; + v[14] = tf[2] ^ iv[6]; + v[15] = tf[3] ^ iv[7]; + + BLAKE2S_ROUND<0>(m, v); + BLAKE2S_ROUND<1>(m, v); + BLAKE2S_ROUND<2>(m, v); + BLAKE2S_ROUND<3>(m, v); + BLAKE2S_ROUND<4>(m, v); + BLAKE2S_ROUND<5>(m, v); + BLAKE2S_ROUND<6>(m, v); + BLAKE2S_ROUND<7>(m, v); + BLAKE2S_ROUND<8>(m, v); + BLAKE2S_ROUND<9>(m, v); + + word32* h = state.h(); + for (unsigned int i = 0; i < 8; ++i) + h[i] = h[i] ^ ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v[i] ^ v[i + 8]); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/blake2.h b/external/ours/library/crypto/src/shared/original/blake2.h new file mode 100755 index 000000000..896421a89 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blake2.h @@ -0,0 +1,444 @@ +// blake2.h - written and placed in the public domain by Jeffrey Walton +// and Zooko Wilcox-O'Hearn. Based on Aumasson, Neves, +// Wilcox-O'Hearn and Winnerlein's reference BLAKE2 +// implementation at http://github.com/BLAKE2/BLAKE2. + +/// \file blake2.h +/// \brief Classes for BLAKE2b and BLAKE2s message digests and keyed message digests +/// \details This implementation follows Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's +/// BLAKE2: simpler, smaller, fast as MD5 (2013.01.29). +/// Static algorithm name return either "BLAKE2b" or "BLAKE2s". An object algorithm name follows +/// the naming described in RFC 7693, The +/// BLAKE2 Cryptographic Hash and Message Authentication Code (MAC). +/// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0, +/// Power8 since Crypto++ 8.0 + +#ifndef CRYPTOPP_BLAKE2_H +#define CRYPTOPP_BLAKE2_H + +#include "cryptlib.h" +#include "secblock.h" +#include "seckey.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief BLAKE2s hash information +/// \since Crypto++ 5.6.4 +struct BLAKE2s_Info : public VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> +{ + typedef VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase; + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH); + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH); + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH); + + CRYPTOPP_CONSTANT(BLOCKSIZE = 64); + CRYPTOPP_CONSTANT(DIGESTSIZE = 32); + CRYPTOPP_CONSTANT(SALTSIZE = 8); + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 8); + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";} +}; + +/// \brief BLAKE2b hash information +/// \since Crypto++ 5.6.4 +struct BLAKE2b_Info : public VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> +{ + typedef VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase; + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH); + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH); + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH); + + CRYPTOPP_CONSTANT(BLOCKSIZE = 128); + CRYPTOPP_CONSTANT(DIGESTSIZE = 64); + CRYPTOPP_CONSTANT(SALTSIZE = 16); + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 16); + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";} +}; + +/// \brief BLAKE2s parameter block +struct CRYPTOPP_NO_VTABLE BLAKE2s_ParameterBlock +{ + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE); + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE); + + BLAKE2s_ParameterBlock() + { + Reset(); + } + + BLAKE2s_ParameterBlock(size_t digestSize) + { + Reset(digestSize); + } + + BLAKE2s_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength); + + void Reset(size_t digestLength=DIGESTSIZE, size_t keyLength=0); + + byte* data() { + return m_data.data(); + } + + const byte* data() const { + return m_data.data(); + } + + size_t size() const { + return m_data.size(); + } + + byte* salt() { + return m_data + SaltOff; + } + + byte* personalization() { + return m_data + PersonalizationOff; + } + + // Offsets into the byte array + enum { + DigestOff = 0, KeyOff = 1, FanoutOff = 2, DepthOff = 3, LeafOff = 4, NodeOff = 8, + NodeDepthOff = 14, InnerOff = 15, SaltOff = 16, PersonalizationOff = 24 + }; + + FixedSizeAlignedSecBlock m_data; +}; + +/// \brief BLAKE2b parameter block +struct CRYPTOPP_NO_VTABLE BLAKE2b_ParameterBlock +{ + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE); + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE); + + BLAKE2b_ParameterBlock() + { + Reset(); + } + + BLAKE2b_ParameterBlock(size_t digestSize) + { + Reset(digestSize); + } + + BLAKE2b_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength); + + void Reset(size_t digestLength=DIGESTSIZE, size_t keyLength=0); + + byte* data() { + return m_data.data(); + } + + const byte* data() const { + return m_data.data(); + } + + size_t size() const { + return m_data.size(); + } + + byte* salt() { + return m_data + SaltOff; + } + + byte* personalization() { + return m_data + PersonalizationOff; + } + + // Offsets into the byte array + enum { + DigestOff = 0, KeyOff = 1, FanoutOff = 2, DepthOff = 3, LeafOff = 4, NodeOff = 8, + NodeDepthOff = 16, InnerOff = 17, RfuOff = 18, SaltOff = 32, PersonalizationOff = 48 + }; + + FixedSizeAlignedSecBlock m_data; +}; + +/// \brief BLAKE2s state information +/// \since Crypto++ 5.6.4 +struct CRYPTOPP_NO_VTABLE BLAKE2s_State +{ + BLAKE2s_State() { + Reset(); + } + + void Reset(); + + inline word32* h() { + return m_hft.data(); + } + + inline word32* t() { + return m_hft.data() + 8; + } + + inline word32* f() { + return m_hft.data() + 10; + } + + inline byte* data() { + return m_buf.data(); + } + + // SSE4, Power7 and NEON depend upon t[] and f[] being side-by-side + CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE); + FixedSizeAlignedSecBlock m_hft; + FixedSizeAlignedSecBlock m_buf; + size_t m_len; +}; + +/// \brief BLAKE2b state information +/// \since Crypto++ 5.6.4 +struct CRYPTOPP_NO_VTABLE BLAKE2b_State +{ + BLAKE2b_State() { + Reset(); + } + + void Reset(); + + inline word64* h() { + return m_hft.data(); + } + + inline word64* t() { + return m_hft.data() + 8; + } + + inline word64* f() { + return m_hft.data() + 10; + } + + inline byte* data() { + return m_buf.data(); + } + + // SSE4, Power8 and NEON depend upon t[] and f[] being side-by-side + CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE); + FixedSizeAlignedSecBlock m_hft; + FixedSizeAlignedSecBlock m_buf; + size_t m_len; +}; + +/// \brief The BLAKE2s cryptographic hash function +/// \details BLAKE2s can function as both a hash and keyed hash. If you want only the hash, +/// then use the BLAKE2s constructor that accepts no parameters or digest size. If you +/// want a keyed hash, then use the constructor that accpts the key as a parameter. +/// Once a key and digest size are selected, its effectively immutable. The Restart() +/// method that accepts a ParameterBlock does not allow you to change it. +/// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's +/// BLAKE2: simpler, smaller, fast as MD5 (2013.01.29). +/// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0, +/// Power8 since Crypto++ 8.0 +class BLAKE2s : public SimpleKeyingInterfaceImpl +{ +public: + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2s_Info::DEFAULT_KEYLENGTH); + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2s_Info::MIN_KEYLENGTH); + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2s_Info::MAX_KEYLENGTH); + + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE); + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE); + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE); + + typedef BLAKE2s_State State; + typedef BLAKE2s_ParameterBlock ParameterBlock; + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";} + + virtual ~BLAKE2s() {} + + /// \brief Construct a BLAKE2s hash + /// \param digestSize the digest size, in bytes + /// \param treeMode flag indicating tree mode + /// \since Crypto++ 5.6.4 + BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Construct a BLAKE2s hash + /// \param digestSize the digest size, in bytes + /// \details treeMode flag is set to false + /// \since Crypto++ 8.2 + BLAKE2s(unsigned int digestSize); + + /// \brief Construct a BLAKE2s hash + /// \param key a byte array used to key the cipher + /// \param keyLength the size of the byte array + /// \param salt a byte array used as salt + /// \param saltLength the size of the byte array + /// \param personalization a byte array used as personalization string + /// \param personalizationLength the size of the byte array + /// \param treeMode flag indicating tree mode + /// \param digestSize the digest size, in bytes + /// \since Crypto++ 5.6.4 + BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, + const byte* personalization = NULLPTR, size_t personalizationLength = 0, + bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Retrieve the object's name + /// \return the object's algorithm name following RFC 7693 + /// \details Object algorithm name follows the naming described in + /// RFC 7693, The BLAKE2 Cryptographic Hash and + /// Message Authentication Code (MAC). For example, "BLAKE2b-512" and "BLAKE2s-256". + std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);} + + unsigned int BlockSize() const {return BLOCKSIZE;} + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const; + + void Update(const byte *input, size_t length); + void Restart(); + + /// \brief Restart a hash with parameter block and counter + /// \param block parameter block + /// \param counter counter array + /// \details Parameter block is persisted across calls to Restart(). + void Restart(const BLAKE2s_ParameterBlock& block, const word32 counter[2]); + + /// \brief Set tree mode + /// \param mode the new tree mode + /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1]. + /// If treeMode=false (default), then State::f[1] is never set. If + /// treeMode=true, then State::f[1] is set when State::f[0] is set. + /// Tree mode is persisted across calls to Restart(). + void SetTreeMode(bool mode) {m_treeMode=mode;} + + /// \brief Get tree mode + /// \return the current tree mode + /// \details Tree mode is persisted across calls to Restart(). + bool GetTreeMode() const {return m_treeMode;} + + void TruncatedFinal(byte *hash, size_t size); + + std::string AlgorithmProvider() const; + +protected: + // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's. + void Compress(const byte *input); + inline void IncrementCounter(size_t count=BLOCKSIZE); + + void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params); + +private: + State m_state; + ParameterBlock m_block; + AlignedSecByteBlock m_key; + word32 m_digestSize, m_keyLength; + bool m_treeMode; +}; + +/// \brief The BLAKE2b cryptographic hash function +/// \details BLAKE2b can function as both a hash and keyed hash. If you want only the hash, +/// then use the BLAKE2b constructor that accepts no parameters or digest size. If you +/// want a keyed hash, then use the constructor that accpts the key as a parameter. +/// Once a key and digest size are selected, its effectively immutable. The Restart() +/// method that accepts a ParameterBlock does not allow you to change it. +/// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's +/// BLAKE2: simpler, smaller, fast as MD5 (2013.01.29). +/// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0, +/// Power8 since Crypto++ 8.0 +class BLAKE2b : public SimpleKeyingInterfaceImpl +{ +public: + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2b_Info::DEFAULT_KEYLENGTH); + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2b_Info::MIN_KEYLENGTH); + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2b_Info::MAX_KEYLENGTH); + + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE); + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE); + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE); + + typedef BLAKE2b_State State; + typedef BLAKE2b_ParameterBlock ParameterBlock; + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";} + + virtual ~BLAKE2b() {} + + /// \brief Construct a BLAKE2b hash + /// \param digestSize the digest size, in bytes + /// \param treeMode flag indicating tree mode + /// \since Crypto++ 5.6.4 + BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Construct a BLAKE2s hash + /// \param digestSize the digest size, in bytes + /// \details treeMode flag is set to false + /// \since Crypto++ 8.2 + BLAKE2b(unsigned int digestSize); + + /// \brief Construct a BLAKE2b hash + /// \param key a byte array used to key the cipher + /// \param keyLength the size of the byte array + /// \param salt a byte array used as salt + /// \param saltLength the size of the byte array + /// \param personalization a byte array used as personalization string + /// \param personalizationLength the size of the byte array + /// \param treeMode flag indicating tree mode + /// \param digestSize the digest size, in bytes + /// \since Crypto++ 5.6.4 + BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, + const byte* personalization = NULLPTR, size_t personalizationLength = 0, + bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Retrieve the object's name + /// \return the object's algorithm name following RFC 7693 + /// \details Object algorithm name follows the naming described in + /// RFC 7693, The BLAKE2 Cryptographic Hash and + /// Message Authentication Code (MAC). For example, "BLAKE2b-512" and "BLAKE2s-256". + std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);} + + unsigned int BlockSize() const {return BLOCKSIZE;} + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const; + + void Update(const byte *input, size_t length); + void Restart(); + + /// \brief Restart a hash with parameter block and counter + /// \param block parameter block + /// \param counter counter array + /// \details Parameter block is persisted across calls to Restart(). + void Restart(const BLAKE2b_ParameterBlock& block, const word64 counter[2]); + + /// \brief Set tree mode + /// \param mode the new tree mode + /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1]. + /// If treeMode=false (default), then State::f[1] is never set. If + /// treeMode=true, then State::f[1] is set when State::f[0] is set. + /// Tree mode is persisted across calls to Restart(). + void SetTreeMode(bool mode) {m_treeMode=mode;} + + /// \brief Get tree mode + /// \return the current tree mode + /// \details Tree mode is persisted across calls to Restart(). + bool GetTreeMode() const {return m_treeMode;} + + void TruncatedFinal(byte *hash, size_t size); + + std::string AlgorithmProvider() const; + +protected: + + // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's. + void Compress(const byte *input); + inline void IncrementCounter(size_t count=BLOCKSIZE); + + void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params); + +private: + State m_state; + ParameterBlock m_block; + AlignedSecByteBlock m_key; + word32 m_digestSize, m_keyLength; + bool m_treeMode; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/blake2b_simd.cpp b/external/ours/library/crypto/src/shared/original/blake2b_simd.cpp new file mode 100755 index 000000000..f408b8fa7 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blake2b_simd.cpp @@ -0,0 +1,1276 @@ +// blake2_simd.cpp - written and placed in the public domain by +// Samuel Neves, Jeffrey Walton, Uri Blumenthal +// and Marcel Raad. +// +// This source file uses intrinsics to gain access to ARMv7a/ARMv8a +// NEON, Power8 and SSE4.1 instructions. A separate source file is +// needed because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "misc.h" +#include "blake2.h" + +// Uncomment for benchmarking C++ against SSE2 or NEON. +// Do so in both blake2.cpp and blake2_simd.cpp. +// #undef CRYPTOPP_SSE41_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE +// #undef CRYPTOPP_ALTIVEC_AVAILABLE + +// Disable NEON/ASIMD for Cortex-A53 and A57. The shifts are too slow and C/C++ is about +// 3 cpb faster than NEON/ASIMD. Also see http://github.com/weidai11/cryptopp/issues/367. +#if (defined(__aarch32__) || defined(__aarch64__)) && defined(CRYPTOPP_SLOW_ARMV8_SHIFT) +# undef CRYPTOPP_ARM_NEON_AVAILABLE +#endif + +// BLAKE2s bug on AIX 7.1 (POWER7) with XLC 12.01 +// https://github.com/weidai11/cryptopp/issues/743 +#if defined(__xlC__) && (__xlC__ < 0x0d01) +# define CRYPTOPP_DISABLE_ALTIVEC 1 +# undef CRYPTOPP_POWER8_AVAILABLE +# undef CRYPTOPP_ALTIVEC_AVAILABLE +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +#if (CRYPTOPP_SSE41_AVAILABLE) +# include +# include +# include +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if (CRYPTOPP_POWER8_AVAILABLE) +# include "ppc_simd.h" +#endif + +#if defined(CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE) +/* Ignore "warning: vec_lvsl is deprecated..." */ +# pragma GCC diagnostic ignored "-Wdeprecated" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char BLAKE2B_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// Exported by blake2.cpp +extern const word32 BLAKE2S_IV[8]; +extern const word64 BLAKE2B_IV[8]; + +#if CRYPTOPP_SSE41_AVAILABLE + +#define LOADU(p) _mm_loadu_si128((const __m128i *)(const void*)(p)) +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(void*)(p), r) +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2b_State& state) +{ + #define BLAKE2B_LOAD_MSG_0_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m1); \ + b1 = _mm_unpacklo_epi64(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_0_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m0, m1); \ + b1 = _mm_unpackhi_epi64(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_0_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m5); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_0_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m5); \ + b1 = _mm_unpackhi_epi64(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m2); \ + b1 = _mm_unpackhi_epi64(m4, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_alignr_epi8(m3, m7, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_3(b0, b1) \ + do { \ + b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ + b1 = _mm_unpackhi_epi64(m5, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m1); \ + b1 = _mm_unpackhi_epi64(m3, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_1(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m6, m5, 8); \ + b1 = _mm_unpackhi_epi64(m2, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m0); \ + b1 = _mm_blend_epi16(m1, m6, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m5, m1, 0xF0); \ + b1 = _mm_unpackhi_epi64(m3, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m3); \ + b1 = _mm_alignr_epi8(m2, m0, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m3, m1); \ + b1 = _mm_unpackhi_epi64(m6, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m0); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m1, m2, 0xF0); \ + b1 = _mm_blend_epi16(m2, m7, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m3, m5); \ + b1 = _mm_unpacklo_epi64(m0, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m2); \ + b1 = _mm_unpacklo_epi64(m1, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_2(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m0, m3, 0xF0); \ + b1 = _mm_blend_epi16(m2, m7, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m7, m5, 0xF0); \ + b1 = _mm_blend_epi16(m3, m1, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_4(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m6, m0, 8); \ + b1 = _mm_blend_epi16(m4, m6, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m1, m3); \ + b1 = _mm_unpacklo_epi64(m0, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m5); \ + b1 = _mm_unpackhi_epi64(m5, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m2, m3, 0xF0); \ + b1 = _mm_unpackhi_epi64(m7, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m6, m2); \ + b1 = _mm_blend_epi16(m7, m4, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_1(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m6, m0, 0xF0); \ + b1 = _mm_unpacklo_epi64(m7, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m2, m7); \ + b1 = _mm_alignr_epi8(m5, m6, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m3); \ + b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m3, m1); \ + b1 = _mm_blend_epi16(m1, m5, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m6, m3); \ + b1 = _mm_blend_epi16(m6, m1, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_2(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m7, m5, 8); \ + b1 = _mm_unpackhi_epi64(m0, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_3(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m2, m7); \ + b1 = _mm_unpacklo_epi64(m4, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m2); \ + b1 = _mm_unpacklo_epi64(m3, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m3, m7); \ + b1 = _mm_alignr_epi8(m0, m5, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m7, m4); \ + b1 = _mm_alignr_epi8(m4, m1, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_3(b0, b1) \ + do { \ + b0 = m6; \ + b1 = _mm_alignr_epi8(m5, m0, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_4(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m1, m3, 0xF0); \ + b1 = m2; \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_unpackhi_epi64(m3, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m1, m2); \ + b1 = _mm_blend_epi16(m3, m2, 0xF0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_3(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m7, m4); \ + b1 = _mm_unpackhi_epi64(m1, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_4(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m7, m5, 8); \ + b1 = _mm_unpacklo_epi64(m6, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m1); \ + b1 = _mm_unpacklo_epi64(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m0, m1); \ + b1 = _mm_unpackhi_epi64(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m5); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m5); \ + b1 = _mm_unpackhi_epi64(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m2); \ + b1 = _mm_unpackhi_epi64(m4, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_alignr_epi8(m3, m7, 8); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_3(b0, b1) \ + do { \ + b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ + b1 = _mm_unpackhi_epi64(m5, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m1); \ + b1 = _mm_unpackhi_epi64(m3, m1); \ + } while(0) + +#ifdef __XOP__ +# define MM_ROTI_EPI64(r, c) \ + _mm_roti_epi64(r, c) +#else +# define MM_ROTI_EPI64(x, c) \ + (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \ + : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c)))) +#endif + +#define BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = MM_ROTI_EPI64(row4l, -32); \ + row4h = MM_ROTI_EPI64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = MM_ROTI_EPI64(row2l, -24); \ + row2h = MM_ROTI_EPI64(row2h, -24); + +#define BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = MM_ROTI_EPI64(row4l, -16); \ + row4h = MM_ROTI_EPI64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = MM_ROTI_EPI64(row2l, -63); \ + row2h = MM_ROTI_EPI64(row2h, -63); \ + +#define BLAKE2B_DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = row4l;\ + t1 = row2l;\ + row4l = row3l;\ + row3l = row3h;\ + row3h = row4l;\ + row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \ + row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \ + row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \ + row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1)) + +#define BLAKE2B_UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = row3l;\ + row3l = row3h;\ + row3h = t0;\ + t0 = row2l;\ + t1 = row4l;\ + row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \ + row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \ + row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \ + row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1)) + +#define BLAKE2B_ROUND(r) \ + BLAKE2B_LOAD_MSG_ ##r ##_1(b0, b1); \ + BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_LOAD_MSG_ ##r ##_2(b0, b1); \ + BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + BLAKE2B_LOAD_MSG_ ##r ##_3(b0, b1); \ + BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_LOAD_MSG_ ##r ##_4(b0, b1); \ + BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; + + const __m128i r16 = _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9); + const __m128i r24 = _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10); + + const __m128i m0 = LOADU(input + 00); + const __m128i m1 = LOADU(input + 16); + const __m128i m2 = LOADU(input + 32); + const __m128i m3 = LOADU(input + 48); + const __m128i m4 = LOADU(input + 64); + const __m128i m5 = LOADU(input + 80); + const __m128i m6 = LOADU(input + 96); + const __m128i m7 = LOADU(input + 112); + + row1l = LOADU(state.h()+0); + row1h = LOADU(state.h()+2); + row2l = LOADU(state.h()+4); + row2h = LOADU(state.h()+6); + row3l = LOADU(BLAKE2B_IV+0); + row3h = LOADU(BLAKE2B_IV+2); + row4l = _mm_xor_si128(LOADU(BLAKE2B_IV+4), LOADU(state.t()+0)); + row4h = _mm_xor_si128(LOADU(BLAKE2B_IV+6), LOADU(state.f()+0)); + + BLAKE2B_ROUND(0); + BLAKE2B_ROUND(1); + BLAKE2B_ROUND(2); + BLAKE2B_ROUND(3); + BLAKE2B_ROUND(4); + BLAKE2B_ROUND(5); + BLAKE2B_ROUND(6); + BLAKE2B_ROUND(7); + BLAKE2B_ROUND(8); + BLAKE2B_ROUND(9); + BLAKE2B_ROUND(10); + BLAKE2B_ROUND(11); + + row1l = _mm_xor_si128(row3l, row1l); + row1h = _mm_xor_si128(row3h, row1h); + STOREU(state.h()+0, _mm_xor_si128(LOADU(state.h()+0), row1l)); + STOREU(state.h()+2, _mm_xor_si128(LOADU(state.h()+2), row1h)); + row2l = _mm_xor_si128(row4l, row2l); + row2h = _mm_xor_si128(row4h, row2h); + STOREU(state.h()+4, _mm_xor_si128(LOADU(state.h()+4), row2l)); + STOREU(state.h()+6, _mm_xor_si128(LOADU(state.h()+6), row2h)); +} +#endif // CRYPTOPP_SSE41_AVAILABLE + +#if CRYPTOPP_ARM_NEON_AVAILABLE +void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state) +{ + #define BLAKE2B_LOAD_MSG_0_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m1)); b1 = vcombine_u64(vget_low_u64(m2), vget_low_u64(m3)); } while(0) + + #define BLAKE2B_LOAD_MSG_0_2(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m0), vget_high_u64(m1)); b1 = vcombine_u64(vget_high_u64(m2), vget_high_u64(m3)); } while(0) + + #define BLAKE2B_LOAD_MSG_0_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m4), vget_low_u64(m5)); b1 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_0_4(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m4), vget_high_u64(m5)); b1 = vcombine_u64(vget_high_u64(m6), vget_high_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_1_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m7), vget_low_u64(m2)); b1 = vcombine_u64(vget_high_u64(m4), vget_high_u64(m6)); } while(0) + + #define BLAKE2B_LOAD_MSG_1_2(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m5), vget_low_u64(m4)); b1 = vextq_u64(m7, m3, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_1_3(b0, b1) \ + do { b0 = vextq_u64(m0, m0, 1); b1 = vcombine_u64(vget_high_u64(m5), vget_high_u64(m2)); } while(0) + + #define BLAKE2B_LOAD_MSG_1_4(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m1)); b1 = vcombine_u64(vget_high_u64(m3), vget_high_u64(m1)); } while(0) + + #define BLAKE2B_LOAD_MSG_2_1(b0, b1) \ + do { b0 = vextq_u64(m5, m6, 1); b1 = vcombine_u64(vget_high_u64(m2), vget_high_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_2_2(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m4), vget_low_u64(m0)); b1 = vcombine_u64(vget_low_u64(m1), vget_high_u64(m6)); } while(0) + + #define BLAKE2B_LOAD_MSG_2_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m5), vget_high_u64(m1)); b1 = vcombine_u64(vget_high_u64(m3), vget_high_u64(m4)); } while(0) + + #define BLAKE2B_LOAD_MSG_2_4(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m7), vget_low_u64(m3)); b1 = vextq_u64(m0, m2, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_3_1(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m3), vget_high_u64(m1)); b1 = vcombine_u64(vget_high_u64(m6), vget_high_u64(m5)); } while(0) + + #define BLAKE2B_LOAD_MSG_3_2(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m4), vget_high_u64(m0)); b1 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_3_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m1), vget_high_u64(m2)); b1 = vcombine_u64(vget_low_u64(m2), vget_high_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_3_4(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m3), vget_low_u64(m5)); b1 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m4)); } while(0) + + #define BLAKE2B_LOAD_MSG_4_1(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m4), vget_high_u64(m2)); b1 = vcombine_u64(vget_low_u64(m1), vget_low_u64(m5)); } while(0) + + #define BLAKE2B_LOAD_MSG_4_2(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m0), vget_high_u64(m3)); b1 = vcombine_u64(vget_low_u64(m2), vget_high_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_4_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m7), vget_high_u64(m5)); b1 = vcombine_u64(vget_low_u64(m3), vget_high_u64(m1)); } while(0) + + #define BLAKE2B_LOAD_MSG_4_4(b0, b1) \ + do { b0 = vextq_u64(m0, m6, 1); b1 = vcombine_u64(vget_low_u64(m4), vget_high_u64(m6)); } while(0) + + #define BLAKE2B_LOAD_MSG_5_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m1), vget_low_u64(m3)); b1 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m4)); } while(0) + + #define BLAKE2B_LOAD_MSG_5_2(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m5)); b1 = vcombine_u64(vget_high_u64(m5), vget_high_u64(m1)); } while(0) + + #define BLAKE2B_LOAD_MSG_5_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m2), vget_high_u64(m3)); b1 = vcombine_u64(vget_high_u64(m7), vget_high_u64(m0)); } while(0) + + #define BLAKE2B_LOAD_MSG_5_4(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m6), vget_high_u64(m2)); b1 = vcombine_u64(vget_low_u64(m7), vget_high_u64(m4)); } while(0) + + #define BLAKE2B_LOAD_MSG_6_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m6), vget_high_u64(m0)); b1 = vcombine_u64(vget_low_u64(m7), vget_low_u64(m2)); } while(0) + + #define BLAKE2B_LOAD_MSG_6_2(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m2), vget_high_u64(m7)); b1 = vextq_u64(m6, m5, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_6_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m3)); b1 = vextq_u64(m4, m4, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_6_4(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m3), vget_high_u64(m1)); b1 = vcombine_u64(vget_low_u64(m1), vget_high_u64(m5)); } while(0) + + #define BLAKE2B_LOAD_MSG_7_1(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m6), vget_high_u64(m3)); b1 = vcombine_u64(vget_low_u64(m6), vget_high_u64(m1)); } while(0) + + #define BLAKE2B_LOAD_MSG_7_2(b0, b1) \ + do { b0 = vextq_u64(m5, m7, 1); b1 = vcombine_u64(vget_high_u64(m0), vget_high_u64(m4)); } while(0) + + #define BLAKE2B_LOAD_MSG_7_3(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m2), vget_high_u64(m7)); b1 = vcombine_u64(vget_low_u64(m4), vget_low_u64(m1)); } while(0) + + #define BLAKE2B_LOAD_MSG_7_4(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m2)); b1 = vcombine_u64(vget_low_u64(m3), vget_low_u64(m5)); } while(0) + + #define BLAKE2B_LOAD_MSG_8_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m3), vget_low_u64(m7)); b1 = vextq_u64(m5, m0, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_8_2(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m7), vget_high_u64(m4)); b1 = vextq_u64(m1, m4, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_8_3(b0, b1) \ + do { b0 = m6; b1 = vextq_u64(m0, m5, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_8_4(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m1), vget_high_u64(m3)); b1 = m2; } while(0) + + #define BLAKE2B_LOAD_MSG_9_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m5), vget_low_u64(m4)); b1 = vcombine_u64(vget_high_u64(m3), vget_high_u64(m0)); } while(0) + + #define BLAKE2B_LOAD_MSG_9_2(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m1), vget_low_u64(m2)); b1 = vcombine_u64(vget_low_u64(m3), vget_high_u64(m2)); } while(0) + + #define BLAKE2B_LOAD_MSG_9_3(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m7), vget_high_u64(m4)); b1 = vcombine_u64(vget_high_u64(m1), vget_high_u64(m6)); } while(0) + + #define BLAKE2B_LOAD_MSG_9_4(b0, b1) \ + do { b0 = vextq_u64(m5, m7, 1); b1 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m0)); } while(0) + + #define BLAKE2B_LOAD_MSG_10_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m1)); b1 = vcombine_u64(vget_low_u64(m2), vget_low_u64(m3)); } while(0) + + #define BLAKE2B_LOAD_MSG_10_2(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m0), vget_high_u64(m1)); b1 = vcombine_u64(vget_high_u64(m2), vget_high_u64(m3)); } while(0) + + #define BLAKE2B_LOAD_MSG_10_3(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m4), vget_low_u64(m5)); b1 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_10_4(b0, b1) \ + do { b0 = vcombine_u64(vget_high_u64(m4), vget_high_u64(m5)); b1 = vcombine_u64(vget_high_u64(m6), vget_high_u64(m7)); } while(0) + + #define BLAKE2B_LOAD_MSG_11_1(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m7), vget_low_u64(m2)); b1 = vcombine_u64(vget_high_u64(m4), vget_high_u64(m6)); } while(0) + + #define BLAKE2B_LOAD_MSG_11_2(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m5), vget_low_u64(m4)); b1 = vextq_u64(m7, m3, 1); } while(0) + + #define BLAKE2B_LOAD_MSG_11_3(b0, b1) \ + do { b0 = vextq_u64(m0, m0, 1); b1 = vcombine_u64(vget_high_u64(m5), vget_high_u64(m2)); } while(0) + + #define BLAKE2B_LOAD_MSG_11_4(b0, b1) \ + do { b0 = vcombine_u64(vget_low_u64(m6), vget_low_u64(m1)); b1 = vcombine_u64(vget_high_u64(m3), vget_high_u64(m1)); } while(0) + + #define vrorq_n_u64_32(x) vreinterpretq_u64_u32(vrev64q_u32(vreinterpretq_u32_u64((x)))) + + #define vrorq_n_u64_24(x) vcombine_u64( \ + vreinterpret_u64_u8(vext_u8(vreinterpret_u8_u64(vget_low_u64(x)), vreinterpret_u8_u64(vget_low_u64(x)), 3)), \ + vreinterpret_u64_u8(vext_u8(vreinterpret_u8_u64(vget_high_u64(x)), vreinterpret_u8_u64(vget_high_u64(x)), 3))) + + #define vrorq_n_u64_16(x) vcombine_u64( \ + vreinterpret_u64_u8(vext_u8(vreinterpret_u8_u64(vget_low_u64(x)), vreinterpret_u8_u64(vget_low_u64(x)), 2)), \ + vreinterpret_u64_u8(vext_u8(vreinterpret_u8_u64(vget_high_u64(x)), vreinterpret_u8_u64(vget_high_u64(x)), 2))) + + #define vrorq_n_u64_63(x) veorq_u64(vaddq_u64(x, x), vshrq_n_u64(x, 63)) + + #define BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + do { \ + row1l = vaddq_u64(vaddq_u64(row1l, b0), row2l); \ + row1h = vaddq_u64(vaddq_u64(row1h, b1), row2h); \ + row4l = veorq_u64(row4l, row1l); row4h = veorq_u64(row4h, row1h); \ + row4l = vrorq_n_u64_32(row4l); row4h = vrorq_n_u64_32(row4h); \ + row3l = vaddq_u64(row3l, row4l); row3h = vaddq_u64(row3h, row4h); \ + row2l = veorq_u64(row2l, row3l); row2h = veorq_u64(row2h, row3h); \ + row2l = vrorq_n_u64_24(row2l); row2h = vrorq_n_u64_24(row2h); \ + } while(0) + + #define BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + do { \ + row1l = vaddq_u64(vaddq_u64(row1l, b0), row2l); \ + row1h = vaddq_u64(vaddq_u64(row1h, b1), row2h); \ + row4l = veorq_u64(row4l, row1l); row4h = veorq_u64(row4h, row1h); \ + row4l = vrorq_n_u64_16(row4l); row4h = vrorq_n_u64_16(row4h); \ + row3l = vaddq_u64(row3l, row4l); row3h = vaddq_u64(row3h, row4h); \ + row2l = veorq_u64(row2l, row3l); row2h = veorq_u64(row2h, row3h); \ + row2l = vrorq_n_u64_63(row2l); row2h = vrorq_n_u64_63(row2h); \ + } while(0) + + #define BLAKE2B_DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + do { \ + uint64x2_t t0 = vextq_u64(row2l, row2h, 1); \ + uint64x2_t t1 = vextq_u64(row2h, row2l, 1); \ + row2l = t0; row2h = t1; t0 = row3l; row3l = row3h; row3h = t0; \ + t0 = vextq_u64(row4h, row4l, 1); t1 = vextq_u64(row4l, row4h, 1); \ + row4l = t0; row4h = t1; \ + } while(0) + + #define BLAKE2B_UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + do { \ + uint64x2_t t0 = vextq_u64(row2h, row2l, 1); \ + uint64x2_t t1 = vextq_u64(row2l, row2h, 1); \ + row2l = t0; row2h = t1; t0 = row3l; row3l = row3h; row3h = t0; \ + t0 = vextq_u64(row4l, row4h, 1); t1 = vextq_u64(row4h, row4l, 1); \ + row4l = t0; row4h = t1; \ + } while(0) + + #define BLAKE2B_ROUND(r) \ + do { \ + uint64x2_t b0, b1; \ + BLAKE2B_LOAD_MSG_ ##r ##_1(b0, b1); \ + BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_LOAD_MSG_ ##r ##_2(b0, b1); \ + BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + BLAKE2B_LOAD_MSG_ ##r ##_3(b0, b1); \ + BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_LOAD_MSG_ ##r ##_4(b0, b1); \ + BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + } while(0) + + const uint64x2_t m0 = vreinterpretq_u64_u8(vld1q_u8(input + 00)); + const uint64x2_t m1 = vreinterpretq_u64_u8(vld1q_u8(input + 16)); + const uint64x2_t m2 = vreinterpretq_u64_u8(vld1q_u8(input + 32)); + const uint64x2_t m3 = vreinterpretq_u64_u8(vld1q_u8(input + 48)); + const uint64x2_t m4 = vreinterpretq_u64_u8(vld1q_u8(input + 64)); + const uint64x2_t m5 = vreinterpretq_u64_u8(vld1q_u8(input + 80)); + const uint64x2_t m6 = vreinterpretq_u64_u8(vld1q_u8(input + 96)); + const uint64x2_t m7 = vreinterpretq_u64_u8(vld1q_u8(input + 112)); + + uint64x2_t row1l, row1h, row2l, row2h; + uint64x2_t row3l, row3h, row4l, row4h; + + const uint64x2_t h0 = row1l = vld1q_u64(state.h()+0); + const uint64x2_t h1 = row1h = vld1q_u64(state.h()+2); + const uint64x2_t h2 = row2l = vld1q_u64(state.h()+4); + const uint64x2_t h3 = row2h = vld1q_u64(state.h()+6); + + row3l = vld1q_u64(BLAKE2B_IV+0); + row3h = vld1q_u64(BLAKE2B_IV+2); + row4l = veorq_u64(vld1q_u64(BLAKE2B_IV+4), vld1q_u64(state.t()+0)); + row4h = veorq_u64(vld1q_u64(BLAKE2B_IV+6), vld1q_u64(state.f()+0)); + + BLAKE2B_ROUND(0); + BLAKE2B_ROUND(1); + BLAKE2B_ROUND(2); + BLAKE2B_ROUND(3); + BLAKE2B_ROUND(4); + BLAKE2B_ROUND(5); + BLAKE2B_ROUND(6); + BLAKE2B_ROUND(7); + BLAKE2B_ROUND(8); + BLAKE2B_ROUND(9); + BLAKE2B_ROUND(10); + BLAKE2B_ROUND(11); + + vst1q_u64(state.h()+0, veorq_u64(h0, veorq_u64(row1l, row3l))); + vst1q_u64(state.h()+2, veorq_u64(h1, veorq_u64(row1h, row3h))); + vst1q_u64(state.h()+4, veorq_u64(h2, veorq_u64(row2l, row4l))); + vst1q_u64(state.h()+6, veorq_u64(h3, veorq_u64(row2h, row4h))); +} +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_POWER8_AVAILABLE) + +inline uint64x2_p VecLoad64(const void* p) +{ + return (uint64x2_p)vec_xl(0, CONST_V32_CAST(p)); +} + +inline uint64x2_p VecLoad64LE(const void* p, const uint8x16_p le_mask) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint32x4_p v = vec_xl(0, CONST_V32_CAST(p)); + return (uint64x2_p)VecPermute(v, v, le_mask); +#else + CRYPTOPP_UNUSED(le_mask); + return (uint64x2_p)vec_xl(0, CONST_V32_CAST(p)); +#endif +} + +inline void VecStore64(void* p, const uint64x2_p x) +{ + vec_xst((uint32x4_p)x, 0, NCONST_V32_CAST(p)); +} + +inline void VecStore64LE(void* p, const uint64x2_p x, const uint8x16_p le_mask) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint64x2_p v = VecPermute(x, x, le_mask); + vec_xst((uint32x4_p)v, 0, NCONST_V32_CAST(p)); +#else + CRYPTOPP_UNUSED(le_mask); + vec_xst((uint32x4_p)x, 0, NCONST_V32_CAST(p)); +#endif +} + +#if defined(CRYPTOPP_BIG_ENDIAN) +#define vec_shl_8(a,b) (uint64x2_p)vec_sld((uint8x16_p)a,(uint8x16_p)b,8) +#else +#define vec_shl_8(a,b) (uint64x2_p)vec_sld((uint8x16_p)b,(uint8x16_p)a,8) +#endif + +#define vec_merge_hi(a, b) vec_mergeh(a,b) +#define vec_merge_hi_lo(a, b) vec_mergeh(a,(uint64x2_p)vec_sld((uint8x16_p)b,(uint8x16_p)b,8)) +#define vec_merge_lo(a, b) vec_mergel(a,b) + +void BLAKE2_Compress64_POWER8(const byte* input, BLAKE2b_State& state) +{ + #define BLAKE2B_LOAD_MSG_0_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m0, m1); \ + b1 = vec_merge_hi(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_0_2(b0, b1) \ + do { \ + b0 = vec_merge_lo(m0, m1); \ + b1 = vec_merge_lo(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_0_3(b0, b1) \ + do { \ + b0 = vec_merge_hi(m4, m5); \ + b1 = vec_merge_hi(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_0_4(b0, b1) \ + do { \ + b0 = vec_merge_lo(m4, m5); \ + b1 = vec_merge_lo(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m7, m2); \ + b1 = vec_merge_lo(m4, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_2(b0, b1) \ + do { \ + b0 = vec_merge_hi(m5, m4); \ + b1 = vec_shl_8(m7, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_3(b0, b1) \ + do { \ + b0 = vec_shl_8(m0, m0); \ + b1 = vec_merge_lo(m5, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_1_4(b0, b1) \ + do { \ + b0 = vec_merge_hi(m6, m1); \ + b1 = vec_merge_lo(m3, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_1(b0, b1) \ + do { \ + b0 = vec_shl_8(m5, m6); \ + b1 = vec_merge_lo(m2, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_2(b0, b1) \ + do { \ + b0 = vec_merge_hi(m4, m0); \ + b1 = vec_merge_hi_lo(m1, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_3(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m5, m1); \ + b1 = vec_merge_lo(m3, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_2_4(b0, b1) \ + do { \ + b0 = vec_merge_hi(m7, m3); \ + b1 = vec_shl_8(m0, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_1(b0, b1) \ + do { \ + b0 = vec_merge_lo(m3, m1); \ + b1 = vec_merge_lo(m6, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_2(b0, b1) \ + do { \ + b0 = vec_merge_lo(m4, m0); \ + b1 = vec_merge_hi(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_3(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m1, m2); \ + b1 = vec_merge_hi_lo(m2, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_3_4(b0, b1) \ + do { \ + b0 = vec_merge_hi(m3, m5); \ + b1 = vec_merge_hi(m0, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_1(b0, b1) \ + do { \ + b0 = vec_merge_lo(m4, m2); \ + b1 = vec_merge_hi(m1, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_2(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m0, m3); \ + b1 = vec_merge_hi_lo(m2, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_3(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m7, m5); \ + b1 = vec_merge_hi_lo(m3, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_4_4(b0, b1) \ + do { \ + b0 = vec_shl_8(m0, m6); \ + b1 = vec_merge_hi_lo(m4, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m1, m3); \ + b1 = vec_merge_hi(m0, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_2(b0, b1) \ + do { \ + b0 = vec_merge_hi(m6, m5); \ + b1 = vec_merge_lo(m5, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_3(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m2, m3); \ + b1 = vec_merge_lo(m7, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_5_4(b0, b1) \ + do { \ + b0 = vec_merge_lo(m6, m2); \ + b1 = vec_merge_hi_lo(m7, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_1(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m6, m0); \ + b1 = vec_merge_hi(m7, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_2(b0, b1) \ + do { \ + b0 = vec_merge_lo(m2, m7); \ + b1 = vec_shl_8(m6, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_3(b0, b1) \ + do { \ + b0 = vec_merge_hi(m0, m3); \ + b1 = vec_shl_8(m4, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_6_4(b0, b1) \ + do { \ + b0 = vec_merge_lo(m3, m1); \ + b1 = vec_merge_hi_lo(m1, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_1(b0, b1) \ + do { \ + b0 = vec_merge_lo(m6, m3); \ + b1 = vec_merge_hi_lo(m6, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_2(b0, b1) \ + do { \ + b0 = vec_shl_8(m5, m7); \ + b1 = vec_merge_lo(m0, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_3(b0, b1) \ + do { \ + b0 = vec_merge_lo(m2, m7); \ + b1 = vec_merge_hi(m4, m1); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_7_4(b0, b1) \ + do { \ + b0 = vec_merge_hi(m0, m2); \ + b1 = vec_merge_hi(m3, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m3, m7); \ + b1 = vec_shl_8(m5, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_2(b0, b1) \ + do { \ + b0 = vec_merge_lo(m7, m4); \ + b1 = vec_shl_8(m1, m4); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_3(b0, b1) \ + do { \ + b0 = m6; \ + b1 = vec_shl_8(m0, m5); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_8_4(b0, b1) \ + do { \ + b0 = vec_merge_hi_lo(m1, m3); \ + b1 = m2; \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m5, m4); \ + b1 = vec_merge_lo(m3, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_2(b0, b1) \ + do { \ + b0 = vec_merge_hi(m1, m2); \ + b1 = vec_merge_hi_lo(m3, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_3(b0, b1) \ + do { \ + b0 = vec_merge_lo(m7, m4); \ + b1 = vec_merge_lo(m1, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_9_4(b0, b1) \ + do { \ + b0 = vec_shl_8(m5, m7); \ + b1 = vec_merge_hi(m6, m0); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m0, m1); \ + b1 = vec_merge_hi(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_2(b0, b1) \ + do { \ + b0 = vec_merge_lo(m0, m1); \ + b1 = vec_merge_lo(m2, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_3(b0, b1) \ + do { \ + b0 = vec_merge_hi(m4, m5); \ + b1 = vec_merge_hi(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_10_4(b0, b1) \ + do { \ + b0 = vec_merge_lo(m4, m5); \ + b1 = vec_merge_lo(m6, m7); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_1(b0, b1) \ + do { \ + b0 = vec_merge_hi(m7, m2); \ + b1 = vec_merge_lo(m4, m6); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_2(b0, b1) \ + do { \ + b0 = vec_merge_hi(m5, m4); \ + b1 = vec_shl_8(m7, m3); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_3(b0, b1) \ + do { \ + b0 = vec_shl_8(m0, m0); \ + b1 = vec_merge_lo(m5, m2); \ + } while(0) + + #define BLAKE2B_LOAD_MSG_11_4(b0, b1) \ + do { \ + b0 = vec_merge_hi(m6, m1); \ + b1 = vec_merge_lo(m3, m1); \ + } while(0) + + // Power8 has packed 64-bit rotate, but in terms of left rotate + const uint64x2_p ROR16_MASK = { 64-16, 64-16 }; + const uint64x2_p ROR24_MASK = { 64-24, 64-24 }; + const uint64x2_p ROR32_MASK = { 64-32, 64-32 }; + const uint64x2_p ROR63_MASK = { 64-63, 64-63 }; + + #define vec_ror_32(x) vec_rl(x, ROR32_MASK) + #define vec_ror_24(x) vec_rl(x, ROR24_MASK) + #define vec_ror_16(x) vec_rl(x, ROR16_MASK) + #define vec_ror_63(x) vec_rl(x, ROR63_MASK) + + #define BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + do { \ + row1l = VecAdd(VecAdd(row1l, b0), row2l); \ + row1h = VecAdd(VecAdd(row1h, b1), row2h); \ + row4l = VecXor(row4l, row1l); row4h = VecXor(row4h, row1h); \ + row4l = vec_ror_32(row4l); row4h = vec_ror_32(row4h); \ + row3l = VecAdd(row3l, row4l); row3h = VecAdd(row3h, row4h); \ + row2l = VecXor(row2l, row3l); row2h = VecXor(row2h, row3h); \ + row2l = vec_ror_24(row2l); row2h = vec_ror_24(row2h); \ + } while(0) + + #define BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + do { \ + row1l = VecAdd(VecAdd(row1l, b0), row2l); \ + row1h = VecAdd(VecAdd(row1h, b1), row2h); \ + row4l = VecXor(row4l, row1l); row4h = VecXor(row4h, row1h); \ + row4l = vec_ror_16(row4l); row4h = vec_ror_16(row4h); \ + row3l = VecAdd(row3l, row4l); row3h = VecAdd(row3h, row4h); \ + row2l = VecXor(row2l, row3l); row2h = VecXor(row2h, row3h); \ + row2l = vec_ror_63(row2l); row2h = vec_ror_63(row2h); \ + } while(0) + + #define BLAKE2B_DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + do { \ + uint64x2_p t0 = vec_shl_8(row2l, row2h); \ + uint64x2_p t1 = vec_shl_8(row2h, row2l); \ + row2l = t0; row2h = t1; t0 = row3l; row3l = row3h; row3h = t0; \ + t0 = vec_shl_8(row4h, row4l); t1 = vec_shl_8(row4l, row4h); \ + row4l = t0; row4h = t1; \ + } while(0) + + #define BLAKE2B_UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + do { \ + uint64x2_p t0 = vec_shl_8(row2h, row2l); \ + uint64x2_p t1 = vec_shl_8(row2l, row2h); \ + row2l = t0; row2h = t1; t0 = row3l; row3l = row3h; row3h = t0; \ + t0 = vec_shl_8(row4l, row4h); t1 = vec_shl_8(row4h, row4l); \ + row4l = t0; row4h = t1; \ + } while(0) + + #define BLAKE2B_ROUND(r) \ + do { \ + uint64x2_p b0, b1; \ + BLAKE2B_LOAD_MSG_ ##r ##_1(b0, b1); \ + BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_LOAD_MSG_ ##r ##_2(b0, b1); \ + BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + BLAKE2B_LOAD_MSG_ ##r ##_3(b0, b1); \ + BLAKE2B_G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_LOAD_MSG_ ##r ##_4(b0, b1); \ + BLAKE2B_G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + BLAKE2B_UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + } while(0) + + // Possibly unaligned user messages + uint64x2_p m0, m1, m2, m3, m4, m5, m6, m7; + // Endian conversion mask + const uint8x16_p le_mask = {7,6,5,4, 3,2,1,0, 15,14,13,12, 11,10,9,8}; + +#if defined(_ARCH_PWR9) + // POWER9 provides loads for char's and short's + m0 = (uint64x2_p) vec_xl( 0, CONST_V8_CAST( input )); + m1 = (uint64x2_p) vec_xl( 16, CONST_V8_CAST( input )); + m2 = (uint64x2_p) vec_xl( 32, CONST_V8_CAST( input )); + m3 = (uint64x2_p) vec_xl( 48, CONST_V8_CAST( input )); + m4 = (uint64x2_p) vec_xl( 64, CONST_V8_CAST( input )); + m5 = (uint64x2_p) vec_xl( 80, CONST_V8_CAST( input )); + m6 = (uint64x2_p) vec_xl( 96, CONST_V8_CAST( input )); + m7 = (uint64x2_p) vec_xl(112, CONST_V8_CAST( input )); + +# if defined(CRYPTOPP_BIG_ENDIAN) + m0 = vec_perm(m0, m0, le_mask); + m1 = vec_perm(m1, m1, le_mask); + m2 = vec_perm(m2, m2, le_mask); + m3 = vec_perm(m3, m3, le_mask); + m4 = vec_perm(m4, m4, le_mask); + m5 = vec_perm(m5, m5, le_mask); + m6 = vec_perm(m6, m6, le_mask); + m7 = vec_perm(m7, m7, le_mask); +# endif +#else + // Altivec only provides 16-byte aligned loads + // http://www.nxp.com/docs/en/reference-manual/ALTIVECPEM.pdf + m0 = (uint64x2_p) vec_ld( 0, CONST_V8_CAST( input )); + m1 = (uint64x2_p) vec_ld( 16, CONST_V8_CAST( input )); + m2 = (uint64x2_p) vec_ld( 32, CONST_V8_CAST( input )); + m3 = (uint64x2_p) vec_ld( 48, CONST_V8_CAST( input )); + m4 = (uint64x2_p) vec_ld( 64, CONST_V8_CAST( input )); + m5 = (uint64x2_p) vec_ld( 80, CONST_V8_CAST( input )); + m6 = (uint64x2_p) vec_ld( 96, CONST_V8_CAST( input )); + m7 = (uint64x2_p) vec_ld(112, CONST_V8_CAST( input )); + + // Alignment check for load of the message buffer + const uintptr_t addr = (uintptr_t)input; + if (addr%16 == 0) + { + // Already aligned. Perform a little-endian swap as required +# if defined(CRYPTOPP_BIG_ENDIAN) + m0 = vec_perm(m0, m0, le_mask); + m1 = vec_perm(m1, m1, le_mask); + m2 = vec_perm(m2, m2, le_mask); + m3 = vec_perm(m3, m3, le_mask); + m4 = vec_perm(m4, m4, le_mask); + m5 = vec_perm(m5, m5, le_mask); + m6 = vec_perm(m6, m6, le_mask); + m7 = vec_perm(m7, m7, le_mask); +# endif + } + else + { + // Not aligned. Fix vectors and perform a little-endian swap as required + // http://mirror.informatimago.com/next/developer.apple.com/ + // hardwaredrivers/ve/code_optimization.html + uint64x2_p ex; uint8x16_p perm; + ex = (uint64x2_p) vec_ld(112+15, CONST_V8_CAST( input )); + perm = vec_lvsl(0, CONST_V8_CAST( addr )); + +# if defined(CRYPTOPP_BIG_ENDIAN) + // Combine the vector permute with the little-endian swap + perm = vec_perm(perm, perm, le_mask); +# endif + + m0 = vec_perm(m0, m1, perm); + m1 = vec_perm(m1, m2, perm); + m2 = vec_perm(m2, m3, perm); + m3 = vec_perm(m3, m4, perm); + m4 = vec_perm(m4, m5, perm); + m5 = vec_perm(m5, m6, perm); + m6 = vec_perm(m6, m7, perm); + m7 = vec_perm(m7, ex, perm); + } +#endif + + uint64x2_p row1l, row1h, row2l, row2h; + uint64x2_p row3l, row3h, row4l, row4h; + + const uint64x2_p h0 = row1l = VecLoad64LE(state.h()+0, le_mask); + const uint64x2_p h1 = row1h = VecLoad64LE(state.h()+2, le_mask); + const uint64x2_p h2 = row2l = VecLoad64LE(state.h()+4, le_mask); + const uint64x2_p h3 = row2h = VecLoad64LE(state.h()+6, le_mask); + + row3l = VecLoad64(BLAKE2B_IV+0); + row3h = VecLoad64(BLAKE2B_IV+2); + row4l = VecXor(VecLoad64(BLAKE2B_IV+4), VecLoad64(state.t()+0)); + row4h = VecXor(VecLoad64(BLAKE2B_IV+6), VecLoad64(state.f()+0)); + + BLAKE2B_ROUND(0); + BLAKE2B_ROUND(1); + BLAKE2B_ROUND(2); + BLAKE2B_ROUND(3); + BLAKE2B_ROUND(4); + BLAKE2B_ROUND(5); + BLAKE2B_ROUND(6); + BLAKE2B_ROUND(7); + BLAKE2B_ROUND(8); + BLAKE2B_ROUND(9); + BLAKE2B_ROUND(10); + BLAKE2B_ROUND(11); + + VecStore64LE(state.h()+0, VecXor(h0, VecXor(row1l, row3l)), le_mask); + VecStore64LE(state.h()+2, VecXor(h1, VecXor(row1h, row3h)), le_mask); + VecStore64LE(state.h()+4, VecXor(h2, VecXor(row2l, row4l)), le_mask); + VecStore64LE(state.h()+6, VecXor(h3, VecXor(row2h, row4h)), le_mask); +} +#endif // CRYPTOPP_POWER8_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/blake2s_simd.cpp b/external/ours/library/crypto/src/shared/original/blake2s_simd.cpp new file mode 100755 index 000000000..4d00f609e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blake2s_simd.cpp @@ -0,0 +1,1091 @@ +// blake2_simd.cpp - written and placed in the public domain by +// Samuel Neves, Jeffrey Walton, Uri Blumenthal +// and Marcel Raad. +// +// This source file uses intrinsics to gain access to ARMv7a/ARMv8a +// NEON, Power7 and SSE4.1 instructions. A separate source file is +// needed because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. + +// The BLAKE2b and BLAKE2s numbers are consistent with the BLAKE2 team's +// numbers. However, we have an Altivec implementation of BLAKE2s, +// and a POWER8 implementation of BLAKE2b (BLAKE2 team is missing them). +// Altivec code is about 2x faster than C++ when using GCC 5.0 or +// above. The POWER8 code is about 2.5x faster than C++ when using GCC 5.0 +// or above. If you use GCC 4.0 (PowerMac) or GCC 4.8 (GCC Compile Farm) +// then the PowerPC code will be slower than C++. Be sure to use GCC 5.0 +// or above for PowerPC builds or disable Altivec for BLAKE2b and BLAKE2s +// if using the old compilers. + +#include "pch.h" +#include "config.h" +#include "misc.h" +#include "blake2.h" + +// Uncomment for benchmarking C++ against SSE2 or NEON. +// Do so in both blake2.cpp and blake2_simd.cpp. +// #undef CRYPTOPP_SSE41_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE +// #undef CRYPTOPP_ALTIVEC_AVAILABLE + +// Disable NEON/ASIMD for Cortex-A53 and A57. The shifts are too slow and C/C++ is about +// 3 cpb faster than NEON/ASIMD. Also see http://github.com/weidai11/cryptopp/issues/367. +#if (defined(__aarch32__) || defined(__aarch64__)) && defined(CRYPTOPP_SLOW_ARMV8_SHIFT) +# undef CRYPTOPP_ARM_NEON_AVAILABLE +#endif + +// BLAKE2s bug on AIX 7.1 (POWER7) with XLC 12.01 +// https://github.com/weidai11/cryptopp/issues/743 +#if defined(__xlC__) && (__xlC__ < 0x0d01) +# define CRYPTOPP_DISABLE_ALTIVEC 1 +# undef CRYPTOPP_POWER7_AVAILABLE +# undef CRYPTOPP_ALTIVEC_AVAILABLE +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +#if (CRYPTOPP_SSE41_AVAILABLE) +# include +# include +# include +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +# include "ppc_simd.h" +#endif + +#if defined(CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE) +/* Ignore "warning: vec_lvsl is deprecated..." */ +# pragma GCC diagnostic ignored "-Wdeprecated" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char BLAKE2S_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// Exported by blake2.cpp +extern const word32 BLAKE2S_IV[8]; +extern const word64 BLAKE2B_IV[8]; + +#if CRYPTOPP_SSE41_AVAILABLE + +#define LOADU(p) _mm_loadu_si128((const __m128i *)(const void*)(p)) +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(void*)(p), r) +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2s_State& state) +{ + #define BLAKE2S_LOAD_MSG_0_1(buf) \ + buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); + + #define BLAKE2S_LOAD_MSG_0_2(buf) \ + buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); + + #define BLAKE2S_LOAD_MSG_0_3(buf) \ + t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE(3,2,0,1)); \ + t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,1,3,2)); \ + buf = _mm_blend_epi16(t0, t1, 0xC3); + + #define BLAKE2S_LOAD_MSG_0_4(buf) \ + t0 = _mm_blend_epi16(t0, t1, 0x3C); \ + buf = _mm_shuffle_epi32(t0, _MM_SHUFFLE(2,3,0,1)); + + #define BLAKE2S_LOAD_MSG_1_1(buf) \ + t0 = _mm_blend_epi16(m1, m2, 0x0C); \ + t1 = _mm_slli_si128(m3, 4); \ + t2 = _mm_blend_epi16(t0, t1, 0xF0); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + + #define BLAKE2S_LOAD_MSG_1_2(buf) \ + t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ + t1 = _mm_blend_epi16(m1,m3,0xC0); \ + t2 = _mm_blend_epi16(t0, t1, 0xF0); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + + #define BLAKE2S_LOAD_MSG_1_3(buf) \ + t0 = _mm_slli_si128(m1, 4); \ + t1 = _mm_blend_epi16(m2, t0, 0x30); \ + t2 = _mm_blend_epi16(m0, t1, 0xF0); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,0,1,2)); + + #define BLAKE2S_LOAD_MSG_1_4(buf) \ + t0 = _mm_unpackhi_epi32(m0,m1); \ + t1 = _mm_slli_si128(m3, 4); \ + t2 = _mm_blend_epi16(t0, t1, 0x0C); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,0,1,2)); + + #define BLAKE2S_LOAD_MSG_2_1(buf) \ + t0 = _mm_unpackhi_epi32(m2,m3); \ + t1 = _mm_blend_epi16(m3,m1,0x0C); \ + t2 = _mm_blend_epi16(t0, t1, 0x0F); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + + #define BLAKE2S_LOAD_MSG_2_2(buf) \ + t0 = _mm_unpacklo_epi32(m2,m0); \ + t1 = _mm_blend_epi16(t0, m0, 0xF0); \ + t2 = _mm_slli_si128(m3, 8); \ + buf = _mm_blend_epi16(t1, t2, 0xC0); + + #define BLAKE2S_LOAD_MSG_2_3(buf) \ + t0 = _mm_blend_epi16(m0, m2, 0x3C); \ + t1 = _mm_srli_si128(m1, 12); \ + t2 = _mm_blend_epi16(t0,t1,0x03); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,3,2,1)); + + #define BLAKE2S_LOAD_MSG_2_4(buf) \ + t0 = _mm_slli_si128(m3, 4); \ + t1 = _mm_blend_epi16(m0, m1, 0x33); \ + t2 = _mm_blend_epi16(t1, t0, 0xC0); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); + + #define BLAKE2S_LOAD_MSG_3_1(buf) \ + t0 = _mm_unpackhi_epi32(m0,m1); \ + t1 = _mm_unpackhi_epi32(t0, m2); \ + t2 = _mm_blend_epi16(t1, m3, 0x0C); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + + #define BLAKE2S_LOAD_MSG_3_2(buf) \ + t0 = _mm_slli_si128(m2, 8); \ + t1 = _mm_blend_epi16(m3,m0,0x0C); \ + t2 = _mm_blend_epi16(t1, t0, 0xC0); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + + #define BLAKE2S_LOAD_MSG_3_3(buf) \ + t0 = _mm_blend_epi16(m0,m1,0x0F); \ + t1 = _mm_blend_epi16(t0, m3, 0xC0); \ + buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(0,1,2,3)); + + #define BLAKE2S_LOAD_MSG_3_4(buf) \ + t0 = _mm_alignr_epi8(m0, m1, 4); \ + buf = _mm_blend_epi16(t0, m2, 0x33); + + #define BLAKE2S_LOAD_MSG_4_1(buf) \ + t0 = _mm_unpacklo_epi64(m1,m2); \ + t1 = _mm_unpackhi_epi64(m0,m2); \ + t2 = _mm_blend_epi16(t0,t1,0x33); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + + #define BLAKE2S_LOAD_MSG_4_2(buf) \ + t0 = _mm_unpackhi_epi64(m1,m3); \ + t1 = _mm_unpacklo_epi64(m0,m1); \ + buf = _mm_blend_epi16(t0,t1,0x33); + + #define BLAKE2S_LOAD_MSG_4_3(buf) \ + t0 = _mm_unpackhi_epi64(m3,m1); \ + t1 = _mm_unpackhi_epi64(m2,m0); \ + t2 = _mm_blend_epi16(t1,t0,0x33); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + + #define BLAKE2S_LOAD_MSG_4_4(buf) \ + t0 = _mm_blend_epi16(m0,m2,0x03); \ + t1 = _mm_slli_si128(t0, 8); \ + t2 = _mm_blend_epi16(t1,m3,0x0F); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,3,1)); + + #define BLAKE2S_LOAD_MSG_5_1(buf) \ + t0 = _mm_unpackhi_epi32(m0,m1); \ + t1 = _mm_unpacklo_epi32(m0,m2); \ + buf = _mm_unpacklo_epi64(t0,t1); + + #define BLAKE2S_LOAD_MSG_5_2(buf) \ + t0 = _mm_srli_si128(m2, 4); \ + t1 = _mm_blend_epi16(m0,m3,0x03); \ + buf = _mm_blend_epi16(t1,t0,0x3C); + + #define BLAKE2S_LOAD_MSG_5_3(buf) \ + t0 = _mm_blend_epi16(m1,m0,0x0C); \ + t1 = _mm_srli_si128(m3, 4); \ + t2 = _mm_blend_epi16(t0,t1,0x30); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + + #define BLAKE2S_LOAD_MSG_5_4(buf) \ + t0 = _mm_unpacklo_epi64(m2,m1); \ + t1 = _mm_shuffle_epi32(m3, _MM_SHUFFLE(2,0,1,0)); \ + t2 = _mm_srli_si128(t0, 4); \ + buf = _mm_blend_epi16(t1,t2,0x33); + + #define BLAKE2S_LOAD_MSG_6_1(buf) \ + t0 = _mm_slli_si128(m1, 12); \ + t1 = _mm_blend_epi16(m0,m3,0x33); \ + buf = _mm_blend_epi16(t1,t0,0xC0); + + #define BLAKE2S_LOAD_MSG_6_2(buf) \ + t0 = _mm_blend_epi16(m3,m2,0x30); \ + t1 = _mm_srli_si128(m1, 4); \ + t2 = _mm_blend_epi16(t0,t1,0x03); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); + + #define BLAKE2S_LOAD_MSG_6_3(buf) \ + t0 = _mm_unpacklo_epi64(m0,m2); \ + t1 = _mm_srli_si128(m1, 4); \ + t2 = _mm_blend_epi16(t0,t1,0x0C); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + + #define BLAKE2S_LOAD_MSG_6_4(buf) \ + t0 = _mm_unpackhi_epi32(m1,m2); \ + t1 = _mm_unpackhi_epi64(m0,t0); \ + buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(0,1,2,3)); + + #define BLAKE2S_LOAD_MSG_7_1(buf) \ + t0 = _mm_unpackhi_epi32(m0,m1); \ + t1 = _mm_blend_epi16(t0,m3,0x0F); \ + buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); + + #define BLAKE2S_LOAD_MSG_7_2(buf) \ + t0 = _mm_blend_epi16(m2,m3,0x30); \ + t1 = _mm_srli_si128(m0,4); \ + t2 = _mm_blend_epi16(t0,t1,0x03); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); + + #define BLAKE2S_LOAD_MSG_7_3(buf) \ + t0 = _mm_unpackhi_epi64(m0,m3); \ + t1 = _mm_unpacklo_epi64(m1,m2); \ + t2 = _mm_blend_epi16(t0,t1,0x3C); \ + buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(2,3,1,0)); + + #define BLAKE2S_LOAD_MSG_7_4(buf) \ + t0 = _mm_unpacklo_epi32(m0,m1); \ + t1 = _mm_unpackhi_epi32(m1,m2); \ + t2 = _mm_unpacklo_epi64(t0,t1); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + + #define BLAKE2S_LOAD_MSG_8_1(buf) \ + t0 = _mm_unpackhi_epi32(m1,m3); \ + t1 = _mm_unpacklo_epi64(t0,m0); \ + t2 = _mm_blend_epi16(t1,m2,0xC0); \ + buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); + + #define BLAKE2S_LOAD_MSG_8_2(buf) \ + t0 = _mm_unpackhi_epi32(m0,m3); \ + t1 = _mm_blend_epi16(m2,t0,0xF0); \ + buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); + + #define BLAKE2S_LOAD_MSG_8_3(buf) \ + t0 = _mm_unpacklo_epi64(m0,m3); \ + t1 = _mm_srli_si128(m2,8); \ + t2 = _mm_blend_epi16(t0,t1,0x03); \ + buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,3,2,0)); + + #define BLAKE2S_LOAD_MSG_8_4(buf) \ + t0 = _mm_blend_epi16(m1,m0,0x30); \ + buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(0,3,2,1)); + + #define BLAKE2S_LOAD_MSG_9_1(buf) \ + t0 = _mm_blend_epi16(m0,m2,0x03); \ + t1 = _mm_blend_epi16(m1,m2,0x30); \ + t2 = _mm_blend_epi16(t1,t0,0x0F); \ + buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); + + #define BLAKE2S_LOAD_MSG_9_2(buf) \ + t0 = _mm_slli_si128(m0,4); \ + t1 = _mm_blend_epi16(m1,t0,0xC0); \ + buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); + + #define BLAKE2S_LOAD_MSG_9_3(buf) \ + t0 = _mm_unpackhi_epi32(m0,m3); \ + t1 = _mm_unpacklo_epi32(m2,m3); \ + t2 = _mm_unpackhi_epi64(t0,t1); \ + buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,1,3)); + + #define BLAKE2S_LOAD_MSG_9_4(buf) \ + t0 = _mm_blend_epi16(m3,m2,0xC0); \ + t1 = _mm_unpacklo_epi32(m0,m3); \ + t2 = _mm_blend_epi16(t0,t1,0x0F); \ + buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,2,3,0)); + +#ifdef __XOP__ +# define MM_ROTI_EPI32(r, c) \ + _mm_roti_epi32(r, c) +#else +# define MM_ROTI_EPI32(r, c) ( \ + (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ + : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ + : _mm_xor_si128(_mm_srli_epi32((r), -(c)), \ + _mm_slli_epi32((r), 32-(-(c))))) +#endif + +#define BLAKE2S_G1(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = MM_ROTI_EPI32(row4, -16); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = MM_ROTI_EPI32(row2, -12); + +#define BLAKE2S_G2(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = MM_ROTI_EPI32(row4, -8); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = MM_ROTI_EPI32(row2, -7); + +#define DIAGONALIZE(row1,row2,row3,row4) \ + row1 = _mm_shuffle_epi32( row1, _MM_SHUFFLE(2,1,0,3) ); \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(1,0,3,2) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(0,3,2,1) ); + +#define UNDIAGONALIZE(row1,row2,row3,row4) \ + row1 = _mm_shuffle_epi32( row1, _MM_SHUFFLE(0,3,2,1) ); \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(1,0,3,2) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(2,1,0,3) ); + +#define BLAKE2S_ROUND(r) \ + BLAKE2S_LOAD_MSG_ ##r ##_1(buf1); \ + BLAKE2S_G1(row1,row2,row3,row4,buf1); \ + BLAKE2S_LOAD_MSG_ ##r ##_2(buf2); \ + BLAKE2S_G2(row1,row2,row3,row4,buf2); \ + DIAGONALIZE(row1,row2,row3,row4); \ + BLAKE2S_LOAD_MSG_ ##r ##_3(buf3); \ + BLAKE2S_G1(row1,row2,row3,row4,buf3); \ + BLAKE2S_LOAD_MSG_ ##r ##_4(buf4); \ + BLAKE2S_G2(row1,row2,row3,row4,buf4); \ + UNDIAGONALIZE(row1,row2,row3,row4); + + __m128i row1, row2, row3, row4; + __m128i buf1, buf2, buf3, buf4; + __m128i t0, t1, t2, ff0, ff1; + + const __m128i r8 = _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1); + const __m128i r16 = _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + + const __m128i m0 = LOADU(input + 00); + const __m128i m1 = LOADU(input + 16); + const __m128i m2 = LOADU(input + 32); + const __m128i m3 = LOADU(input + 48); + + row1 = ff0 = LOADU(state.h()+0); + row2 = ff1 = LOADU(state.h()+4); + row3 = LOADU(BLAKE2S_IV+0); + row4 = _mm_xor_si128(LOADU(BLAKE2S_IV+4), LOADU(state.t()+0)); + + BLAKE2S_ROUND(0); + BLAKE2S_ROUND(1); + BLAKE2S_ROUND(2); + BLAKE2S_ROUND(3); + BLAKE2S_ROUND(4); + BLAKE2S_ROUND(5); + BLAKE2S_ROUND(6); + BLAKE2S_ROUND(7); + BLAKE2S_ROUND(8); + BLAKE2S_ROUND(9); + + STOREU(state.h()+0, _mm_xor_si128(ff0, _mm_xor_si128(row1, row3))); + STOREU(state.h()+4, _mm_xor_si128(ff1, _mm_xor_si128(row2, row4))); +} +#endif // CRYPTOPP_SSE41_AVAILABLE + +#if CRYPTOPP_ARM_NEON_AVAILABLE +void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state) +{ + #define BLAKE2S_LOAD_MSG_0_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m0), vget_high_u32(m0)).val[0]; \ + t1 = vzip_u32(vget_low_u32(m1), vget_high_u32(m1)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_0_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m0), vget_high_u32(m0)).val[1]; \ + t1 = vzip_u32(vget_low_u32(m1), vget_high_u32(m1)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_0_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m2), vget_high_u32(m2)).val[0]; \ + t1 = vzip_u32(vget_low_u32(m3), vget_high_u32(m3)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_0_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m2), vget_high_u32(m2)).val[1]; \ + t1 = vzip_u32(vget_low_u32(m3), vget_high_u32(m3)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_1_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m3), vget_low_u32(m1)).val[0]; \ + t1 = vzip_u32(vget_low_u32(m2), vget_low_u32(m3)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_1_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m2), vget_low_u32(m2)).val[0]; \ + t1 = vext_u32(vget_high_u32(m3), vget_high_u32(m1), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_1_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vext_u32(vget_low_u32(m0), vget_low_u32(m0), 1); \ + t1 = vzip_u32(vget_high_u32(m2), vget_low_u32(m1)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_1_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m3), vget_high_u32(m0)).val[0]; \ + t1 = vzip_u32(vget_high_u32(m1), vget_high_u32(m0)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_2_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vext_u32(vget_high_u32(m2), vget_low_u32(m3), 1); \ + t1 = vzip_u32(vget_low_u32(m1), vget_high_u32(m3)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_2_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m2), vget_low_u32(m0)).val[0]; \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m0), vget_low_u32(m3)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_2_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m2), vget_high_u32(m0)); \ + t1 = vzip_u32(vget_high_u32(m1), vget_low_u32(m2)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_2_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m3), vget_high_u32(m1)).val[0]; \ + t1 = vext_u32(vget_low_u32(m0), vget_low_u32(m1), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_3_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m1), vget_high_u32(m0)).val[1]; \ + t1 = vzip_u32(vget_low_u32(m3), vget_high_u32(m2)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_3_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m2), vget_low_u32(m0)).val[1]; \ + t1 = vzip_u32(vget_low_u32(m3), vget_high_u32(m3)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_3_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m0), vget_low_u32(m1)); \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m1), vget_high_u32(m3)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_3_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m1), vget_high_u32(m2)).val[0]; \ + t1 = vzip_u32(vget_low_u32(m0), vget_low_u32(m2)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_4_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m2), vget_low_u32(m1)).val[1]; \ + t1 = vzip_u32((vget_high_u32(m0)), vget_high_u32(m2)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_4_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m0), vget_high_u32(m1)); \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m1), vget_high_u32(m3)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_4_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m3), vget_high_u32(m2)); \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m1), vget_high_u32(m0)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_4_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vext_u32(vget_low_u32(m0), vget_low_u32(m3), 1); \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m2), vget_low_u32(m3)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_5_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32((vget_high_u32(m0)), vget_high_u32(m1)).val[0]; \ + t1 = vzip_u32(vget_low_u32(m0), vget_low_u32(m2)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_5_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m3), vget_high_u32(m2)).val[0]; \ + t1 = vzip_u32(vget_high_u32(m2), vget_high_u32(m0)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_5_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m1), vget_high_u32(m1)); \ + t1 = vzip_u32(vget_high_u32(m3), vget_low_u32(m0)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_5_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m3), vget_low_u32(m1)).val[1]; \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m3), vget_low_u32(m2)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_6_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m3), vget_low_u32(m0)); \ + t1 = vzip_u32(vget_high_u32(m3), vget_low_u32(m1)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_6_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m1), vget_high_u32(m3)).val[1]; \ + t1 = vext_u32(vget_low_u32(m3), vget_high_u32(m2), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_6_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m0), vget_high_u32(m1)).val[0]; \ + t1 = vext_u32(vget_low_u32(m2), vget_low_u32(m2), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_6_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m1), vget_high_u32(m0)).val[1]; \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m0), vget_high_u32(m2)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_7_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m3), vget_high_u32(m1)).val[1]; \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m3), vget_high_u32(m0)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_7_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vext_u32(vget_high_u32(m2), vget_high_u32(m3), 1); \ + t1 = vzip_u32(vget_low_u32(m0), vget_low_u32(m2)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_7_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m1), vget_high_u32(m3)).val[1]; \ + t1 = vzip_u32(vget_low_u32(m2), vget_high_u32(m0)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_7_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_low_u32(m0), vget_low_u32(m1)).val[0]; \ + t1 = vzip_u32(vget_high_u32(m1), vget_high_u32(m2)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_8_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m1), vget_high_u32(m3)).val[0]; \ + t1 = vext_u32(vget_high_u32(m2), vget_low_u32(m0), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_8_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m3), vget_low_u32(m2)).val[1]; \ + t1 = vext_u32(vget_high_u32(m0), vget_low_u32(m2), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_8_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m3), vget_low_u32(m3)); \ + t1 = vext_u32(vget_low_u32(m0), vget_high_u32(m2), 1); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_8_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m0), vget_high_u32(m1)); \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_low_u32(m1), vget_low_u32(m1)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_9_1(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m2), vget_low_u32(m2)).val[0]; \ + t1 = vzip_u32(vget_high_u32(m1), vget_low_u32(m0)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_9_2(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32((vget_high_u32(m0)), vget_low_u32(m1)).val[0]; \ + t1 = vbsl_u32(vcreate_u32(0xFFFFFFFF), vget_high_u32(m1), vget_low_u32(m1)); \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_9_3(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vzip_u32(vget_high_u32(m3), vget_low_u32(m2)).val[1]; \ + t1 = vzip_u32((vget_high_u32(m0)), vget_low_u32(m3)).val[1]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define BLAKE2S_LOAD_MSG_9_4(buf) \ + do { uint32x2_t t0, t1; \ + t0 = vext_u32(vget_high_u32(m2), vget_high_u32(m3), 1); \ + t1 = vzip_u32(vget_low_u32(m3), vget_low_u32(m0)).val[0]; \ + buf = vcombine_u32(t0, t1); } while(0) + + #define vrorq_n_u32_16(x) vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(x))) + + #define vrorq_n_u32_8(x) vsriq_n_u32(vshlq_n_u32((x), 24), (x), 8) + + #define vrorq_n_u32(x, c) vsriq_n_u32(vshlq_n_u32((x), 32-(c)), (x), (c)) + + #define BLAKE2S_G1(row1,row2,row3,row4,buf) \ + do { \ + row1 = vaddq_u32(vaddq_u32(row1, buf), row2); row4 = veorq_u32(row4, row1); \ + row4 = vrorq_n_u32_16(row4); row3 = vaddq_u32(row3, row4); \ + row2 = veorq_u32(row2, row3); row2 = vrorq_n_u32(row2, 12); \ + } while(0) + + #define BLAKE2S_G2(row1,row2,row3,row4,buf) \ + do { \ + row1 = vaddq_u32(vaddq_u32(row1, buf), row2); row4 = veorq_u32(row4, row1); \ + row4 = vrorq_n_u32_8(row4); row3 = vaddq_u32(row3, row4); \ + row2 = veorq_u32(row2, row3); row2 = vrorq_n_u32(row2, 7); \ + } while(0) + + #define BLAKE2S_DIAGONALIZE(row1,row2,row3,row4) \ + do { \ + row4 = vextq_u32(row4, row4, 3); row3 = vextq_u32(row3, row3, 2); row2 = vextq_u32(row2, row2, 1); \ + } while(0) + + #define BLAKE2S_UNDIAGONALIZE(row1,row2,row3,row4) \ + do { \ + row4 = vextq_u32(row4, row4, 1); \ + row3 = vextq_u32(row3, row3, 2); \ + row2 = vextq_u32(row2, row2, 3); \ + } while(0) + + #define BLAKE2S_ROUND(r) \ + do { \ + uint32x4_t buf1, buf2, buf3, buf4; \ + BLAKE2S_LOAD_MSG_ ##r ##_1(buf1); \ + BLAKE2S_G1(row1,row2,row3,row4,buf1); \ + BLAKE2S_LOAD_MSG_ ##r ##_2(buf2); \ + BLAKE2S_G2(row1,row2,row3,row4,buf2); \ + BLAKE2S_DIAGONALIZE(row1,row2,row3,row4); \ + BLAKE2S_LOAD_MSG_ ##r ##_3(buf3); \ + BLAKE2S_G1(row1,row2,row3,row4,buf3); \ + BLAKE2S_LOAD_MSG_ ##r ##_4(buf4); \ + BLAKE2S_G2(row1,row2,row3,row4,buf4); \ + BLAKE2S_UNDIAGONALIZE(row1,row2,row3,row4); \ + } while(0) + + const uint32x4_t m0 = vreinterpretq_u32_u8(vld1q_u8(input + 00)); + const uint32x4_t m1 = vreinterpretq_u32_u8(vld1q_u8(input + 16)); + const uint32x4_t m2 = vreinterpretq_u32_u8(vld1q_u8(input + 32)); + const uint32x4_t m3 = vreinterpretq_u32_u8(vld1q_u8(input + 48)); + + uint32x4_t row1, row2, row3, row4; + + const uint32x4_t f0 = row1 = vld1q_u32(state.h()+0); + const uint32x4_t f1 = row2 = vld1q_u32(state.h()+4); + row3 = vld1q_u32(BLAKE2S_IV+0); + row4 = veorq_u32(vld1q_u32(BLAKE2S_IV+4), vld1q_u32(state.t()+0)); + + BLAKE2S_ROUND(0); + BLAKE2S_ROUND(1); + BLAKE2S_ROUND(2); + BLAKE2S_ROUND(3); + BLAKE2S_ROUND(4); + BLAKE2S_ROUND(5); + BLAKE2S_ROUND(6); + BLAKE2S_ROUND(7); + BLAKE2S_ROUND(8); + BLAKE2S_ROUND(9); + + vst1q_u32(state.h()+0, veorq_u32(f0, veorq_u32(row1, row3))); + vst1q_u32(state.h()+4, veorq_u32(f1, veorq_u32(row2, row4))); +} +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + +template +inline uint32x4_p VecLoad32(const T* p) +{ + return VecLoad(p); +} + +template +inline uint32x4_p VecLoad32LE(const T* p, const uint8x16_p le_mask) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint32x4_p v = VecLoad(p); + return VecPermute(v, v, le_mask); +#else + CRYPTOPP_UNUSED(le_mask); + return VecLoad(p); +#endif +} + +template +inline void VecStore32(T* p, const uint32x4_p x) +{ + VecStore(x, p); +} + +template +inline void VecStore32LE(T* p, const uint32x4_p x, const uint8x16_p le_mask) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint32x4_p v = VecPermute(x, x, le_mask); + VecStore(v, p); +#else + CRYPTOPP_UNUSED(le_mask); + VecStore(x, p); +#endif +} + +template +inline uint32x4_p VectorSet32(const uint32x4_p a, const uint32x4_p b) +{ + // Re-index. I'd like to use something like Z=Y*4 and then + // VecShiftLeftOctet(b) but it crashes early Red Hat + // GCC compilers. + enum {X=E1&3, Y=E2&3}; + + // Don't care element + const unsigned int DC = 31; + + // Element 0 combinations + if (X == 0 && Y == 0) + { + const uint8x16_p mask = {0,1,2,3, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, b, mask); + } + else if (X == 0 && Y == 1) + { + const uint8x16_p mask = {0,1,2,3, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<4>(b), mask); + } + else if (X == 0 && Y == 2) + { + const uint8x16_p mask = {0,1,2,3, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<8>(b), mask); + } + else if (X == 0 && Y == 3) + { + const uint8x16_p mask = {0,1,2,3, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<12>(b), mask); + } + + // Element 1 combinations + else if (X == 1 && Y == 0) + { + const uint8x16_p mask = {4,5,6,7, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, b, mask); + } + else if (X == 1 && Y == 1) + { + const uint8x16_p mask = {4,5,6,7, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<4>(b), mask); + } + else if (X == 1 && Y == 2) + { + const uint8x16_p mask = {4,5,6,7, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<8>(b), mask); + } + else if (X == 1 && Y == 3) + { + const uint8x16_p mask = {4,5,6,7, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<12>(b), mask); + } + + // Element 2 combinations + else if (X == 2 && Y == 0) + { + const uint8x16_p mask = {8,9,10,11, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, b, mask); + } + else if (X == 2 && Y == 1) + { + const uint8x16_p mask = {8,9,10,11, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<4>(b), mask); + } + else if (X == 2 && Y == 2) + { + const uint8x16_p mask = {8,9,10,11, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<8>(b), mask); + } + else if (X == 2 && Y == 3) + { + const uint8x16_p mask = {8,9,10,11, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<12>(b), mask); + } + + // Element 3 combinations + else if (X == 3 && Y == 0) + { + const uint8x16_p mask = {12,13,14,15, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, b, mask); + } + else if (X == 3 && Y == 1) + { + const uint8x16_p mask = {12,13,14,15, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<4>(b), mask); + } + else if (X == 3 && Y == 2) + { + const uint8x16_p mask = {12,13,14,15, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<8>(b), mask); + } + else if (X == 3 && Y == 3) + { + const uint8x16_p mask = {12,13,14,15, 16,17,18,19, DC,DC,DC,DC, DC,DC,DC,DC}; + return VecPermute(a, VecShiftLeftOctet<12>(b), mask); + } + + // Quiet IBM XLC warning + return VecXor(a, a); +} + +template +inline uint32x4_p VectorSet32(const uint32x4_p a, const uint32x4_p b, + const uint32x4_p c, const uint32x4_p d) +{ + // Re-index + enum {W=E1&3, X=E2&3, Y=E3&3, Z=E4&3}; + + const uint32x4_p t0 = VectorSet32(a, b); + const uint32x4_p t1 = VectorSet32(c, d); + + // PowerPC follows SSE2's implementation, and this is _mm_set_epi32. + const uint8x16_p mask = {20,21,22,23, 16,17,18,19, 4,5,6,7, 0,1,2,3}; + return VecPermute(t0, t1, mask); +} + +template<> +uint32x4_p VectorSet32<2,0,2,0>(const uint32x4_p a, const uint32x4_p b, + const uint32x4_p c, const uint32x4_p d) +{ + // a=b, c=d, mask is {2,0, 2,0} + CRYPTOPP_UNUSED(b); CRYPTOPP_UNUSED(d); + const uint8x16_p mask = {16,17,18,19, 24,25,26,27, 0,1,2,3, 8,9,10,11}; + return VecPermute(a, c, mask); +} + +template<> +uint32x4_p VectorSet32<3,1,3,1>(const uint32x4_p a, const uint32x4_p b, + const uint32x4_p c, const uint32x4_p d) +{ + // a=b, c=d, mask is {3,1, 3,1} + CRYPTOPP_UNUSED(b); CRYPTOPP_UNUSED(d); + const uint8x16_p mask = {20,21,22,23, 28,29,30,31, 4,5,6,7, 12,13,14,15}; + return VecPermute(a, c, mask); +} + +void BLAKE2_Compress32_ALTIVEC(const byte* input, BLAKE2s_State& state) +{ + # define m1 m0 + # define m2 m0 + # define m3 m0 + + # define m5 m4 + # define m6 m4 + # define m7 m4 + + # define m9 m8 + # define m10 m8 + # define m11 m8 + + # define m13 m12 + # define m14 m12 + # define m15 m12 + + // #define BLAKE2S_LOAD_MSG_0_1(buf) buf = VectorSet32<6,4,2,0>(m6,m4,m2,m0); + #define BLAKE2S_LOAD_MSG_0_1(buf) buf = VectorSet32<2,0,2,0>(m6,m4,m2,m0); + // #define BLAKE2S_LOAD_MSG_0_2(buf) buf = VectorSet32<7,5,3,1>(m7,m5,m3,m1); + #define BLAKE2S_LOAD_MSG_0_2(buf) buf = VectorSet32<3,1,3,1>(m7,m5,m3,m1); + // #define BLAKE2S_LOAD_MSG_0_3(buf) buf = VectorSet32<14,12,10,8>(m14,m12,m10,m8); + #define BLAKE2S_LOAD_MSG_0_3(buf) buf = VectorSet32<2,0,2,0>(m14,m12,m10,m8); + // #define BLAKE2S_LOAD_MSG_0_4(buf) buf = VectorSet32<15,13,11,9>(m15,m13,m11,m9); + #define BLAKE2S_LOAD_MSG_0_4(buf) buf = VectorSet32<3,1,3,1>(m15,m13,m11,m9); + + #define BLAKE2S_LOAD_MSG_1_1(buf) buf = VectorSet32<13,9,4,14>(m13,m9,m4,m14); + #define BLAKE2S_LOAD_MSG_1_2(buf) buf = VectorSet32<6,15,8,10>(m6,m15,m8,m10) + #define BLAKE2S_LOAD_MSG_1_3(buf) buf = VectorSet32<5,11,0,1>(m5,m11,m0,m1) + #define BLAKE2S_LOAD_MSG_1_4(buf) buf = VectorSet32<3,7,2,12>(m3,m7,m2,m12) + + #define BLAKE2S_LOAD_MSG_2_1(buf) buf = VectorSet32<15,5,12,11>(m15,m5,m12,m11) + #define BLAKE2S_LOAD_MSG_2_2(buf) buf = VectorSet32<13,2,0,8>(m13,m2,m0,m8) + #define BLAKE2S_LOAD_MSG_2_3(buf) buf = VectorSet32<9,7,3,10>(m9,m7,m3,m10) + #define BLAKE2S_LOAD_MSG_2_4(buf) buf = VectorSet32<4,1,6,14>(m4,m1,m6,m14) + + #define BLAKE2S_LOAD_MSG_3_1(buf) buf = VectorSet32<11,13,3,7>(m11,m13,m3,m7) + #define BLAKE2S_LOAD_MSG_3_2(buf) buf = VectorSet32<14,12,1,9>(m14,m12,m1,m9) + #define BLAKE2S_LOAD_MSG_3_3(buf) buf = VectorSet32<15,4,5,2>(m15,m4,m5,m2) + #define BLAKE2S_LOAD_MSG_3_4(buf) buf = VectorSet32<8,0,10,6>(m8,m0,m10,m6) + + #define BLAKE2S_LOAD_MSG_4_1(buf) buf = VectorSet32<10,2,5,9>(m10,m2,m5,m9) + #define BLAKE2S_LOAD_MSG_4_2(buf) buf = VectorSet32<15,4,7,0>(m15,m4,m7,m0) + #define BLAKE2S_LOAD_MSG_4_3(buf) buf = VectorSet32<3,6,11,14>(m3,m6,m11,m14) + #define BLAKE2S_LOAD_MSG_4_4(buf) buf = VectorSet32<13,8,12,1>(m13,m8,m12,m1) + + #define BLAKE2S_LOAD_MSG_5_1(buf) buf = VectorSet32<8,0,6,2>(m8,m0,m6,m2) + #define BLAKE2S_LOAD_MSG_5_2(buf) buf = VectorSet32<3,11,10,12>(m3,m11,m10,m12) + #define BLAKE2S_LOAD_MSG_5_3(buf) buf = VectorSet32<1,15,7,4>(m1,m15,m7,m4) + #define BLAKE2S_LOAD_MSG_5_4(buf) buf = VectorSet32<9,14,5,13>(m9,m14,m5,m13) + + #define BLAKE2S_LOAD_MSG_6_1(buf) buf = VectorSet32<4,14,1,12>(m4,m14,m1,m12) + #define BLAKE2S_LOAD_MSG_6_2(buf) buf = VectorSet32<10,13,15,5>(m10,m13,m15,m5) + #define BLAKE2S_LOAD_MSG_6_3(buf) buf = VectorSet32<8,9,6,0>(m8,m9,m6,m0) + #define BLAKE2S_LOAD_MSG_6_4(buf) buf = VectorSet32<11,2,3,7>(m11,m2,m3,m7) + + #define BLAKE2S_LOAD_MSG_7_1(buf) buf = VectorSet32<3,12,7,13>(m3,m12,m7,m13) + #define BLAKE2S_LOAD_MSG_7_2(buf) buf = VectorSet32<9,1,14,11>(m9,m1,m14,m11) + #define BLAKE2S_LOAD_MSG_7_3(buf) buf = VectorSet32<2,8,15,5>(m2,m8,m15,m5) + #define BLAKE2S_LOAD_MSG_7_4(buf) buf = VectorSet32<10,6,4,0>(m10,m6,m4,m0) + + #define BLAKE2S_LOAD_MSG_8_1(buf) buf = VectorSet32<0,11,14,6>(m0,m11,m14,m6) + #define BLAKE2S_LOAD_MSG_8_2(buf) buf = VectorSet32<8,3,9,15>(m8,m3,m9,m15) + #define BLAKE2S_LOAD_MSG_8_3(buf) buf = VectorSet32<10,1,13,12>(m10,m1,m13,m12) + #define BLAKE2S_LOAD_MSG_8_4(buf) buf = VectorSet32<5,4,7,2>(m5,m4,m7,m2) + + #define BLAKE2S_LOAD_MSG_9_1(buf) buf = VectorSet32<1,7,8,10>(m1,m7,m8,m10) + #define BLAKE2S_LOAD_MSG_9_2(buf) buf = VectorSet32<5,6,4,2>(m5,m6,m4,m2) + #define BLAKE2S_LOAD_MSG_9_3(buf) buf = VectorSet32<13,3,9,15>(m13,m3,m9,m15) + #define BLAKE2S_LOAD_MSG_9_4(buf) buf = VectorSet32<0,12,14,11>(m0,m12,m14,m11) + + #define vec_ror_16(x) VecRotateRight<16>(x) + #define vec_ror_12(x) VecRotateRight<12>(x) + #define vec_ror_8(x) VecRotateRight<8>(x) + #define vec_ror_7(x) VecRotateRight<7>(x) + + #define BLAKE2S_G1(row1,row2,row3,row4,buf) \ + row1 = VecAdd(VecAdd(row1, buf), row2); \ + row4 = VecXor(row4, row1); \ + row4 = vec_ror_16(row4); \ + row3 = VecAdd(row3, row4); \ + row2 = VecXor(row2, row3); \ + row2 = vec_ror_12(row2); + + #define BLAKE2S_G2(row1,row2,row3,row4,buf) \ + row1 = VecAdd(VecAdd(row1, buf), row2); \ + row4 = VecXor(row4, row1); \ + row4 = vec_ror_8(row4); \ + row3 = VecAdd(row3, row4); \ + row2 = VecXor(row2, row3); \ + row2 = vec_ror_7(row2); + + const uint8x16_p D2103_MASK = {12,13,14,15, 0,1,2,3, 4,5,6,7, 8,9,10,11}; + const uint8x16_p D1032_MASK = {8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7}; + const uint8x16_p D0321_MASK = {4,5,6,7, 8,9,10,11, 12,13,14,15, 0,1,2,3}; + + #define BLAKE2S_DIAGONALIZE(row1,row2,row3,row4) \ + row4 = VecPermute(row4, row4, D2103_MASK); \ + row3 = VecPermute(row3, row3, D1032_MASK); \ + row2 = VecPermute(row2, row2, D0321_MASK); + + #define BLAKE2S_UNDIAGONALIZE(row1,row2,row3,row4) \ + row4 = VecPermute(row4, row4, D0321_MASK); \ + row3 = VecPermute(row3, row3, D1032_MASK); \ + row2 = VecPermute(row2, row2, D2103_MASK); + + #define BLAKE2S_ROUND(r) \ + BLAKE2S_LOAD_MSG_ ##r ##_1(buf1); \ + BLAKE2S_G1(row1,row2,row3,row4,buf1); \ + BLAKE2S_LOAD_MSG_ ##r ##_2(buf2); \ + BLAKE2S_G2(row1,row2,row3,row4,buf2); \ + BLAKE2S_DIAGONALIZE(row1,row2,row3,row4); \ + BLAKE2S_LOAD_MSG_ ##r ##_3(buf3); \ + BLAKE2S_G1(row1,row2,row3,row4,buf3); \ + BLAKE2S_LOAD_MSG_ ##r ##_4(buf4); \ + BLAKE2S_G2(row1,row2,row3,row4,buf4); \ + BLAKE2S_UNDIAGONALIZE(row1,row2,row3,row4); + + // Possibly unaligned user messages + uint32x4_p m0, m4, m8, m12; + // Endian conversion mask + const uint8x16_p le_mask = {3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12}; + +#if defined(_ARCH_PWR9) + // POWER9 provides loads for char's and short's + m0 = (uint32x4_p) vec_xl( 0, CONST_V8_CAST( input )); + m4 = (uint32x4_p) vec_xl( 16, CONST_V8_CAST( input )); + m8 = (uint32x4_p) vec_xl( 32, CONST_V8_CAST( input )); + m12 = (uint32x4_p) vec_xl( 48, CONST_V8_CAST( input )); + +# if defined(CRYPTOPP_BIG_ENDIAN) + m0 = vec_perm(m0, m0, le_mask); + m4 = vec_perm(m4, m4, le_mask); + m8 = vec_perm(m8, m8, le_mask); + m12 = vec_perm(m12, m12, le_mask); +# endif +#else + // Altivec only provides 16-byte aligned loads + // http://www.nxp.com/docs/en/reference-manual/ALTIVECPEM.pdf + m0 = (uint32x4_p) vec_ld( 0, CONST_V8_CAST( input )); + m4 = (uint32x4_p) vec_ld( 16, CONST_V8_CAST( input )); + m8 = (uint32x4_p) vec_ld( 32, CONST_V8_CAST( input )); + m12 = (uint32x4_p) vec_ld( 48, CONST_V8_CAST( input )); + + // Alignment check for load of the message buffer + const uintptr_t addr = (uintptr_t)input; + if (addr%16 == 0) + { + // Already aligned. Perform a little-endian swap as required +# if defined(CRYPTOPP_BIG_ENDIAN) + m0 = vec_perm(m0, m0, le_mask); + m4 = vec_perm(m4, m4, le_mask); + m8 = vec_perm(m8, m8, le_mask); + m12 = vec_perm(m12, m12, le_mask); +# endif + } + else + { + // Not aligned. Fix vectors and perform a little-endian swap as required + // http://mirror.informatimago.com/next/developer.apple.com/ + // hardwaredrivers/ve/code_optimization.html + uint32x4_p ex; uint8x16_p perm; + ex = (uint32x4_p) vec_ld(48+15, CONST_V8_CAST( input )); + perm = vec_lvsl(0, CONST_V8_CAST( addr )); + +# if defined(CRYPTOPP_BIG_ENDIAN) + // Combine the vector permute with the little-endian swap + perm = vec_perm(perm, perm, le_mask); +# endif + + m0 = vec_perm(m0, m4, perm); + m4 = vec_perm(m4, m8, perm); + m8 = vec_perm(m8, m12, perm); + m12 = vec_perm(m12, ex, perm); + } +#endif + + uint32x4_p row1, row2, row3, row4; + uint32x4_p buf1, buf2, buf3, buf4; + uint32x4_p ff0, ff1; + + row1 = ff0 = VecLoad32LE(state.h()+0, le_mask); + row2 = ff1 = VecLoad32LE(state.h()+4, le_mask); + row3 = VecLoad32(BLAKE2S_IV+0); + row4 = VecXor(VecLoad32(BLAKE2S_IV+4), VecLoad32(state.t()+0)); + + BLAKE2S_ROUND(0); + BLAKE2S_ROUND(1); + BLAKE2S_ROUND(2); + BLAKE2S_ROUND(3); + BLAKE2S_ROUND(4); + BLAKE2S_ROUND(5); + BLAKE2S_ROUND(6); + BLAKE2S_ROUND(7); + BLAKE2S_ROUND(8); + BLAKE2S_ROUND(9); + + VecStore32LE(state.h()+0, VecXor(ff0, VecXor(row1, row3)), le_mask); + VecStore32LE(state.h()+4, VecXor(ff1, VecXor(row2, row4)), le_mask); +} +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/blowfish.cpp b/external/ours/library/crypto/src/shared/original/blowfish.cpp new file mode 100755 index 000000000..e615da3b6 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blowfish.cpp @@ -0,0 +1,99 @@ +// blowfish.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "blowfish.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Blowfish::Base::UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + unsigned i, j=0, k; + word32 data, dspace[2] = {0, 0}; + + memcpy(pbox, p_init, sizeof(p_init)); + memcpy(sbox, s_init, sizeof(s_init)); + + // Xor key string into encryption key vector + for (i=0 ; i Block; + + word32 left, right; + Block::Get(inBlock)(left)(right); + + const word32 *const s=sbox; + const word32 *p=pbox; + + left ^= p[0]; + + for (unsigned i=0; i, public VariableKeyLength<16, 4, 56>, public FixedRounds<16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Blowfish";} +}; + +// Blowfish + +/// \brief Blowfish block cipher +/// \since Crypto++ 1.0 +class Blowfish : public Blowfish_Info, public BlockCipherDocumentation +{ + /// \brief Class specific implementation and overrides used to operate the cipher. + /// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + void UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs ¶ms); + + private: + void crypt_block(const word32 in[2], word32 out[2]) const; + + static const word32 p_init[ROUNDS+2]; + static const word32 s_init[4*256]; + + FixedSizeSecBlock pbox; + FixedSizeSecBlock sbox; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Blowfish::Encryption BlowfishEncryption; +typedef Blowfish::Decryption BlowfishDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/blumshub.cpp b/external/ours/library/crypto/src/shared/original/blumshub.cpp new file mode 100755 index 000000000..7465d8da4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blumshub.cpp @@ -0,0 +1,64 @@ +// blumshub.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "blumshub.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed) + : modn(n), + current(modn.Square(modn.Square(seed))), + maxBits(BitPrecision(n.BitCount())-1), + bitsLeft(maxBits) +{ +} + +unsigned int PublicBlumBlumShub::GenerateBit() +{ + if (bitsLeft==0) + { + current = modn.Square(current); + bitsLeft = maxBits; + } + + return static_cast(current.GetBit(--bitsLeft)); +} + +byte PublicBlumBlumShub::GenerateByte() +{ + byte b=0; + for (int i=0; i<8; i++) + b = byte((b << 1) | PublicBlumBlumShub::GenerateBit()); + return b; +} + +void PublicBlumBlumShub::GenerateBlock(byte *output, size_t size) +{ + while (size--) + *output++ = PublicBlumBlumShub::GenerateByte(); +} + +void PublicBlumBlumShub::ProcessData(byte *outString, const byte *inString, size_t length) +{ + while (length--) + *outString++ = *inString++ ^ PublicBlumBlumShub::GenerateByte(); +} + +BlumBlumShub::BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed) + : PublicBlumBlumShub(p*q, seed), + p(p), q(q), + x0(modn.Square(seed)) +{ +} + +void BlumBlumShub::Seek(lword index) +{ + Integer i(Integer::POSITIVE, index); + i *= 8; + Integer e = a_exp_b_mod_c (2, i / maxBits + 1, (p-1)*(q-1)); + current = modn.Exponentiate(x0, e); + bitsLeft = maxBits - i % maxBits; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/blumshub.h b/external/ours/library/crypto/src/shared/original/blumshub.h new file mode 100755 index 000000000..8c1c981fd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/blumshub.h @@ -0,0 +1,70 @@ +// blumshub.h - originally written and placed in the public domain by Wei Dai + +/// \file blumshub.h +/// \brief Classes for Blum Blum Shub generator + +#ifndef CRYPTOPP_BLUMSHUB_H +#define CRYPTOPP_BLUMSHUB_H + +#include "cryptlib.h" +#include "modarith.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief BlumBlumShub without factorization of the modulus +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +class PublicBlumBlumShub : public RandomNumberGenerator, + public StreamTransformation +{ +public: + virtual ~PublicBlumBlumShub() {} + + /// \brief Construct a PublicBlumBlumShub + /// \param n the modulus + /// \param seed the seed for the generator + /// \details seed is the secret key and should be about as large as n. + PublicBlumBlumShub(const Integer &n, const Integer &seed); + + unsigned int GenerateBit(); + byte GenerateByte(); + void GenerateBlock(byte *output, size_t size); + void ProcessData(byte *outString, const byte *inString, size_t length); + + bool IsSelfInverting() const {return true;} + bool IsForwardTransformation() const {return true;} + +protected: + ModularArithmetic modn; + Integer current; + word maxBits, bitsLeft; +}; + +/// \brief BlumBlumShub with factorization of the modulus +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +class BlumBlumShub : public PublicBlumBlumShub +{ +public: + virtual ~BlumBlumShub() {} + + /// \brief Construct a BlumBlumShub + /// \param p the first prime factor + /// \param q the second prime factor + /// \param seed the seed for the generator + /// \details Esure p and q are both primes congruent to 3 mod 4 and at least 512 bits long. + /// seed is the secret key and should be about as large as p*q. + BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed); + + bool IsRandomAccess() const {return true;} + void Seek(lword index); + +protected: + const Integer p, q; + const Integer x0; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/camellia.cpp b/external/ours/library/crypto/src/shared/original/camellia.cpp new file mode 100755 index 000000000..30b8bc99c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/camellia.cpp @@ -0,0 +1,539 @@ +// camellia.cpp - by Kevin Springle, 2003 +// This code is hereby placed in the public domain. + +/* +Optimisations and defense against timing attacks added in Jan 2007 by Wei Dai. + +The first 2 rounds and the last round seem especially vulnerable to timing +attacks. The protection is similar to what was implemented for Rijndael. +See comments at top of rijndael.cpp for more details. +*/ + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4456) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6246) +# endif +#endif + +#include "camellia.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +// round implementation that uses a small table for protection against timing attacks +#define SLOW_ROUND(lh, ll, rh, rl, kh, kl) { \ + word32 zr = ll ^ kl; \ + word32 zl = lh ^ kh; \ + zr= rotlConstant<1>(s1[GETBYTE(zr, 3)]) | \ + (rotrConstant<1>(s1[GETBYTE(zr, 2)]) << 24) | \ + (s1[rotlConstant<1>(CRYPTOPP_GET_BYTE_AS_BYTE(zr, 1))] << 16) | \ + (s1[GETBYTE(zr, 0)] << 8); \ + zl= (s1[GETBYTE(zl, 3)] << 24) | \ + (rotlConstant<1>(s1[GETBYTE(zl, 2)]) << 16) | \ + (rotrConstant<1>(s1[GETBYTE(zl, 1)]) << 8) | \ + s1[rotlConstant<1>(CRYPTOPP_GET_BYTE_AS_BYTE(zl, 0))]; \ + zl ^= zr; \ + zr = zl ^ rotlConstant<8>(zr); \ + zl = zr ^ rotrConstant<8>(zl); \ + rh ^= rotlConstant<16>(zr); \ + rh ^= zl; \ + rl ^= rotlConstant<8>(zl); \ + } + +// normal round - same output as above but using larger tables for faster speed +#define ROUND(lh, ll, rh, rl, kh, kl) { \ + word32 th = lh ^ kh; \ + word32 tl = ll ^ kl; \ + word32 d = SP[0][GETBYTE(tl,0)] ^ SP[1][GETBYTE(tl,3)] ^ SP[2][GETBYTE(tl,2)] ^ SP[3][GETBYTE(tl,1)]; \ + word32 u = SP[0][GETBYTE(th,3)] ^ SP[1][GETBYTE(th,2)] ^ SP[2][GETBYTE(th,1)] ^ SP[3][GETBYTE(th,0)]; \ + d ^= u; \ + rh ^= d; \ + rl ^= d; \ + rl ^= rotrConstant<8>(u);} + +#define DOUBLE_ROUND(lh, ll, rh, rl, k0, k1, k2, k3) \ + ROUND(lh, ll, rh, rl, k0, k1) \ + ROUND(rh, rl, lh, ll, k2, k3) + +#if (CRYPTOPP_LITTLE_ENDIAN) +#define EFI(i) (1-(i)) +#else +#define EFI(i) (i) +#endif + +void Camellia::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &) +{ + m_rounds = (keylen >= 24) ? 4 : 3; + unsigned int kslen = (8 * m_rounds + 2); + m_key.New(kslen*2); + word32 *ks32 = m_key.data(); + int m=0, a=0; + if (!IsForwardTransformation()) + m = -1, a = kslen-1; + + word32 kl0, kl1, kl2, kl3; + GetBlock getBlock(key); + getBlock(kl0)(kl1)(kl2)(kl3); + word32 k0=kl0, k1=kl1, k2=kl2, k3=kl3; + +#define CALC_ADDR2(base, i, j) ((byte *)(base)+8*(i)+4*(j)+((-16*(i))&m)) +#define CALC_ADDR(base, i) CALC_ADDR2(base, i, 0) + +#if 1 + word64 kwl, kwr; + ks32 += 2*a; +#define PREPARE_KS_ROUNDS \ + kwl = (word64(k0) << 32) | k1; \ + kwr = (word64(k2) << 32) | k3 +#define KS_ROUND_0(i) \ + CRYPTOPP_ASSERT(IsAlignedOn(CALC_ADDR(ks32, i+EFI(0)),GetAlignmentOf())); \ + CRYPTOPP_ASSERT(IsAlignedOn(CALC_ADDR(ks32, i+EFI(1)),GetAlignmentOf())); \ + *(word64*)(void*)CALC_ADDR(ks32, i+EFI(0)) = kwl; \ + *(word64*)(void*)CALC_ADDR(ks32, i+EFI(1)) = kwr +#define KS_ROUND(i, r, which) \ + CRYPTOPP_ASSERT(IsAlignedOn(CALC_ADDR(ks32, i+EFI(r<64)),GetAlignmentOf())); \ + CRYPTOPP_ASSERT(IsAlignedOn(CALC_ADDR(ks32, i+EFI(r>64)),GetAlignmentOf())); \ + if (which & (1<> (64 - (r%64))); \ + if (which & (1<64))) *(word64*)(void*)CALC_ADDR(ks32, i+EFI(r>64)) = (kwl << (r%64)) | (kwr >> (64 - (r%64))) +#else + // SSE2 version is 30% faster on Intel Core 2. Doesn't seem worth the hassle of maintenance, but left here + // #if'd out in case someone needs it. + __m128i kw, kw2; + __m128i *ks128 = (__m128i *)ks32+a/2; + ks32 += 2*a; +#define PREPARE_KS_ROUNDS \ + kw = _mm_set_epi32(k0, k1, k2, k3); \ + if (m) kw2 = kw, kw = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2)); \ + else kw2 = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2)) +#define KS_ROUND_0(i) \ + _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), kw) +#define KS_ROUND(i, r, which) { \ + __m128i temp; \ + if (r<64 && (which!=1 || m)) temp = _mm_or_si128(_mm_slli_epi64(kw, r%64), _mm_srli_epi64(kw2, 64-r%64)); \ + else temp = _mm_or_si128(_mm_slli_epi64(kw2, r%64), _mm_srli_epi64(kw, 64-r%64)); \ + if (which & 2) _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), temp); \ + else _mm_storel_epi64((__m128i*)CALC_ADDR(ks32, i+EFI(0)), temp); \ + } +#endif + + if (keylen == 16) + { + // KL + PREPARE_KS_ROUNDS; + KS_ROUND_0(0); + KS_ROUND(4, 15, 3); + KS_ROUND(10, 45, 3); + KS_ROUND(12, 60, 2); + KS_ROUND(16, 77, 3); + KS_ROUND(18, 94, 3); + KS_ROUND(22, 111, 3); + + // KA + k0=kl0, k1=kl1, k2=kl2, k3=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xA09E667Ful, 0x3BCC908Bul, 0xB67AE858ul, 0x4CAA73B2ul); + k0^=kl0, k1^=kl1, k2^=kl2, k3^=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xC6EF372Ful, 0xE94F82BEul, 0x54FF53A5ul, 0xF1D36F1Cul); + + PREPARE_KS_ROUNDS; + KS_ROUND_0(2); + KS_ROUND(6, 15, 3); + KS_ROUND(8, 30, 3); + KS_ROUND(12, 45, 1); + KS_ROUND(14, 60, 3); + KS_ROUND(20, 94, 3); + KS_ROUND(24, 47, 3); + } + else + { + // KL + PREPARE_KS_ROUNDS; + KS_ROUND_0(0); + KS_ROUND(12, 45, 3); + KS_ROUND(16, 60, 3); + KS_ROUND(22, 77, 3); + KS_ROUND(30, 111, 3); + + // KR + word32 kr0, kr1, kr2, kr3; + GetBlock(key+16)(kr0)(kr1); + if (keylen == 24) + kr2 = ~kr0, kr3 = ~kr1; + else + GetBlock(key+24)(kr2)(kr3); + k0=kr0, k1=kr1, k2=kr2, k3=kr3; + + PREPARE_KS_ROUNDS; + KS_ROUND(4, 15, 3); + KS_ROUND(8, 30, 3); + KS_ROUND(18, 60, 3); + KS_ROUND(26, 94, 3); + + // KA + k0^=kl0, k1^=kl1, k2^=kl2, k3^=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xA09E667Ful, 0x3BCC908Bul, 0xB67AE858ul, 0x4CAA73B2ul); + k0^=kl0, k1^=kl1, k2^=kl2, k3^=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xC6EF372Ful, 0xE94F82BEul, 0x54FF53A5ul, 0xF1D36F1Cul); + + PREPARE_KS_ROUNDS; + KS_ROUND(6, 15, 3); + KS_ROUND(14, 45, 3); + KS_ROUND(24, 77, 3); + KS_ROUND(28, 94, 3); + + // KB + k0^=kr0, k1^=kr1, k2^=kr2, k3^=kr3; + DOUBLE_ROUND(k0, k1, k2, k3, 0x10E527FAul, 0xDE682D1Dul, 0xB05688C2ul, 0xB3E6C1FDul); + + PREPARE_KS_ROUNDS; + KS_ROUND_0(2); + KS_ROUND(10, 30, 3); + KS_ROUND(20, 60, 3); + KS_ROUND(32, 47, 3); + } +} + +void Camellia::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ +#define KS(i, j) ks[i*4 + EFI(j/2)*2 + EFI(j%2)] + +#define FL(klh, kll, krh, krl) \ + ll ^= rotlConstant<1>(lh & klh);\ + lh ^= (ll | kll); \ + rh ^= (rl | krl); \ + rl ^= rotlConstant<1>(rh & krh); + + word32 lh, ll, rh, rl; + typedef BlockGetAndPut Block; + Block::Get(inBlock)(lh)(ll)(rh)(rl); + const word32 *ks = m_key.data(); + lh ^= KS(0,0); + ll ^= KS(0,1); + rh ^= KS(0,2); + rl ^= KS(0,3); + + // Timing attack countermeasure. see comments in Rijndael for more details + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + volatile word32 _u = 0; + word32 u = _u; + + for (i=0; i<256; i+=cacheLineSize) + u &= *(const word32 *)(void*)(s1+i); + u &= *(const word32 *)(void*)(s1+252); + lh |= u; ll |= u; + + SLOW_ROUND(lh, ll, rh, rl, KS(1,0), KS(1,1)) + SLOW_ROUND(rh, rl, lh, ll, KS(1,2), KS(1,3)) + for (i = m_rounds-1; i > 0; --i) + { + DOUBLE_ROUND(lh, ll, rh, rl, KS(2,0), KS(2,1), KS(2,2), KS(2,3)) + DOUBLE_ROUND(lh, ll, rh, rl, KS(3,0), KS(3,1), KS(3,2), KS(3,3)) + FL(KS(4,0), KS(4,1), KS(4,2), KS(4,3)); + DOUBLE_ROUND(lh, ll, rh, rl, KS(5,0), KS(5,1), KS(5,2), KS(5,3)) + ks += 16; + } + DOUBLE_ROUND(lh, ll, rh, rl, KS(2,0), KS(2,1), KS(2,2), KS(2,3)) + ROUND(lh, ll, rh, rl, KS(3,0), KS(3,1)) + SLOW_ROUND(rh, rl, lh, ll, KS(3,2), KS(3,3)) + lh ^= KS(4,0); + ll ^= KS(4,1); + rh ^= KS(4,2); + rl ^= KS(4,3); + Block::Put(xorBlock, outBlock)(rh)(rl)(lh)(ll); +} + +// The Camellia s-boxes + +CRYPTOPP_ALIGN_DATA(4) +const byte Camellia::Base::s1[256] = +{ + 112,130,44,236,179,39,192,229,228,133,87,53,234,12,174,65, + 35,239,107,147,69,25,165,33,237,14,79,78,29,101,146,189, + 134,184,175,143,124,235,31,206,62,48,220,95,94,197,11,26, + 166,225,57,202,213,71,93,61,217,1,90,214,81,86,108,77, + 139,13,154,102,251,204,176,45,116,18,43,32,240,177,132,153, + 223,76,203,194,52,126,118,5,109,183,169,49,209,23,4,215, + 20,88,58,97,222,27,17,28,50,15,156,22,83,24,242,34, + 254,68,207,178,195,181,122,145,36,8,232,168,96,252,105,80, + 170,208,160,125,161,137,98,151,84,91,30,149,224,255,100,210, + 16,196,0,72,163,247,117,219,138,3,230,218,9,63,221,148, + 135,92,131,2,205,74,144,51,115,103,246,243,157,127,191,226, + 82,155,216,38,200,55,198,59,129,150,111,75,19,190,99,46, + 233,121,167,140,159,110,188,142,41,245,249,182,47,253,180,89, + 120,152,6,106,231,70,113,186,212,37,171,66,136,162,141,250, + 114,7,185,85,248,238,172,10,54,73,42,104,60,56,241,164, + 64,40,211,123,187,201,67,193,21,227,173,244,119,199,128,158 +}; + +const word32 Camellia::Base::SP[4][256] = { + { + 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, + 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, + 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, + 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, + 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, + 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, + 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, + 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, + 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, + 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, + 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, + 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, + 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, + 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, + 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, + 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, + 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, + 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, + 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, + 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, + 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, + 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, + 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, + 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, + 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, + 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, + 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, + 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, + 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, + 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, + 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, + 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, + 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, + 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, + 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, + 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, + 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, + 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, + 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, + 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, + 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, + 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, + 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 + }, + { + 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, + 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, + 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, + 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, + 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, + 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, + 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, + 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, + 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, + 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, + 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, + 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, + 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, + 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, + 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, + 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, + 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, + 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, + 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, + 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, + 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, + 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, + 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, + 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, + 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, + 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, + 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, + 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, + 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, + 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, + 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, + 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, + 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, + 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, + 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, + 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, + 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, + 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, + 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, + 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, + 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, + 0x00777777, 0x00939393, 0x00868686, 0x00838383, + 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d + }, + { + 0x38003838, 0x41004141, 0x16001616, 0x76007676, + 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, + 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, + 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, + 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, + 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, + 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, + 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, + 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, + 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, + 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, + 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, + 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, + 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, + 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, + 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, + 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, + 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, + 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, + 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, + 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, + 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, + 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, + 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, + 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, + 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, + 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, + 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, + 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, + 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, + 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, + 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, + 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, + 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, + 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, + 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, + 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, + 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, + 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, + 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, + 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, + 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, + 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f + }, + { + 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, + 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, + 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, + 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, + 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, + 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, + 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, + 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, + 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, + 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, + 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, + 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, + 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, + 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, + 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, + 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, + 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, + 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, + 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, + 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, + 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, + 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, + 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, + 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, + 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, + 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, + 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, + 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, + 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, + 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, + 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, + 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, + 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, + 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, + 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, + 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, + 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, + 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, + 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, + 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, + 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, + 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, + 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e + }}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/camellia.h b/external/ours/library/crypto/src/shared/original/camellia.h new file mode 100755 index 000000000..e83a20608 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/camellia.h @@ -0,0 +1,49 @@ +// camellia.h - originally written and placed in the public domain by Wei Dai + +/// \file camellia.h +/// \brief Classes for the Camellia block cipher + +#ifndef CRYPTOPP_CAMELLIA_H +#define CRYPTOPP_CAMELLIA_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Camellia block cipher information +struct Camellia_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Camellia";} +}; + +/// \brief Camellia block cipher +/// \sa Camellia +class Camellia : public Camellia_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + CRYPTOPP_ALIGN_DATA(4) static const byte s1[256]; + static const word32 SP[4][256]; + + unsigned int m_rounds; + SecBlock m_key; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Camellia::Encryption CamelliaEncryption; +typedef Camellia::Decryption CamelliaDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/cast.cpp b/external/ours/library/crypto/src/shared/original/cast.cpp new file mode 100755 index 000000000..a63e3f8b9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cast.cpp @@ -0,0 +1,292 @@ +// cast.cpp - originally written and placed in the public domain by Wei Dai and Leonard Janke +// based on Steve Reid's public domain cast.c + +#include "pch.h" +#include "cast.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/* Macros to access 8-bit bytes out of a 32-bit word */ +#define U8a(x) GETBYTE(x,3) +#define U8b(x) GETBYTE(x,2) +#define U8c(x) GETBYTE(x,1) +#define U8d(x) GETBYTE(x,0) + +/* CAST uses three different round functions */ +#define f1(l, r, km, kr) \ + t = rotlVariable(km + r, kr); \ + l ^= ((S[0][U8a(t)] ^ S[1][U8b(t)]) - \ + S[2][U8c(t)]) + S[3][U8d(t)]; +#define f2(l, r, km, kr) \ + t = rotlVariable(km ^ r, kr); \ + l ^= ((S[0][U8a(t)] - S[1][U8b(t)]) + \ + S[2][U8c(t)]) ^ S[3][U8d(t)]; +#define f3(l, r, km, kr) \ + t = rotlVariable(km - r, kr); \ + l ^= ((S[0][U8a(t)] + S[1][U8b(t)]) ^ \ + S[2][U8c(t)]) - S[3][U8d(t)]; + +#define F1(l, r, i, j) f1(l, r, K[i], K[i+j]) +#define F2(l, r, i, j) f2(l, r, K[i], K[i+j]) +#define F3(l, r, i, j) f3(l, r, K[i], K[i+j]) + +typedef BlockGetAndPut Block; + +void CAST128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 &t=m_t[0], &l=m_t[1], &r=m_t[2]; + + /* Get inblock into l,r */ + Block::Get(inBlock)(l)(r); + /* Do the work */ + F1(l, r, 0, 16); + F2(r, l, 1, 16); + F3(l, r, 2, 16); + F1(r, l, 3, 16); + F2(l, r, 4, 16); + F3(r, l, 5, 16); + F1(l, r, 6, 16); + F2(r, l, 7, 16); + F3(l, r, 8, 16); + F1(r, l, 9, 16); + F2(l, r, 10, 16); + F3(r, l, 11, 16); + /* Only do full 16 rounds if key length > 80 bits */ + if (!reduced) { + F1(l, r, 12, 16); + F2(r, l, 13, 16); + F3(l, r, 14, 16); + F1(r, l, 15, 16); + } + /* Put l,r into outblock */ + Block::Put(xorBlock, outBlock)(r)(l); +} + +void CAST128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 &t=m_t[0], &l=m_t[1], &r=m_t[2]; + + /* Get inblock into l,r */ + Block::Get(inBlock)(r)(l); + /* Only do full 16 rounds if key length > 80 bits */ + if (!reduced) { + F1(r, l, 15, 16); + F3(l, r, 14, 16); + F2(r, l, 13, 16); + F1(l, r, 12, 16); + } + F3(r, l, 11, 16); + F2(l, r, 10, 16); + F1(r, l, 9, 16); + F3(l, r, 8, 16); + F2(r, l, 7, 16); + F1(l, r, 6, 16); + F3(r, l, 5, 16); + F2(l, r, 4, 16); + F1(r, l, 3, 16); + F3(l, r, 2, 16); + F2(r, l, 1, 16); + F1(l, r, 0, 16); + /* Put l,r into outblock */ + Block::Put(xorBlock, outBlock)(l)(r); +} + +void CAST128::Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + reduced = (keylength <= 10); + + word32 X[4], Z[4]={0}; + GetUserKey(BIG_ENDIAN_ORDER, X, 4, userKey, keylength); + +#define x(i) GETBYTE(X[i/4], 3-i%4) +#define z(i) GETBYTE(Z[i/4], 3-i%4) + + unsigned int i; + for (i=0; i<=16; i+=16) + { + // this part is copied directly from RFC 2144 (with some search and replace) by Wei Dai + Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)]; + Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)]; + Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)]; + Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)]; + K[i+0] = S[4][z(0x8)] ^ S[5][z(0x9)] ^ S[6][z(0x7)] ^ S[7][z(0x6)] ^ S[4][z(0x2)]; + K[i+1] = S[4][z(0xA)] ^ S[5][z(0xB)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[5][z(0x6)]; + K[i+2] = S[4][z(0xC)] ^ S[5][z(0xD)] ^ S[6][z(0x3)] ^ S[7][z(0x2)] ^ S[6][z(0x9)]; + K[i+3] = S[4][z(0xE)] ^ S[5][z(0xF)] ^ S[6][z(0x1)] ^ S[7][z(0x0)] ^ S[7][z(0xC)]; + X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)]; + X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)]; + X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)]; + X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)]; + K[i+4] = S[4][x(0x3)] ^ S[5][x(0x2)] ^ S[6][x(0xC)] ^ S[7][x(0xD)] ^ S[4][x(0x8)]; + K[i+5] = S[4][x(0x1)] ^ S[5][x(0x0)] ^ S[6][x(0xE)] ^ S[7][x(0xF)] ^ S[5][x(0xD)]; + K[i+6] = S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x8)] ^ S[7][x(0x9)] ^ S[6][x(0x3)]; + K[i+7] = S[4][x(0x5)] ^ S[5][x(0x4)] ^ S[6][x(0xA)] ^ S[7][x(0xB)] ^ S[7][x(0x7)]; + Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)]; + Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)]; + Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)]; + Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)]; + K[i+8] = S[4][z(0x3)] ^ S[5][z(0x2)] ^ S[6][z(0xC)] ^ S[7][z(0xD)] ^ S[4][z(0x9)]; + K[i+9] = S[4][z(0x1)] ^ S[5][z(0x0)] ^ S[6][z(0xE)] ^ S[7][z(0xF)] ^ S[5][z(0xC)]; + K[i+10] = S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x8)] ^ S[7][z(0x9)] ^ S[6][z(0x2)]; + K[i+11] = S[4][z(0x5)] ^ S[5][z(0x4)] ^ S[6][z(0xA)] ^ S[7][z(0xB)] ^ S[7][z(0x6)]; + X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)]; + X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)]; + X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)]; + X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)]; + K[i+12] = S[4][x(0x8)] ^ S[5][x(0x9)] ^ S[6][x(0x7)] ^ S[7][x(0x6)] ^ S[4][x(0x3)]; + K[i+13] = S[4][x(0xA)] ^ S[5][x(0xB)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[5][x(0x7)]; + K[i+14] = S[4][x(0xC)] ^ S[5][x(0xD)] ^ S[6][x(0x3)] ^ S[7][x(0x2)] ^ S[6][x(0x8)]; + K[i+15] = S[4][x(0xE)] ^ S[5][x(0xF)] ^ S[6][x(0x1)] ^ S[7][x(0x0)] ^ S[7][x(0xD)]; + } + + for (i=16; i<32; i++) + K[i] &= 0x1f; +} + +// The following CAST-256 implementation was contributed by Leonard Janke + +const word32 CAST256::Base::t_m[8][24]={ +{ 0x5a827999, 0xd151d6a1, 0x482133a9, 0xbef090b1, 0x35bfedb9, 0xac8f4ac1, + 0x235ea7c9, 0x9a2e04d1, 0x10fd61d9, 0x87ccbee1, 0xfe9c1be9, 0x756b78f1, + 0xec3ad5f9, 0x630a3301, 0xd9d99009, 0x50a8ed11, 0xc7784a19, 0x3e47a721, + 0xb5170429, 0x2be66131, 0xa2b5be39, 0x19851b41, 0x90547849, 0x0723d551}, +{ 0xc95c653a, 0x402bc242, 0xb6fb1f4a, 0x2dca7c52, 0xa499d95a, 0x1b693662, + 0x9238936a, 0x0907f072, 0x7fd74d7a, 0xf6a6aa82, 0x6d76078a, 0xe4456492, + 0x5b14c19a, 0xd1e41ea2, 0x48b37baa, 0xbf82d8b2, 0x365235ba, 0xad2192c2, + 0x23f0efca, 0x9ac04cd2, 0x118fa9da, 0x885f06e2, 0xff2e63ea, 0x75fdc0f2}, +{ 0x383650db, 0xaf05ade3, 0x25d50aeb, 0x9ca467f3, 0x1373c4fb, 0x8a432203, + 0x01127f0b, 0x77e1dc13, 0xeeb1391b, 0x65809623, 0xdc4ff32b, 0x531f5033, + 0xc9eead3b, 0x40be0a43, 0xb78d674b, 0x2e5cc453, 0xa52c215b, 0x1bfb7e63, + 0x92cadb6b, 0x099a3873, 0x8069957b, 0xf738f283, 0x6e084f8b, 0xe4d7ac93}, +{ 0xa7103c7c, 0x1ddf9984, 0x94aef68c, 0x0b7e5394, 0x824db09c, 0xf91d0da4, + 0x6fec6aac, 0xe6bbc7b4, 0x5d8b24bc, 0xd45a81c4, 0x4b29decc, 0xc1f93bd4, + 0x38c898dc, 0xaf97f5e4, 0x266752ec, 0x9d36aff4, 0x14060cfc, 0x8ad56a04, + 0x01a4c70c, 0x78742414, 0xef43811c, 0x6612de24, 0xdce23b2c, 0x53b19834}, +{ 0x15ea281d, 0x8cb98525, 0x0388e22d, 0x7a583f35, 0xf1279c3d, 0x67f6f945, + 0xdec6564d, 0x5595b355, 0xcc65105d, 0x43346d65, 0xba03ca6d, 0x30d32775, + 0xa7a2847d, 0x1e71e185, 0x95413e8d, 0x0c109b95, 0x82dff89d, 0xf9af55a5, + 0x707eb2ad, 0xe74e0fb5, 0x5e1d6cbd, 0xd4ecc9c5, 0x4bbc26cd, 0xc28b83d5}, +{ 0x84c413be, 0xfb9370c6, 0x7262cdce, 0xe9322ad6, 0x600187de, 0xd6d0e4e6, + 0x4da041ee, 0xc46f9ef6, 0x3b3efbfe, 0xb20e5906, 0x28ddb60e, 0x9fad1316, + 0x167c701e, 0x8d4bcd26, 0x041b2a2e, 0x7aea8736, 0xf1b9e43e, 0x68894146, + 0xdf589e4e, 0x5627fb56, 0xccf7585e, 0x43c6b566, 0xba96126e, 0x31656f76}, +{ 0xf39dff5f, 0x6a6d5c67, 0xe13cb96f, 0x580c1677, 0xcedb737f, 0x45aad087, + 0xbc7a2d8f, 0x33498a97, 0xaa18e79f, 0x20e844a7, 0x97b7a1af, 0x0e86feb7, + 0x85565bbf, 0xfc25b8c7, 0x72f515cf, 0xe9c472d7, 0x6093cfdf, 0xd7632ce7, + 0x4e3289ef, 0xc501e6f7, 0x3bd143ff, 0xb2a0a107, 0x296ffe0f, 0xa03f5b17}, +{ 0x6277eb00, 0xd9474808, 0x5016a510, 0xc6e60218, 0x3db55f20, 0xb484bc28, + 0x2b541930, 0xa2237638, 0x18f2d340, 0x8fc23048, 0x06918d50, 0x7d60ea58, + 0xf4304760, 0x6affa468, 0xe1cf0170, 0x589e5e78, 0xcf6dbb80, 0x463d1888, + 0xbd0c7590, 0x33dbd298, 0xaaab2fa0, 0x217a8ca8, 0x9849e9b0, 0x0f1946b8} +}; + +const unsigned int CAST256::Base::t_r[8][24]={ + {19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11}, + {4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28}, + {21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13}, + {6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30}, + {23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15}, + {8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0}, + {25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17}, + {10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2} +}; + +#define Q(i) \ + F1(block[2],block[3],8*i+4,-4); \ + F2(block[1],block[2],8*i+5,-4); \ + F3(block[0],block[1],8*i+6,-4); \ + F1(block[3],block[0],8*i+7,-4); + +#define QBar(i) \ + F1(block[3],block[0],8*i+7,-4); \ + F3(block[0],block[1],8*i+6,-4); \ + F2(block[1],block[2],8*i+5,-4); \ + F1(block[2],block[3],8*i+4,-4); + +/* CAST256's encrypt/decrypt functions are identical except for the order that +the keys are used */ + +void CAST256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // TODO: add a SecBlock workspace to the class when the ABI can change + word32 t, block[4]; + Block::Get(inBlock)(block[0])(block[1])(block[2])(block[3]); + + // Perform 6 forward quad rounds + Q(0); + Q(1); + Q(2); + Q(3); + Q(4); + Q(5); + + // Perform 6 reverse quad rounds + QBar(6); + QBar(7); + QBar(8); + QBar(9); + QBar(10); + QBar(11); + + Block::Put(xorBlock, outBlock)(block[0])(block[1])(block[2])(block[3]); +} + +/* Set up a CAST-256 key */ + +void CAST256::Base::Omega(int i, word32 kappa[8]) +{ + word32 t; + + f1(kappa[6],kappa[7],t_m[0][i],t_r[0][i]); + f2(kappa[5],kappa[6],t_m[1][i],t_r[1][i]); + f3(kappa[4],kappa[5],t_m[2][i],t_r[2][i]); + f1(kappa[3],kappa[4],t_m[3][i],t_r[3][i]); + f2(kappa[2],kappa[3],t_m[4][i],t_r[4][i]); + f3(kappa[1],kappa[2],t_m[5][i],t_r[5][i]); + f1(kappa[0],kappa[1],t_m[6][i],t_r[6][i]); + f2(kappa[7],kappa[0],t_m[7][i],t_r[7][i]); +} + +void CAST256::Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + GetUserKey(BIG_ENDIAN_ORDER, kappa.begin(), 8, userKey, keylength); + + for(int i=0; i<12; ++i) + { + Omega(2*i,kappa); + Omega(2*i+1,kappa); + + K[8*i]=kappa[0] & 31; + K[8*i+1]=kappa[2] & 31; + K[8*i+2]=kappa[4] & 31; + K[8*i+3]=kappa[6] & 31; + K[8*i+4]=kappa[7]; + K[8*i+5]=kappa[5]; + K[8*i+6]=kappa[3]; + K[8*i+7]=kappa[1]; + } + + if (!IsForwardTransformation()) + { + for(int j=0; j<6; ++j) + { + for(int i=0; i<4; ++i) + { + int i1=8*j+i; + int i2=8*(11-j)+i; + + CRYPTOPP_ASSERT(i1, public VariableKeyLength<16, 5, 16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "CAST-128";} +}; + +/// \brief CAST128 block cipher +/// \sa CAST-128 +/// \since Crypto++ 2.2 +class CAST128 : public CAST128_Info, public BlockCipherDocumentation +{ + /// \brief CAST128 block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public CAST, public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + bool reduced; + FixedSizeSecBlock K; + mutable FixedSizeSecBlock m_t; + }; + + /// \brief CAST128 block cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief CAST128 block cipher decryption operation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief CAST256 block cipher information +/// \since Crypto++ 4.0 +struct CAST256_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 4> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "CAST-256";} +}; + +/// \brief CAST256 block cipher +/// \sa CAST-256 +/// \since Crypto++ 4.0 +class CAST256 : public CAST256_Info, public BlockCipherDocumentation +{ + /// \brief CAST256 block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public CAST, public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + static const word32 t_m[8][24]; + static const unsigned int t_r[8][24]; + + static void Omega(int i, word32 kappa[8]); + + FixedSizeSecBlock K; + mutable FixedSizeSecBlock kappa; + mutable FixedSizeSecBlock m_t; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef CAST128::Encryption CAST128Encryption; +typedef CAST128::Decryption CAST128Decryption; + +typedef CAST256::Encryption CAST256Encryption; +typedef CAST256::Decryption CAST256Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/casts.cpp b/external/ours/library/crypto/src/shared/original/casts.cpp new file mode 100755 index 000000000..d823d725c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/casts.cpp @@ -0,0 +1,545 @@ +#include "pch.h" +#include "cast.h" + +NAMESPACE_BEGIN(CryptoPP) + +// CAST S-boxes + +const word32 CAST::S[8][256] = { +{ + 0x30FB40D4UL, 0x9FA0FF0BUL, 0x6BECCD2FUL, 0x3F258C7AUL, + 0x1E213F2FUL, 0x9C004DD3UL, 0x6003E540UL, 0xCF9FC949UL, + 0xBFD4AF27UL, 0x88BBBDB5UL, 0xE2034090UL, 0x98D09675UL, + 0x6E63A0E0UL, 0x15C361D2UL, 0xC2E7661DUL, 0x22D4FF8EUL, + 0x28683B6FUL, 0xC07FD059UL, 0xFF2379C8UL, 0x775F50E2UL, + 0x43C340D3UL, 0xDF2F8656UL, 0x887CA41AUL, 0xA2D2BD2DUL, + 0xA1C9E0D6UL, 0x346C4819UL, 0x61B76D87UL, 0x22540F2FUL, + 0x2ABE32E1UL, 0xAA54166BUL, 0x22568E3AUL, 0xA2D341D0UL, + 0x66DB40C8UL, 0xA784392FUL, 0x004DFF2FUL, 0x2DB9D2DEUL, + 0x97943FACUL, 0x4A97C1D8UL, 0x527644B7UL, 0xB5F437A7UL, + 0xB82CBAEFUL, 0xD751D159UL, 0x6FF7F0EDUL, 0x5A097A1FUL, + 0x827B68D0UL, 0x90ECF52EUL, 0x22B0C054UL, 0xBC8E5935UL, + 0x4B6D2F7FUL, 0x50BB64A2UL, 0xD2664910UL, 0xBEE5812DUL, + 0xB7332290UL, 0xE93B159FUL, 0xB48EE411UL, 0x4BFF345DUL, + 0xFD45C240UL, 0xAD31973FUL, 0xC4F6D02EUL, 0x55FC8165UL, + 0xD5B1CAADUL, 0xA1AC2DAEUL, 0xA2D4B76DUL, 0xC19B0C50UL, + 0x882240F2UL, 0x0C6E4F38UL, 0xA4E4BFD7UL, 0x4F5BA272UL, + 0x564C1D2FUL, 0xC59C5319UL, 0xB949E354UL, 0xB04669FEUL, + 0xB1B6AB8AUL, 0xC71358DDUL, 0x6385C545UL, 0x110F935DUL, + 0x57538AD5UL, 0x6A390493UL, 0xE63D37E0UL, 0x2A54F6B3UL, + 0x3A787D5FUL, 0x6276A0B5UL, 0x19A6FCDFUL, 0x7A42206AUL, + 0x29F9D4D5UL, 0xF61B1891UL, 0xBB72275EUL, 0xAA508167UL, + 0x38901091UL, 0xC6B505EBUL, 0x84C7CB8CUL, 0x2AD75A0FUL, + 0x874A1427UL, 0xA2D1936BUL, 0x2AD286AFUL, 0xAA56D291UL, + 0xD7894360UL, 0x425C750DUL, 0x93B39E26UL, 0x187184C9UL, + 0x6C00B32DUL, 0x73E2BB14UL, 0xA0BEBC3CUL, 0x54623779UL, + 0x64459EABUL, 0x3F328B82UL, 0x7718CF82UL, 0x59A2CEA6UL, + 0x04EE002EUL, 0x89FE78E6UL, 0x3FAB0950UL, 0x325FF6C2UL, + 0x81383F05UL, 0x6963C5C8UL, 0x76CB5AD6UL, 0xD49974C9UL, + 0xCA180DCFUL, 0x380782D5UL, 0xC7FA5CF6UL, 0x8AC31511UL, + 0x35E79E13UL, 0x47DA91D0UL, 0xF40F9086UL, 0xA7E2419EUL, + 0x31366241UL, 0x051EF495UL, 0xAA573B04UL, 0x4A805D8DUL, + 0x548300D0UL, 0x00322A3CUL, 0xBF64CDDFUL, 0xBA57A68EUL, + 0x75C6372BUL, 0x50AFD341UL, 0xA7C13275UL, 0x915A0BF5UL, + 0x6B54BFABUL, 0x2B0B1426UL, 0xAB4CC9D7UL, 0x449CCD82UL, + 0xF7FBF265UL, 0xAB85C5F3UL, 0x1B55DB94UL, 0xAAD4E324UL, + 0xCFA4BD3FUL, 0x2DEAA3E2UL, 0x9E204D02UL, 0xC8BD25ACUL, + 0xEADF55B3UL, 0xD5BD9E98UL, 0xE31231B2UL, 0x2AD5AD6CUL, + 0x954329DEUL, 0xADBE4528UL, 0xD8710F69UL, 0xAA51C90FUL, + 0xAA786BF6UL, 0x22513F1EUL, 0xAA51A79BUL, 0x2AD344CCUL, + 0x7B5A41F0UL, 0xD37CFBADUL, 0x1B069505UL, 0x41ECE491UL, + 0xB4C332E6UL, 0x032268D4UL, 0xC9600ACCUL, 0xCE387E6DUL, + 0xBF6BB16CUL, 0x6A70FB78UL, 0x0D03D9C9UL, 0xD4DF39DEUL, + 0xE01063DAUL, 0x4736F464UL, 0x5AD328D8UL, 0xB347CC96UL, + 0x75BB0FC3UL, 0x98511BFBUL, 0x4FFBCC35UL, 0xB58BCF6AUL, + 0xE11F0ABCUL, 0xBFC5FE4AUL, 0xA70AEC10UL, 0xAC39570AUL, + 0x3F04442FUL, 0x6188B153UL, 0xE0397A2EUL, 0x5727CB79UL, + 0x9CEB418FUL, 0x1CACD68DUL, 0x2AD37C96UL, 0x0175CB9DUL, + 0xC69DFF09UL, 0xC75B65F0UL, 0xD9DB40D8UL, 0xEC0E7779UL, + 0x4744EAD4UL, 0xB11C3274UL, 0xDD24CB9EUL, 0x7E1C54BDUL, + 0xF01144F9UL, 0xD2240EB1UL, 0x9675B3FDUL, 0xA3AC3755UL, + 0xD47C27AFUL, 0x51C85F4DUL, 0x56907596UL, 0xA5BB15E6UL, + 0x580304F0UL, 0xCA042CF1UL, 0x011A37EAUL, 0x8DBFAADBUL, + 0x35BA3E4AUL, 0x3526FFA0UL, 0xC37B4D09UL, 0xBC306ED9UL, + 0x98A52666UL, 0x5648F725UL, 0xFF5E569DUL, 0x0CED63D0UL, + 0x7C63B2CFUL, 0x700B45E1UL, 0xD5EA50F1UL, 0x85A92872UL, + 0xAF1FBDA7UL, 0xD4234870UL, 0xA7870BF3UL, 0x2D3B4D79UL, + 0x42E04198UL, 0x0CD0EDE7UL, 0x26470DB8UL, 0xF881814CUL, + 0x474D6AD7UL, 0x7C0C5E5CUL, 0xD1231959UL, 0x381B7298UL, + 0xF5D2F4DBUL, 0xAB838653UL, 0x6E2F1E23UL, 0x83719C9EUL, + 0xBD91E046UL, 0x9A56456EUL, 0xDC39200CUL, 0x20C8C571UL, + 0x962BDA1CUL, 0xE1E696FFUL, 0xB141AB08UL, 0x7CCA89B9UL, + 0x1A69E783UL, 0x02CC4843UL, 0xA2F7C579UL, 0x429EF47DUL, + 0x427B169CUL, 0x5AC9F049UL, 0xDD8F0F00UL, 0x5C8165BFUL +}, + +{ + 0x1F201094UL, 0xEF0BA75BUL, 0x69E3CF7EUL, 0x393F4380UL, + 0xFE61CF7AUL, 0xEEC5207AUL, 0x55889C94UL, 0x72FC0651UL, + 0xADA7EF79UL, 0x4E1D7235UL, 0xD55A63CEUL, 0xDE0436BAUL, + 0x99C430EFUL, 0x5F0C0794UL, 0x18DCDB7DUL, 0xA1D6EFF3UL, + 0xA0B52F7BUL, 0x59E83605UL, 0xEE15B094UL, 0xE9FFD909UL, + 0xDC440086UL, 0xEF944459UL, 0xBA83CCB3UL, 0xE0C3CDFBUL, + 0xD1DA4181UL, 0x3B092AB1UL, 0xF997F1C1UL, 0xA5E6CF7BUL, + 0x01420DDBUL, 0xE4E7EF5BUL, 0x25A1FF41UL, 0xE180F806UL, + 0x1FC41080UL, 0x179BEE7AUL, 0xD37AC6A9UL, 0xFE5830A4UL, + 0x98DE8B7FUL, 0x77E83F4EUL, 0x79929269UL, 0x24FA9F7BUL, + 0xE113C85BUL, 0xACC40083UL, 0xD7503525UL, 0xF7EA615FUL, + 0x62143154UL, 0x0D554B63UL, 0x5D681121UL, 0xC866C359UL, + 0x3D63CF73UL, 0xCEE234C0UL, 0xD4D87E87UL, 0x5C672B21UL, + 0x071F6181UL, 0x39F7627FUL, 0x361E3084UL, 0xE4EB573BUL, + 0x602F64A4UL, 0xD63ACD9CUL, 0x1BBC4635UL, 0x9E81032DUL, + 0x2701F50CUL, 0x99847AB4UL, 0xA0E3DF79UL, 0xBA6CF38CUL, + 0x10843094UL, 0x2537A95EUL, 0xF46F6FFEUL, 0xA1FF3B1FUL, + 0x208CFB6AUL, 0x8F458C74UL, 0xD9E0A227UL, 0x4EC73A34UL, + 0xFC884F69UL, 0x3E4DE8DFUL, 0xEF0E0088UL, 0x3559648DUL, + 0x8A45388CUL, 0x1D804366UL, 0x721D9BFDUL, 0xA58684BBUL, + 0xE8256333UL, 0x844E8212UL, 0x128D8098UL, 0xFED33FB4UL, + 0xCE280AE1UL, 0x27E19BA5UL, 0xD5A6C252UL, 0xE49754BDUL, + 0xC5D655DDUL, 0xEB667064UL, 0x77840B4DUL, 0xA1B6A801UL, + 0x84DB26A9UL, 0xE0B56714UL, 0x21F043B7UL, 0xE5D05860UL, + 0x54F03084UL, 0x066FF472UL, 0xA31AA153UL, 0xDADC4755UL, + 0xB5625DBFUL, 0x68561BE6UL, 0x83CA6B94UL, 0x2D6ED23BUL, + 0xECCF01DBUL, 0xA6D3D0BAUL, 0xB6803D5CUL, 0xAF77A709UL, + 0x33B4A34CUL, 0x397BC8D6UL, 0x5EE22B95UL, 0x5F0E5304UL, + 0x81ED6F61UL, 0x20E74364UL, 0xB45E1378UL, 0xDE18639BUL, + 0x881CA122UL, 0xB96726D1UL, 0x8049A7E8UL, 0x22B7DA7BUL, + 0x5E552D25UL, 0x5272D237UL, 0x79D2951CUL, 0xC60D894CUL, + 0x488CB402UL, 0x1BA4FE5BUL, 0xA4B09F6BUL, 0x1CA815CFUL, + 0xA20C3005UL, 0x8871DF63UL, 0xB9DE2FCBUL, 0x0CC6C9E9UL, + 0x0BEEFF53UL, 0xE3214517UL, 0xB4542835UL, 0x9F63293CUL, + 0xEE41E729UL, 0x6E1D2D7CUL, 0x50045286UL, 0x1E6685F3UL, + 0xF33401C6UL, 0x30A22C95UL, 0x31A70850UL, 0x60930F13UL, + 0x73F98417UL, 0xA1269859UL, 0xEC645C44UL, 0x52C877A9UL, + 0xCDFF33A6UL, 0xA02B1741UL, 0x7CBAD9A2UL, 0x2180036FUL, + 0x50D99C08UL, 0xCB3F4861UL, 0xC26BD765UL, 0x64A3F6ABUL, + 0x80342676UL, 0x25A75E7BUL, 0xE4E6D1FCUL, 0x20C710E6UL, + 0xCDF0B680UL, 0x17844D3BUL, 0x31EEF84DUL, 0x7E0824E4UL, + 0x2CCB49EBUL, 0x846A3BAEUL, 0x8FF77888UL, 0xEE5D60F6UL, + 0x7AF75673UL, 0x2FDD5CDBUL, 0xA11631C1UL, 0x30F66F43UL, + 0xB3FAEC54UL, 0x157FD7FAUL, 0xEF8579CCUL, 0xD152DE58UL, + 0xDB2FFD5EUL, 0x8F32CE19UL, 0x306AF97AUL, 0x02F03EF8UL, + 0x99319AD5UL, 0xC242FA0FUL, 0xA7E3EBB0UL, 0xC68E4906UL, + 0xB8DA230CUL, 0x80823028UL, 0xDCDEF3C8UL, 0xD35FB171UL, + 0x088A1BC8UL, 0xBEC0C560UL, 0x61A3C9E8UL, 0xBCA8F54DUL, + 0xC72FEFFAUL, 0x22822E99UL, 0x82C570B4UL, 0xD8D94E89UL, + 0x8B1C34BCUL, 0x301E16E6UL, 0x273BE979UL, 0xB0FFEAA6UL, + 0x61D9B8C6UL, 0x00B24869UL, 0xB7FFCE3FUL, 0x08DC283BUL, + 0x43DAF65AUL, 0xF7E19798UL, 0x7619B72FUL, 0x8F1C9BA4UL, + 0xDC8637A0UL, 0x16A7D3B1UL, 0x9FC393B7UL, 0xA7136EEBUL, + 0xC6BCC63EUL, 0x1A513742UL, 0xEF6828BCUL, 0x520365D6UL, + 0x2D6A77ABUL, 0x3527ED4BUL, 0x821FD216UL, 0x095C6E2EUL, + 0xDB92F2FBUL, 0x5EEA29CBUL, 0x145892F5UL, 0x91584F7FUL, + 0x5483697BUL, 0x2667A8CCUL, 0x85196048UL, 0x8C4BACEAUL, + 0x833860D4UL, 0x0D23E0F9UL, 0x6C387E8AUL, 0x0AE6D249UL, + 0xB284600CUL, 0xD835731DUL, 0xDCB1C647UL, 0xAC4C56EAUL, + 0x3EBD81B3UL, 0x230EABB0UL, 0x6438BC87UL, 0xF0B5B1FAUL, + 0x8F5EA2B3UL, 0xFC184642UL, 0x0A036B7AUL, 0x4FB089BDUL, + 0x649DA589UL, 0xA345415EUL, 0x5C038323UL, 0x3E5D3BB9UL, + 0x43D79572UL, 0x7E6DD07CUL, 0x06DFDF1EUL, 0x6C6CC4EFUL, + 0x7160A539UL, 0x73BFBE70UL, 0x83877605UL, 0x4523ECF1UL +}, + +{ + 0x8DEFC240UL, 0x25FA5D9FUL, 0xEB903DBFUL, 0xE810C907UL, + 0x47607FFFUL, 0x369FE44BUL, 0x8C1FC644UL, 0xAECECA90UL, + 0xBEB1F9BFUL, 0xEEFBCAEAUL, 0xE8CF1950UL, 0x51DF07AEUL, + 0x920E8806UL, 0xF0AD0548UL, 0xE13C8D83UL, 0x927010D5UL, + 0x11107D9FUL, 0x07647DB9UL, 0xB2E3E4D4UL, 0x3D4F285EUL, + 0xB9AFA820UL, 0xFADE82E0UL, 0xA067268BUL, 0x8272792EUL, + 0x553FB2C0UL, 0x489AE22BUL, 0xD4EF9794UL, 0x125E3FBCUL, + 0x21FFFCEEUL, 0x825B1BFDUL, 0x9255C5EDUL, 0x1257A240UL, + 0x4E1A8302UL, 0xBAE07FFFUL, 0x528246E7UL, 0x8E57140EUL, + 0x3373F7BFUL, 0x8C9F8188UL, 0xA6FC4EE8UL, 0xC982B5A5UL, + 0xA8C01DB7UL, 0x579FC264UL, 0x67094F31UL, 0xF2BD3F5FUL, + 0x40FFF7C1UL, 0x1FB78DFCUL, 0x8E6BD2C1UL, 0x437BE59BUL, + 0x99B03DBFUL, 0xB5DBC64BUL, 0x638DC0E6UL, 0x55819D99UL, + 0xA197C81CUL, 0x4A012D6EUL, 0xC5884A28UL, 0xCCC36F71UL, + 0xB843C213UL, 0x6C0743F1UL, 0x8309893CUL, 0x0FEDDD5FUL, + 0x2F7FE850UL, 0xD7C07F7EUL, 0x02507FBFUL, 0x5AFB9A04UL, + 0xA747D2D0UL, 0x1651192EUL, 0xAF70BF3EUL, 0x58C31380UL, + 0x5F98302EUL, 0x727CC3C4UL, 0x0A0FB402UL, 0x0F7FEF82UL, + 0x8C96FDADUL, 0x5D2C2AAEUL, 0x8EE99A49UL, 0x50DA88B8UL, + 0x8427F4A0UL, 0x1EAC5790UL, 0x796FB449UL, 0x8252DC15UL, + 0xEFBD7D9BUL, 0xA672597DUL, 0xADA840D8UL, 0x45F54504UL, + 0xFA5D7403UL, 0xE83EC305UL, 0x4F91751AUL, 0x925669C2UL, + 0x23EFE941UL, 0xA903F12EUL, 0x60270DF2UL, 0x0276E4B6UL, + 0x94FD6574UL, 0x927985B2UL, 0x8276DBCBUL, 0x02778176UL, + 0xF8AF918DUL, 0x4E48F79EUL, 0x8F616DDFUL, 0xE29D840EUL, + 0x842F7D83UL, 0x340CE5C8UL, 0x96BBB682UL, 0x93B4B148UL, + 0xEF303CABUL, 0x984FAF28UL, 0x779FAF9BUL, 0x92DC560DUL, + 0x224D1E20UL, 0x8437AA88UL, 0x7D29DC96UL, 0x2756D3DCUL, + 0x8B907CEEUL, 0xB51FD240UL, 0xE7C07CE3UL, 0xE566B4A1UL, + 0xC3E9615EUL, 0x3CF8209DUL, 0x6094D1E3UL, 0xCD9CA341UL, + 0x5C76460EUL, 0x00EA983BUL, 0xD4D67881UL, 0xFD47572CUL, + 0xF76CEDD9UL, 0xBDA8229CUL, 0x127DADAAUL, 0x438A074EUL, + 0x1F97C090UL, 0x081BDB8AUL, 0x93A07EBEUL, 0xB938CA15UL, + 0x97B03CFFUL, 0x3DC2C0F8UL, 0x8D1AB2ECUL, 0x64380E51UL, + 0x68CC7BFBUL, 0xD90F2788UL, 0x12490181UL, 0x5DE5FFD4UL, + 0xDD7EF86AUL, 0x76A2E214UL, 0xB9A40368UL, 0x925D958FUL, + 0x4B39FFFAUL, 0xBA39AEE9UL, 0xA4FFD30BUL, 0xFAF7933BUL, + 0x6D498623UL, 0x193CBCFAUL, 0x27627545UL, 0x825CF47AUL, + 0x61BD8BA0UL, 0xD11E42D1UL, 0xCEAD04F4UL, 0x127EA392UL, + 0x10428DB7UL, 0x8272A972UL, 0x9270C4A8UL, 0x127DE50BUL, + 0x285BA1C8UL, 0x3C62F44FUL, 0x35C0EAA5UL, 0xE805D231UL, + 0x428929FBUL, 0xB4FCDF82UL, 0x4FB66A53UL, 0x0E7DC15BUL, + 0x1F081FABUL, 0x108618AEUL, 0xFCFD086DUL, 0xF9FF2889UL, + 0x694BCC11UL, 0x236A5CAEUL, 0x12DECA4DUL, 0x2C3F8CC5UL, + 0xD2D02DFEUL, 0xF8EF5896UL, 0xE4CF52DAUL, 0x95155B67UL, + 0x494A488CUL, 0xB9B6A80CUL, 0x5C8F82BCUL, 0x89D36B45UL, + 0x3A609437UL, 0xEC00C9A9UL, 0x44715253UL, 0x0A874B49UL, + 0xD773BC40UL, 0x7C34671CUL, 0x02717EF6UL, 0x4FEB5536UL, + 0xA2D02FFFUL, 0xD2BF60C4UL, 0xD43F03C0UL, 0x50B4EF6DUL, + 0x07478CD1UL, 0x006E1888UL, 0xA2E53F55UL, 0xB9E6D4BCUL, + 0xA2048016UL, 0x97573833UL, 0xD7207D67UL, 0xDE0F8F3DUL, + 0x72F87B33UL, 0xABCC4F33UL, 0x7688C55DUL, 0x7B00A6B0UL, + 0x947B0001UL, 0x570075D2UL, 0xF9BB88F8UL, 0x8942019EUL, + 0x4264A5FFUL, 0x856302E0UL, 0x72DBD92BUL, 0xEE971B69UL, + 0x6EA22FDEUL, 0x5F08AE2BUL, 0xAF7A616DUL, 0xE5C98767UL, + 0xCF1FEBD2UL, 0x61EFC8C2UL, 0xF1AC2571UL, 0xCC8239C2UL, + 0x67214CB8UL, 0xB1E583D1UL, 0xB7DC3E62UL, 0x7F10BDCEUL, + 0xF90A5C38UL, 0x0FF0443DUL, 0x606E6DC6UL, 0x60543A49UL, + 0x5727C148UL, 0x2BE98A1DUL, 0x8AB41738UL, 0x20E1BE24UL, + 0xAF96DA0FUL, 0x68458425UL, 0x99833BE5UL, 0x600D457DUL, + 0x282F9350UL, 0x8334B362UL, 0xD91D1120UL, 0x2B6D8DA0UL, + 0x642B1E31UL, 0x9C305A00UL, 0x52BCE688UL, 0x1B03588AUL, + 0xF7BAEFD5UL, 0x4142ED9CUL, 0xA4315C11UL, 0x83323EC5UL, + 0xDFEF4636UL, 0xA133C501UL, 0xE9D3531CUL, 0xEE353783UL +}, + +{ + 0x9DB30420UL, 0x1FB6E9DEUL, 0xA7BE7BEFUL, 0xD273A298UL, + 0x4A4F7BDBUL, 0x64AD8C57UL, 0x85510443UL, 0xFA020ED1UL, + 0x7E287AFFUL, 0xE60FB663UL, 0x095F35A1UL, 0x79EBF120UL, + 0xFD059D43UL, 0x6497B7B1UL, 0xF3641F63UL, 0x241E4ADFUL, + 0x28147F5FUL, 0x4FA2B8CDUL, 0xC9430040UL, 0x0CC32220UL, + 0xFDD30B30UL, 0xC0A5374FUL, 0x1D2D00D9UL, 0x24147B15UL, + 0xEE4D111AUL, 0x0FCA5167UL, 0x71FF904CUL, 0x2D195FFEUL, + 0x1A05645FUL, 0x0C13FEFEUL, 0x081B08CAUL, 0x05170121UL, + 0x80530100UL, 0xE83E5EFEUL, 0xAC9AF4F8UL, 0x7FE72701UL, + 0xD2B8EE5FUL, 0x06DF4261UL, 0xBB9E9B8AUL, 0x7293EA25UL, + 0xCE84FFDFUL, 0xF5718801UL, 0x3DD64B04UL, 0xA26F263BUL, + 0x7ED48400UL, 0x547EEBE6UL, 0x446D4CA0UL, 0x6CF3D6F5UL, + 0x2649ABDFUL, 0xAEA0C7F5UL, 0x36338CC1UL, 0x503F7E93UL, + 0xD3772061UL, 0x11B638E1UL, 0x72500E03UL, 0xF80EB2BBUL, + 0xABE0502EUL, 0xEC8D77DEUL, 0x57971E81UL, 0xE14F6746UL, + 0xC9335400UL, 0x6920318FUL, 0x081DBB99UL, 0xFFC304A5UL, + 0x4D351805UL, 0x7F3D5CE3UL, 0xA6C866C6UL, 0x5D5BCCA9UL, + 0xDAEC6FEAUL, 0x9F926F91UL, 0x9F46222FUL, 0x3991467DUL, + 0xA5BF6D8EUL, 0x1143C44FUL, 0x43958302UL, 0xD0214EEBUL, + 0x022083B8UL, 0x3FB6180CUL, 0x18F8931EUL, 0x281658E6UL, + 0x26486E3EUL, 0x8BD78A70UL, 0x7477E4C1UL, 0xB506E07CUL, + 0xF32D0A25UL, 0x79098B02UL, 0xE4EABB81UL, 0x28123B23UL, + 0x69DEAD38UL, 0x1574CA16UL, 0xDF871B62UL, 0x211C40B7UL, + 0xA51A9EF9UL, 0x0014377BUL, 0x041E8AC8UL, 0x09114003UL, + 0xBD59E4D2UL, 0xE3D156D5UL, 0x4FE876D5UL, 0x2F91A340UL, + 0x557BE8DEUL, 0x00EAE4A7UL, 0x0CE5C2ECUL, 0x4DB4BBA6UL, + 0xE756BDFFUL, 0xDD3369ACUL, 0xEC17B035UL, 0x06572327UL, + 0x99AFC8B0UL, 0x56C8C391UL, 0x6B65811CUL, 0x5E146119UL, + 0x6E85CB75UL, 0xBE07C002UL, 0xC2325577UL, 0x893FF4ECUL, + 0x5BBFC92DUL, 0xD0EC3B25UL, 0xB7801AB7UL, 0x8D6D3B24UL, + 0x20C763EFUL, 0xC366A5FCUL, 0x9C382880UL, 0x0ACE3205UL, + 0xAAC9548AUL, 0xECA1D7C7UL, 0x041AFA32UL, 0x1D16625AUL, + 0x6701902CUL, 0x9B757A54UL, 0x31D477F7UL, 0x9126B031UL, + 0x36CC6FDBUL, 0xC70B8B46UL, 0xD9E66A48UL, 0x56E55A79UL, + 0x026A4CEBUL, 0x52437EFFUL, 0x2F8F76B4UL, 0x0DF980A5UL, + 0x8674CDE3UL, 0xEDDA04EBUL, 0x17A9BE04UL, 0x2C18F4DFUL, + 0xB7747F9DUL, 0xAB2AF7B4UL, 0xEFC34D20UL, 0x2E096B7CUL, + 0x1741A254UL, 0xE5B6A035UL, 0x213D42F6UL, 0x2C1C7C26UL, + 0x61C2F50FUL, 0x6552DAF9UL, 0xD2C231F8UL, 0x25130F69UL, + 0xD8167FA2UL, 0x0418F2C8UL, 0x001A96A6UL, 0x0D1526ABUL, + 0x63315C21UL, 0x5E0A72ECUL, 0x49BAFEFDUL, 0x187908D9UL, + 0x8D0DBD86UL, 0x311170A7UL, 0x3E9B640CUL, 0xCC3E10D7UL, + 0xD5CAD3B6UL, 0x0CAEC388UL, 0xF73001E1UL, 0x6C728AFFUL, + 0x71EAE2A1UL, 0x1F9AF36EUL, 0xCFCBD12FUL, 0xC1DE8417UL, + 0xAC07BE6BUL, 0xCB44A1D8UL, 0x8B9B0F56UL, 0x013988C3UL, + 0xB1C52FCAUL, 0xB4BE31CDUL, 0xD8782806UL, 0x12A3A4E2UL, + 0x6F7DE532UL, 0x58FD7EB6UL, 0xD01EE900UL, 0x24ADFFC2UL, + 0xF4990FC5UL, 0x9711AAC5UL, 0x001D7B95UL, 0x82E5E7D2UL, + 0x109873F6UL, 0x00613096UL, 0xC32D9521UL, 0xADA121FFUL, + 0x29908415UL, 0x7FBB977FUL, 0xAF9EB3DBUL, 0x29C9ED2AUL, + 0x5CE2A465UL, 0xA730F32CUL, 0xD0AA3FE8UL, 0x8A5CC091UL, + 0xD49E2CE7UL, 0x0CE454A9UL, 0xD60ACD86UL, 0x015F1919UL, + 0x77079103UL, 0xDEA03AF6UL, 0x78A8565EUL, 0xDEE356DFUL, + 0x21F05CBEUL, 0x8B75E387UL, 0xB3C50651UL, 0xB8A5C3EFUL, + 0xD8EEB6D2UL, 0xE523BE77UL, 0xC2154529UL, 0x2F69EFDFUL, + 0xAFE67AFBUL, 0xF470C4B2UL, 0xF3E0EB5BUL, 0xD6CC9876UL, + 0x39E4460CUL, 0x1FDA8538UL, 0x1987832FUL, 0xCA007367UL, + 0xA99144F8UL, 0x296B299EUL, 0x492FC295UL, 0x9266BEABUL, + 0xB5676E69UL, 0x9BD3DDDAUL, 0xDF7E052FUL, 0xDB25701CUL, + 0x1B5E51EEUL, 0xF65324E6UL, 0x6AFCE36CUL, 0x0316CC04UL, + 0x8644213EUL, 0xB7DC59D0UL, 0x7965291FUL, 0xCCD6FD43UL, + 0x41823979UL, 0x932BCDF6UL, 0xB657C34DUL, 0x4EDFD282UL, + 0x7AE5290CUL, 0x3CB9536BUL, 0x851E20FEUL, 0x9833557EUL, + 0x13ECF0B0UL, 0xD3FFB372UL, 0x3F85C5C1UL, 0x0AEF7ED2UL +}, + +{ + 0x7EC90C04UL, 0x2C6E74B9UL, 0x9B0E66DFUL, 0xA6337911UL, + 0xB86A7FFFUL, 0x1DD358F5UL, 0x44DD9D44UL, 0x1731167FUL, + 0x08FBF1FAUL, 0xE7F511CCUL, 0xD2051B00UL, 0x735ABA00UL, + 0x2AB722D8UL, 0x386381CBUL, 0xACF6243AUL, 0x69BEFD7AUL, + 0xE6A2E77FUL, 0xF0C720CDUL, 0xC4494816UL, 0xCCF5C180UL, + 0x38851640UL, 0x15B0A848UL, 0xE68B18CBUL, 0x4CAADEFFUL, + 0x5F480A01UL, 0x0412B2AAUL, 0x259814FCUL, 0x41D0EFE2UL, + 0x4E40B48DUL, 0x248EB6FBUL, 0x8DBA1CFEUL, 0x41A99B02UL, + 0x1A550A04UL, 0xBA8F65CBUL, 0x7251F4E7UL, 0x95A51725UL, + 0xC106ECD7UL, 0x97A5980AUL, 0xC539B9AAUL, 0x4D79FE6AUL, + 0xF2F3F763UL, 0x68AF8040UL, 0xED0C9E56UL, 0x11B4958BUL, + 0xE1EB5A88UL, 0x8709E6B0UL, 0xD7E07156UL, 0x4E29FEA7UL, + 0x6366E52DUL, 0x02D1C000UL, 0xC4AC8E05UL, 0x9377F571UL, + 0x0C05372AUL, 0x578535F2UL, 0x2261BE02UL, 0xD642A0C9UL, + 0xDF13A280UL, 0x74B55BD2UL, 0x682199C0UL, 0xD421E5ECUL, + 0x53FB3CE8UL, 0xC8ADEDB3UL, 0x28A87FC9UL, 0x3D959981UL, + 0x5C1FF900UL, 0xFE38D399UL, 0x0C4EFF0BUL, 0x062407EAUL, + 0xAA2F4FB1UL, 0x4FB96976UL, 0x90C79505UL, 0xB0A8A774UL, + 0xEF55A1FFUL, 0xE59CA2C2UL, 0xA6B62D27UL, 0xE66A4263UL, + 0xDF65001FUL, 0x0EC50966UL, 0xDFDD55BCUL, 0x29DE0655UL, + 0x911E739AUL, 0x17AF8975UL, 0x32C7911CUL, 0x89F89468UL, + 0x0D01E980UL, 0x524755F4UL, 0x03B63CC9UL, 0x0CC844B2UL, + 0xBCF3F0AAUL, 0x87AC36E9UL, 0xE53A7426UL, 0x01B3D82BUL, + 0x1A9E7449UL, 0x64EE2D7EUL, 0xCDDBB1DAUL, 0x01C94910UL, + 0xB868BF80UL, 0x0D26F3FDUL, 0x9342EDE7UL, 0x04A5C284UL, + 0x636737B6UL, 0x50F5B616UL, 0xF24766E3UL, 0x8ECA36C1UL, + 0x136E05DBUL, 0xFEF18391UL, 0xFB887A37UL, 0xD6E7F7D4UL, + 0xC7FB7DC9UL, 0x3063FCDFUL, 0xB6F589DEUL, 0xEC2941DAUL, + 0x26E46695UL, 0xB7566419UL, 0xF654EFC5UL, 0xD08D58B7UL, + 0x48925401UL, 0xC1BACB7FUL, 0xE5FF550FUL, 0xB6083049UL, + 0x5BB5D0E8UL, 0x87D72E5AUL, 0xAB6A6EE1UL, 0x223A66CEUL, + 0xC62BF3CDUL, 0x9E0885F9UL, 0x68CB3E47UL, 0x086C010FUL, + 0xA21DE820UL, 0xD18B69DEUL, 0xF3F65777UL, 0xFA02C3F6UL, + 0x407EDAC3UL, 0xCBB3D550UL, 0x1793084DUL, 0xB0D70EBAUL, + 0x0AB378D5UL, 0xD951FB0CUL, 0xDED7DA56UL, 0x4124BBE4UL, + 0x94CA0B56UL, 0x0F5755D1UL, 0xE0E1E56EUL, 0x6184B5BEUL, + 0x580A249FUL, 0x94F74BC0UL, 0xE327888EUL, 0x9F7B5561UL, + 0xC3DC0280UL, 0x05687715UL, 0x646C6BD7UL, 0x44904DB3UL, + 0x66B4F0A3UL, 0xC0F1648AUL, 0x697ED5AFUL, 0x49E92FF6UL, + 0x309E374FUL, 0x2CB6356AUL, 0x85808573UL, 0x4991F840UL, + 0x76F0AE02UL, 0x083BE84DUL, 0x28421C9AUL, 0x44489406UL, + 0x736E4CB8UL, 0xC1092910UL, 0x8BC95FC6UL, 0x7D869CF4UL, + 0x134F616FUL, 0x2E77118DUL, 0xB31B2BE1UL, 0xAA90B472UL, + 0x3CA5D717UL, 0x7D161BBAUL, 0x9CAD9010UL, 0xAF462BA2UL, + 0x9FE459D2UL, 0x45D34559UL, 0xD9F2DA13UL, 0xDBC65487UL, + 0xF3E4F94EUL, 0x176D486FUL, 0x097C13EAUL, 0x631DA5C7UL, + 0x445F7382UL, 0x175683F4UL, 0xCDC66A97UL, 0x70BE0288UL, + 0xB3CDCF72UL, 0x6E5DD2F3UL, 0x20936079UL, 0x459B80A5UL, + 0xBE60E2DBUL, 0xA9C23101UL, 0xEBA5315CUL, 0x224E42F2UL, + 0x1C5C1572UL, 0xF6721B2CUL, 0x1AD2FFF3UL, 0x8C25404EUL, + 0x324ED72FUL, 0x4067B7FDUL, 0x0523138EUL, 0x5CA3BC78UL, + 0xDC0FD66EUL, 0x75922283UL, 0x784D6B17UL, 0x58EBB16EUL, + 0x44094F85UL, 0x3F481D87UL, 0xFCFEAE7BUL, 0x77B5FF76UL, + 0x8C2302BFUL, 0xAAF47556UL, 0x5F46B02AUL, 0x2B092801UL, + 0x3D38F5F7UL, 0x0CA81F36UL, 0x52AF4A8AUL, 0x66D5E7C0UL, + 0xDF3B0874UL, 0x95055110UL, 0x1B5AD7A8UL, 0xF61ED5ADUL, + 0x6CF6E479UL, 0x20758184UL, 0xD0CEFA65UL, 0x88F7BE58UL, + 0x4A046826UL, 0x0FF6F8F3UL, 0xA09C7F70UL, 0x5346ABA0UL, + 0x5CE96C28UL, 0xE176EDA3UL, 0x6BAC307FUL, 0x376829D2UL, + 0x85360FA9UL, 0x17E3FE2AUL, 0x24B79767UL, 0xF5A96B20UL, + 0xD6CD2595UL, 0x68FF1EBFUL, 0x7555442CUL, 0xF19F06BEUL, + 0xF9E0659AUL, 0xEEB9491DUL, 0x34010718UL, 0xBB30CAB8UL, + 0xE822FE15UL, 0x88570983UL, 0x750E6249UL, 0xDA627E55UL, + 0x5E76FFA8UL, 0xB1534546UL, 0x6D47DE08UL, 0xEFE9E7D4UL +}, + +{ + 0xF6FA8F9DUL, 0x2CAC6CE1UL, 0x4CA34867UL, 0xE2337F7CUL, + 0x95DB08E7UL, 0x016843B4UL, 0xECED5CBCUL, 0x325553ACUL, + 0xBF9F0960UL, 0xDFA1E2EDUL, 0x83F0579DUL, 0x63ED86B9UL, + 0x1AB6A6B8UL, 0xDE5EBE39UL, 0xF38FF732UL, 0x8989B138UL, + 0x33F14961UL, 0xC01937BDUL, 0xF506C6DAUL, 0xE4625E7EUL, + 0xA308EA99UL, 0x4E23E33CUL, 0x79CBD7CCUL, 0x48A14367UL, + 0xA3149619UL, 0xFEC94BD5UL, 0xA114174AUL, 0xEAA01866UL, + 0xA084DB2DUL, 0x09A8486FUL, 0xA888614AUL, 0x2900AF98UL, + 0x01665991UL, 0xE1992863UL, 0xC8F30C60UL, 0x2E78EF3CUL, + 0xD0D51932UL, 0xCF0FEC14UL, 0xF7CA07D2UL, 0xD0A82072UL, + 0xFD41197EUL, 0x9305A6B0UL, 0xE86BE3DAUL, 0x74BED3CDUL, + 0x372DA53CUL, 0x4C7F4448UL, 0xDAB5D440UL, 0x6DBA0EC3UL, + 0x083919A7UL, 0x9FBAEED9UL, 0x49DBCFB0UL, 0x4E670C53UL, + 0x5C3D9C01UL, 0x64BDB941UL, 0x2C0E636AUL, 0xBA7DD9CDUL, + 0xEA6F7388UL, 0xE70BC762UL, 0x35F29ADBUL, 0x5C4CDD8DUL, + 0xF0D48D8CUL, 0xB88153E2UL, 0x08A19866UL, 0x1AE2EAC8UL, + 0x284CAF89UL, 0xAA928223UL, 0x9334BE53UL, 0x3B3A21BFUL, + 0x16434BE3UL, 0x9AEA3906UL, 0xEFE8C36EUL, 0xF890CDD9UL, + 0x80226DAEUL, 0xC340A4A3UL, 0xDF7E9C09UL, 0xA694A807UL, + 0x5B7C5ECCUL, 0x221DB3A6UL, 0x9A69A02FUL, 0x68818A54UL, + 0xCEB2296FUL, 0x53C0843AUL, 0xFE893655UL, 0x25BFE68AUL, + 0xB4628ABCUL, 0xCF222EBFUL, 0x25AC6F48UL, 0xA9A99387UL, + 0x53BDDB65UL, 0xE76FFBE7UL, 0xE967FD78UL, 0x0BA93563UL, + 0x8E342BC1UL, 0xE8A11BE9UL, 0x4980740DUL, 0xC8087DFCUL, + 0x8DE4BF99UL, 0xA11101A0UL, 0x7FD37975UL, 0xDA5A26C0UL, + 0xE81F994FUL, 0x9528CD89UL, 0xFD339FEDUL, 0xB87834BFUL, + 0x5F04456DUL, 0x22258698UL, 0xC9C4C83BUL, 0x2DC156BEUL, + 0x4F628DAAUL, 0x57F55EC5UL, 0xE2220ABEUL, 0xD2916EBFUL, + 0x4EC75B95UL, 0x24F2C3C0UL, 0x42D15D99UL, 0xCD0D7FA0UL, + 0x7B6E27FFUL, 0xA8DC8AF0UL, 0x7345C106UL, 0xF41E232FUL, + 0x35162386UL, 0xE6EA8926UL, 0x3333B094UL, 0x157EC6F2UL, + 0x372B74AFUL, 0x692573E4UL, 0xE9A9D848UL, 0xF3160289UL, + 0x3A62EF1DUL, 0xA787E238UL, 0xF3A5F676UL, 0x74364853UL, + 0x20951063UL, 0x4576698DUL, 0xB6FAD407UL, 0x592AF950UL, + 0x36F73523UL, 0x4CFB6E87UL, 0x7DA4CEC0UL, 0x6C152DAAUL, + 0xCB0396A8UL, 0xC50DFE5DUL, 0xFCD707ABUL, 0x0921C42FUL, + 0x89DFF0BBUL, 0x5FE2BE78UL, 0x448F4F33UL, 0x754613C9UL, + 0x2B05D08DUL, 0x48B9D585UL, 0xDC049441UL, 0xC8098F9BUL, + 0x7DEDE786UL, 0xC39A3373UL, 0x42410005UL, 0x6A091751UL, + 0x0EF3C8A6UL, 0x890072D6UL, 0x28207682UL, 0xA9A9F7BEUL, + 0xBF32679DUL, 0xD45B5B75UL, 0xB353FD00UL, 0xCBB0E358UL, + 0x830F220AUL, 0x1F8FB214UL, 0xD372CF08UL, 0xCC3C4A13UL, + 0x8CF63166UL, 0x061C87BEUL, 0x88C98F88UL, 0x6062E397UL, + 0x47CF8E7AUL, 0xB6C85283UL, 0x3CC2ACFBUL, 0x3FC06976UL, + 0x4E8F0252UL, 0x64D8314DUL, 0xDA3870E3UL, 0x1E665459UL, + 0xC10908F0UL, 0x513021A5UL, 0x6C5B68B7UL, 0x822F8AA0UL, + 0x3007CD3EUL, 0x74719EEFUL, 0xDC872681UL, 0x073340D4UL, + 0x7E432FD9UL, 0x0C5EC241UL, 0x8809286CUL, 0xF592D891UL, + 0x08A930F6UL, 0x957EF305UL, 0xB7FBFFBDUL, 0xC266E96FUL, + 0x6FE4AC98UL, 0xB173ECC0UL, 0xBC60B42AUL, 0x953498DAUL, + 0xFBA1AE12UL, 0x2D4BD736UL, 0x0F25FAABUL, 0xA4F3FCEBUL, + 0xE2969123UL, 0x257F0C3DUL, 0x9348AF49UL, 0x361400BCUL, + 0xE8816F4AUL, 0x3814F200UL, 0xA3F94043UL, 0x9C7A54C2UL, + 0xBC704F57UL, 0xDA41E7F9UL, 0xC25AD33AUL, 0x54F4A084UL, + 0xB17F5505UL, 0x59357CBEUL, 0xEDBD15C8UL, 0x7F97C5ABUL, + 0xBA5AC7B5UL, 0xB6F6DEAFUL, 0x3A479C3AUL, 0x5302DA25UL, + 0x653D7E6AUL, 0x54268D49UL, 0x51A477EAUL, 0x5017D55BUL, + 0xD7D25D88UL, 0x44136C76UL, 0x0404A8C8UL, 0xB8E5A121UL, + 0xB81A928AUL, 0x60ED5869UL, 0x97C55B96UL, 0xEAEC991BUL, + 0x29935913UL, 0x01FDB7F1UL, 0x088E8DFAUL, 0x9AB6F6F5UL, + 0x3B4CBF9FUL, 0x4A5DE3ABUL, 0xE6051D35UL, 0xA0E1D855UL, + 0xD36B4CF1UL, 0xF544EDEBUL, 0xB0E93524UL, 0xBEBB8FBDUL, + 0xA2D762CFUL, 0x49C92F54UL, 0x38B5F331UL, 0x7128A454UL, + 0x48392905UL, 0xA65B1DB8UL, 0x851C97BDUL, 0xD675CF2FUL +}, + +{ + 0x85E04019UL, 0x332BF567UL, 0x662DBFFFUL, 0xCFC65693UL, + 0x2A8D7F6FUL, 0xAB9BC912UL, 0xDE6008A1UL, 0x2028DA1FUL, + 0x0227BCE7UL, 0x4D642916UL, 0x18FAC300UL, 0x50F18B82UL, + 0x2CB2CB11UL, 0xB232E75CUL, 0x4B3695F2UL, 0xB28707DEUL, + 0xA05FBCF6UL, 0xCD4181E9UL, 0xE150210CUL, 0xE24EF1BDUL, + 0xB168C381UL, 0xFDE4E789UL, 0x5C79B0D8UL, 0x1E8BFD43UL, + 0x4D495001UL, 0x38BE4341UL, 0x913CEE1DUL, 0x92A79C3FUL, + 0x089766BEUL, 0xBAEEADF4UL, 0x1286BECFUL, 0xB6EACB19UL, + 0x2660C200UL, 0x7565BDE4UL, 0x64241F7AUL, 0x8248DCA9UL, + 0xC3B3AD66UL, 0x28136086UL, 0x0BD8DFA8UL, 0x356D1CF2UL, + 0x107789BEUL, 0xB3B2E9CEUL, 0x0502AA8FUL, 0x0BC0351EUL, + 0x166BF52AUL, 0xEB12FF82UL, 0xE3486911UL, 0xD34D7516UL, + 0x4E7B3AFFUL, 0x5F43671BUL, 0x9CF6E037UL, 0x4981AC83UL, + 0x334266CEUL, 0x8C9341B7UL, 0xD0D854C0UL, 0xCB3A6C88UL, + 0x47BC2829UL, 0x4725BA37UL, 0xA66AD22BUL, 0x7AD61F1EUL, + 0x0C5CBAFAUL, 0x4437F107UL, 0xB6E79962UL, 0x42D2D816UL, + 0x0A961288UL, 0xE1A5C06EUL, 0x13749E67UL, 0x72FC081AUL, + 0xB1D139F7UL, 0xF9583745UL, 0xCF19DF58UL, 0xBEC3F756UL, + 0xC06EBA30UL, 0x07211B24UL, 0x45C28829UL, 0xC95E317FUL, + 0xBC8EC511UL, 0x38BC46E9UL, 0xC6E6FA14UL, 0xBAE8584AUL, + 0xAD4EBC46UL, 0x468F508BUL, 0x7829435FUL, 0xF124183BUL, + 0x821DBA9FUL, 0xAFF60FF4UL, 0xEA2C4E6DUL, 0x16E39264UL, + 0x92544A8BUL, 0x009B4FC3UL, 0xABA68CEDUL, 0x9AC96F78UL, + 0x06A5B79AUL, 0xB2856E6EUL, 0x1AEC3CA9UL, 0xBE838688UL, + 0x0E0804E9UL, 0x55F1BE56UL, 0xE7E5363BUL, 0xB3A1F25DUL, + 0xF7DEBB85UL, 0x61FE033CUL, 0x16746233UL, 0x3C034C28UL, + 0xDA6D0C74UL, 0x79AAC56CUL, 0x3CE4E1ADUL, 0x51F0C802UL, + 0x98F8F35AUL, 0x1626A49FUL, 0xEED82B29UL, 0x1D382FE3UL, + 0x0C4FB99AUL, 0xBB325778UL, 0x3EC6D97BUL, 0x6E77A6A9UL, + 0xCB658B5CUL, 0xD45230C7UL, 0x2BD1408BUL, 0x60C03EB7UL, + 0xB9068D78UL, 0xA33754F4UL, 0xF430C87DUL, 0xC8A71302UL, + 0xB96D8C32UL, 0xEBD4E7BEUL, 0xBE8B9D2DUL, 0x7979FB06UL, + 0xE7225308UL, 0x8B75CF77UL, 0x11EF8DA4UL, 0xE083C858UL, + 0x8D6B786FUL, 0x5A6317A6UL, 0xFA5CF7A0UL, 0x5DDA0033UL, + 0xF28EBFB0UL, 0xF5B9C310UL, 0xA0EAC280UL, 0x08B9767AUL, + 0xA3D9D2B0UL, 0x79D34217UL, 0x021A718DUL, 0x9AC6336AUL, + 0x2711FD60UL, 0x438050E3UL, 0x069908A8UL, 0x3D7FEDC4UL, + 0x826D2BEFUL, 0x4EEB8476UL, 0x488DCF25UL, 0x36C9D566UL, + 0x28E74E41UL, 0xC2610ACAUL, 0x3D49A9CFUL, 0xBAE3B9DFUL, + 0xB65F8DE6UL, 0x92AEAF64UL, 0x3AC7D5E6UL, 0x9EA80509UL, + 0xF22B017DUL, 0xA4173F70UL, 0xDD1E16C3UL, 0x15E0D7F9UL, + 0x50B1B887UL, 0x2B9F4FD5UL, 0x625ABA82UL, 0x6A017962UL, + 0x2EC01B9CUL, 0x15488AA9UL, 0xD716E740UL, 0x40055A2CUL, + 0x93D29A22UL, 0xE32DBF9AUL, 0x058745B9UL, 0x3453DC1EUL, + 0xD699296EUL, 0x496CFF6FUL, 0x1C9F4986UL, 0xDFE2ED07UL, + 0xB87242D1UL, 0x19DE7EAEUL, 0x053E561AUL, 0x15AD6F8CUL, + 0x66626C1CUL, 0x7154C24CUL, 0xEA082B2AUL, 0x93EB2939UL, + 0x17DCB0F0UL, 0x58D4F2AEUL, 0x9EA294FBUL, 0x52CF564CUL, + 0x9883FE66UL, 0x2EC40581UL, 0x763953C3UL, 0x01D6692EUL, + 0xD3A0C108UL, 0xA1E7160EUL, 0xE4F2DFA6UL, 0x693ED285UL, + 0x74904698UL, 0x4C2B0EDDUL, 0x4F757656UL, 0x5D393378UL, + 0xA132234FUL, 0x3D321C5DUL, 0xC3F5E194UL, 0x4B269301UL, + 0xC79F022FUL, 0x3C997E7EUL, 0x5E4F9504UL, 0x3FFAFBBDUL, + 0x76F7AD0EUL, 0x296693F4UL, 0x3D1FCE6FUL, 0xC61E45BEUL, + 0xD3B5AB34UL, 0xF72BF9B7UL, 0x1B0434C0UL, 0x4E72B567UL, + 0x5592A33DUL, 0xB5229301UL, 0xCFD2A87FUL, 0x60AEB767UL, + 0x1814386BUL, 0x30BCC33DUL, 0x38A0C07DUL, 0xFD1606F2UL, + 0xC363519BUL, 0x589DD390UL, 0x5479F8E6UL, 0x1CB8D647UL, + 0x97FD61A9UL, 0xEA7759F4UL, 0x2D57539DUL, 0x569A58CFUL, + 0xE84E63ADUL, 0x462E1B78UL, 0x6580F87EUL, 0xF3817914UL, + 0x91DA55F4UL, 0x40A230F3UL, 0xD1988F35UL, 0xB6E318D2UL, + 0x3FFA50BCUL, 0x3D40F021UL, 0xC3C0BDAEUL, 0x4958C24CUL, + 0x518F36B2UL, 0x84B1D370UL, 0x0FEDCE83UL, 0x878DDADAUL, + 0xF2A279C7UL, 0x94E01BE8UL, 0x90716F4BUL, 0x954B8AA3UL +}, + +{ + 0xE216300DUL, 0xBBDDFFFCUL, 0xA7EBDABDUL, 0x35648095UL, + 0x7789F8B7UL, 0xE6C1121BUL, 0x0E241600UL, 0x052CE8B5UL, + 0x11A9CFB0UL, 0xE5952F11UL, 0xECE7990AUL, 0x9386D174UL, + 0x2A42931CUL, 0x76E38111UL, 0xB12DEF3AUL, 0x37DDDDFCUL, + 0xDE9ADEB1UL, 0x0A0CC32CUL, 0xBE197029UL, 0x84A00940UL, + 0xBB243A0FUL, 0xB4D137CFUL, 0xB44E79F0UL, 0x049EEDFDUL, + 0x0B15A15DUL, 0x480D3168UL, 0x8BBBDE5AUL, 0x669DED42UL, + 0xC7ECE831UL, 0x3F8F95E7UL, 0x72DF191BUL, 0x7580330DUL, + 0x94074251UL, 0x5C7DCDFAUL, 0xABBE6D63UL, 0xAA402164UL, + 0xB301D40AUL, 0x02E7D1CAUL, 0x53571DAEUL, 0x7A3182A2UL, + 0x12A8DDECUL, 0xFDAA335DUL, 0x176F43E8UL, 0x71FB46D4UL, + 0x38129022UL, 0xCE949AD4UL, 0xB84769ADUL, 0x965BD862UL, + 0x82F3D055UL, 0x66FB9767UL, 0x15B80B4EUL, 0x1D5B47A0UL, + 0x4CFDE06FUL, 0xC28EC4B8UL, 0x57E8726EUL, 0x647A78FCUL, + 0x99865D44UL, 0x608BD593UL, 0x6C200E03UL, 0x39DC5FF6UL, + 0x5D0B00A3UL, 0xAE63AFF2UL, 0x7E8BD632UL, 0x70108C0CUL, + 0xBBD35049UL, 0x2998DF04UL, 0x980CF42AUL, 0x9B6DF491UL, + 0x9E7EDD53UL, 0x06918548UL, 0x58CB7E07UL, 0x3B74EF2EUL, + 0x522FFFB1UL, 0xD24708CCUL, 0x1C7E27CDUL, 0xA4EB215BUL, + 0x3CF1D2E2UL, 0x19B47A38UL, 0x424F7618UL, 0x35856039UL, + 0x9D17DEE7UL, 0x27EB35E6UL, 0xC9AFF67BUL, 0x36BAF5B8UL, + 0x09C467CDUL, 0xC18910B1UL, 0xE11DBF7BUL, 0x06CD1AF8UL, + 0x7170C608UL, 0x2D5E3354UL, 0xD4DE495AUL, 0x64C6D006UL, + 0xBCC0C62CUL, 0x3DD00DB3UL, 0x708F8F34UL, 0x77D51B42UL, + 0x264F620FUL, 0x24B8D2BFUL, 0x15C1B79EUL, 0x46A52564UL, + 0xF8D7E54EUL, 0x3E378160UL, 0x7895CDA5UL, 0x859C15A5UL, + 0xE6459788UL, 0xC37BC75FUL, 0xDB07BA0CUL, 0x0676A3ABUL, + 0x7F229B1EUL, 0x31842E7BUL, 0x24259FD7UL, 0xF8BEF472UL, + 0x835FFCB8UL, 0x6DF4C1F2UL, 0x96F5B195UL, 0xFD0AF0FCUL, + 0xB0FE134CUL, 0xE2506D3DUL, 0x4F9B12EAUL, 0xF215F225UL, + 0xA223736FUL, 0x9FB4C428UL, 0x25D04979UL, 0x34C713F8UL, + 0xC4618187UL, 0xEA7A6E98UL, 0x7CD16EFCUL, 0x1436876CUL, + 0xF1544107UL, 0xBEDEEE14UL, 0x56E9AF27UL, 0xA04AA441UL, + 0x3CF7C899UL, 0x92ECBAE6UL, 0xDD67016DUL, 0x151682EBUL, + 0xA842EEDFUL, 0xFDBA60B4UL, 0xF1907B75UL, 0x20E3030FUL, + 0x24D8C29EUL, 0xE139673BUL, 0xEFA63FB8UL, 0x71873054UL, + 0xB6F2CF3BUL, 0x9F326442UL, 0xCB15A4CCUL, 0xB01A4504UL, + 0xF1E47D8DUL, 0x844A1BE5UL, 0xBAE7DFDCUL, 0x42CBDA70UL, + 0xCD7DAE0AUL, 0x57E85B7AUL, 0xD53F5AF6UL, 0x20CF4D8CUL, + 0xCEA4D428UL, 0x79D130A4UL, 0x3486EBFBUL, 0x33D3CDDCUL, + 0x77853B53UL, 0x37EFFCB5UL, 0xC5068778UL, 0xE580B3E6UL, + 0x4E68B8F4UL, 0xC5C8B37EUL, 0x0D809EA2UL, 0x398FEB7CUL, + 0x132A4F94UL, 0x43B7950EUL, 0x2FEE7D1CUL, 0x223613BDUL, + 0xDD06CAA2UL, 0x37DF932BUL, 0xC4248289UL, 0xACF3EBC3UL, + 0x5715F6B7UL, 0xEF3478DDUL, 0xF267616FUL, 0xC148CBE4UL, + 0x9052815EUL, 0x5E410FABUL, 0xB48A2465UL, 0x2EDA7FA4UL, + 0xE87B40E4UL, 0xE98EA084UL, 0x5889E9E1UL, 0xEFD390FCUL, + 0xDD07D35BUL, 0xDB485694UL, 0x38D7E5B2UL, 0x57720101UL, + 0x730EDEBCUL, 0x5B643113UL, 0x94917E4FUL, 0x503C2FBAUL, + 0x646F1282UL, 0x7523D24AUL, 0xE0779695UL, 0xF9C17A8FUL, + 0x7A5B2121UL, 0xD187B896UL, 0x29263A4DUL, 0xBA510CDFUL, + 0x81F47C9FUL, 0xAD1163EDUL, 0xEA7B5965UL, 0x1A00726EUL, + 0x11403092UL, 0x00DA6D77UL, 0x4A0CDD61UL, 0xAD1F4603UL, + 0x605BDFB0UL, 0x9EEDC364UL, 0x22EBE6A8UL, 0xCEE7D28AUL, + 0xA0E736A0UL, 0x5564A6B9UL, 0x10853209UL, 0xC7EB8F37UL, + 0x2DE705CAUL, 0x8951570FUL, 0xDF09822BUL, 0xBD691A6CUL, + 0xAA12E4F2UL, 0x87451C0FUL, 0xE0F6A27AUL, 0x3ADA4819UL, + 0x4CF1764FUL, 0x0D771C2BUL, 0x67CDB156UL, 0x350D8384UL, + 0x5938FA0FUL, 0x42399EF3UL, 0x36997B07UL, 0x0E84093DUL, + 0x4AA93E61UL, 0x8360D87BUL, 0x1FA98B0CUL, 0x1149382CUL, + 0xE97625A5UL, 0x0614D1B7UL, 0x0E25244BUL, 0x0C768347UL, + 0x589E8D82UL, 0x0D2059D1UL, 0xA466BB1EUL, 0xF8DA0A82UL, + 0x04F19130UL, 0xBA6E4EC0UL, 0x99265164UL, 0x1EE7230DUL, + 0x50B2AD80UL, 0xEAEE6801UL, 0x8DB2A283UL, 0xEA8BF59EUL +}}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/cbcmac.cpp b/external/ours/library/crypto/src/shared/original/cbcmac.cpp new file mode 100755 index 000000000..b0c46de22 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cbcmac.cpp @@ -0,0 +1,62 @@ +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cbcmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +void CBC_MAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + AccessCipher().SetKey(key, length, params); + m_reg.CleanNew(AccessCipher().BlockSize()); + m_counter = 0; +} + +void CBC_MAC_Base::Update(const byte *input, size_t length) +{ + unsigned int blockSize = AccessCipher().BlockSize(); + + while (m_counter && length) + { + m_reg[m_counter++] ^= *input++; + if (m_counter == blockSize) + ProcessBuf(); + length--; + } + + if (length >= blockSize) + { + size_t leftOver = AccessCipher().AdvancedProcessBlocks(m_reg, input, m_reg, length, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + input += (length - leftOver); + length = leftOver; + } + + while (length--) + { + m_reg[m_counter++] ^= *input++; + if (m_counter == blockSize) + ProcessBuf(); + } +} + +void CBC_MAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + if (m_counter) + ProcessBuf(); + + memcpy(mac, m_reg, size); + memset(m_reg, 0, AccessCipher().BlockSize()); +} + +void CBC_MAC_Base::ProcessBuf() +{ + AccessCipher().ProcessBlock(m_reg); + m_counter = 0; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/cbcmac.h b/external/ours/library/crypto/src/shared/original/cbcmac.h new file mode 100755 index 000000000..ca3ff689a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cbcmac.h @@ -0,0 +1,63 @@ +// cbcmac.h - originally written and placed in the public domain by Wei Dai + +/// \file +/// \brief Classes for CBC MAC +/// \since Crypto++ 3.1 + +#ifndef CRYPTOPP_CBCMAC_H +#define CRYPTOPP_CBCMAC_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief CBC-MAC base class +/// \since Crypto++ 3.1 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_MAC_Base : public MessageAuthenticationCode +{ +public: + CBC_MAC_Base() : m_counter(0) {} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int DigestSize() const {return const_cast(this)->AccessCipher().BlockSize();} + +protected: + virtual BlockCipher & AccessCipher() =0; + +private: + void ProcessBuf(); + SecByteBlock m_reg; + unsigned int m_counter; +}; + +/// \brief CBC-MAC +/// \tparam T BlockCipherDocumentation derived class +/// \details CBC-MAC is compatible with FIPS 113. The MAC is secure only for fixed +/// length messages. For variable length messages use CMAC or DMAC. +/// \sa CBC-MAC +/// \since Crypto++ 3.1 +template +class CBC_MAC : public MessageAuthenticationCodeImpl >, public SameKeyLengthAs +{ +public: + /// \brief Construct a CBC_MAC + CBC_MAC() {} + /// \brief Construct a CBC_MAC + /// \param key a byte buffer used to key the cipher + /// \param length the length of the byte buffer + CBC_MAC(const byte *key, size_t length=SameKeyLengthAs::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} + + static std::string StaticAlgorithmName() {return std::string("CBC-MAC(") + T::StaticAlgorithmName() + ")";} + +private: + BlockCipher & AccessCipher() {return m_cipher;} + typename T::Encryption m_cipher; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ccm.cpp b/external/ours/library/crypto/src/shared/original/ccm.cpp new file mode 100755 index 000000000..c0c2c3523 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ccm.cpp @@ -0,0 +1,139 @@ +// ccm.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "ccm.h" + +NAMESPACE_BEGIN(CryptoPP) + +void CCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) +{ + BlockCipher &blockCipher = AccessBlockCipher(); + blockCipher.SetKey(userKey, keylength, params); + + if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE) + throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16"); + + m_digestSize = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize()); + if (m_digestSize % 2 > 0 || m_digestSize < 4 || m_digestSize > 16) + throw InvalidArgument(AlgorithmName() + ": DigestSize must be 4, 6, 8, 10, 12, 14, or 16"); + + m_buffer.Grow(2*REQUIRED_BLOCKSIZE); + m_L = 8; +} + +void CCM_Base::Resync(const byte *iv, size_t len) +{ + BlockCipher &cipher = AccessBlockCipher(); + + m_L = REQUIRED_BLOCKSIZE-1-(int)len; + CRYPTOPP_ASSERT(m_L >= 2); + if (m_L > 8) + m_L = 8; + + m_buffer[0] = byte(m_L-1); // flag + memcpy(m_buffer+1, iv, len); + memset(m_buffer+1+len, 0, REQUIRED_BLOCKSIZE-1-len); + + if (m_state >= State_IVSet) + m_ctr.Resynchronize(m_buffer, REQUIRED_BLOCKSIZE); + else + m_ctr.SetCipherWithIV(cipher, m_buffer); + + m_ctr.Seek(REQUIRED_BLOCKSIZE); + m_aadLength = 0; + m_messageLength = 0; +} + +void CCM_Base::UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword /*footerLength*/) +{ + if (m_state != State_IVSet) + throw BadState(AlgorithmName(), "SpecifyDataLengths", "or after State_IVSet"); + + m_aadLength = headerLength; + m_messageLength = messageLength; + + byte *cbcBuffer = CBC_Buffer(); + const BlockCipher &cipher = GetBlockCipher(); + + cbcBuffer[0] = byte(64*(headerLength>0) + 8*((m_digestSize-2)/2) + (m_L-1)); // flag + PutWord(true, BIG_ENDIAN_ORDER, cbcBuffer+REQUIRED_BLOCKSIZE-8, m_messageLength); + memcpy(cbcBuffer+1, m_buffer+1, REQUIRED_BLOCKSIZE-1-m_L); + cipher.ProcessBlock(cbcBuffer); + + if (headerLength>0) + { + CRYPTOPP_ASSERT(m_bufferedDataLength == 0); + + if (headerLength < ((1<<16) - (1<<8))) + { + PutWord(true, BIG_ENDIAN_ORDER, m_buffer, (word16)headerLength); + m_bufferedDataLength = 2; + } + else if (headerLength < (W64LIT(1)<<32)) + { + m_buffer[0] = 0xff; + m_buffer[1] = 0xfe; + PutWord(false, BIG_ENDIAN_ORDER, m_buffer+2, (word32)headerLength); + m_bufferedDataLength = 6; + } + else + { + m_buffer[0] = 0xff; + m_buffer[1] = 0xff; + PutWord(false, BIG_ENDIAN_ORDER, m_buffer+2, headerLength); + m_bufferedDataLength = 10; + } + } +} + +size_t CCM_Base::AuthenticateBlocks(const byte *data, size_t len) +{ + byte *cbcBuffer = CBC_Buffer(); + const BlockCipher &cipher = GetBlockCipher(); + return cipher.AdvancedProcessBlocks(cbcBuffer, data, cbcBuffer, len, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); +} + +void CCM_Base::AuthenticateLastHeaderBlock() +{ + byte *cbcBuffer = CBC_Buffer(); + const BlockCipher &cipher = GetBlockCipher(); + + if (m_aadLength != m_totalHeaderLength) + throw InvalidArgument(AlgorithmName() + ": header length doesn't match that given in SpecifyDataLengths"); + + if (m_bufferedDataLength > 0) + { + xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength); + cipher.ProcessBlock(cbcBuffer); + m_bufferedDataLength = 0; + } +} + +void CCM_Base::AuthenticateLastConfidentialBlock() +{ + byte *cbcBuffer = CBC_Buffer(); + const BlockCipher &cipher = GetBlockCipher(); + + if (m_messageLength != m_totalMessageLength) + throw InvalidArgument(AlgorithmName() + ": message length doesn't match that given in SpecifyDataLengths"); + + if (m_bufferedDataLength > 0) + { + xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength); + cipher.ProcessBlock(cbcBuffer); + m_bufferedDataLength = 0; + } +} + +void CCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize) +{ + m_ctr.Seek(0); + m_ctr.ProcessData(mac, CBC_Buffer(), macSize); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ccm.h b/external/ours/library/crypto/src/shared/original/ccm.h new file mode 100755 index 000000000..5207a2fdf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ccm.h @@ -0,0 +1,123 @@ +// ccm.h - originally written and placed in the public domain by Wei Dai + +/// \file ccm.h +/// \brief CCM block cipher mode of operation +/// \since Crypto++ 5.6.0 + +#ifndef CRYPTOPP_CCM_H +#define CRYPTOPP_CCM_H + +#include "authenc.h" +#include "modes.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief CCM block cipher base implementation +/// \details Base implementation of the AuthenticatedSymmetricCipher interface +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCipherBase +{ +public: + CCM_Base() + : m_digestSize(0), m_L(0), m_messageLength(0), m_aadLength(0) {} + + // AuthenticatedSymmetricCipher + std::string AlgorithmName() const + {return GetBlockCipher().AlgorithmName() + std::string("/CCM");} + std::string AlgorithmProvider() const + {return GetBlockCipher().AlgorithmProvider();} + size_t MinKeyLength() const + {return GetBlockCipher().MinKeyLength();} + size_t MaxKeyLength() const + {return GetBlockCipher().MaxKeyLength();} + size_t DefaultKeyLength() const + {return GetBlockCipher().DefaultKeyLength();} + size_t GetValidKeyLength(size_t keylength) const + {return GetBlockCipher().GetValidKeyLength(keylength);} + bool IsValidKeyLength(size_t keylength) const + {return GetBlockCipher().IsValidKeyLength(keylength);} + unsigned int OptimalDataAlignment() const + {return GetBlockCipher().OptimalDataAlignment();} + IV_Requirement IVRequirement() const + {return UNIQUE_IV;} + unsigned int IVSize() const + {return 8;} + unsigned int MinIVLength() const + {return 7;} + unsigned int MaxIVLength() const + {return 13;} + unsigned int DigestSize() const + {return m_digestSize;} + lword MaxHeaderLength() const + {return W64LIT(0)-1;} + lword MaxMessageLength() const + {return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;} + bool NeedsPrespecifiedDataLengths() const + {return true;} + void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength); + +protected: + // AuthenticatedSymmetricCipherBase + bool AuthenticationIsOnPlaintext() const + {return true;} + unsigned int AuthenticationBlockSize() const + {return GetBlockCipher().BlockSize();} + void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); + void Resync(const byte *iv, size_t len); + size_t AuthenticateBlocks(const byte *data, size_t len); + void AuthenticateLastHeaderBlock(); + void AuthenticateLastConfidentialBlock(); + void AuthenticateLastFooterBlock(byte *mac, size_t macSize); + SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} + + virtual BlockCipher & AccessBlockCipher() =0; + virtual int DefaultDigestSize() const =0; + + const BlockCipher & GetBlockCipher() const {return const_cast(this)->AccessBlockCipher();} + byte *CBC_Buffer() {return m_buffer+REQUIRED_BLOCKSIZE;} + + enum {REQUIRED_BLOCKSIZE = 16}; + int m_digestSize, m_L; + word64 m_messageLength, m_aadLength; + CTR_Mode_ExternalCipher::Encryption m_ctr; +}; + +/// \brief CCM block cipher final implementation +/// \tparam T_BlockCipher block cipher +/// \tparam T_DefaultDigestSize default digest size, in bytes +/// \tparam T_IsEncryption direction in which to operate the cipher +/// \since Crypto++ 5.6.0 +template +class CCM_Final : public CCM_Base +{ +public: + static std::string StaticAlgorithmName() + {return T_BlockCipher::StaticAlgorithmName() + std::string("/CCM");} + bool IsForwardTransformation() const + {return T_IsEncryption;} + +private: + BlockCipher & AccessBlockCipher() {return m_cipher;} + int DefaultDigestSize() const {return T_DefaultDigestSize;} + typename T_BlockCipher::Encryption m_cipher; +}; + +/// \brief CCM block cipher mode of operation +/// \tparam T_BlockCipher block cipher +/// \tparam T_DefaultDigestSize default digest size, in bytes +/// \details \p CCM provides the \p Encryption and \p Decryption typedef. See GCM_Base +/// and GCM_Final for the AuthenticatedSymmetricCipher implementation. +/// \sa CCM Mode and +/// Modes of Operation +/// on the Crypto++ wiki. +/// \since Crypto++ 5.6.0 +template +struct CCM : public AuthenticatedSymmetricCipherDocumentation +{ + typedef CCM_Final Encryption; + typedef CCM_Final Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/chacha.cpp b/external/ours/library/crypto/src/shared/original/chacha.cpp new file mode 100755 index 000000000..5c50d52c1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/chacha.cpp @@ -0,0 +1,568 @@ +// chacha.cpp - written and placed in the public domain by Jeffrey Walton. +// Based on Wei Dai's Salsa20, Botan's SSE2 implementation, +// and Bernstein's reference ChaCha family implementation at +// http://cr.yp.to/chacha.html. + +#include "pch.h" +#include "config.h" +#include "chacha.h" +#include "argnames.h" +#include "misc.h" +#include "cpu.h" + +// Internal compiler error in GCC 3.3 and below +#if defined(__GNUC__) && (__GNUC__ < 4) +# undef CRYPTOPP_SSE2_INTRIN_AVAILABLE +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) +extern void ChaCha_OperateKeystream_NEON(const word32 *state, const byte* input, byte *output, unsigned int rounds); +#endif + +#if (CRYPTOPP_AVX2_AVAILABLE) +extern void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *output, unsigned int rounds); +#endif +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) +extern void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds); +#endif + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +extern void ChaCha_OperateKeystream_ALTIVEC(const word32 *state, const byte* input, byte *output, unsigned int rounds); +#endif + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void ChaCha_TestInstantiations() +{ + ChaCha::Encryption x; + ChaChaTLS::Encryption y; + XChaCha20::Encryption z; +} +#endif + +NAMESPACE_END // CryptoPP + +////////////////////////////// ChaCha Core ////////////////////////////// + +#define CHACHA_QUARTER_ROUND(a,b,c,d) \ + a += b; d ^= a; d = rotlConstant<16,word32>(d); \ + c += d; b ^= c; b = rotlConstant<12,word32>(b); \ + a += b; d ^= a; d = rotlConstant<8,word32>(d); \ + c += d; b ^= c; b = rotlConstant<7,word32>(b); + +#define CHACHA_OUTPUT(x){\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + state[0]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x1 + state[1]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x2 + state[2]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x3 + state[3]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + state[4]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x5 + state[5]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x6 + state[6]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x7 + state[7]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + state[8]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x9 + state[9]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x10 + state[10]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x11 + state[11]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + state[12]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x13 + state[13]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x14 + state[14]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x15 + state[15]);} + +ANONYMOUS_NAMESPACE_BEGIN + +// Hacks... Bring in all symbols, and supply +// the stuff the templates normally provide. +using namespace CryptoPP; +typedef word32 WordType; +enum {BYTES_PER_ITERATION=64}; + +// MultiBlockSafe detects a condition that can arise in the SIMD +// implementations where we overflow one of the 32-bit state words during +// addition in an intermediate result. Preconditions for the issue include +// a user seeks to around 2^32 blocks (256 GB of data) for ChaCha; or a +// user specifies an arbitrarily large initial counter block for ChaChaTLS. +// Also see https://github.com/weidai11/cryptopp/issues/732. +inline bool MultiBlockSafe(unsigned int ctrLow, unsigned int blocks) +{ + return 0xffffffff - ctrLow > blocks; +} + +// OperateKeystream always produces a key stream. The key stream is written +// to output. Optionally a message may be supplied to xor with the key stream. +// The message is input, and output = output ^ input. +void ChaCha_OperateKeystream(KeystreamOperation operation, + word32 state[16], word32& ctrLow, word32& ctrHigh, word32 rounds, + byte *output, const byte *input, size_t iterationCount) +{ + do + { +#if (CRYPTOPP_AVX2_AVAILABLE) + if (HasAVX2()) + { + while (iterationCount >= 8 && MultiBlockSafe(state[12], 8)) + { + const bool xorInput = (operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL); + ChaCha_OperateKeystream_AVX2(state, xorInput ? input : NULLPTR, output, rounds); + + // MultiBlockSafe avoids overflow on the counter words + state[12] += 8; + + input += (!!xorInput) * 8 * BYTES_PER_ITERATION; + output += 8 * BYTES_PER_ITERATION; + iterationCount -= 8; + } + } +#endif + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) + if (HasSSE2()) + { + while (iterationCount >= 4 && MultiBlockSafe(state[12], 4)) + { + const bool xorInput = (operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL); + ChaCha_OperateKeystream_SSE2(state, xorInput ? input : NULLPTR, output, rounds); + + // MultiBlockSafe avoids overflow on the counter words + state[12] += 4; + + input += (!!xorInput)*4*BYTES_PER_ITERATION; + output += 4*BYTES_PER_ITERATION; + iterationCount -= 4; + } + } +#endif + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + { + while (iterationCount >= 4 && MultiBlockSafe(state[12], 4)) + { + const bool xorInput = (operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL); + ChaCha_OperateKeystream_NEON(state, xorInput ? input : NULLPTR, output, rounds); + + // MultiBlockSafe avoids overflow on the counter words + state[12] += 4; + + input += (!!xorInput)*4*BYTES_PER_ITERATION; + output += 4*BYTES_PER_ITERATION; + iterationCount -= 4; + } + } +#endif + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + { + while (iterationCount >= 4 && MultiBlockSafe(state[12], 4)) + { + const bool xorInput = (operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL); + ChaCha_OperateKeystream_ALTIVEC(state, xorInput ? input : NULLPTR, output, rounds); + + // MultiBlockSafe avoids overflow on the counter words + state[12] += 4; + + input += (!!xorInput)*4*BYTES_PER_ITERATION; + output += 4*BYTES_PER_ITERATION; + iterationCount -= 4; + } + } +#endif + + if (iterationCount) + { + word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + x0 = state[0]; x1 = state[1]; x2 = state[2]; x3 = state[3]; + x4 = state[4]; x5 = state[5]; x6 = state[6]; x7 = state[7]; + x8 = state[8]; x9 = state[9]; x10 = state[10]; x11 = state[11]; + x12 = state[12]; x13 = state[13]; x14 = state[14]; x15 = state[15]; + + for (int i = static_cast(rounds); i > 0; i -= 2) + { + CHACHA_QUARTER_ROUND(x0, x4, x8, x12); + CHACHA_QUARTER_ROUND(x1, x5, x9, x13); + CHACHA_QUARTER_ROUND(x2, x6, x10, x14); + CHACHA_QUARTER_ROUND(x3, x7, x11, x15); + + CHACHA_QUARTER_ROUND(x0, x5, x10, x15); + CHACHA_QUARTER_ROUND(x1, x6, x11, x12); + CHACHA_QUARTER_ROUND(x2, x7, x8, x13); + CHACHA_QUARTER_ROUND(x3, x4, x9, x14); + } + + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(CHACHA_OUTPUT, BYTES_PER_ITERATION); + + // This is state[12] and state[13] from ChaCha. In the case of + // ChaChaTLS ctrHigh is a reference to a discard value. + if (++ctrLow == 0) + ctrHigh++; + } + + // We may re-enter a SIMD keystream operation from here. + } while (iterationCount--); +} + +// XChaCha key derivation +void HChaCha_OperateKeystream(const word32 state[16], word32 output[8]) +{ + word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + x0 = state[0]; x1 = state[1]; x2 = state[2]; x3 = state[3]; + x4 = state[4]; x5 = state[5]; x6 = state[6]; x7 = state[7]; + x8 = state[8]; x9 = state[9]; x10 = state[10]; x11 = state[11]; + x12 = state[12]; x13 = state[13]; x14 = state[14]; x15 = state[15]; + + for (int i = 20; i > 0; i -= 2) + { + CHACHA_QUARTER_ROUND(x0, x4, x8, x12); + CHACHA_QUARTER_ROUND(x1, x5, x9, x13); + CHACHA_QUARTER_ROUND(x2, x6, x10, x14); + CHACHA_QUARTER_ROUND(x3, x7, x11, x15); + + CHACHA_QUARTER_ROUND(x0, x5, x10, x15); + CHACHA_QUARTER_ROUND(x1, x6, x11, x12); + CHACHA_QUARTER_ROUND(x2, x7, x8, x13); + CHACHA_QUARTER_ROUND(x3, x4, x9, x14); + } + + output[0] = x0; output[1] = x1; + output[2] = x2; output[3] = x3; + output[4] = x12; output[5] = x13; + output[6] = x14; output[7] = x15; +} + +std::string ChaCha_AlgorithmProvider() +{ +#if (CRYPTOPP_AVX2_AVAILABLE) + if (HasAVX2()) + return "AVX2"; + else +#endif +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) + if (HasSSE2()) + return "SSE2"; + else +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; + else +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return "Altivec"; + else +#endif + return "C++"; +} + +unsigned int ChaCha_GetAlignment() +{ +#if (CRYPTOPP_AVX2_AVAILABLE) + if (HasAVX2()) + return 16; + else +#endif +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) + if (HasSSE2()) + return 16; + else +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return 16; + else +#endif + return GetAlignmentOf(); +} + +unsigned int ChaCha_GetOptimalBlockSize() +{ +#if (CRYPTOPP_AVX2_AVAILABLE) + if (HasAVX2()) + return 8 * BYTES_PER_ITERATION; + else +#endif +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) + if (HasSSE2()) + return 4*BYTES_PER_ITERATION; + else +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return 4*BYTES_PER_ITERATION; + else +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return 4*BYTES_PER_ITERATION; + else +#endif + return BYTES_PER_ITERATION; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +////////////////////////////// Bernstein ChaCha ////////////////////////////// + +std::string ChaCha_Policy::AlgorithmName() const +{ + return std::string("ChaCha")+IntToString(m_rounds); +} + +std::string ChaCha_Policy::AlgorithmProvider() const +{ + return ChaCha_AlgorithmProvider(); +} + +void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 16 || length == 32); + CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length); + + // Use previous rounds as the default value + int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds); + if (rounds != 20 && rounds != 12 && rounds != 8) + throw InvalidRounds(ChaCha::StaticAlgorithmName(), rounds); + + // Latch a good value + m_rounds = rounds; + + // "expand 16-byte k" or "expand 32-byte k" + m_state[0] = 0x61707865; + m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e; + m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32; + m_state[3] = 0x6b206574; + + GetBlock get1(key); + get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]); + + GetBlock get2(key + ((length == 32) ? 16 : 0)); + get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]); +} + +void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==8); CRYPTOPP_UNUSED(length); + + GetBlock get(IV); + m_state[12] = m_state[13] = 0; + get(m_state[14])(m_state[15]); +} + +void ChaCha_Policy::SeekToIteration(lword iterationCount) +{ + m_state[12] = (word32)iterationCount; // low word + m_state[13] = (word32)SafeRightShift<32>(iterationCount); +} + +unsigned int ChaCha_Policy::GetAlignment() const +{ + return ChaCha_GetAlignment(); +} + +unsigned int ChaCha_Policy::GetOptimalBlockSize() const +{ + return ChaCha_GetOptimalBlockSize(); +} + +void ChaCha_Policy::OperateKeystream(KeystreamOperation operation, + byte *output, const byte *input, size_t iterationCount) +{ + ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13], + m_rounds, output, input, iterationCount); +} + +////////////////////////////// IETF ChaChaTLS ////////////////////////////// + +std::string ChaChaTLS_Policy::AlgorithmName() const +{ + return std::string("ChaChaTLS"); +} + +std::string ChaChaTLS_Policy::AlgorithmProvider() const +{ + return ChaCha_AlgorithmProvider(); +} + +void ChaChaTLS_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 32); + CRYPTOPP_UNUSED(length); + + // ChaChaTLS is always 20 rounds. Fetch Rounds() to avoid a spurious failure. + int rounds = params.GetIntValueWithDefault(Name::Rounds(), ROUNDS); + if (rounds != 20) + throw InvalidRounds(ChaChaTLS::StaticAlgorithmName(), rounds); + + // RFC 8439 test vectors use an initial block counter. However, the counter + // can be an arbitrary value per RFC 8439 Section 2.4. We stash the counter + // away in state[16] and use it for a Resynchronize() operation. I think + // the initial counter is used more like a Tweak when non-0, and it should + // be provided in Resynchronize() (light-weight re-keying). However, + // Resynchronize() does not have an overload that allows us to pass it into + // the function, so we have to use the heavier-weight SetKey to change it. + word64 block; + if (params.GetValue("InitialBlock", block)) + m_counter = static_cast(block); + else + m_counter = 0; + + // State words are defined in RFC 8439, Section 2.3. Key is 32-bytes. + GetBlock get(key); + get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3]) + (m_state[KEY+4])(m_state[KEY+5])(m_state[KEY+6])(m_state[KEY+7]); +} + +void ChaChaTLS_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==12); + + // State words are defined in RFC 8439, Section 2.3. + m_state[0] = 0x61707865; m_state[1] = 0x3320646e; + m_state[2] = 0x79622d32; m_state[3] = 0x6b206574; + + // Copy saved key into state + std::memcpy(m_state+4, m_state+KEY, 8*sizeof(word32)); + + // State words are defined in RFC 8439, Section 2.3 + GetBlock get(IV); + m_state[12] = m_counter; + get(m_state[13])(m_state[14])(m_state[15]); +} + +void ChaChaTLS_Policy::SeekToIteration(lword iterationCount) +{ + // Should we throw here??? If the initial block counter is + // large then we can wrap and process more data as long as + // data processed in the security context does not exceed + // 2^32 blocks or approximately 256 GB of data. + CRYPTOPP_ASSERT(iterationCount <= std::numeric_limits::max()); + m_state[12] = (word32)iterationCount; // low word +} + +unsigned int ChaChaTLS_Policy::GetAlignment() const +{ + return ChaCha_GetAlignment(); +} + +unsigned int ChaChaTLS_Policy::GetOptimalBlockSize() const +{ + return ChaCha_GetOptimalBlockSize(); +} + +void ChaChaTLS_Policy::OperateKeystream(KeystreamOperation operation, + byte *output, const byte *input, size_t iterationCount) +{ + word32 discard=0; + ChaCha_OperateKeystream(operation, m_state, m_state[12], discard, + ROUNDS, output, input, iterationCount); + + // If this fires it means ChaCha_OperateKeystream generated a counter + // block carry that was discarded. The problem is, the RFC does not + // specify what should happen when the counter block wraps. All we can + // do is inform the user that something bad may happen because we don't + // know what we should do. + // Also see https://github.com/weidai11/cryptopp/issues/790 and + // https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU + // CRYPTOPP_ASSERT(discard==0); +} + +////////////////////////////// IETF XChaCha20 ////////////////////////////// + +std::string XChaCha20_Policy::AlgorithmName() const +{ + return std::string("XChaCha20"); +} + +std::string XChaCha20_Policy::AlgorithmProvider() const +{ + return ChaCha_AlgorithmProvider(); +} + +void XChaCha20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 32); + CRYPTOPP_UNUSED(length); + + // Use previous rounds as the default value + int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds); + if (rounds != 20 && rounds != 12) + throw InvalidRounds(ChaCha::StaticAlgorithmName(), rounds); + + // Latch a good value + m_rounds = rounds; + + word64 block; + if (params.GetValue("InitialBlock", block)) + m_counter = static_cast(block); + else + m_counter = 1; + + // Stash key away for use in CipherResynchronize + GetBlock get(key); + get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3]) + (m_state[KEY+4])(m_state[KEY+5])(m_state[KEY+6])(m_state[KEY+7]); +} + +void XChaCha20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==24); + + // HChaCha derivation + m_state[0] = 0x61707865; m_state[1] = 0x3320646e; + m_state[2] = 0x79622d32; m_state[3] = 0x6b206574; + + // Copy saved key into state + std::memcpy(m_state+4, m_state+KEY, 8*sizeof(word32)); + + GetBlock get(iv); + get(m_state[12])(m_state[13])(m_state[14])(m_state[15]); + + // Operate the keystream without adding state back in. + // This function also gathers the key words into a + // contiguous 8-word block. + HChaCha_OperateKeystream(m_state, m_state+4); + + // XChaCha state + m_state[0] = 0x61707865; m_state[1] = 0x3320646e; + m_state[2] = 0x79622d32; m_state[3] = 0x6b206574; + + // Setup new IV + m_state[12] = m_counter; + m_state[13] = 0; + m_state[14] = GetWord(false, LITTLE_ENDIAN_ORDER, iv+16); + m_state[15] = GetWord(false, LITTLE_ENDIAN_ORDER, iv+20); +} + +void XChaCha20_Policy::SeekToIteration(lword iterationCount) +{ + // Should we throw here??? XChaCha does not have a block + // counter, so I'm not sure how to seek on it. + CRYPTOPP_ASSERT(0); CRYPTOPP_UNUSED(iterationCount); +} + +unsigned int XChaCha20_Policy::GetAlignment() const +{ + return ChaCha_GetAlignment(); +} + +unsigned int XChaCha20_Policy::GetOptimalBlockSize() const +{ + return ChaCha_GetOptimalBlockSize(); +} + +void XChaCha20_Policy::OperateKeystream(KeystreamOperation operation, + byte *output, const byte *input, size_t iterationCount) +{ + ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13], + m_rounds, output, input, iterationCount); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/chacha.h b/external/ours/library/crypto/src/shared/original/chacha.h new file mode 100755 index 000000000..8c6dfde5f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/chacha.h @@ -0,0 +1,223 @@ +// chacha.h - written and placed in the public domain by Jeffrey Walton. +// Based on Wei Dai's Salsa20, Botan's SSE2 implementation, +// and Bernstein's reference ChaCha family implementation at +// http://cr.yp.to/chacha.html. + +// The library added Bernstein's ChaCha classses at Crypto++ 5.6.4. The IETF +// uses a slightly different implementation than Bernstein, and the IETF +// ChaCha and XChaCha classes were added at Crypto++ 8.1. We wanted to maintain +// ABI compatibility at the 8.1 release so the original ChaCha classes were not +// disturbed. Instead new classes were added for IETF ChaCha. The back-end +// implementation shares code as expected, however. + +/// \file chacha.h +/// \brief Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers +/// \details Crypto++ provides Bernstein and ECRYPT's ChaCha from ChaCha, a +/// variant of Salsa20 (2008.01.28). Crypto++ also provides the +/// IETF implementation of ChaCha using the ChaChaTLS name. Bernstein's +/// implementation is _slightly_ different from the TLS working group's +/// implementation for cipher suites +/// TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, +/// TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, +/// and TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256. Finally, +/// the library provides XChaCha: +/// eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03). +/// \since ChaCha since Crypto++ 5.6.4, ChaChaTLS and XChaCha20 since Crypto++ 8.1 + +#ifndef CRYPTOPP_CHACHA_H +#define CRYPTOPP_CHACHA_H + +#include "strciphr.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +////////////////////////////// Bernstein ChaCha ////////////////////////////// + +/// \brief ChaCha stream cipher information +/// \since Crypto++ 5.6.4 +struct ChaCha_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + /// \details Bernstein named the cipher variants ChaCha8, ChaCha12 and + /// ChaCha20. More generally, Bernstein called the family ChaCha{r}. + /// AlgorithmName() provides the exact name once rounds are set. + static const char* StaticAlgorithmName() { + return "ChaCha"; + } +}; + +/// \brief ChaCha stream cipher implementation +/// \since Crypto++ 5.6.4 +class CRYPTOPP_NO_VTABLE ChaCha_Policy : public AdditiveCipherConcretePolicy +{ +public: + virtual ~ChaCha_Policy() {} + ChaCha_Policy() : m_rounds(ROUNDS) {} + +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + bool CipherIsRandomAccess() const {return true;} + void SeekToIteration(lword iterationCount); + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; + + std::string AlgorithmName() const; + std::string AlgorithmProvider() const; + + CRYPTOPP_CONSTANT(ROUNDS = 20); // Default rounds + FixedSizeAlignedSecBlock m_state; + unsigned int m_rounds; +}; + +/// \brief ChaCha stream cipher +/// \details This is Bernstein and ECRYPT's ChaCha. It is _slightly_ different +/// from the IETF's version of ChaCha called ChaChaTLS. +/// \sa ChaCha, a variant +/// of Salsa20 (2008.01.28). +/// \since Crypto++ 5.6.4 +struct ChaCha : public ChaCha_Info, public SymmetricCipherDocumentation +{ + /// \brief ChaCha Encryption + typedef SymmetricCipherFinal >, ChaCha_Info > Encryption; + /// \brief ChaCha Decryption + typedef Encryption Decryption; +}; + +////////////////////////////// IETF ChaChaTLS ////////////////////////////// + +/// \brief IETF ChaCha20 stream cipher information +/// \since Crypto++ 8.1 +struct ChaChaTLS_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 12>, FixedRounds<20> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + /// \details This is the IETF's variant of Bernstein's ChaCha from RFC + /// 8439. IETF ChaCha is called ChaChaTLS in the Crypto++ library. It + /// is _slightly_ different from Bernstein's implementation. + static const char* StaticAlgorithmName() { + return "ChaChaTLS"; + } +}; + +/// \brief IETF ChaCha20 stream cipher implementation +/// \since Crypto++ 8.1 +class CRYPTOPP_NO_VTABLE ChaChaTLS_Policy : public AdditiveCipherConcretePolicy +{ +public: + virtual ~ChaChaTLS_Policy() {} + ChaChaTLS_Policy() : m_counter(0) {} + +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + bool CipherIsRandomAccess() const {return true;} + void SeekToIteration(lword iterationCount); + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; + + std::string AlgorithmName() const; + std::string AlgorithmProvider() const; + + FixedSizeAlignedSecBlock m_state; + unsigned int m_counter; + CRYPTOPP_CONSTANT(ROUNDS = ChaChaTLS_Info::ROUNDS); + CRYPTOPP_CONSTANT(KEY = 16); // Index into m_state + CRYPTOPP_CONSTANT(CTR = 24); // Index into m_state +}; + +/// \brief IETF ChaCha20 stream cipher +/// \details This is the IETF's variant of Bernstein's ChaCha from RFC 8439. +/// IETF ChaCha is called ChaChaTLS in the Crypto++ library. It is +/// _slightly_ different from the Bernstein implementation. ChaCha-TLS +/// can be used for cipher suites +/// TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, +/// TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, and +/// TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256. +/// \sa RFC 8439, ChaCha20 and +/// Poly1305 for IETF Protocols, How +/// to handle block counter wrap in IETF's ChaCha algorithm? and +/// Issue +/// 790, ChaChaTLS results when counter block wraps. +/// \since Crypto++ 8.1 +struct ChaChaTLS : public ChaChaTLS_Info, public SymmetricCipherDocumentation +{ + /// \brief ChaCha-TLS Encryption + typedef SymmetricCipherFinal >, ChaChaTLS_Info > Encryption; + /// \brief ChaCha-TLS Decryption + typedef Encryption Decryption; +}; + +////////////////////////////// IETF XChaCha20 draft ////////////////////////////// + +/// \brief IETF XChaCha20 stream cipher information +/// \since Crypto++ 8.1 +struct XChaCha20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + /// \details This is the IETF's XChaCha from draft-arciszewski-xchacha. + static const char* StaticAlgorithmName() { + return "XChaCha20"; + } +}; + +/// \brief IETF XChaCha20 stream cipher implementation +/// \since Crypto++ 8.1 +class CRYPTOPP_NO_VTABLE XChaCha20_Policy : public AdditiveCipherConcretePolicy +{ +public: + virtual ~XChaCha20_Policy() {} + XChaCha20_Policy() : m_counter(0), m_rounds(ROUNDS) {} + +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + bool CipherIsRandomAccess() const {return false;} + void SeekToIteration(lword iterationCount); + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; + + std::string AlgorithmName() const; + std::string AlgorithmProvider() const; + + FixedSizeAlignedSecBlock m_state; + unsigned int m_counter, m_rounds; + CRYPTOPP_CONSTANT(ROUNDS = 20); // Default rounds + CRYPTOPP_CONSTANT(KEY = 16); // Index into m_state +}; + +/// \brief IETF XChaCha20 stream cipher +/// \details This is the IETF's XChaCha from draft-arciszewski-xchacha. +/// \sa XChaCha: +/// eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03), How +/// to handle block counter wrap in IETF's ChaCha algorithm? and +/// Issue +/// 790, ChaCha20 results when counter block wraps. +/// \since Crypto++ 8.1 +struct XChaCha20 : public XChaCha20_Info, public SymmetricCipherDocumentation +{ + /// \brief XChaCha Encryption + typedef SymmetricCipherFinal >, XChaCha20_Info > Encryption; + /// \brief XChaCha Decryption + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_CHACHA_H diff --git a/external/ours/library/crypto/src/shared/original/chacha_avx.cpp b/external/ours/library/crypto/src/shared/original/chacha_avx.cpp new file mode 100755 index 000000000..8bd8ddc2b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/chacha_avx.cpp @@ -0,0 +1,422 @@ +// chacha_avx.cpp - written and placed in the public domain by +// Jack Lloyd and Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// AVX2 instructions. A separate source file is needed because +// additional CXXFLAGS are required to enable the appropriate +// instructions sets in some build configurations. +// +// AVX2 implementation based on Botan's chacha_avx.cpp. Many thanks +// to Jack Lloyd and the Botan team for allowing us to use it. +// +// Here are some relative numbers for ChaCha8: +// * Intel Skylake, 3.0 GHz: AVX2 at 4411 MB/s; 0.57 cpb. +// * Intel Broadwell, 2.3 GHz: AVX2 at 3828 MB/s; 0.58 cpb. +// * AMD Bulldozer, 3.3 GHz: AVX2 at 1680 MB/s; 1.47 cpb. + +#include "pch.h" +#include "config.h" + +#include "chacha.h" +#include "misc.h" + +#if defined(CRYPTOPP_AVX2_AVAILABLE) +# include +# include +# include +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char CHACHA_AVX_FNAME[] = __FILE__; + +// Sun Studio 12.4 OK, 12.5 and 12.6 compile error. +#if (__SUNPRO_CC >= 0x5140) && (__SUNPRO_CC <= 0x5150) +# define MAYBE_CONST +#else +# define MAYBE_CONST const +#endif + +// VS2017 and global optimization bug. TODO, figure out when +// we can re-enable full optimizations for VS2017. Also see +// https://github.com/weidai11/cryptopp/issues/649 and +// https://github.com/weidai11/cryptopp/issues/735. The +// 649 issue affects AES but it is the same here. The 735 +// issue is ChaCha AVX2 cut-in where it surfaced again. +#if (_MSC_VER >= 1910) +# ifndef CRYPTOPP_DEBUG +# pragma optimize("", off) +# pragma optimize("ts", on) +# endif +#endif + +// The data is aligned, but Clang issues warning based on type +// and not the actual alignment of the variable and data. +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wcast-align" +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +#if (CRYPTOPP_AVX2_AVAILABLE) + +template +inline __m256i RotateLeft(const __m256i val) +{ + return _mm256_or_si256(_mm256_slli_epi32(val, R), _mm256_srli_epi32(val, 32-R)); +} + +template <> +inline __m256i RotateLeft<8>(const __m256i val) +{ + const __m256i mask = _mm256_set_epi8(14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3, + 14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3); + return _mm256_shuffle_epi8(val, mask); +} + +template <> +inline __m256i RotateLeft<16>(const __m256i val) +{ + const __m256i mask = _mm256_set_epi8(13,12,15,14, 9,8,11,10, 5,4,7,6, 1,0,3,2, + 13,12,15,14, 9,8,11,10, 5,4,7,6, 1,0,3,2); + return _mm256_shuffle_epi8(val, mask); +} + +#endif // CRYPTOPP_AVX2_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_AVX2_AVAILABLE) + +void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *output, unsigned int rounds) +{ + const __m256i state0 = _mm256_broadcastsi128_si256( + _mm_loadu_si128(reinterpret_cast(state+0*4))); + const __m256i state1 = _mm256_broadcastsi128_si256( + _mm_loadu_si128(reinterpret_cast(state+1*4))); + const __m256i state2 = _mm256_broadcastsi128_si256( + _mm_loadu_si128(reinterpret_cast(state+2*4))); + const __m256i state3 = _mm256_broadcastsi128_si256( + _mm_loadu_si128(reinterpret_cast(state+3*4))); + + const word32 C = 0xFFFFFFFFu - state[12]; + const __m256i CTR0 = _mm256_set_epi32(0, 0, 0, 0, 0, 0, C < 4, 4); + const __m256i CTR1 = _mm256_set_epi32(0, 0, C < 1, 1, 0, 0, C < 5, 5); + const __m256i CTR2 = _mm256_set_epi32(0, 0, C < 2, 2, 0, 0, C < 6, 6); + const __m256i CTR3 = _mm256_set_epi32(0, 0, C < 3, 3, 0, 0, C < 7, 7); + + __m256i X0_0 = state0; + __m256i X0_1 = state1; + __m256i X0_2 = state2; + __m256i X0_3 = _mm256_add_epi32(state3, CTR0); + + __m256i X1_0 = state0; + __m256i X1_1 = state1; + __m256i X1_2 = state2; + __m256i X1_3 = _mm256_add_epi32(state3, CTR1); + + __m256i X2_0 = state0; + __m256i X2_1 = state1; + __m256i X2_2 = state2; + __m256i X2_3 = _mm256_add_epi32(state3, CTR2); + + __m256i X3_0 = state0; + __m256i X3_1 = state1; + __m256i X3_2 = state2; + __m256i X3_3 = _mm256_add_epi32(state3, CTR3); + + for (int i = static_cast(rounds); i > 0; i -= 2) + { + X0_0 = _mm256_add_epi32(X0_0, X0_1); + X1_0 = _mm256_add_epi32(X1_0, X1_1); + X2_0 = _mm256_add_epi32(X2_0, X2_1); + X3_0 = _mm256_add_epi32(X3_0, X3_1); + + X0_3 = _mm256_xor_si256(X0_3, X0_0); + X1_3 = _mm256_xor_si256(X1_3, X1_0); + X2_3 = _mm256_xor_si256(X2_3, X2_0); + X3_3 = _mm256_xor_si256(X3_3, X3_0); + + X0_3 = RotateLeft<16>(X0_3); + X1_3 = RotateLeft<16>(X1_3); + X2_3 = RotateLeft<16>(X2_3); + X3_3 = RotateLeft<16>(X3_3); + + X0_2 = _mm256_add_epi32(X0_2, X0_3); + X1_2 = _mm256_add_epi32(X1_2, X1_3); + X2_2 = _mm256_add_epi32(X2_2, X2_3); + X3_2 = _mm256_add_epi32(X3_2, X3_3); + + X0_1 = _mm256_xor_si256(X0_1, X0_2); + X1_1 = _mm256_xor_si256(X1_1, X1_2); + X2_1 = _mm256_xor_si256(X2_1, X2_2); + X3_1 = _mm256_xor_si256(X3_1, X3_2); + + X0_1 = RotateLeft<12>(X0_1); + X1_1 = RotateLeft<12>(X1_1); + X2_1 = RotateLeft<12>(X2_1); + X3_1 = RotateLeft<12>(X3_1); + + X0_0 = _mm256_add_epi32(X0_0, X0_1); + X1_0 = _mm256_add_epi32(X1_0, X1_1); + X2_0 = _mm256_add_epi32(X2_0, X2_1); + X3_0 = _mm256_add_epi32(X3_0, X3_1); + + X0_3 = _mm256_xor_si256(X0_3, X0_0); + X1_3 = _mm256_xor_si256(X1_3, X1_0); + X2_3 = _mm256_xor_si256(X2_3, X2_0); + X3_3 = _mm256_xor_si256(X3_3, X3_0); + + X0_3 = RotateLeft<8>(X0_3); + X1_3 = RotateLeft<8>(X1_3); + X2_3 = RotateLeft<8>(X2_3); + X3_3 = RotateLeft<8>(X3_3); + + X0_2 = _mm256_add_epi32(X0_2, X0_3); + X1_2 = _mm256_add_epi32(X1_2, X1_3); + X2_2 = _mm256_add_epi32(X2_2, X2_3); + X3_2 = _mm256_add_epi32(X3_2, X3_3); + + X0_1 = _mm256_xor_si256(X0_1, X0_2); + X1_1 = _mm256_xor_si256(X1_1, X1_2); + X2_1 = _mm256_xor_si256(X2_1, X2_2); + X3_1 = _mm256_xor_si256(X3_1, X3_2); + + X0_1 = RotateLeft<7>(X0_1); + X1_1 = RotateLeft<7>(X1_1); + X2_1 = RotateLeft<7>(X2_1); + X3_1 = RotateLeft<7>(X3_1); + + X0_1 = _mm256_shuffle_epi32(X0_1, _MM_SHUFFLE(0, 3, 2, 1)); + X0_2 = _mm256_shuffle_epi32(X0_2, _MM_SHUFFLE(1, 0, 3, 2)); + X0_3 = _mm256_shuffle_epi32(X0_3, _MM_SHUFFLE(2, 1, 0, 3)); + + X1_1 = _mm256_shuffle_epi32(X1_1, _MM_SHUFFLE(0, 3, 2, 1)); + X1_2 = _mm256_shuffle_epi32(X1_2, _MM_SHUFFLE(1, 0, 3, 2)); + X1_3 = _mm256_shuffle_epi32(X1_3, _MM_SHUFFLE(2, 1, 0, 3)); + + X2_1 = _mm256_shuffle_epi32(X2_1, _MM_SHUFFLE(0, 3, 2, 1)); + X2_2 = _mm256_shuffle_epi32(X2_2, _MM_SHUFFLE(1, 0, 3, 2)); + X2_3 = _mm256_shuffle_epi32(X2_3, _MM_SHUFFLE(2, 1, 0, 3)); + + X3_1 = _mm256_shuffle_epi32(X3_1, _MM_SHUFFLE(0, 3, 2, 1)); + X3_2 = _mm256_shuffle_epi32(X3_2, _MM_SHUFFLE(1, 0, 3, 2)); + X3_3 = _mm256_shuffle_epi32(X3_3, _MM_SHUFFLE(2, 1, 0, 3)); + + X0_0 = _mm256_add_epi32(X0_0, X0_1); + X1_0 = _mm256_add_epi32(X1_0, X1_1); + X2_0 = _mm256_add_epi32(X2_0, X2_1); + X3_0 = _mm256_add_epi32(X3_0, X3_1); + + X0_3 = _mm256_xor_si256(X0_3, X0_0); + X1_3 = _mm256_xor_si256(X1_3, X1_0); + X2_3 = _mm256_xor_si256(X2_3, X2_0); + X3_3 = _mm256_xor_si256(X3_3, X3_0); + + X0_3 = RotateLeft<16>(X0_3); + X1_3 = RotateLeft<16>(X1_3); + X2_3 = RotateLeft<16>(X2_3); + X3_3 = RotateLeft<16>(X3_3); + + X0_2 = _mm256_add_epi32(X0_2, X0_3); + X1_2 = _mm256_add_epi32(X1_2, X1_3); + X2_2 = _mm256_add_epi32(X2_2, X2_3); + X3_2 = _mm256_add_epi32(X3_2, X3_3); + + X0_1 = _mm256_xor_si256(X0_1, X0_2); + X1_1 = _mm256_xor_si256(X1_1, X1_2); + X2_1 = _mm256_xor_si256(X2_1, X2_2); + X3_1 = _mm256_xor_si256(X3_1, X3_2); + + X0_1 = RotateLeft<12>(X0_1); + X1_1 = RotateLeft<12>(X1_1); + X2_1 = RotateLeft<12>(X2_1); + X3_1 = RotateLeft<12>(X3_1); + + X0_0 = _mm256_add_epi32(X0_0, X0_1); + X1_0 = _mm256_add_epi32(X1_0, X1_1); + X2_0 = _mm256_add_epi32(X2_0, X2_1); + X3_0 = _mm256_add_epi32(X3_0, X3_1); + + X0_3 = _mm256_xor_si256(X0_3, X0_0); + X1_3 = _mm256_xor_si256(X1_3, X1_0); + X2_3 = _mm256_xor_si256(X2_3, X2_0); + X3_3 = _mm256_xor_si256(X3_3, X3_0); + + X0_3 = RotateLeft<8>(X0_3); + X1_3 = RotateLeft<8>(X1_3); + X2_3 = RotateLeft<8>(X2_3); + X3_3 = RotateLeft<8>(X3_3); + + X0_2 = _mm256_add_epi32(X0_2, X0_3); + X1_2 = _mm256_add_epi32(X1_2, X1_3); + X2_2 = _mm256_add_epi32(X2_2, X2_3); + X3_2 = _mm256_add_epi32(X3_2, X3_3); + + X0_1 = _mm256_xor_si256(X0_1, X0_2); + X1_1 = _mm256_xor_si256(X1_1, X1_2); + X2_1 = _mm256_xor_si256(X2_1, X2_2); + X3_1 = _mm256_xor_si256(X3_1, X3_2); + + X0_1 = RotateLeft<7>(X0_1); + X1_1 = RotateLeft<7>(X1_1); + X2_1 = RotateLeft<7>(X2_1); + X3_1 = RotateLeft<7>(X3_1); + + X0_1 = _mm256_shuffle_epi32(X0_1, _MM_SHUFFLE(2, 1, 0, 3)); + X0_2 = _mm256_shuffle_epi32(X0_2, _MM_SHUFFLE(1, 0, 3, 2)); + X0_3 = _mm256_shuffle_epi32(X0_3, _MM_SHUFFLE(0, 3, 2, 1)); + + X1_1 = _mm256_shuffle_epi32(X1_1, _MM_SHUFFLE(2, 1, 0, 3)); + X1_2 = _mm256_shuffle_epi32(X1_2, _MM_SHUFFLE(1, 0, 3, 2)); + X1_3 = _mm256_shuffle_epi32(X1_3, _MM_SHUFFLE(0, 3, 2, 1)); + + X2_1 = _mm256_shuffle_epi32(X2_1, _MM_SHUFFLE(2, 1, 0, 3)); + X2_2 = _mm256_shuffle_epi32(X2_2, _MM_SHUFFLE(1, 0, 3, 2)); + X2_3 = _mm256_shuffle_epi32(X2_3, _MM_SHUFFLE(0, 3, 2, 1)); + + X3_1 = _mm256_shuffle_epi32(X3_1, _MM_SHUFFLE(2, 1, 0, 3)); + X3_2 = _mm256_shuffle_epi32(X3_2, _MM_SHUFFLE(1, 0, 3, 2)); + X3_3 = _mm256_shuffle_epi32(X3_3, _MM_SHUFFLE(0, 3, 2, 1)); + } + + X0_0 = _mm256_add_epi32(X0_0, state0); + X0_1 = _mm256_add_epi32(X0_1, state1); + X0_2 = _mm256_add_epi32(X0_2, state2); + X0_3 = _mm256_add_epi32(X0_3, state3); + X0_3 = _mm256_add_epi32(X0_3, CTR0); + + X1_0 = _mm256_add_epi32(X1_0, state0); + X1_1 = _mm256_add_epi32(X1_1, state1); + X1_2 = _mm256_add_epi32(X1_2, state2); + X1_3 = _mm256_add_epi32(X1_3, state3); + X1_3 = _mm256_add_epi32(X1_3, CTR1); + + X2_0 = _mm256_add_epi32(X2_0, state0); + X2_1 = _mm256_add_epi32(X2_1, state1); + X2_2 = _mm256_add_epi32(X2_2, state2); + X2_3 = _mm256_add_epi32(X2_3, state3); + X2_3 = _mm256_add_epi32(X2_3, CTR2); + + X3_0 = _mm256_add_epi32(X3_0, state0); + X3_1 = _mm256_add_epi32(X3_1, state1); + X3_2 = _mm256_add_epi32(X3_2, state2); + X3_3 = _mm256_add_epi32(X3_3, state3); + X3_3 = _mm256_add_epi32(X3_3, CTR3); + + if (input) + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+0*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+0*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+1*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+1*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+2*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+2*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+3*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+3*32))))); + } + else + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+0*32), + _mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+1*32), + _mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+2*32), + _mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+3*32), + _mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4))); + } + + if (input) + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+4*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+4*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+5*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+5*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+6*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+6*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+7*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+7*32))))); + } + else + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+4*32), + _mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+5*32), + _mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+6*32), + _mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+7*32), + _mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4))); + } + + if (input) + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 8*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+8*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 9*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+9*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+10*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+10*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+11*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+11*32))))); + } + else + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 8*32), + _mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 9*32), + _mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+10*32), + _mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+11*32), + _mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4))); + } + + if (input) + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+12*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+12*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+13*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+13*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+14*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+14*32))))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+15*32), + _mm256_xor_si256(_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)), + _mm256_loadu_si256(const_cast(reinterpret_cast(input+15*32))))); + } + else + { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+12*32), + _mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+13*32), + _mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+14*32), + _mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4))); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+15*32), + _mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4))); + } + + // https://software.intel.com/en-us/articles/avoiding-avx-sse-transition-penalties + _mm256_zeroupper(); +} + +#endif // CRYPTOPP_AVX2_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/chacha_simd.cpp b/external/ours/library/crypto/src/shared/original/chacha_simd.cpp new file mode 100755 index 000000000..4e5a3cc37 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/chacha_simd.cpp @@ -0,0 +1,1109 @@ +// chacha_simd.cpp - written and placed in the public domain by +// Jack Lloyd and Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// SSE2, ARM NEON and ARMv8a, Power7 and Altivec instructions. A separate +// source file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. +// +// SSE2 implementation based on Botan's chacha_sse2.cpp. Many thanks +// to Jack Lloyd and the Botan team for allowing us to use it. +// +// The SSE2 implementation is kind of unusual among Crypto++ algorithms. +// We guard on CRYTPOPP_SSE2_AVAILABLE and use HasSSE2() at runtime. However, +// if the compiler says a target machine has SSSE3 or XOP available (say, by +// way of -march=native), then we can pull another 150 to 800 MB/s out of +// ChaCha. To capture SSSE3 and XOP we use the compiler defines __SSSE3__ and +// __XOP__ and forgo runtime tests. +// +// Runtime tests for HasSSSE3() and HasXop() are too expensive to make a +// sub-case of SSE2. The rotates are on a critical path and the runtime tests +// crush performance. +// +// Here are some relative numbers for ChaCha8: +// * Intel Skylake, 3.0 GHz: SSE2 at 2160 MB/s; SSSE3 at 2310 MB/s. +// * AMD Bulldozer, 3.3 GHz: SSE2 at 1680 MB/s; XOP at 2510 MB/s. + +#include "pch.h" +#include "config.h" + +#include "chacha.h" +#include "misc.h" + +// Internal compiler error in GCC 3.3 and below +#if defined(__GNUC__) && (__GNUC__ < 4) +# undef CRYPTOPP_SSE2_INTRIN_AVAILABLE +#endif + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) +# include +# include +#endif + +#if defined(__SSSE3__) +# include +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char CHACHA_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +// ***************************** NEON ***************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +template +inline uint32x4_t RotateLeft(const uint32x4_t& val) +{ + return vorrq_u32(vshlq_n_u32(val, R), vshrq_n_u32(val, 32 - R)); +} + +template +inline uint32x4_t RotateRight(const uint32x4_t& val) +{ + return vorrq_u32(vshlq_n_u32(val, 32 - R), vshrq_n_u32(val, R)); +} + +template <> +inline uint32x4_t RotateLeft<8>(const uint32x4_t& val) +{ +#if defined(__aarch32__) || defined(__aarch64__) + const uint8_t maskb[16] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 }; + const uint8x16_t mask = vld1q_u8(maskb); + + return vreinterpretq_u32_u8( + vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); +#else + // fallback to slower C++ rotation. + return vorrq_u32(vshlq_n_u32(val, 8), + vshrq_n_u32(val, 32 - 8)); +#endif +} + +template <> +inline uint32x4_t RotateLeft<16>(const uint32x4_t& val) +{ +#if defined(__aarch32__) || defined(__aarch64__) + return vreinterpretq_u32_u16( + vrev32q_u16(vreinterpretq_u16_u32(val))); +#else + // fallback to slower C++ rotation. + return vorrq_u32(vshlq_n_u32(val, 16), + vshrq_n_u32(val, 32 - 16)); +#endif +} + +template <> +inline uint32x4_t RotateRight<8>(const uint32x4_t& val) +{ +#if defined(__aarch32__) || defined(__aarch64__) + const uint8_t maskb[16] = { 1,2,3,0, 5,6,7,4, 9,10,11,8, 13,14,15,12 }; + const uint8x16_t mask = vld1q_u8(maskb); + + return vreinterpretq_u32_u8( + vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); +#else + // fallback to slower C++ rotation. + return vorrq_u32(vshrq_n_u32(val, 8), + vshlq_n_u32(val, 32 - 8)); +#endif +} + +template <> +inline uint32x4_t RotateRight<16>(const uint32x4_t& val) +{ +#if defined(__aarch32__) || defined(__aarch64__) + return vreinterpretq_u32_u16( + vrev32q_u16(vreinterpretq_u16_u32(val))); +#else + // fallback to slower C++ rotation. + return vorrq_u32(vshrq_n_u32(val, 16), + vshlq_n_u32(val, 32 - 16)); +#endif +} + +// ChaCha's use of x86 shuffle is really a 4, 8, or 12 byte +// rotation on the 128-bit vector word: +// * [3,2,1,0] => [0,3,2,1] is Extract<1>(x) +// * [3,2,1,0] => [1,0,3,2] is Extract<2>(x) +// * [3,2,1,0] => [2,1,0,3] is Extract<3>(x) +template +inline uint32x4_t Extract(const uint32x4_t& val) +{ + return vextq_u32(val, val, S); +} + +// Helper to perform 64-bit addition across two elements of 32-bit vectors +inline uint32x4_t Add64(const uint32x4_t& a, const uint32x4_t& b) +{ + return vreinterpretq_u32_u64( + vaddq_u64( + vreinterpretq_u64_u32(a), + vreinterpretq_u64_u32(b))); +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// ***************************** SSE2 ***************************** // + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) + +template +inline __m128i RotateLeft(const __m128i val) +{ +#ifdef __XOP__ + return _mm_roti_epi32(val, R); +#else + return _mm_or_si128(_mm_slli_epi32(val, R), _mm_srli_epi32(val, 32-R)); +#endif +} + +template <> +inline __m128i RotateLeft<8>(const __m128i val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 8); +#elif defined(__SSSE3__) + const __m128i mask = _mm_set_epi8(14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3); + return _mm_shuffle_epi8(val, mask); +#else + return _mm_or_si128(_mm_slli_epi32(val, 8), _mm_srli_epi32(val, 32-8)); +#endif +} + +template <> +inline __m128i RotateLeft<16>(const __m128i val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 16); +#elif defined(__SSSE3__) + const __m128i mask = _mm_set_epi8(13,12,15,14, 9,8,11,10, 5,4,7,6, 1,0,3,2); + return _mm_shuffle_epi8(val, mask); +#else + return _mm_or_si128(_mm_slli_epi32(val, 16), _mm_srli_epi32(val, 32-16)); +#endif +} + +#endif // CRYPTOPP_SSE2_INTRIN_AVAILABLE + +// **************************** Altivec **************************** // + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + +// ChaCha_OperateKeystream is optimized for Altivec. However, Altivec +// is supported by using vec_ld and vec_st, and using a composite VecAdd +// that supports 64-bit element adds. vec_ld and vec_st add significant +// overhead when memory is not aligned. Despite the drawbacks Altivec +// is profitable. The numbers for ChaCha8 are: +// +// PowerMac, C++, 2.0 GHz: 205 MB/s, 9.29 cpb +// PowerMac, Altivec, 2.0 GHz: 471 MB/s, 4.09 cpb + +using CryptoPP::uint8x16_p; +using CryptoPP::uint32x4_p; +using CryptoPP::VecLoad; +using CryptoPP::VecLoadAligned; +using CryptoPP::VecStore; +using CryptoPP::VecPermute; + +// Permutes bytes in packed 32-bit words to little endian. +// State is already in proper endian order. Input and +// output must be permuted during load and save. +inline uint32x4_p VecLoad32LE(const uint8_t src[16]) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p mask = {3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12}; + const uint32x4_p val = VecLoad(src); + return VecPermute(val, val, mask); +#else + return VecLoad(src); +#endif +} + +// Permutes bytes in packed 32-bit words to little endian. +// State is already in proper endian order. Input and +// output must be permuted during load and save. +inline void VecStore32LE(uint8_t dest[16], const uint32x4_p& val) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p mask = {3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12}; + VecStore(VecPermute(val, val, mask), dest); +#else + return VecStore(val, dest); +#endif +} + +// ChaCha's use of x86 shuffle is really a 4, 8, or 12 byte +// rotation on the 128-bit vector word: +// * [3,2,1,0] => [0,3,2,1] is Shuffle<1>(x) +// * [3,2,1,0] => [1,0,3,2] is Shuffle<2>(x) +// * [3,2,1,0] => [2,1,0,3] is Shuffle<3>(x) +template +inline uint32x4_p Shuffle(const uint32x4_p& val) +{ + CRYPTOPP_ASSERT(0); + return val; +} + +template <> +inline uint32x4_p Shuffle<1>(const uint32x4_p& val) +{ + const uint8x16_p mask = {4,5,6,7, 8,9,10,11, 12,13,14,15, 0,1,2,3}; + return VecPermute(val, val, mask); +} + +template <> +inline uint32x4_p Shuffle<2>(const uint32x4_p& val) +{ + const uint8x16_p mask = {8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7}; + return VecPermute(val, val, mask); +} + +template <> +inline uint32x4_p Shuffle<3>(const uint32x4_p& val) +{ + const uint8x16_p mask = {12,13,14,15, 0,1,2,3, 4,5,6,7, 8,9,10,11}; + return VecPermute(val, val, mask); +} + +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +// ***************************** NEON ***************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +void ChaCha_OperateKeystream_NEON(const word32 *state, const byte* input, byte *output, unsigned int rounds) +{ + const uint32x4_t state0 = vld1q_u32(state + 0*4); + const uint32x4_t state1 = vld1q_u32(state + 1*4); + const uint32x4_t state2 = vld1q_u32(state + 2*4); + const uint32x4_t state3 = vld1q_u32(state + 3*4); + + const unsigned int w[] = {1,0,0,0, 2,0,0,0, 3,0,0,0}; + const uint32x4_t CTRS[3] = { + vld1q_u32(w+0), vld1q_u32(w+4), vld1q_u32(w+8) + }; + + uint32x4_t r0_0 = state0; + uint32x4_t r0_1 = state1; + uint32x4_t r0_2 = state2; + uint32x4_t r0_3 = state3; + + uint32x4_t r1_0 = state0; + uint32x4_t r1_1 = state1; + uint32x4_t r1_2 = state2; + uint32x4_t r1_3 = Add64(r0_3, CTRS[0]); + + uint32x4_t r2_0 = state0; + uint32x4_t r2_1 = state1; + uint32x4_t r2_2 = state2; + uint32x4_t r2_3 = Add64(r0_3, CTRS[1]); + + uint32x4_t r3_0 = state0; + uint32x4_t r3_1 = state1; + uint32x4_t r3_2 = state2; + uint32x4_t r3_3 = Add64(r0_3, CTRS[2]); + + for (int i = static_cast(rounds); i > 0; i -= 2) + { + r0_0 = vaddq_u32(r0_0, r0_1); + r1_0 = vaddq_u32(r1_0, r1_1); + r2_0 = vaddq_u32(r2_0, r2_1); + r3_0 = vaddq_u32(r3_0, r3_1); + + r0_3 = veorq_u32(r0_3, r0_0); + r1_3 = veorq_u32(r1_3, r1_0); + r2_3 = veorq_u32(r2_3, r2_0); + r3_3 = veorq_u32(r3_3, r3_0); + + r0_3 = RotateLeft<16>(r0_3); + r1_3 = RotateLeft<16>(r1_3); + r2_3 = RotateLeft<16>(r2_3); + r3_3 = RotateLeft<16>(r3_3); + + r0_2 = vaddq_u32(r0_2, r0_3); + r1_2 = vaddq_u32(r1_2, r1_3); + r2_2 = vaddq_u32(r2_2, r2_3); + r3_2 = vaddq_u32(r3_2, r3_3); + + r0_1 = veorq_u32(r0_1, r0_2); + r1_1 = veorq_u32(r1_1, r1_2); + r2_1 = veorq_u32(r2_1, r2_2); + r3_1 = veorq_u32(r3_1, r3_2); + + r0_1 = RotateLeft<12>(r0_1); + r1_1 = RotateLeft<12>(r1_1); + r2_1 = RotateLeft<12>(r2_1); + r3_1 = RotateLeft<12>(r3_1); + + r0_0 = vaddq_u32(r0_0, r0_1); + r1_0 = vaddq_u32(r1_0, r1_1); + r2_0 = vaddq_u32(r2_0, r2_1); + r3_0 = vaddq_u32(r3_0, r3_1); + + r0_3 = veorq_u32(r0_3, r0_0); + r1_3 = veorq_u32(r1_3, r1_0); + r2_3 = veorq_u32(r2_3, r2_0); + r3_3 = veorq_u32(r3_3, r3_0); + + r0_3 = RotateLeft<8>(r0_3); + r1_3 = RotateLeft<8>(r1_3); + r2_3 = RotateLeft<8>(r2_3); + r3_3 = RotateLeft<8>(r3_3); + + r0_2 = vaddq_u32(r0_2, r0_3); + r1_2 = vaddq_u32(r1_2, r1_3); + r2_2 = vaddq_u32(r2_2, r2_3); + r3_2 = vaddq_u32(r3_2, r3_3); + + r0_1 = veorq_u32(r0_1, r0_2); + r1_1 = veorq_u32(r1_1, r1_2); + r2_1 = veorq_u32(r2_1, r2_2); + r3_1 = veorq_u32(r3_1, r3_2); + + r0_1 = RotateLeft<7>(r0_1); + r1_1 = RotateLeft<7>(r1_1); + r2_1 = RotateLeft<7>(r2_1); + r3_1 = RotateLeft<7>(r3_1); + + r0_1 = Extract<1>(r0_1); + r0_2 = Extract<2>(r0_2); + r0_3 = Extract<3>(r0_3); + + r1_1 = Extract<1>(r1_1); + r1_2 = Extract<2>(r1_2); + r1_3 = Extract<3>(r1_3); + + r2_1 = Extract<1>(r2_1); + r2_2 = Extract<2>(r2_2); + r2_3 = Extract<3>(r2_3); + + r3_1 = Extract<1>(r3_1); + r3_2 = Extract<2>(r3_2); + r3_3 = Extract<3>(r3_3); + + r0_0 = vaddq_u32(r0_0, r0_1); + r1_0 = vaddq_u32(r1_0, r1_1); + r2_0 = vaddq_u32(r2_0, r2_1); + r3_0 = vaddq_u32(r3_0, r3_1); + + r0_3 = veorq_u32(r0_3, r0_0); + r1_3 = veorq_u32(r1_3, r1_0); + r2_3 = veorq_u32(r2_3, r2_0); + r3_3 = veorq_u32(r3_3, r3_0); + + r0_3 = RotateLeft<16>(r0_3); + r1_3 = RotateLeft<16>(r1_3); + r2_3 = RotateLeft<16>(r2_3); + r3_3 = RotateLeft<16>(r3_3); + + r0_2 = vaddq_u32(r0_2, r0_3); + r1_2 = vaddq_u32(r1_2, r1_3); + r2_2 = vaddq_u32(r2_2, r2_3); + r3_2 = vaddq_u32(r3_2, r3_3); + + r0_1 = veorq_u32(r0_1, r0_2); + r1_1 = veorq_u32(r1_1, r1_2); + r2_1 = veorq_u32(r2_1, r2_2); + r3_1 = veorq_u32(r3_1, r3_2); + + r0_1 = RotateLeft<12>(r0_1); + r1_1 = RotateLeft<12>(r1_1); + r2_1 = RotateLeft<12>(r2_1); + r3_1 = RotateLeft<12>(r3_1); + + r0_0 = vaddq_u32(r0_0, r0_1); + r1_0 = vaddq_u32(r1_0, r1_1); + r2_0 = vaddq_u32(r2_0, r2_1); + r3_0 = vaddq_u32(r3_0, r3_1); + + r0_3 = veorq_u32(r0_3, r0_0); + r1_3 = veorq_u32(r1_3, r1_0); + r2_3 = veorq_u32(r2_3, r2_0); + r3_3 = veorq_u32(r3_3, r3_0); + + r0_3 = RotateLeft<8>(r0_3); + r1_3 = RotateLeft<8>(r1_3); + r2_3 = RotateLeft<8>(r2_3); + r3_3 = RotateLeft<8>(r3_3); + + r0_2 = vaddq_u32(r0_2, r0_3); + r1_2 = vaddq_u32(r1_2, r1_3); + r2_2 = vaddq_u32(r2_2, r2_3); + r3_2 = vaddq_u32(r3_2, r3_3); + + r0_1 = veorq_u32(r0_1, r0_2); + r1_1 = veorq_u32(r1_1, r1_2); + r2_1 = veorq_u32(r2_1, r2_2); + r3_1 = veorq_u32(r3_1, r3_2); + + r0_1 = RotateLeft<7>(r0_1); + r1_1 = RotateLeft<7>(r1_1); + r2_1 = RotateLeft<7>(r2_1); + r3_1 = RotateLeft<7>(r3_1); + + r0_1 = Extract<3>(r0_1); + r0_2 = Extract<2>(r0_2); + r0_3 = Extract<1>(r0_3); + + r1_1 = Extract<3>(r1_1); + r1_2 = Extract<2>(r1_2); + r1_3 = Extract<1>(r1_3); + + r2_1 = Extract<3>(r2_1); + r2_2 = Extract<2>(r2_2); + r2_3 = Extract<1>(r2_3); + + r3_1 = Extract<3>(r3_1); + r3_2 = Extract<2>(r3_2); + r3_3 = Extract<1>(r3_3); + } + + r0_0 = vaddq_u32(r0_0, state0); + r0_1 = vaddq_u32(r0_1, state1); + r0_2 = vaddq_u32(r0_2, state2); + r0_3 = vaddq_u32(r0_3, state3); + + r1_0 = vaddq_u32(r1_0, state0); + r1_1 = vaddq_u32(r1_1, state1); + r1_2 = vaddq_u32(r1_2, state2); + r1_3 = vaddq_u32(r1_3, state3); + r1_3 = Add64(r1_3, CTRS[0]); + + r2_0 = vaddq_u32(r2_0, state0); + r2_1 = vaddq_u32(r2_1, state1); + r2_2 = vaddq_u32(r2_2, state2); + r2_3 = vaddq_u32(r2_3, state3); + r2_3 = Add64(r2_3, CTRS[1]); + + r3_0 = vaddq_u32(r3_0, state0); + r3_1 = vaddq_u32(r3_1, state1); + r3_2 = vaddq_u32(r3_2, state2); + r3_3 = vaddq_u32(r3_3, state3); + r3_3 = Add64(r3_3, CTRS[2]); + + if (input) + { + r0_0 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 0*16)), r0_0); + r0_1 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 1*16)), r0_1); + r0_2 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 2*16)), r0_2); + r0_3 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 3*16)), r0_3); + } + + vst1q_u8(output + 0*16, vreinterpretq_u8_u32(r0_0)); + vst1q_u8(output + 1*16, vreinterpretq_u8_u32(r0_1)); + vst1q_u8(output + 2*16, vreinterpretq_u8_u32(r0_2)); + vst1q_u8(output + 3*16, vreinterpretq_u8_u32(r0_3)); + + if (input) + { + r1_0 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 4*16)), r1_0); + r1_1 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 5*16)), r1_1); + r1_2 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 6*16)), r1_2); + r1_3 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 7*16)), r1_3); + } + + vst1q_u8(output + 4*16, vreinterpretq_u8_u32(r1_0)); + vst1q_u8(output + 5*16, vreinterpretq_u8_u32(r1_1)); + vst1q_u8(output + 6*16, vreinterpretq_u8_u32(r1_2)); + vst1q_u8(output + 7*16, vreinterpretq_u8_u32(r1_3)); + + if (input) + { + r2_0 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 8*16)), r2_0); + r2_1 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 9*16)), r2_1); + r2_2 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 10*16)), r2_2); + r2_3 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 11*16)), r2_3); + } + + vst1q_u8(output + 8*16, vreinterpretq_u8_u32(r2_0)); + vst1q_u8(output + 9*16, vreinterpretq_u8_u32(r2_1)); + vst1q_u8(output + 10*16, vreinterpretq_u8_u32(r2_2)); + vst1q_u8(output + 11*16, vreinterpretq_u8_u32(r2_3)); + + if (input) + { + r3_0 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 12*16)), r3_0); + r3_1 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 13*16)), r3_1); + r3_2 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 14*16)), r3_2); + r3_3 = veorq_u32(vreinterpretq_u32_u8(vld1q_u8(input + 15*16)), r3_3); + } + + vst1q_u8(output + 12*16, vreinterpretq_u8_u32(r3_0)); + vst1q_u8(output + 13*16, vreinterpretq_u8_u32(r3_1)); + vst1q_u8(output + 14*16, vreinterpretq_u8_u32(r3_2)); + vst1q_u8(output + 15*16, vreinterpretq_u8_u32(r3_3)); +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// ***************************** SSE2 ***************************** // + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) + +void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds) +{ + const __m128i state0 = _mm_load_si128(reinterpret_cast(state+0*4)); + const __m128i state1 = _mm_load_si128(reinterpret_cast(state+1*4)); + const __m128i state2 = _mm_load_si128(reinterpret_cast(state+2*4)); + const __m128i state3 = _mm_load_si128(reinterpret_cast(state+3*4)); + + __m128i r0_0 = state0; + __m128i r0_1 = state1; + __m128i r0_2 = state2; + __m128i r0_3 = state3; + + __m128i r1_0 = state0; + __m128i r1_1 = state1; + __m128i r1_2 = state2; + __m128i r1_3 = _mm_add_epi64(r0_3, _mm_set_epi32(0, 0, 0, 1)); + + __m128i r2_0 = state0; + __m128i r2_1 = state1; + __m128i r2_2 = state2; + __m128i r2_3 = _mm_add_epi64(r0_3, _mm_set_epi32(0, 0, 0, 2)); + + __m128i r3_0 = state0; + __m128i r3_1 = state1; + __m128i r3_2 = state2; + __m128i r3_3 = _mm_add_epi64(r0_3, _mm_set_epi32(0, 0, 0, 3)); + + for (int i = static_cast(rounds); i > 0; i -= 2) + { + r0_0 = _mm_add_epi32(r0_0, r0_1); + r1_0 = _mm_add_epi32(r1_0, r1_1); + r2_0 = _mm_add_epi32(r2_0, r2_1); + r3_0 = _mm_add_epi32(r3_0, r3_1); + + r0_3 = _mm_xor_si128(r0_3, r0_0); + r1_3 = _mm_xor_si128(r1_3, r1_0); + r2_3 = _mm_xor_si128(r2_3, r2_0); + r3_3 = _mm_xor_si128(r3_3, r3_0); + + r0_3 = RotateLeft<16>(r0_3); + r1_3 = RotateLeft<16>(r1_3); + r2_3 = RotateLeft<16>(r2_3); + r3_3 = RotateLeft<16>(r3_3); + + r0_2 = _mm_add_epi32(r0_2, r0_3); + r1_2 = _mm_add_epi32(r1_2, r1_3); + r2_2 = _mm_add_epi32(r2_2, r2_3); + r3_2 = _mm_add_epi32(r3_2, r3_3); + + r0_1 = _mm_xor_si128(r0_1, r0_2); + r1_1 = _mm_xor_si128(r1_1, r1_2); + r2_1 = _mm_xor_si128(r2_1, r2_2); + r3_1 = _mm_xor_si128(r3_1, r3_2); + + r0_1 = RotateLeft<12>(r0_1); + r1_1 = RotateLeft<12>(r1_1); + r2_1 = RotateLeft<12>(r2_1); + r3_1 = RotateLeft<12>(r3_1); + + r0_0 = _mm_add_epi32(r0_0, r0_1); + r1_0 = _mm_add_epi32(r1_0, r1_1); + r2_0 = _mm_add_epi32(r2_0, r2_1); + r3_0 = _mm_add_epi32(r3_0, r3_1); + + r0_3 = _mm_xor_si128(r0_3, r0_0); + r1_3 = _mm_xor_si128(r1_3, r1_0); + r2_3 = _mm_xor_si128(r2_3, r2_0); + r3_3 = _mm_xor_si128(r3_3, r3_0); + + r0_3 = RotateLeft<8>(r0_3); + r1_3 = RotateLeft<8>(r1_3); + r2_3 = RotateLeft<8>(r2_3); + r3_3 = RotateLeft<8>(r3_3); + + r0_2 = _mm_add_epi32(r0_2, r0_3); + r1_2 = _mm_add_epi32(r1_2, r1_3); + r2_2 = _mm_add_epi32(r2_2, r2_3); + r3_2 = _mm_add_epi32(r3_2, r3_3); + + r0_1 = _mm_xor_si128(r0_1, r0_2); + r1_1 = _mm_xor_si128(r1_1, r1_2); + r2_1 = _mm_xor_si128(r2_1, r2_2); + r3_1 = _mm_xor_si128(r3_1, r3_2); + + r0_1 = RotateLeft<7>(r0_1); + r1_1 = RotateLeft<7>(r1_1); + r2_1 = RotateLeft<7>(r2_1); + r3_1 = RotateLeft<7>(r3_1); + + r0_1 = _mm_shuffle_epi32(r0_1, _MM_SHUFFLE(0, 3, 2, 1)); + r0_2 = _mm_shuffle_epi32(r0_2, _MM_SHUFFLE(1, 0, 3, 2)); + r0_3 = _mm_shuffle_epi32(r0_3, _MM_SHUFFLE(2, 1, 0, 3)); + + r1_1 = _mm_shuffle_epi32(r1_1, _MM_SHUFFLE(0, 3, 2, 1)); + r1_2 = _mm_shuffle_epi32(r1_2, _MM_SHUFFLE(1, 0, 3, 2)); + r1_3 = _mm_shuffle_epi32(r1_3, _MM_SHUFFLE(2, 1, 0, 3)); + + r2_1 = _mm_shuffle_epi32(r2_1, _MM_SHUFFLE(0, 3, 2, 1)); + r2_2 = _mm_shuffle_epi32(r2_2, _MM_SHUFFLE(1, 0, 3, 2)); + r2_3 = _mm_shuffle_epi32(r2_3, _MM_SHUFFLE(2, 1, 0, 3)); + + r3_1 = _mm_shuffle_epi32(r3_1, _MM_SHUFFLE(0, 3, 2, 1)); + r3_2 = _mm_shuffle_epi32(r3_2, _MM_SHUFFLE(1, 0, 3, 2)); + r3_3 = _mm_shuffle_epi32(r3_3, _MM_SHUFFLE(2, 1, 0, 3)); + + r0_0 = _mm_add_epi32(r0_0, r0_1); + r1_0 = _mm_add_epi32(r1_0, r1_1); + r2_0 = _mm_add_epi32(r2_0, r2_1); + r3_0 = _mm_add_epi32(r3_0, r3_1); + + r0_3 = _mm_xor_si128(r0_3, r0_0); + r1_3 = _mm_xor_si128(r1_3, r1_0); + r2_3 = _mm_xor_si128(r2_3, r2_0); + r3_3 = _mm_xor_si128(r3_3, r3_0); + + r0_3 = RotateLeft<16>(r0_3); + r1_3 = RotateLeft<16>(r1_3); + r2_3 = RotateLeft<16>(r2_3); + r3_3 = RotateLeft<16>(r3_3); + + r0_2 = _mm_add_epi32(r0_2, r0_3); + r1_2 = _mm_add_epi32(r1_2, r1_3); + r2_2 = _mm_add_epi32(r2_2, r2_3); + r3_2 = _mm_add_epi32(r3_2, r3_3); + + r0_1 = _mm_xor_si128(r0_1, r0_2); + r1_1 = _mm_xor_si128(r1_1, r1_2); + r2_1 = _mm_xor_si128(r2_1, r2_2); + r3_1 = _mm_xor_si128(r3_1, r3_2); + + r0_1 = RotateLeft<12>(r0_1); + r1_1 = RotateLeft<12>(r1_1); + r2_1 = RotateLeft<12>(r2_1); + r3_1 = RotateLeft<12>(r3_1); + + r0_0 = _mm_add_epi32(r0_0, r0_1); + r1_0 = _mm_add_epi32(r1_0, r1_1); + r2_0 = _mm_add_epi32(r2_0, r2_1); + r3_0 = _mm_add_epi32(r3_0, r3_1); + + r0_3 = _mm_xor_si128(r0_3, r0_0); + r1_3 = _mm_xor_si128(r1_3, r1_0); + r2_3 = _mm_xor_si128(r2_3, r2_0); + r3_3 = _mm_xor_si128(r3_3, r3_0); + + r0_3 = RotateLeft<8>(r0_3); + r1_3 = RotateLeft<8>(r1_3); + r2_3 = RotateLeft<8>(r2_3); + r3_3 = RotateLeft<8>(r3_3); + + r0_2 = _mm_add_epi32(r0_2, r0_3); + r1_2 = _mm_add_epi32(r1_2, r1_3); + r2_2 = _mm_add_epi32(r2_2, r2_3); + r3_2 = _mm_add_epi32(r3_2, r3_3); + + r0_1 = _mm_xor_si128(r0_1, r0_2); + r1_1 = _mm_xor_si128(r1_1, r1_2); + r2_1 = _mm_xor_si128(r2_1, r2_2); + r3_1 = _mm_xor_si128(r3_1, r3_2); + + r0_1 = RotateLeft<7>(r0_1); + r1_1 = RotateLeft<7>(r1_1); + r2_1 = RotateLeft<7>(r2_1); + r3_1 = RotateLeft<7>(r3_1); + + r0_1 = _mm_shuffle_epi32(r0_1, _MM_SHUFFLE(2, 1, 0, 3)); + r0_2 = _mm_shuffle_epi32(r0_2, _MM_SHUFFLE(1, 0, 3, 2)); + r0_3 = _mm_shuffle_epi32(r0_3, _MM_SHUFFLE(0, 3, 2, 1)); + + r1_1 = _mm_shuffle_epi32(r1_1, _MM_SHUFFLE(2, 1, 0, 3)); + r1_2 = _mm_shuffle_epi32(r1_2, _MM_SHUFFLE(1, 0, 3, 2)); + r1_3 = _mm_shuffle_epi32(r1_3, _MM_SHUFFLE(0, 3, 2, 1)); + + r2_1 = _mm_shuffle_epi32(r2_1, _MM_SHUFFLE(2, 1, 0, 3)); + r2_2 = _mm_shuffle_epi32(r2_2, _MM_SHUFFLE(1, 0, 3, 2)); + r2_3 = _mm_shuffle_epi32(r2_3, _MM_SHUFFLE(0, 3, 2, 1)); + + r3_1 = _mm_shuffle_epi32(r3_1, _MM_SHUFFLE(2, 1, 0, 3)); + r3_2 = _mm_shuffle_epi32(r3_2, _MM_SHUFFLE(1, 0, 3, 2)); + r3_3 = _mm_shuffle_epi32(r3_3, _MM_SHUFFLE(0, 3, 2, 1)); + } + + r0_0 = _mm_add_epi32(r0_0, state0); + r0_1 = _mm_add_epi32(r0_1, state1); + r0_2 = _mm_add_epi32(r0_2, state2); + r0_3 = _mm_add_epi32(r0_3, state3); + + r1_0 = _mm_add_epi32(r1_0, state0); + r1_1 = _mm_add_epi32(r1_1, state1); + r1_2 = _mm_add_epi32(r1_2, state2); + r1_3 = _mm_add_epi32(r1_3, state3); + r1_3 = _mm_add_epi64(r1_3, _mm_set_epi32(0, 0, 0, 1)); + + r2_0 = _mm_add_epi32(r2_0, state0); + r2_1 = _mm_add_epi32(r2_1, state1); + r2_2 = _mm_add_epi32(r2_2, state2); + r2_3 = _mm_add_epi32(r2_3, state3); + r2_3 = _mm_add_epi64(r2_3, _mm_set_epi32(0, 0, 0, 2)); + + r3_0 = _mm_add_epi32(r3_0, state0); + r3_1 = _mm_add_epi32(r3_1, state1); + r3_2 = _mm_add_epi32(r3_2, state2); + r3_3 = _mm_add_epi32(r3_3, state3); + r3_3 = _mm_add_epi64(r3_3, _mm_set_epi32(0, 0, 0, 3)); + + if (input) + { + r0_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+0*16)), r0_0); + r0_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+1*16)), r0_1); + r0_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+2*16)), r0_2); + r0_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+3*16)), r0_3); + } + + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+0*16), r0_0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+1*16), r0_1); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+2*16), r0_2); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+3*16), r0_3); + + if (input) + { + r1_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+4*16)), r1_0); + r1_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+5*16)), r1_1); + r1_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+6*16)), r1_2); + r1_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+7*16)), r1_3); + } + + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+4*16), r1_0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+5*16), r1_1); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+6*16), r1_2); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+7*16), r1_3); + + if (input) + { + r2_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+ 8*16)), r2_0); + r2_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+ 9*16)), r2_1); + r2_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+10*16)), r2_2); + r2_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+11*16)), r2_3); + } + + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+ 8*16), r2_0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+ 9*16), r2_1); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+10*16), r2_2); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+11*16), r2_3); + + if (input) + { + r3_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+12*16)), r3_0); + r3_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+13*16)), r3_1); + r3_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+14*16)), r3_2); + r3_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(input+15*16)), r3_3); + } + + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+12*16), r3_0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+13*16), r3_1); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+14*16), r3_2); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output+15*16), r3_3); +} + +#endif // CRYPTOPP_SSE2_INTRIN_AVAILABLE + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + +// ChaCha_OperateKeystream_CORE will use either POWER7 or ALTIVEC, +// depending on the flags used to compile this source file. The +// abstractions are handled in VecLoad, VecStore and friends. In +// the future we may to provide both POWER7 or ALTIVEC at the same +// time to better support distros. +inline void ChaCha_OperateKeystream_CORE(const word32 *state, const byte* input, byte *output, unsigned int rounds) +{ + const uint32x4_p state0 = VecLoadAligned(state + 0*4); + const uint32x4_p state1 = VecLoadAligned(state + 1*4); + const uint32x4_p state2 = VecLoadAligned(state + 2*4); + const uint32x4_p state3 = VecLoadAligned(state + 3*4); + + const uint32x4_p CTRS[3] = { + {1,0,0,0}, {2,0,0,0}, {3,0,0,0} + }; + + uint32x4_p r0_0 = state0; + uint32x4_p r0_1 = state1; + uint32x4_p r0_2 = state2; + uint32x4_p r0_3 = state3; + + uint32x4_p r1_0 = state0; + uint32x4_p r1_1 = state1; + uint32x4_p r1_2 = state2; + uint32x4_p r1_3 = VecAdd64(r0_3, CTRS[0]); + + uint32x4_p r2_0 = state0; + uint32x4_p r2_1 = state1; + uint32x4_p r2_2 = state2; + uint32x4_p r2_3 = VecAdd64(r0_3, CTRS[1]); + + uint32x4_p r3_0 = state0; + uint32x4_p r3_1 = state1; + uint32x4_p r3_2 = state2; + uint32x4_p r3_3 = VecAdd64(r0_3, CTRS[2]); + + for (int i = static_cast(rounds); i > 0; i -= 2) + { + r0_0 = VecAdd(r0_0, r0_1); + r1_0 = VecAdd(r1_0, r1_1); + r2_0 = VecAdd(r2_0, r2_1); + r3_0 = VecAdd(r3_0, r3_1); + + r0_3 = VecXor(r0_3, r0_0); + r1_3 = VecXor(r1_3, r1_0); + r2_3 = VecXor(r2_3, r2_0); + r3_3 = VecXor(r3_3, r3_0); + + r0_3 = VecRotateLeft<16>(r0_3); + r1_3 = VecRotateLeft<16>(r1_3); + r2_3 = VecRotateLeft<16>(r2_3); + r3_3 = VecRotateLeft<16>(r3_3); + + r0_2 = VecAdd(r0_2, r0_3); + r1_2 = VecAdd(r1_2, r1_3); + r2_2 = VecAdd(r2_2, r2_3); + r3_2 = VecAdd(r3_2, r3_3); + + r0_1 = VecXor(r0_1, r0_2); + r1_1 = VecXor(r1_1, r1_2); + r2_1 = VecXor(r2_1, r2_2); + r3_1 = VecXor(r3_1, r3_2); + + r0_1 = VecRotateLeft<12>(r0_1); + r1_1 = VecRotateLeft<12>(r1_1); + r2_1 = VecRotateLeft<12>(r2_1); + r3_1 = VecRotateLeft<12>(r3_1); + + r0_0 = VecAdd(r0_0, r0_1); + r1_0 = VecAdd(r1_0, r1_1); + r2_0 = VecAdd(r2_0, r2_1); + r3_0 = VecAdd(r3_0, r3_1); + + r0_3 = VecXor(r0_3, r0_0); + r1_3 = VecXor(r1_3, r1_0); + r2_3 = VecXor(r2_3, r2_0); + r3_3 = VecXor(r3_3, r3_0); + + r0_3 = VecRotateLeft<8>(r0_3); + r1_3 = VecRotateLeft<8>(r1_3); + r2_3 = VecRotateLeft<8>(r2_3); + r3_3 = VecRotateLeft<8>(r3_3); + + r0_2 = VecAdd(r0_2, r0_3); + r1_2 = VecAdd(r1_2, r1_3); + r2_2 = VecAdd(r2_2, r2_3); + r3_2 = VecAdd(r3_2, r3_3); + + r0_1 = VecXor(r0_1, r0_2); + r1_1 = VecXor(r1_1, r1_2); + r2_1 = VecXor(r2_1, r2_2); + r3_1 = VecXor(r3_1, r3_2); + + r0_1 = VecRotateLeft<7>(r0_1); + r1_1 = VecRotateLeft<7>(r1_1); + r2_1 = VecRotateLeft<7>(r2_1); + r3_1 = VecRotateLeft<7>(r3_1); + + r0_1 = Shuffle<1>(r0_1); + r0_2 = Shuffle<2>(r0_2); + r0_3 = Shuffle<3>(r0_3); + + r1_1 = Shuffle<1>(r1_1); + r1_2 = Shuffle<2>(r1_2); + r1_3 = Shuffle<3>(r1_3); + + r2_1 = Shuffle<1>(r2_1); + r2_2 = Shuffle<2>(r2_2); + r2_3 = Shuffle<3>(r2_3); + + r3_1 = Shuffle<1>(r3_1); + r3_2 = Shuffle<2>(r3_2); + r3_3 = Shuffle<3>(r3_3); + + r0_0 = VecAdd(r0_0, r0_1); + r1_0 = VecAdd(r1_0, r1_1); + r2_0 = VecAdd(r2_0, r2_1); + r3_0 = VecAdd(r3_0, r3_1); + + r0_3 = VecXor(r0_3, r0_0); + r1_3 = VecXor(r1_3, r1_0); + r2_3 = VecXor(r2_3, r2_0); + r3_3 = VecXor(r3_3, r3_0); + + r0_3 = VecRotateLeft<16>(r0_3); + r1_3 = VecRotateLeft<16>(r1_3); + r2_3 = VecRotateLeft<16>(r2_3); + r3_3 = VecRotateLeft<16>(r3_3); + + r0_2 = VecAdd(r0_2, r0_3); + r1_2 = VecAdd(r1_2, r1_3); + r2_2 = VecAdd(r2_2, r2_3); + r3_2 = VecAdd(r3_2, r3_3); + + r0_1 = VecXor(r0_1, r0_2); + r1_1 = VecXor(r1_1, r1_2); + r2_1 = VecXor(r2_1, r2_2); + r3_1 = VecXor(r3_1, r3_2); + + r0_1 = VecRotateLeft<12>(r0_1); + r1_1 = VecRotateLeft<12>(r1_1); + r2_1 = VecRotateLeft<12>(r2_1); + r3_1 = VecRotateLeft<12>(r3_1); + + r0_0 = VecAdd(r0_0, r0_1); + r1_0 = VecAdd(r1_0, r1_1); + r2_0 = VecAdd(r2_0, r2_1); + r3_0 = VecAdd(r3_0, r3_1); + + r0_3 = VecXor(r0_3, r0_0); + r1_3 = VecXor(r1_3, r1_0); + r2_3 = VecXor(r2_3, r2_0); + r3_3 = VecXor(r3_3, r3_0); + + r0_3 = VecRotateLeft<8>(r0_3); + r1_3 = VecRotateLeft<8>(r1_3); + r2_3 = VecRotateLeft<8>(r2_3); + r3_3 = VecRotateLeft<8>(r3_3); + + r0_2 = VecAdd(r0_2, r0_3); + r1_2 = VecAdd(r1_2, r1_3); + r2_2 = VecAdd(r2_2, r2_3); + r3_2 = VecAdd(r3_2, r3_3); + + r0_1 = VecXor(r0_1, r0_2); + r1_1 = VecXor(r1_1, r1_2); + r2_1 = VecXor(r2_1, r2_2); + r3_1 = VecXor(r3_1, r3_2); + + r0_1 = VecRotateLeft<7>(r0_1); + r1_1 = VecRotateLeft<7>(r1_1); + r2_1 = VecRotateLeft<7>(r2_1); + r3_1 = VecRotateLeft<7>(r3_1); + + r0_1 = Shuffle<3>(r0_1); + r0_2 = Shuffle<2>(r0_2); + r0_3 = Shuffle<1>(r0_3); + + r1_1 = Shuffle<3>(r1_1); + r1_2 = Shuffle<2>(r1_2); + r1_3 = Shuffle<1>(r1_3); + + r2_1 = Shuffle<3>(r2_1); + r2_2 = Shuffle<2>(r2_2); + r2_3 = Shuffle<1>(r2_3); + + r3_1 = Shuffle<3>(r3_1); + r3_2 = Shuffle<2>(r3_2); + r3_3 = Shuffle<1>(r3_3); + } + + r0_0 = VecAdd(r0_0, state0); + r0_1 = VecAdd(r0_1, state1); + r0_2 = VecAdd(r0_2, state2); + r0_3 = VecAdd(r0_3, state3); + + r1_0 = VecAdd(r1_0, state0); + r1_1 = VecAdd(r1_1, state1); + r1_2 = VecAdd(r1_2, state2); + r1_3 = VecAdd(r1_3, state3); + r1_3 = VecAdd64(r1_3, CTRS[0]); + + r2_0 = VecAdd(r2_0, state0); + r2_1 = VecAdd(r2_1, state1); + r2_2 = VecAdd(r2_2, state2); + r2_3 = VecAdd(r2_3, state3); + r2_3 = VecAdd64(r2_3, CTRS[1]); + + r3_0 = VecAdd(r3_0, state0); + r3_1 = VecAdd(r3_1, state1); + r3_2 = VecAdd(r3_2, state2); + r3_3 = VecAdd(r3_3, state3); + r3_3 = VecAdd64(r3_3, CTRS[2]); + + if (input) + { + r0_0 = VecXor(VecLoad32LE(input + 0*16), r0_0); + r0_1 = VecXor(VecLoad32LE(input + 1*16), r0_1); + r0_2 = VecXor(VecLoad32LE(input + 2*16), r0_2); + r0_3 = VecXor(VecLoad32LE(input + 3*16), r0_3); + } + + VecStore32LE(output + 0*16, r0_0); + VecStore32LE(output + 1*16, r0_1); + VecStore32LE(output + 2*16, r0_2); + VecStore32LE(output + 3*16, r0_3); + + if (input) + { + r1_0 = VecXor(VecLoad32LE(input + 4*16), r1_0); + r1_1 = VecXor(VecLoad32LE(input + 5*16), r1_1); + r1_2 = VecXor(VecLoad32LE(input + 6*16), r1_2); + r1_3 = VecXor(VecLoad32LE(input + 7*16), r1_3); + } + + VecStore32LE(output + 4*16, r1_0); + VecStore32LE(output + 5*16, r1_1); + VecStore32LE(output + 6*16, r1_2); + VecStore32LE(output + 7*16, r1_3); + + if (input) + { + r2_0 = VecXor(VecLoad32LE(input + 8*16), r2_0); + r2_1 = VecXor(VecLoad32LE(input + 9*16), r2_1); + r2_2 = VecXor(VecLoad32LE(input + 10*16), r2_2); + r2_3 = VecXor(VecLoad32LE(input + 11*16), r2_3); + } + + VecStore32LE(output + 8*16, r2_0); + VecStore32LE(output + 9*16, r2_1); + VecStore32LE(output + 10*16, r2_2); + VecStore32LE(output + 11*16, r2_3); + + if (input) + { + r3_0 = VecXor(VecLoad32LE(input + 12*16), r3_0); + r3_1 = VecXor(VecLoad32LE(input + 13*16), r3_1); + r3_2 = VecXor(VecLoad32LE(input + 14*16), r3_2); + r3_3 = VecXor(VecLoad32LE(input + 15*16), r3_3); + } + + VecStore32LE(output + 12*16, r3_0); + VecStore32LE(output + 13*16, r3_1); + VecStore32LE(output + 14*16, r3_2); + VecStore32LE(output + 15*16, r3_3); +} + +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + +void ChaCha_OperateKeystream_ALTIVEC(const word32 *state, const byte* input, byte *output, unsigned int rounds) +{ + ChaCha_OperateKeystream_CORE(state, input, output, rounds); +} + +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/chachapoly.cpp b/external/ours/library/crypto/src/shared/original/chachapoly.cpp new file mode 100755 index 000000000..934740605 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/chachapoly.cpp @@ -0,0 +1,211 @@ +// chachapoly.cpp - written and placed in the public domain by Jeffrey Walton +// RFC 8439, Section 2.8, AEAD Construction, http://tools.ietf.org/html/rfc8439 + +#include "pch.h" +#include "chachapoly.h" +#include "algparam.h" +#include "misc.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4244) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +////////////////////////////// IETF ChaChaTLS ////////////////////////////// + +// RekeyCipherAndMac is heavier-weight than we like. The Authenc framework was +// predicated on BlockCiphers, where the key and key schedule could be +// calculated independent of the IV being used. However, the ChaCha and +// ChaCha20Poly1305 construction combines key setup and IV. That is, both are +// needed to key or rekey the cipher. Even a simple Resync() requires us to +// regenerate the initial state for both ChaCha20 and Poly1305. +void ChaCha20Poly1305_Base::RekeyCipherAndMac(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) +{ + // Derive MAC key + AlgorithmParameters block0 = MakeParameters("InitialBlock", (word64)0, true); + AccessSymmetricCipher().SetKey(userKey, keylength, CombinedNameValuePairs(params, block0)); + + // Only the first 256-bits are used to key the MAC + SecByteBlock derived(NULLPTR, 32); + AccessSymmetricCipher().ProcessString(derived, derived.size()); + + // Key the Poly1305 MAC + AccessMAC().SetKey(derived, derived.size(), params); + + // Key the ChaCha20 cipher + AlgorithmParameters block1 = MakeParameters("InitialBlock", (word64)1, true); + AccessSymmetricCipher().SetKey(userKey, keylength, CombinedNameValuePairs(params, block1)); +} + +void ChaCha20Poly1305_Base::SetKeyWithoutResync(const byte *userKey, size_t userKeyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(userKey && userKeyLength == 32); + m_userKey.Assign(userKey, userKeyLength); + + // ChaCha/Poly1305 initial state depends on both the key and IV. The + // IV may or may not be present during the call to SetKeyWithoutResync. + // If the IV is present, the framework will call SetKeyWithoutResync + // followed by Resynchronize which calls Resync. In this case we defer + // calculating the initial state until the call to Resynchronize. + // If the IV is not present, it avoids calling ChaCha's SetKey without + // an IV, which results in an exception. In this case the user will need + // to call Resynchronize to key ChaCha and Poly1305. + // RekeyCipherAndMac(userKey, userKeyLength, params); + CRYPTOPP_UNUSED(params); +} + +void ChaCha20Poly1305_Base::Resync(const byte *iv, size_t len) +{ + CRYPTOPP_ASSERT(iv && len == 12); + RekeyCipherAndMac(m_userKey, m_userKey.SizeInBytes(), + MakeParameters(Name::IV(), ConstByteArrayParameter(iv,len))); +} + +size_t ChaCha20Poly1305_Base::AuthenticateBlocks(const byte *data, size_t len) +{ + AccessMAC().Update(data, len); + return 0; +} + +void ChaCha20Poly1305_Base::AuthenticateLastHeaderBlock() +{ + // Pad to a multiple of 16 or 0 + const byte zero[16] = {0}; + size_t pad = (16U - (m_totalHeaderLength % 16)) % 16; + AccessMAC().Update(zero, pad); +} + +void ChaCha20Poly1305_Base::AuthenticateLastConfidentialBlock() +{ + // Pad to a multiple of 16 or 0 + const byte zero[16] = {0}; + size_t pad = (16U - (m_totalMessageLength % 16)) % 16; + AccessMAC().Update(zero, pad); +} + +void ChaCha20Poly1305_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize) +{ + CRYPTOPP_ALIGN_DATA(8) byte length[2*sizeof(word64)]; + PutWord(true, LITTLE_ENDIAN_ORDER, length+0, m_totalHeaderLength); + PutWord(true, LITTLE_ENDIAN_ORDER, length+8, m_totalMessageLength); + AccessMAC().Update(length, sizeof(length)); + AccessMAC().TruncatedFinal(mac, macSize); + m_state = State_KeySet; +} + +void ChaCha20Poly1305_Base::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength) +{ + Resynchronize(iv, ivLength); + Update(aad, aadLength); + ProcessString(ciphertext, message, messageLength); + TruncatedFinal(mac, macSize); +} + +bool ChaCha20Poly1305_Base::DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *ciphertext, size_t ciphertextLength) +{ + Resynchronize(iv, ivLength); + Update(aad, aadLength); + ProcessString(message, ciphertext, ciphertextLength); + return TruncatedVerify(mac, macLength); +} + +////////////////////////////// IETF XChaCha20 draft ////////////////////////////// + +// RekeyCipherAndMac is heavier-weight than we like. The Authenc framework was +// predicated on BlockCiphers, where the key and key schedule could be +// calculated independent of the IV being used. However, the ChaCha and +// ChaCha20Poly1305 construction combines key setup and IV. That is, both are +// needed to key or rekey the cipher. Even a simple Resync() requires us to +// regenerate the initial state for both ChaCha20 and Poly1305. +void XChaCha20Poly1305_Base::RekeyCipherAndMac(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) +{ + // Derive MAC key + AlgorithmParameters block0 = MakeParameters("InitialBlock", (word64)0, true); + AccessSymmetricCipher().SetKey(userKey, keylength, CombinedNameValuePairs(params, block0)); + + // Only the first 256-bits are used to key the MAC + SecByteBlock derived(NULLPTR, 32); + AccessSymmetricCipher().ProcessString(derived, derived.size()); + + // Key the Poly1305 MAC + AccessMAC().SetKey(derived, derived.size(), params); + + // Key the ChaCha20 cipher + AlgorithmParameters block1 = MakeParameters("InitialBlock", (word64)1, true); + AccessSymmetricCipher().SetKey(userKey, keylength, CombinedNameValuePairs(params, block1)); +} + +void XChaCha20Poly1305_Base::SetKeyWithoutResync(const byte *userKey, size_t userKeyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(userKey && userKeyLength == 32); + m_userKey.Assign(userKey, userKeyLength); + + // XChaCha20/Poly1305 initial state depends on both the key and IV. The + // IV may or may not be present during the call to SetKeyWithoutResync. + // If the IV is present, the framework will call SetKeyWithoutResync + // followed by Resynchronize which calls Resync. In this case we defer + // calculating the initial state until the call to Resynchronize. + // If the IV is not present, it avoids calling ChaCha's SetKey without + // an IV, which results in an exception. In this case the user will need + // to call Resynchronize to key ChaCha and Poly1305. + // RekeyCipherAndMac(userKey, userKeyLength, params); + CRYPTOPP_UNUSED(params); +} + +void XChaCha20Poly1305_Base::Resync(const byte *iv, size_t len) +{ + CRYPTOPP_ASSERT(iv && len == 24); + RekeyCipherAndMac(m_userKey, m_userKey.SizeInBytes(), + MakeParameters(Name::IV(), ConstByteArrayParameter(iv,len))); +} + +size_t XChaCha20Poly1305_Base::AuthenticateBlocks(const byte *data, size_t len) +{ + AccessMAC().Update(data, len); + return 0; +} + +void XChaCha20Poly1305_Base::AuthenticateLastHeaderBlock() +{ + // Pad to a multiple of 16 or 0 + const byte zero[16] = {0}; + size_t pad = (16 - (m_totalHeaderLength % 16)) % 16; + AccessMAC().Update(zero, pad); +} + +void XChaCha20Poly1305_Base::AuthenticateLastConfidentialBlock() +{ + // Pad to a multiple of 16 or 0 + const byte zero[16] = {0}; + size_t pad = (16 - (m_totalMessageLength % 16)) % 16; + AccessMAC().Update(zero, pad); +} + +void XChaCha20Poly1305_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize) +{ + CRYPTOPP_ALIGN_DATA(8) byte length[2*sizeof(word64)]; + PutWord(true, LITTLE_ENDIAN_ORDER, length+0, m_totalHeaderLength); + PutWord(true, LITTLE_ENDIAN_ORDER, length+8, m_totalMessageLength); + AccessMAC().Update(length, sizeof(length)); + AccessMAC().TruncatedFinal(mac, macSize); + m_state = State_KeySet; +} + +void XChaCha20Poly1305_Base::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength) +{ + Resynchronize(iv, ivLength); + Update(aad, aadLength); + ProcessString(ciphertext, message, messageLength); + TruncatedFinal(mac, macSize); +} + +bool XChaCha20Poly1305_Base::DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *ciphertext, size_t ciphertextLength) +{ + Resynchronize(iv, ivLength); + Update(aad, aadLength); + ProcessString(message, ciphertext, ciphertextLength); + return TruncatedVerify(mac, macLength); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/chachapoly.h b/external/ours/library/crypto/src/shared/original/chachapoly.h new file mode 100755 index 000000000..e480456db --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/chachapoly.h @@ -0,0 +1,322 @@ +// chachapoly.h - written and placed in the public domain by Jeffrey Walton +// RFC 8439, Section 2.8, AEAD Construction, http://tools.ietf.org/html/rfc8439 + +/// \file chachapoly.h +/// \brief IETF ChaCha20/Poly1305 AEAD scheme +/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines +/// ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8, +/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20 +/// and Poly1305. +/// \sa RFC 8439, ChaCha20 and Poly1305 +/// for IETF Protocols. +/// \since Crypto++ 8.1 + +#ifndef CRYPTOPP_CHACHA_POLY1305_H +#define CRYPTOPP_CHACHA_POLY1305_H + +#include "cryptlib.h" +#include "authenc.h" +#include "chacha.h" +#include "poly1305.h" + +NAMESPACE_BEGIN(CryptoPP) + +////////////////////////////// IETF ChaChaTLS ////////////////////////////// + +/// \brief IETF ChaCha20Poly1305 cipher base implementation +/// \details Base implementation of the AuthenticatedSymmetricCipher interface +/// \since Crypto++ 8.1 +class ChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() + {return "ChaCha20/Poly1305";} + + virtual ~ChaCha20Poly1305_Base() {} + + // AuthenticatedSymmetricCipher + std::string AlgorithmName() const + {return std::string("ChaCha20/Poly1305");} + std::string AlgorithmProvider() const + {return GetSymmetricCipher().AlgorithmProvider();} + size_t MinKeyLength() const + {return 32;} + size_t MaxKeyLength() const + {return 32;} + size_t DefaultKeyLength() const + {return 32;} + size_t GetValidKeyLength(size_t n) const + {CRYPTOPP_UNUSED(n); return 32;} + bool IsValidKeyLength(size_t n) const + {return n==32;} + unsigned int OptimalDataAlignment() const + {return GetSymmetricCipher().OptimalDataAlignment();} + IV_Requirement IVRequirement() const + {return UNIQUE_IV;} + unsigned int IVSize() const + {return 12;} + unsigned int MinIVLength() const + {return 12;} + unsigned int MaxIVLength() const + {return 12;} + unsigned int DigestSize() const + {return 16;} + lword MaxHeaderLength() const + {return LWORD_MAX;} // 2^64-1 bytes + lword MaxMessageLength() const + {return W64LIT(274877906880);} // 2^38-1 blocks + lword MaxFooterLength() const + {return 0;} + + /// \brief Encrypts and calculates a MAC in one call + /// \param ciphertext the encryption buffer + /// \param mac the mac buffer + /// \param macSize the size of the MAC buffer, in bytes + /// \param iv the iv buffer + /// \param ivLength the size of the IV buffer, in bytes + /// \param aad the AAD buffer + /// \param aadLength the size of the AAD buffer, in bytes + /// \param message the message buffer + /// \param messageLength the size of the messagetext buffer, in bytes + /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function + /// truncates the MAC if macSize < TagSize(). + virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength); + + /// \brief Decrypts and verifies a MAC in one call + /// \param message the decryption buffer + /// \param mac the mac buffer + /// \param macSize the size of the MAC buffer, in bytes + /// \param iv the iv buffer + /// \param ivLength the size of the IV buffer, in bytes + /// \param aad the AAD buffer + /// \param aadLength the size of the AAD buffer, in bytes + /// \param ciphertext the cipher buffer + /// \param ciphertextLength the size of the ciphertext buffer, in bytes + /// \return true if the MAC is valid and the decoding succeeded, false otherwise + /// \details DecryptAndVerify() decrypts and verifies the MAC in one call. + /// message is a decryption buffer and should be at least as large as the ciphertext buffer. + /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC + /// is truncated if macLength < TagSize(). + virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *ciphertext, size_t ciphertextLength); + +protected: + // AuthenticatedSymmetricCipherBase + bool AuthenticationIsOnPlaintext() const {return false;} + unsigned int AuthenticationBlockSize() const {return 1;} + void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); + void Resync(const byte *iv, size_t len); + size_t AuthenticateBlocks(const byte *data, size_t len); + void AuthenticateLastHeaderBlock(); + void AuthenticateLastConfidentialBlock(); + void AuthenticateLastFooterBlock(byte *mac, size_t macSize); + + // See comments in chachapoly.cpp + void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs ¶ms); + + virtual const MessageAuthenticationCode & GetMAC() const = 0; + virtual MessageAuthenticationCode & AccessMAC() = 0; + +private: + SecByteBlock m_userKey; +}; + +/// \brief IETF ChaCha20Poly1305 cipher final implementation +/// \tparam T_IsEncryption flag indicating cipher direction +/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines +/// ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8, +/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20 +/// and Poly1305. +/// \sa RFC 8439, ChaCha20 and Poly1305 +/// for IETF Protocols. +/// \since Crypto++ 8.1 +template +class ChaCha20Poly1305_Final : public ChaCha20Poly1305_Base +{ +public: + virtual ~ChaCha20Poly1305_Final() {} + +protected: + const SymmetricCipher & GetSymmetricCipher() + {return const_cast(this)->AccessSymmetricCipher();} + SymmetricCipher & AccessSymmetricCipher() + {return m_cipher;} + bool IsForwardTransformation() const + {return T_IsEncryption;} + + const MessageAuthenticationCode & GetMAC() const + {return const_cast(this)->AccessMAC();} + MessageAuthenticationCode & AccessMAC() + {return m_mac;} + +private: + ChaChaTLS::Encryption m_cipher; + Poly1305TLS m_mac; +}; + +/// \brief IETF ChaCha20/Poly1305 AEAD scheme +/// \details ChaCha20Poly1305 is an authenticated encryption scheme that combines +/// ChaCha20TLS and Poly1305TLS. The scheme is defined in RFC 8439, section 2.8, +/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20 +/// and Poly1305. +/// \sa RFC 8439, ChaCha20 and Poly1305 +/// for IETF Protocols. +/// \since Crypto++ 8.1 +struct ChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation +{ + /// \brief ChaCha20Poly1305 encryption + typedef ChaCha20Poly1305_Final Encryption; + /// \brief ChaCha20Poly1305 decryption + typedef ChaCha20Poly1305_Final Decryption; +}; + +////////////////////////////// IETF XChaCha20 draft ////////////////////////////// + +/// \brief IETF XChaCha20Poly1305 cipher base implementation +/// \details Base implementation of the AuthenticatedSymmetricCipher interface +/// \since Crypto++ 8.1 +class XChaCha20Poly1305_Base : public AuthenticatedSymmetricCipherBase +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() + {return "XChaCha20/Poly1305";} + + virtual ~XChaCha20Poly1305_Base() {} + + // AuthenticatedSymmetricCipher + std::string AlgorithmName() const + {return std::string("XChaCha20/Poly1305");} + std::string AlgorithmProvider() const + {return GetSymmetricCipher().AlgorithmProvider();} + size_t MinKeyLength() const + {return 32;} + size_t MaxKeyLength() const + {return 32;} + size_t DefaultKeyLength() const + {return 32;} + size_t GetValidKeyLength(size_t n) const + {CRYPTOPP_UNUSED(n); return 32;} + bool IsValidKeyLength(size_t n) const + {return n==32;} + unsigned int OptimalDataAlignment() const + {return GetSymmetricCipher().OptimalDataAlignment();} + IV_Requirement IVRequirement() const + {return UNIQUE_IV;} + unsigned int IVSize() const + {return 24;} + unsigned int MinIVLength() const + {return 24;} + unsigned int MaxIVLength() const + {return 24;} + unsigned int DigestSize() const + {return 16;} + lword MaxHeaderLength() const + {return LWORD_MAX;} // 2^64-1 bytes + lword MaxMessageLength() const + {return W64LIT(274877906880);} // 2^38-1 blocks + lword MaxFooterLength() const + {return 0;} + + /// \brief Encrypts and calculates a MAC in one call + /// \param ciphertext the encryption buffer + /// \param mac the mac buffer + /// \param macSize the size of the MAC buffer, in bytes + /// \param iv the iv buffer + /// \param ivLength the size of the IV buffer, in bytes + /// \param aad the AAD buffer + /// \param aadLength the size of the AAD buffer, in bytes + /// \param message the message buffer + /// \param messageLength the size of the messagetext buffer, in bytes + /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function + /// truncates the MAC if macSize < TagSize(). + virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength); + + /// \brief Decrypts and verifies a MAC in one call + /// \param message the decryption buffer + /// \param mac the mac buffer + /// \param macSize the size of the MAC buffer, in bytes + /// \param iv the iv buffer + /// \param ivLength the size of the IV buffer, in bytes + /// \param aad the AAD buffer + /// \param aadLength the size of the AAD buffer, in bytes + /// \param ciphertext the cipher buffer + /// \param ciphertextLength the size of the ciphertext buffer, in bytes + /// \return true if the MAC is valid and the decoding succeeded, false otherwise + /// \details DecryptAndVerify() decrypts and verifies the MAC in one call. + /// message is a decryption buffer and should be at least as large as the ciphertext buffer. + /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC + /// is truncated if macLength < TagSize(). + virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *ciphertext, size_t ciphertextLength); + +protected: + // AuthenticatedSymmetricCipherBase + bool AuthenticationIsOnPlaintext() const {return false;} + unsigned int AuthenticationBlockSize() const {return 1;} + void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); + void Resync(const byte *iv, size_t len); + size_t AuthenticateBlocks(const byte *data, size_t len); + void AuthenticateLastHeaderBlock(); + void AuthenticateLastConfidentialBlock(); + void AuthenticateLastFooterBlock(byte *mac, size_t macSize); + + // See comments in chachapoly.cpp + void RekeyCipherAndMac(const byte *userKey, size_t userKeyLength, const NameValuePairs ¶ms); + + virtual const MessageAuthenticationCode & GetMAC() const = 0; + virtual MessageAuthenticationCode & AccessMAC() = 0; + +private: + SecByteBlock m_userKey; +}; + +/// \brief IETF XChaCha20Poly1305 cipher final implementation +/// \tparam T_IsEncryption flag indicating cipher direction +/// \details XChaCha20Poly1305 is an authenticated encryption scheme that combines +/// XChaCha20 and Poly1305-TLS. The scheme is defined in RFC 8439, section 2.8, +/// AEAD_CHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20 +/// and Poly1305. +/// \sa RFC 8439, ChaCha20 and Poly1305 +/// for IETF Protocols. +/// \since Crypto++ 8.1 +template +class XChaCha20Poly1305_Final : public XChaCha20Poly1305_Base +{ +public: + virtual ~XChaCha20Poly1305_Final() {} + +protected: + const SymmetricCipher & GetSymmetricCipher() + {return const_cast(this)->AccessSymmetricCipher();} + SymmetricCipher & AccessSymmetricCipher() + {return m_cipher;} + bool IsForwardTransformation() const + {return T_IsEncryption;} + + const MessageAuthenticationCode & GetMAC() const + {return const_cast(this)->AccessMAC();} + MessageAuthenticationCode & AccessMAC() + {return m_mac;} + +private: + XChaCha20::Encryption m_cipher; + Poly1305TLS m_mac; +}; + +/// \brief IETF XChaCha20/Poly1305 AEAD scheme +/// \details XChaCha20Poly1305 is an authenticated encryption scheme that combines +/// XChaCha20 and Poly1305-TLS. The scheme is defined in RFC 8439, section 2.8, +/// AEAD_XCHACHA20_POLY1305 construction, and uses the IETF versions of ChaCha20 +/// and Poly1305. +/// \sa RFC 8439, ChaCha20 and Poly1305 +/// for IETF Protocols. +/// \since Crypto++ 8.1 +struct XChaCha20Poly1305 : public AuthenticatedSymmetricCipherDocumentation +{ + /// \brief XChaCha20Poly1305 encryption + typedef XChaCha20Poly1305_Final Encryption; + /// \brief XChaCha20Poly1305 decryption + typedef XChaCha20Poly1305_Final Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_CHACHA_POLY1305_H diff --git a/external/ours/library/crypto/src/shared/original/cham.cpp b/external/ours/library/crypto/src/shared/original/cham.cpp new file mode 100755 index 000000000..6cd5d1c26 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cham.cpp @@ -0,0 +1,365 @@ +// cham.cpp - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "CHAM: A Family of Lightweight Block Ciphers for +// Resource-Constrained Devices" by Bonwook Koo, Dongyoung Roh, +// Hyeonjin Kim, Younghoon Jung, Dong-Geon Lee, and Daesung Kwon + +#include "pch.h" +#include "config.h" + +#include "cham.h" +#include "misc.h" +#include "cpu.h" + +// CHAM table of parameters +// +------------------------------------------------- +// +cipher n k r w k/w +// +------------------------------------------------- +// +CHAM-64/128 64 128 80 16 8 +// +CHAM-128/128 128 128 80 32 4 +// +CHAM-128/256 128 256 96 32 8 +// +------------------------------------------------- + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::rotlConstant; +using CryptoPP::rotrConstant; + +/// \brief CHAM encryption round +/// \tparam RR the round number residue +/// \tparam KW the number of key words +/// \tparam T words type +/// \param x the state array +/// \param k the subkey table +/// \param i the round number +/// \details CHAM_EncRound applies the encryption round to the plain text. +/// RR is the "round residue" and it is used modulo 4. ProcessAndXorBlock +/// may provide a fully unrolled encryption transformation, or provide +/// a transformation that loops using multiples of 4 encryption rounds. +/// \details CHAM_EncRound calculates indexes into the x[] array based +/// on the round number residue. There is no need for the assignments +/// that shift values in preparations for the next round. +/// \details CHAM_EncRound depends on the round number. The actual round +/// being executed is passed through the parameter i. If +/// ProcessAndXorBlock fully unrolled the loop then the parameter +/// i would be unnecessary. +template +inline void CHAM_EncRound(T x[4], const T k[KW], unsigned int i) +{ + CRYPTOPP_CONSTANT(IDX0 = (RR+0) % 4); + CRYPTOPP_CONSTANT(IDX1 = (RR+1) % 4); + CRYPTOPP_CONSTANT(IDX3 = (RR+3+1) % 4); + CRYPTOPP_CONSTANT(R1 = (RR % 2 == 0) ? 1 : 8); + CRYPTOPP_CONSTANT(R2 = (RR % 2 == 0) ? 8 : 1); + + // Follows conventions in the ref impl + const T kk = k[i % KW]; + const T aa = x[IDX0] ^ static_cast(i); + const T bb = rotlConstant(x[IDX1]) ^ kk; + x[IDX3] = rotlConstant(static_cast(aa + bb)); +} + +/// \brief CHAM decryption round +/// \tparam RR the round number residue +/// \tparam KW the number of key words +/// \tparam T words type +/// \param x the state array +/// \param k the subkey table +/// \param i the round number +/// \details CHAM_DecRound applies the decryption round to the cipher text. +/// RR is the "round residue" and it is used modulo 4. ProcessAndXorBlock +/// may provide a fully unrolled decryption transformation, or provide +/// a transformation that loops using multiples of 4 decryption rounds. +/// \details CHAM_DecRound calculates indexes into the x[] array based +/// on the round number residue. There is no need for the assignments +/// that shift values in preparations for the next round. +/// \details CHAM_DecRound depends on the round number. The actual round +/// being executed is passed through the parameter i. If +/// ProcessAndXorBlock fully unrolled the loop then the parameter +/// i would be unnecessary. +template +inline void CHAM_DecRound(T x[4], const T k[KW], unsigned int i) +{ + CRYPTOPP_CONSTANT(IDX0 = (RR+0) % 4); + CRYPTOPP_CONSTANT(IDX1 = (RR+1) % 4); + CRYPTOPP_CONSTANT(IDX3 = (RR+3+1) % 4); + CRYPTOPP_CONSTANT(R1 = (RR % 2 == 0) ? 8 : 1); + CRYPTOPP_CONSTANT(R2 = (RR % 2 == 0) ? 1 : 8); + + // Follows conventions in the ref impl + const T kk = k[i % KW]; + const T aa = rotrConstant(x[IDX3]); + const T bb = rotlConstant(x[IDX1]) ^ kk; + x[IDX0] = static_cast(aa - bb) ^ static_cast(i); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS +# if (CRYPTOPP_SSSE3_AVAILABLE) +extern size_t CHAM64_Enc_AdvancedProcessBlocks_SSSE3(const word16* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t CHAM64_Dec_AdvancedProcessBlocks_SSSE3(const word16* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t CHAM128_Enc_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t CHAM128_Dec_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +# endif // CRYPTOPP_SSSE3_AVAILABLE +#endif // CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS + +void CHAM64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + m_kw = keyLength/sizeof(word16); + m_rk.New(2*m_kw); + + for (size_t i = 0; i < m_kw; userKey += sizeof(word32)) + { + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + const word32 rk = GetWord(false, BIG_ENDIAN_ORDER, userKey); + + const word16 rk1 = static_cast(rk >> 16); + m_rk[i] = rk1 ^ rotlConstant<1>(rk1) ^ rotlConstant<8>(rk1); + m_rk[(i + m_kw) ^ 1] = rk1 ^ rotlConstant<1>(rk1) ^ rotlConstant<11>(rk1); + i++; + + const word16 rk2 = static_cast(rk & 0xffff); + m_rk[i] = rk2 ^ rotlConstant<1>(rk2) ^ rotlConstant<8>(rk2); + m_rk[(i + m_kw) ^ 1] = rk2 ^ rotlConstant<1>(rk2) ^ rotlConstant<11>(rk2); + i++; + } +} + +void CHAM64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); + + const int R = 80; + for (int i = 0; i < R; i+=16) + { + CHAM_EncRound< 0, 16>(m_x.begin(), m_rk.begin(), i+0); + CHAM_EncRound< 1, 16>(m_x.begin(), m_rk.begin(), i+1); + CHAM_EncRound< 2, 16>(m_x.begin(), m_rk.begin(), i+2); + CHAM_EncRound< 3, 16>(m_x.begin(), m_rk.begin(), i+3); + CHAM_EncRound< 4, 16>(m_x.begin(), m_rk.begin(), i+4); + CHAM_EncRound< 5, 16>(m_x.begin(), m_rk.begin(), i+5); + CHAM_EncRound< 6, 16>(m_x.begin(), m_rk.begin(), i+6); + CHAM_EncRound< 7, 16>(m_x.begin(), m_rk.begin(), i+7); + CHAM_EncRound< 8, 16>(m_x.begin(), m_rk.begin(), i+8); + CHAM_EncRound< 9, 16>(m_x.begin(), m_rk.begin(), i+9); + CHAM_EncRound<10, 16>(m_x.begin(), m_rk.begin(), i+10); + CHAM_EncRound<11, 16>(m_x.begin(), m_rk.begin(), i+11); + CHAM_EncRound<12, 16>(m_x.begin(), m_rk.begin(), i+12); + CHAM_EncRound<13, 16>(m_x.begin(), m_rk.begin(), i+13); + CHAM_EncRound<14, 16>(m_x.begin(), m_rk.begin(), i+14); + CHAM_EncRound<15, 16>(m_x.begin(), m_rk.begin(), i+15); + } + + PutBlock oblock(xorBlock, outBlock); + oblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); +} + +void CHAM64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); + + const int R = 80; + for (int i = R-1; i >=0 ; i-=16) + { + CHAM_DecRound<15, 16>(m_x.begin(), m_rk.begin(), i-0); + CHAM_DecRound<14, 16>(m_x.begin(), m_rk.begin(), i-1); + CHAM_DecRound<13, 16>(m_x.begin(), m_rk.begin(), i-2); + CHAM_DecRound<12, 16>(m_x.begin(), m_rk.begin(), i-3); + CHAM_DecRound<11, 16>(m_x.begin(), m_rk.begin(), i-4); + CHAM_DecRound<10, 16>(m_x.begin(), m_rk.begin(), i-5); + CHAM_DecRound< 9, 16>(m_x.begin(), m_rk.begin(), i-6); + CHAM_DecRound< 8, 16>(m_x.begin(), m_rk.begin(), i-7); + CHAM_DecRound< 7, 16>(m_x.begin(), m_rk.begin(), i-8); + CHAM_DecRound< 6, 16>(m_x.begin(), m_rk.begin(), i-9); + CHAM_DecRound< 5, 16>(m_x.begin(), m_rk.begin(), i-10); + CHAM_DecRound< 4, 16>(m_x.begin(), m_rk.begin(), i-11); + CHAM_DecRound< 3, 16>(m_x.begin(), m_rk.begin(), i-12); + CHAM_DecRound< 2, 16>(m_x.begin(), m_rk.begin(), i-13); + CHAM_DecRound< 1, 16>(m_x.begin(), m_rk.begin(), i-14); + CHAM_DecRound< 0, 16>(m_x.begin(), m_rk.begin(), i-15); + } + + PutBlock oblock(xorBlock, outBlock); + oblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); +} + +std::string CHAM128::Base::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return "SSSE3"; +#endif + return "C++"; +} + +void CHAM128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + m_kw = keyLength/sizeof(word32); + m_rk.New(2*m_kw); + + for (size_t i = 0; i < m_kw; userKey += sizeof(word32)) + { + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + const word32 rk = GetWord(false, BIG_ENDIAN_ORDER, userKey); + m_rk[i] = rk ^ rotlConstant<1>(rk) ^ rotlConstant<8>(rk); + m_rk[(i + m_kw) ^ 1] = rk ^ rotlConstant<1>(rk) ^ rotlConstant<11>(rk); + i++; + } +} + +void CHAM128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); + + switch (m_kw) + { + case 4: // 128-bit key + { + const int R = 80; + for (int i = 0; i < R; i+=8) + { + CHAM_EncRound<0, 8>(m_x.begin(), m_rk.begin(), i+0); + CHAM_EncRound<1, 8>(m_x.begin(), m_rk.begin(), i+1); + CHAM_EncRound<2, 8>(m_x.begin(), m_rk.begin(), i+2); + CHAM_EncRound<3, 8>(m_x.begin(), m_rk.begin(), i+3); + CHAM_EncRound<4, 8>(m_x.begin(), m_rk.begin(), i+4); + CHAM_EncRound<5, 8>(m_x.begin(), m_rk.begin(), i+5); + CHAM_EncRound<6, 8>(m_x.begin(), m_rk.begin(), i+6); + CHAM_EncRound<7, 8>(m_x.begin(), m_rk.begin(), i+7); + } + break; + } + case 8: // 256-bit key + { + const int R = 96; + for (int i = 0; i < R; i+=16) + { + CHAM_EncRound< 0, 16>(m_x.begin(), m_rk.begin(), i+0); + CHAM_EncRound< 1, 16>(m_x.begin(), m_rk.begin(), i+1); + CHAM_EncRound< 2, 16>(m_x.begin(), m_rk.begin(), i+2); + CHAM_EncRound< 3, 16>(m_x.begin(), m_rk.begin(), i+3); + CHAM_EncRound< 4, 16>(m_x.begin(), m_rk.begin(), i+4); + CHAM_EncRound< 5, 16>(m_x.begin(), m_rk.begin(), i+5); + CHAM_EncRound< 6, 16>(m_x.begin(), m_rk.begin(), i+6); + CHAM_EncRound< 7, 16>(m_x.begin(), m_rk.begin(), i+7); + CHAM_EncRound< 8, 16>(m_x.begin(), m_rk.begin(), i+8); + CHAM_EncRound< 9, 16>(m_x.begin(), m_rk.begin(), i+9); + CHAM_EncRound<10, 16>(m_x.begin(), m_rk.begin(), i+10); + CHAM_EncRound<11, 16>(m_x.begin(), m_rk.begin(), i+11); + CHAM_EncRound<12, 16>(m_x.begin(), m_rk.begin(), i+12); + CHAM_EncRound<13, 16>(m_x.begin(), m_rk.begin(), i+13); + CHAM_EncRound<14, 16>(m_x.begin(), m_rk.begin(), i+14); + CHAM_EncRound<15, 16>(m_x.begin(), m_rk.begin(), i+15); + } + break; + } + default: + CRYPTOPP_ASSERT(0); + } + + PutBlock oblock(xorBlock, outBlock); + oblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); +} + +void CHAM128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); + + switch (m_kw) + { + case 4: // 128-bit key + { + const int R = 80; + for (int i = R-1; i >= 0; i-=8) + { + CHAM_DecRound<7, 8>(m_x.begin(), m_rk.begin(), i-0); + CHAM_DecRound<6, 8>(m_x.begin(), m_rk.begin(), i-1); + CHAM_DecRound<5, 8>(m_x.begin(), m_rk.begin(), i-2); + CHAM_DecRound<4, 8>(m_x.begin(), m_rk.begin(), i-3); + CHAM_DecRound<3, 8>(m_x.begin(), m_rk.begin(), i-4); + CHAM_DecRound<2, 8>(m_x.begin(), m_rk.begin(), i-5); + CHAM_DecRound<1, 8>(m_x.begin(), m_rk.begin(), i-6); + CHAM_DecRound<0, 8>(m_x.begin(), m_rk.begin(), i-7); + } + break; + } + case 8: // 256-bit key + { + const int R = 96; + for (int i = R-1; i >= 0; i-=16) + { + CHAM_DecRound<15, 16>(m_x.begin(), m_rk.begin(), i-0); + CHAM_DecRound<14, 16>(m_x.begin(), m_rk.begin(), i-1); + CHAM_DecRound<13, 16>(m_x.begin(), m_rk.begin(), i-2); + CHAM_DecRound<12, 16>(m_x.begin(), m_rk.begin(), i-3); + CHAM_DecRound<11, 16>(m_x.begin(), m_rk.begin(), i-4); + CHAM_DecRound<10, 16>(m_x.begin(), m_rk.begin(), i-5); + CHAM_DecRound< 9, 16>(m_x.begin(), m_rk.begin(), i-6); + CHAM_DecRound< 8, 16>(m_x.begin(), m_rk.begin(), i-7); + CHAM_DecRound< 7, 16>(m_x.begin(), m_rk.begin(), i-8); + CHAM_DecRound< 6, 16>(m_x.begin(), m_rk.begin(), i-9); + CHAM_DecRound< 5, 16>(m_x.begin(), m_rk.begin(), i-10); + CHAM_DecRound< 4, 16>(m_x.begin(), m_rk.begin(), i-11); + CHAM_DecRound< 3, 16>(m_x.begin(), m_rk.begin(), i-12); + CHAM_DecRound< 2, 16>(m_x.begin(), m_rk.begin(), i-13); + CHAM_DecRound< 1, 16>(m_x.begin(), m_rk.begin(), i-14); + CHAM_DecRound< 0, 16>(m_x.begin(), m_rk.begin(), i-15); + } + break; + } + default: + CRYPTOPP_ASSERT(0); + } + + PutBlock oblock(xorBlock, outBlock); + oblock(m_x[0])(m_x[1])(m_x[2])(m_x[3]); +} + +#if CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS +size_t CHAM128::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) { + const size_t rounds = (m_kw == 4 ? 80 : 96); + return CHAM128_Enc_AdvancedProcessBlocks_SSSE3(m_rk, rounds, + inBlocks, xorBlocks, outBlocks, length, flags); + } +# endif // CRYPTOPP_SSSE3_AVAILABLE + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t CHAM128::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) { + const size_t rounds = (m_kw == 4 ? 80 : 96); + return CHAM128_Dec_AdvancedProcessBlocks_SSSE3(m_rk, rounds, + inBlocks, xorBlocks, outBlocks, length, flags); + } +# endif // CRYPTOPP_SSSE3_AVAILABLE + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/cham.h b/external/ours/library/crypto/src/shared/original/cham.h new file mode 100755 index 000000000..5100dd45d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cham.h @@ -0,0 +1,179 @@ +// cham.h - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "CHAM: A Family of Lightweight Block Ciphers for +// Resource-Constrained Devices" by Bonwook Koo, Dongyoung Roh, +// Hyeonjin Kim, Younghoon Jung, Dong-Geon Lee, and Daesung Kwon + +/// \file cham.h +/// \brief Classes for the CHAM block cipher +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_CHAM_H +#define CRYPTOPP_CHAM_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +#if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86) +# define CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS 1 +#endif + +// Yet another SunStudio/SunCC workaround. Failed self tests +// in SSE code paths on i386 for SunStudio 12.3 and below. +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) +# undef CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief CHAM block cipher information +/// \since Crypto++ 8.0 +struct CHAM64_Info : public FixedBlockSize<8>, public FixedKeyLength<16> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "CHAM-64"; + } +}; + +/// \brief CHAM block cipher information +/// \since Crypto++ 8.0 +struct CHAM128_Info : public FixedBlockSize<16>, public VariableKeyLength<16,16,32,16> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "CHAM-128"; + } +}; + +/// \brief CHAM 64-bit block cipher +/// \details CHAM64 provides 64-bit block size. The valid key size is 128-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa CHAM128, CHAM, +/// +/// CHAM: A Family of Lightweight Block Ciphers for Resource-Constrained Devices +/// \since Crypto++ 8.0 +class CRYPTOPP_NO_VTABLE CHAM64 : public CHAM64_Info, public BlockCipherDocumentation +{ +public: + /// \brief CHAM block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + + SecBlock m_rk; + mutable FixedSizeSecBlock m_x; + unsigned int m_kw; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief CHAM64 encryption + typedef BlockCipherFinal Encryption; + /// \brief CHAM64 decryption + typedef BlockCipherFinal Decryption; +}; + +/// \brief CHAM64 encryption +typedef CHAM64::Encryption CHAM64Encryption; +/// \brief CHAM64 decryption +typedef CHAM64::Decryption CHAM64Decryption; + +/// \brief CHAM 128-bit block cipher +/// \details CHAM128 provides 128-bit block size. The valid key size is 128-bit and 256-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa CHAM64, CHAM, +/// +/// CHAM: A Family of Lightweight Block Ciphers for Resource-Constrained Devices +/// \since Crypto++ 8.0 +class CRYPTOPP_NO_VTABLE CHAM128 : public CHAM128_Info, public BlockCipherDocumentation +{ +public: + /// \brief CHAM block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + std::string AlgorithmProvider() const; + + SecBlock m_rk; + mutable FixedSizeSecBlock m_x; + unsigned int m_kw; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + +#if CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + +#if CRYPTOPP_CHAM128_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief CHAM128 encryption + typedef BlockCipherFinal Encryption; + /// \brief CHAM128 decryption + typedef BlockCipherFinal Decryption; +}; + +/// \brief CHAM128 encryption +typedef CHAM128::Encryption CHAM128Encryption; +/// \brief CHAM128 decryption +typedef CHAM128::Decryption CHAM128Decryption; + +NAMESPACE_END + +#endif // CRYPTOPP_CHAM_H diff --git a/external/ours/library/crypto/src/shared/original/cham_simd.cpp b/external/ours/library/crypto/src/shared/original/cham_simd.cpp new file mode 100755 index 000000000..b848ba107 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cham_simd.cpp @@ -0,0 +1,478 @@ +// cham_simd.cpp - written and placed in the public domain by Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// SSSE3, ARM NEON and ARMv8a, and Power7 Altivec instructions. A separate +// source file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#include "cham.h" +#include "misc.h" + +// Uncomment for benchmarking C++ against SSE or NEON. +// Do so in both simon.cpp and simon_simd.cpp. +// #undef CRYPTOPP_SSSE3_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_SSSE3_AVAILABLE) +#include "adv_simd.h" +# include +# include +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670 +#define DOUBLE_CAST(x) ((double*)(void*)(x)) +#define CONST_DOUBLE_CAST(x) ((const double*)(const void*)(x)) + +// Squash MS LNK4221 and libtool warnings +extern const char CHAM_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word16; +using CryptoPP::word32; + +#if (CRYPTOPP_SSSE3_AVAILABLE) + +////////////////////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(W32) // CHAM128, 32-bit word size + +template +inline __m128i RotateLeft32(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, R); +#else + return _mm_or_si128( + _mm_slli_epi32(val, R), _mm_srli_epi32(val, 32-R)); +#endif +} + +template +inline __m128i RotateRight32(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 32-R); +#else + return _mm_or_si128( + _mm_slli_epi32(val, 32-R), _mm_srli_epi32(val, R)); +#endif +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +inline __m128i RotateLeft32<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 8); +#else + const __m128i mask = _mm_set_epi8(14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3); + return _mm_shuffle_epi8(val, mask); +#endif +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +inline __m128i RotateRight32<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 32-8); +#else + const __m128i mask = _mm_set_epi8(12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1); + return _mm_shuffle_epi8(val, mask); +#endif +} + +template +inline __m128i UnpackXMM(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(a); CRYPTOPP_UNUSED(b); + CRYPTOPP_UNUSED(c); CRYPTOPP_UNUSED(d); + CRYPTOPP_ASSERT(0); + return _mm_setzero_si128(); +} + +template <> +inline __m128i UnpackXMM<0>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // The shuffle converts to and from little-endian for SSE. A specialized + // CHAM implementation can avoid the shuffle by framing the data for + // encryption, decryption and benchmarks. The library cannot take the + // speed-up because of the byte oriented API. + const __m128i r1 = _mm_unpacklo_epi32(a, b); + const __m128i r2 = _mm_unpacklo_epi32(c, d); + return _mm_shuffle_epi8(_mm_unpacklo_epi64(r1, r2), + _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3)); +} + +template <> +inline __m128i UnpackXMM<1>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // The shuffle converts to and from little-endian for SSE. A specialized + // CHAM implementation can avoid the shuffle by framing the data for + // encryption, decryption and benchmarks. The library cannot take the + // speed-up because of the byte oriented API. + const __m128i r1 = _mm_unpacklo_epi32(a, b); + const __m128i r2 = _mm_unpacklo_epi32(c, d); + return _mm_shuffle_epi8(_mm_unpackhi_epi64(r1, r2), + _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3)); +} + +template <> +inline __m128i UnpackXMM<2>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // The shuffle converts to and from little-endian for SSE. A specialized + // CHAM implementation can avoid the shuffle by framing the data for + // encryption, decryption and benchmarks. The library cannot take the + // speed-up because of the byte oriented API. + const __m128i r1 = _mm_unpackhi_epi32(a, b); + const __m128i r2 = _mm_unpackhi_epi32(c, d); + return _mm_shuffle_epi8(_mm_unpacklo_epi64(r1, r2), + _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3)); +} + +template <> +inline __m128i UnpackXMM<3>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // The shuffle converts to and from little-endian for SSE. A specialized + // CHAM implementation can avoid the shuffle by framing the data for + // encryption, decryption and benchmarks. The library cannot take the + // speed-up because of the byte oriented API. + const __m128i r1 = _mm_unpackhi_epi32(a, b); + const __m128i r2 = _mm_unpackhi_epi32(c, d); + return _mm_shuffle_epi8(_mm_unpackhi_epi64(r1, r2), + _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3)); +} + +template +inline __m128i UnpackXMM(const __m128i& v) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(v); CRYPTOPP_ASSERT(0); + return _mm_setzero_si128(); +} + +template <> +inline __m128i UnpackXMM<0>(const __m128i& v) +{ + return _mm_shuffle_epi8(v, _mm_set_epi8(0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3)); +} + +template <> +inline __m128i UnpackXMM<1>(const __m128i& v) +{ + return _mm_shuffle_epi8(v, _mm_set_epi8(4,5,6,7, 4,5,6,7, 4,5,6,7, 4,5,6,7)); +} + +template <> +inline __m128i UnpackXMM<2>(const __m128i& v) +{ + return _mm_shuffle_epi8(v, _mm_set_epi8(8,9,10,11, 8,9,10,11, 8,9,10,11, 8,9,10,11)); +} + +template <> +inline __m128i UnpackXMM<3>(const __m128i& v) +{ + return _mm_shuffle_epi8(v, _mm_set_epi8(12,13,14,15, 12,13,14,15, 12,13,14,15, 12,13,14,15)); +} + +template +inline __m128i RepackXMM(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + return UnpackXMM(a, b, c, d); +} + +template +inline __m128i RepackXMM(const __m128i& v) +{ + return UnpackXMM(v); +} + +inline void CHAM128_Enc_Block(__m128i &block0, + const word32 *subkeys, unsigned int rounds) +{ + // Rearrange the data for vectorization. UnpackXMM includes a + // little-endian swap for SSE. Thanks to Peter Cordes for help + // with packing and unpacking. + // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 B1 C1 D1][A2 B2 C2 D2] ... + __m128i a = UnpackXMM<0>(block0); + __m128i b = UnpackXMM<1>(block0); + __m128i c = UnpackXMM<2>(block0); + __m128i d = UnpackXMM<3>(block0); + + __m128i counter = _mm_set_epi32(0,0,0,0); + __m128i increment = _mm_set_epi32(1,1,1,1); + + const unsigned int MASK = (rounds == 80 ? 7 : 15); + for (int i=0; i(rounds); i+=4) + { + __m128i k, k1, k2, t1, t2; + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + + t1 = _mm_xor_si128(a, counter); + t2 = _mm_xor_si128(RotateLeft32<1>(b), k1); + a = RotateLeft32<8>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + + t1 = _mm_xor_si128(b, counter); + t2 = _mm_xor_si128(RotateLeft32<8>(c), k2); + b = RotateLeft32<1>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+2) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + + t1 = _mm_xor_si128(c, counter); + t2 = _mm_xor_si128(RotateLeft32<1>(d), k1); + c = RotateLeft32<8>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + + t1 = _mm_xor_si128(d, counter); + t2 = _mm_xor_si128(RotateLeft32<8>(a), k2); + d = RotateLeft32<1>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + } + + // [A1 B1 C1 D1][A2 B2 C2 D2] ... => [A1 A2 A3 A4][B1 B2 B3 B4] ... + block0 = RepackXMM<0>(a,b,c,d); +} + +inline void CHAM128_Dec_Block(__m128i &block0, + const word32 *subkeys, unsigned int rounds) +{ + // Rearrange the data for vectorization. UnpackXMM includes a + // little-endian swap for SSE. Thanks to Peter Cordes for help + // with packing and unpacking. + // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 B1 C1 D1][A2 B2 C2 D2] ... + __m128i a = UnpackXMM<0>(block0); + __m128i b = UnpackXMM<1>(block0); + __m128i c = UnpackXMM<2>(block0); + __m128i d = UnpackXMM<3>(block0); + + __m128i counter = _mm_set_epi32(rounds-1,rounds-1,rounds-1,rounds-1); + __m128i decrement = _mm_set_epi32(1,1,1,1); + + const unsigned int MASK = (rounds == 80 ? 7 : 15); + for (int i = static_cast(rounds)-1; i >= 0; i-=4) + { + __m128i k, k1, k2, t1, t2; + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-1) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + + // Odd round + t1 = RotateRight32<1>(d); + t2 = _mm_xor_si128(RotateLeft32<8>(a), k1); + d = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + + // Even round + t1 = RotateRight32<8>(c); + t2 = _mm_xor_si128(RotateLeft32<1>(d), k2); + c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + + // Odd round + t1 = RotateRight32<1>(b); + t2 = _mm_xor_si128(RotateLeft32<8>(c), k1); + b = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + + // Even round + t1 = RotateRight32<8>(a); + t2 = _mm_xor_si128(RotateLeft32<1>(b), k2); + a = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + } + + // [A1 B1 C1 D1][A2 B2 C2 D2] ... => [A1 A2 A3 A4][B1 B2 B3 B4] ... + block0 = RepackXMM<0>(a,b,c,d); +} + +inline void CHAM128_Enc_4_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys, unsigned int rounds) +{ + // Rearrange the data for vectorization. UnpackXMM includes a + // little-endian swap for SSE. Thanks to Peter Cordes for help + // with packing and unpacking. + // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 B1 C1 D1][A2 B2 C2 D2] ... + __m128i a = UnpackXMM<0>(block0, block1, block2, block3); + __m128i b = UnpackXMM<1>(block0, block1, block2, block3); + __m128i c = UnpackXMM<2>(block0, block1, block2, block3); + __m128i d = UnpackXMM<3>(block0, block1, block2, block3); + + __m128i counter = _mm_set_epi32(0,0,0,0); + __m128i increment = _mm_set_epi32(1,1,1,1); + + const unsigned int MASK = (rounds == 80 ? 7 : 15); + for (int i=0; i(rounds); i+=4) + { + __m128i k, k1, k2, t1, t2; + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + + t1 = _mm_xor_si128(a, counter); + t2 = _mm_xor_si128(RotateLeft32<1>(b), k1); + a = RotateLeft32<8>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + + t1 = _mm_xor_si128(b, counter); + t2 = _mm_xor_si128(RotateLeft32<8>(c), k2); + b = RotateLeft32<1>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+2) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + + t1 = _mm_xor_si128(c, counter); + t2 = _mm_xor_si128(RotateLeft32<1>(d), k1); + c = RotateLeft32<8>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + + t1 = _mm_xor_si128(d, counter); + t2 = _mm_xor_si128(RotateLeft32<8>(a), k2); + d = RotateLeft32<1>(_mm_add_epi32(t1, t2)); + + counter = _mm_add_epi32(counter, increment); + } + + // [A1 B1 C1 D1][A2 B2 C2 D2] ... => [A1 A2 A3 A4][B1 B2 B3 B4] ... + block0 = RepackXMM<0>(a,b,c,d); + block1 = RepackXMM<1>(a,b,c,d); + block2 = RepackXMM<2>(a,b,c,d); + block3 = RepackXMM<3>(a,b,c,d); +} + +inline void CHAM128_Dec_4_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys, unsigned int rounds) +{ + // Rearrange the data for vectorization. UnpackXMM includes a + // little-endian swap for SSE. Thanks to Peter Cordes for help + // with packing and unpacking. + // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 B1 C1 D1][A2 B2 C2 D2] ... + __m128i a = UnpackXMM<0>(block0, block1, block2, block3); + __m128i b = UnpackXMM<1>(block0, block1, block2, block3); + __m128i c = UnpackXMM<2>(block0, block1, block2, block3); + __m128i d = UnpackXMM<3>(block0, block1, block2, block3); + + __m128i counter = _mm_set_epi32(rounds-1,rounds-1,rounds-1,rounds-1); + __m128i decrement = _mm_set_epi32(1,1,1,1); + + const unsigned int MASK = (rounds == 80 ? 7 : 15); + for (int i = static_cast(rounds)-1; i >= 0; i-=4) + { + __m128i k, k1, k2, t1, t2; + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-1) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + + // Odd round + t1 = RotateRight32<1>(d); + t2 = _mm_xor_si128(RotateLeft32<8>(a), k1); + d = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + + // Even round + t1 = RotateRight32<8>(c); + t2 = _mm_xor_si128(RotateLeft32<1>(d), k2); + c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK]))); + + // Shuffle out two subkeys + k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); + k2 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); + + // Odd round + t1 = RotateRight32<1>(b); + t2 = _mm_xor_si128(RotateLeft32<8>(c), k1); + b = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + + // Even round + t1 = RotateRight32<8>(a); + t2 = _mm_xor_si128(RotateLeft32<1>(b), k2); + a = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); + + counter = _mm_sub_epi32(counter, decrement); + } + + // [A1 B1 C1 D1][A2 B2 C2 D2] ... => [A1 A2 A3 A4][B1 B2 B3 B4] ... + block0 = RepackXMM<0>(a,b,c,d); + block1 = RepackXMM<1>(a,b,c,d); + block2 = RepackXMM<2>(a,b,c,d); + block3 = RepackXMM<3>(a,b,c,d); +} + +////////////////////////////////////////////////////////////////////////// + +NAMESPACE_END // W32 + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) +size_t CHAM128_Enc_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_SSE(W32::CHAM128_Enc_Block, W32::CHAM128_Enc_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t CHAM128_Dec_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_SSE(W32::CHAM128_Dec_Block, W32::CHAM128_Dec_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SSSE3_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/channels.cpp b/external/ours/library/crypto/src/shared/original/channels.cpp new file mode 100755 index 000000000..ec7a98a0f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/channels.cpp @@ -0,0 +1,316 @@ +// channels.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cryptlib.h" +#include "channels.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if 0 +void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel) +{ + m_defaultRoutes.push_back(Route(&destination, channel)); +} + +void MessageSwitch::AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel) +{ + RangeRoute route(begin, end, Route(&destination, channel)); + RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route); + m_routes.insert(it, route); +} + +/* +class MessageRouteIterator +{ +public: + typedef MessageSwitch::RouteList::const_iterator RouteIterator; + typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator; + + bool m_useDefault; + RouteIterator m_itRouteCurrent, m_itRouteEnd; + DefaultIterator m_itDefaultCurrent, m_itDefaultEnd; + + MessageRouteIterator(MessageSwitch &ms, const std::string &channel) + : m_channel(channel) + { + std::pair range = cs.m_routeMap.equal_range(channel); + if (range.first == range.second) + { + m_useDefault = true; + m_itListCurrent = cs.m_defaultRoutes.begin(); + m_itListEnd = cs.m_defaultRoutes.end(); + } + else + { + m_useDefault = false; + m_itMapCurrent = range.first; + m_itMapEnd = range.second; + } + } + + bool End() const + { + return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; + } + + void Next() + { + if (m_useDefault) + ++m_itListCurrent; + else + ++m_itMapCurrent; + } + + BufferedTransformation & Destination() + { + return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; + } + + const std::string & Message() + { + if (m_useDefault) + return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; + else + return m_itMapCurrent->second.second; + } +}; + +void MessageSwitch::Put(byte inByte); +void MessageSwitch::Put(const byte *inString, unsigned int length); + +void MessageSwitch::Flush(bool completeFlush, int propagation=-1); +void MessageSwitch::MessageEnd(int propagation=-1); +void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); +void MessageSwitch::MessageSeriesEnd(int propagation=-1); +*/ +#endif + + +// +// ChannelRouteIterator +////////////////////////// + +void ChannelRouteIterator::Reset(const std::string &channel) +{ + m_channel = channel; + std::pair range = m_cs.m_routeMap.equal_range(channel); + if (range.first == range.second) + { + m_useDefault = true; + m_itListCurrent = m_cs.m_defaultRoutes.begin(); + m_itListEnd = m_cs.m_defaultRoutes.end(); + } + else + { + m_useDefault = false; + m_itMapCurrent = range.first; + m_itMapEnd = range.second; + } +} + +bool ChannelRouteIterator::End() const +{ + return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; +} + +void ChannelRouteIterator::Next() +{ + if (m_useDefault) + ++m_itListCurrent; + else + ++m_itMapCurrent; +} + +BufferedTransformation & ChannelRouteIterator::Destination() +{ + return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; +} + +const std::string & ChannelRouteIterator::Channel() +{ + if (m_useDefault) + return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; + else + return m_itMapCurrent->second.second; +} + + +// +// ChannelSwitch +/////////////////// + +size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (m_blocked) + { + m_blocked = false; + goto WasBlocked; + } + + m_it.Reset(channel); + + while (!m_it.End()) + { +WasBlocked: + if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking)) + { + m_blocked = true; + return 1; + } + + m_it.Next(); + } + + return 0; +} + +void ChannelSwitch::IsolatedInitialize(const NameValuePairs& parameters) +{ + CRYPTOPP_UNUSED(parameters); + m_routeMap.clear(); + m_defaultRoutes.clear(); + m_blocked = false; +} + +bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) +{ + if (m_blocked) + { + m_blocked = false; + goto WasBlocked; + } + + m_it.Reset(channel); + + while (!m_it.End()) + { + WasBlocked: + if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking)) + { + m_blocked = true; + return true; + } + + m_it.Next(); + } + + return false; +} + +bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) +{ + CRYPTOPP_UNUSED(blocking); + if (m_blocked) + { + m_blocked = false; + goto WasBlocked; + } + + m_it.Reset(channel); + + while (!m_it.End()) + { + WasBlocked: + if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation)) + { + m_blocked = true; + return true; + } + + m_it.Next(); + } + + return false; +} + +byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size) +{ + m_it.Reset(channel); + if (!m_it.End()) + { + BufferedTransformation &target = m_it.Destination(); + const std::string &ch = m_it.Channel(); + m_it.Next(); + if (m_it.End()) // there is only one target channel + return target.ChannelCreatePutSpace(ch, size); + } + size = 0; + return NULLPTR; +} + +size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) +{ + ChannelRouteIterator it(*this); + it.Reset(channel); + + if (!it.End()) + { + BufferedTransformation &target = it.Destination(); + const std::string &targetChannel = it.Channel(); + it.Next(); + if (it.End()) // there is only one target channel + return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking); + } + + return ChannelPut2(channel, inString, length, messageEnd, blocking); +} + +void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination) +{ + m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr(NULLPTR))); +} + +void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination) +{ + for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) + if (it->first == &destination && !it->second.get()) + { + m_defaultRoutes.erase(it); + break; + } +} + +void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) +{ + m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel)); +} + +void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) +{ + for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) + if (it->first == &destination && (it->second.get() && *it->second == outChannel)) + { + m_defaultRoutes.erase(it); + break; + } +} + +void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) +{ + m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel))); +} + +void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) +{ + typedef ChannelSwitch::RouteMap::iterator MapIterator; + std::pair range = m_routeMap.equal_range(inChannel); + + for (MapIterator it = range.first; it != range.second; ++it) + if (it->second.first == &destination && it->second.second == outChannel) + { + m_routeMap.erase(it); + break; + } +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/channels.h b/external/ours/library/crypto/src/shared/original/channels.h new file mode 100755 index 000000000..da470a2b1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/channels.h @@ -0,0 +1,142 @@ +// channels.h - originally written and placed in the public domain by Wei Dai + +/// \file channels.h +/// \brief Classes for multiple named channels + +#ifndef CRYPTOPP_CHANNELS_H +#define CRYPTOPP_CHANNELS_H + +#include "cryptlib.h" +#include "simple.h" +#include "smartptr.h" +#include "stdcpp.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if 0 +/// Route input on default channel to different and/or multiple channels based on message sequence number +class MessageSwitch : public Sink +{ +public: + void AddDefaultRoute(BufferedTransformation &destination, const std::string &channel); + void AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel); + + void Put(byte inByte); + void Put(const byte *inString, unsigned int length); + + void Flush(bool completeFlush, int propagation=-1); + void MessageEnd(int propagation=-1); + void PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); + void MessageSeriesEnd(int propagation=-1); + +private: + typedef std::pair Route; + struct RangeRoute + { + RangeRoute(unsigned int begin, unsigned int end, const Route &route) + : begin(begin), end(end), route(route) {} + bool operator<(const RangeRoute &rhs) const {return begin < rhs.begin;} + unsigned int begin, end; + Route route; + }; + + typedef std::list RouteList; + typedef std::list DefaultRouteList; + + RouteList m_routes; + DefaultRouteList m_defaultRoutes; + unsigned int m_nCurrentMessage; +}; +#endif + +class ChannelSwitchTypedefs +{ +public: + typedef std::pair Route; + typedef std::multimap RouteMap; + + typedef std::pair > DefaultRoute; + typedef std::list DefaultRouteList; + + // SunCC workaround: can't use const_iterator here + typedef RouteMap::iterator MapIterator; + typedef DefaultRouteList::iterator ListIterator; +}; + +class ChannelSwitch; + +class ChannelRouteIterator : public ChannelSwitchTypedefs +{ +public: + ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs), m_useDefault(false) {} + + void Reset(const std::string &channel); + bool End() const; + void Next(); + BufferedTransformation & Destination(); + const std::string & Channel(); + + ChannelSwitch& m_cs; + std::string m_channel; + bool m_useDefault; + MapIterator m_itMapCurrent, m_itMapEnd; + ListIterator m_itListCurrent, m_itListEnd; + +protected: + // Hide this to see if we break something... + ChannelRouteIterator(); +}; + +/// Route input to different and/or multiple channels based on channel ID +class CRYPTOPP_DLL ChannelSwitch : public Multichannel, public ChannelSwitchTypedefs +{ +public: + ChannelSwitch() : m_it(*this), m_blocked(false) {} + ChannelSwitch(BufferedTransformation &destination) : m_it(*this), m_blocked(false) + { + AddDefaultRoute(destination); + } + ChannelSwitch(BufferedTransformation &destination, const std::string &outChannel) : m_it(*this), m_blocked(false) + { + AddDefaultRoute(destination, outChannel); + } + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); + + bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true); + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); + + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); + + void AddDefaultRoute(BufferedTransformation &destination); + void RemoveDefaultRoute(BufferedTransformation &destination); + void AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel); + void RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel); + void AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); + void RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); + +private: + RouteMap m_routeMap; + DefaultRouteList m_defaultRoutes; + + ChannelRouteIterator m_it; + bool m_blocked; + + friend class ChannelRouteIterator; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/cmac.cpp b/external/ours/library/crypto/src/shared/original/cmac.cpp new file mode 100755 index 000000000..3ff57f1e3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cmac.cpp @@ -0,0 +1,164 @@ +// cmac.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cmac.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::IsPowerOf2; + +void MulU(byte *k, unsigned int len) +{ + byte carry = 0; + for (int i=len-1; i>=1; i-=2) + { + byte carry2 = k[i] >> 7; + k[i] += k[i] + carry; + carry = k[i-1] >> 7; + k[i-1] += k[i-1] + carry2; + } + +#ifndef CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS + CRYPTOPP_ASSERT(len == 16); + + if (carry) + { + k[15] ^= 0x87; + return; + } +#else + CRYPTOPP_ASSERT(IsPowerOf2(len)); + CRYPTOPP_ASSERT(len >= 8); + CRYPTOPP_ASSERT(len <= 128); + + if (carry) + { + switch (len) + { + case 8: + k[7] ^= 0x1b; + break; + case 16: + k[15] ^= 0x87; + break; + case 32: + // https://crypto.stackexchange.com/q/9815/10496 + // Polynomial x^256 + x^10 + x^5 + x^2 + 1 + k[30] ^= 4; + k[31] ^= 0x25; + break; + case 64: + // https://crypto.stackexchange.com/q/9815/10496 + // Polynomial x^512 + x^8 + x^5 + x^2 + 1 + k[62] ^= 1; + k[63] ^= 0x25; + break; + case 128: + // https://crypto.stackexchange.com/q/9815/10496 + // Polynomial x^1024 + x^19 + x^6 + x + 1 + k[125] ^= 8; + k[126] ^= 0x00; + k[127] ^= 0x43; + break; + default: + CRYPTOPP_ASSERT(0); + } + } +#endif // CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + BlockCipher &cipher = AccessCipher(); + cipher.SetKey(key, length, params); + + unsigned int blockSize = cipher.BlockSize(); + m_reg.CleanNew(3*blockSize); + m_counter = 0; + + cipher.ProcessBlock(m_reg, m_reg+blockSize); + MulU(m_reg+blockSize, blockSize); + memcpy(m_reg+2*blockSize, m_reg+blockSize, blockSize); + MulU(m_reg+2*blockSize, blockSize); +} + +void CMAC_Base::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT((input && length) || !(input || length)); + if (!length) + return; + + BlockCipher &cipher = AccessCipher(); + unsigned int blockSize = cipher.BlockSize(); + + if (m_counter > 0) + { + const unsigned int len = UnsignedMin(blockSize - m_counter, length); + if (len) + { + xorbuf(m_reg+m_counter, input, len); + length -= len; + input += len; + m_counter += len; + } + + if (m_counter == blockSize && length > 0) + { + cipher.ProcessBlock(m_reg); + m_counter = 0; + } + } + + if (length > blockSize) + { + CRYPTOPP_ASSERT(m_counter == 0); + size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + input += (length - leftOver); + length = leftOver; + } + + if (length > 0) + { + CRYPTOPP_ASSERT(m_counter + length <= blockSize); + xorbuf(m_reg+m_counter, input, length); + m_counter += (unsigned int)length; + } + + CRYPTOPP_ASSERT(m_counter > 0); +} + +void CMAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + BlockCipher &cipher = AccessCipher(); + unsigned int blockSize = cipher.BlockSize(); + + if (m_counter < blockSize) + { + m_reg[m_counter] ^= 0x80; + cipher.AdvancedProcessBlocks(m_reg, m_reg+2*blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + } + else + cipher.AdvancedProcessBlocks(m_reg, m_reg+blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + + // UBsan finding + if (mac) + memcpy(mac, m_reg, size); + + m_counter = 0; + memset(m_reg, 0, blockSize); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/cmac.h b/external/ours/library/crypto/src/shared/original/cmac.h new file mode 100755 index 000000000..59a9f0201 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cmac.h @@ -0,0 +1,76 @@ +// cmac.h - originally written and placed in the public domain by Wei Dai + +/// \file cmac.h +/// \brief Classes for CMAC message authentication code +/// \since Crypto++ 5.6.0 + +#ifndef CRYPTOPP_CMAC_H +#define CRYPTOPP_CMAC_H + +#include "seckey.h" +#include "secblock.h" + +/// \brief Enable CMAC and wide block ciphers +/// \details CMAC is only defined for AES. The library can support wide +/// block ciphers like Kaylna and Threefish since we know the polynomials. +#ifndef CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS +# define CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS 1 +#endif // CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief CMAC base implementation +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode +{ +public: + + virtual ~CMAC_Base() {} + CMAC_Base() : m_counter(0) {} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int DigestSize() const {return GetCipher().BlockSize();} + unsigned int OptimalBlockSize() const {return GetCipher().BlockSize();} + unsigned int OptimalDataAlignment() const {return GetCipher().OptimalDataAlignment();} + std::string AlgorithmProvider() const {return GetCipher().AlgorithmProvider();} + +protected: + friend class EAX_Base; + + const BlockCipher & GetCipher() const {return const_cast(this)->AccessCipher();} + virtual BlockCipher & AccessCipher() =0; + + void ProcessBuf(); + SecByteBlock m_reg; + unsigned int m_counter; +}; + +/// \brief CMAC message authentication code +/// \tparam T block cipher +/// \details Template parameter T should be a class derived from BlockCipherDocumentation, for example AES, with a block size of 8, 16, or 32. +/// \sa CMAC +/// \since Crypto++ 5.6.0 +template +class CMAC : public MessageAuthenticationCodeImpl >, public SameKeyLengthAs +{ +public: + /// \brief Construct a CMAC + CMAC() {} + /// \brief Construct a CMAC + /// \param key the MAC key + /// \param length the key size, in bytes + CMAC(const byte *key, size_t length=SameKeyLengthAs::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} + + static std::string StaticAlgorithmName() {return std::string("CMAC(") + T::StaticAlgorithmName() + ")";} + +private: + BlockCipher & AccessCipher() {return m_cipher;} + typename T::Encryption m_cipher; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/config.h b/external/ours/library/crypto/src/shared/original/config.h index f0dfb23ee..cb4d24661 100755 --- a/external/ours/library/crypto/src/shared/original/config.h +++ b/external/ours/library/crypto/src/shared/original/config.h @@ -1,165 +1,33 @@ -#ifndef CRYPTOPP_CONFIG_H -#define CRYPTOPP_CONFIG_H - -// ***************** Important Settings ******************** - -// define this if running on a big-endian CPU -#if defined(__sparc__) || defined(__hppa__) || defined(__ppc__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__)) -#define IS_BIG_ENDIAN -#endif - -// define this if running on a little-endian CPU -// big endian will be assumed if IS_LITTLE_ENDIAN is not defined -#ifndef IS_BIG_ENDIAN -#define IS_LITTLE_ENDIAN -#endif - -// define this if you want to disable all OS-dependent features, -// such as sockets and OS-provided random number generators -// #define NO_OS_DEPENDENCE - -// Define this to use features provided by Microsoft's CryptoAPI. -// Currently the only feature used is random number generation. -// This macro will be ignored if NO_OS_DEPENDENCE is defined. -#define USE_MS_CRYPTOAPI - -// define this if your compiler does not support namespaces -// #define NO_NAMESPACE -#ifdef NO_NAMESPACE -#define std -#define CryptoPP -#define USING_NAMESPACE(x) -#define NAMESPACE_BEGIN(x) -#define NAMESPACE_END -#define ANONYMOUS_NAMESPACE_BEGIN -#else -#define USING_NAMESPACE(x) using namespace x; -#define NAMESPACE_BEGIN(x) namespace x { -#define ANONYMOUS_NAMESPACE_BEGIN namespace { -#define NAMESPACE_END } -#endif - -// ***************** Less Important Settings *************** - -// switch between different secure memory allocation mechnisms, this is the only -// one available right now -#define SECALLOC_DEFAULT - -#define GZIP_OS_CODE 0 - -// Try this if your CPU has 256K internal cache or a slow multiply instruction -// and you want a (possibly) faster IDEA implementation using log tables -// #define IDEA_LARGECACHE - -// Try this if you have a large cache or your CPU is slow manipulating -// individual bytes. -// #define DIAMOND_USE_PERMTABLE - -// Define this if, for the linear congruential RNG, you want to use -// the original constants as specified in S.K. Park and K.W. Miller's -// CACM paper. -// #define LCRNG_ORIGINAL_NUMBERS - -// choose which style of sockets to wrap (mostly useful for cygwin which has both) -#define PREFER_BERKELEY_STYLE_SOCKETS -// #define PREFER_WINDOWS_STYLE_SOCKETS - -// ***************** Important Settings Again ******************** -// But the defaults should be ok. - -typedef unsigned char byte; // moved outside namespace for Borland C++Builder 5 - -NAMESPACE_BEGIN(CryptoPP) - -typedef unsigned short word16; -#if defined(__alpha) && !defined(_MSC_VER) -typedef unsigned int word32; -#else -typedef unsigned long word32; -#endif - -#if defined(__GNUC__) || defined(__MWERKS__) -#define WORD64_AVAILABLE -typedef unsigned long long word64; -#define W64LIT(x) x##LL -#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) -#define WORD64_AVAILABLE -typedef unsigned __int64 word64; -#define W64LIT(x) x##ui64 -#endif - -// defined this if your CPU is not 64-bit -#if defined(WORD64_AVAILABLE) && !defined(__alpha) -#define SLOW_WORD64 -#endif - -// word should have the same size as your CPU registers -// dword should be twice as big as word - -#if (defined(__GNUC__) && !defined(__alpha)) || defined(__MWERKS__) -typedef unsigned long word; -typedef unsigned long long dword; -#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) -typedef unsigned __int32 word; -typedef unsigned __int64 dword; -#else -typedef unsigned int word; -typedef unsigned long dword; -#endif - -const unsigned int WORD_SIZE = sizeof(word); -const unsigned int WORD_BITS = WORD_SIZE * 8; - -#define LOW_WORD(x) (word)(x) - -union dword_union -{ - dword_union (const dword &dw) : dw(dw) {} - dword dw; - word w[2]; -}; - -#ifdef IS_LITTLE_ENDIAN -#define HIGH_WORD(x) (dword_union(x).w[1]) -#else -#define HIGH_WORD(x) (dword_union(x).w[0]) -#endif - -// if the above HIGH_WORD macro doesn't work (if you are not sure, compile it -// and run the validation tests), try this: -// #define HIGH_WORD(x) (word)((x)>>WORD_BITS) - -#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) -#define INTEL_INTRINSICS -#define FAST_ROTATE -#elif defined(__MWERKS__) && TARGET_CPU_PPC -#define PPC_INTRINSICS -#define FAST_ROTATE -#elif defined(__GNUC__) && defined(__i386__) -// GCC does peephole optimizations which should result in using rotate instructions -#define FAST_ROTATE -#endif - -// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0 -template -inline const _Tp& STDMIN(const _Tp& __a, const _Tp& __b) { - return __b < __a ? __b : __a; -} - -template -inline const _Tp& STDMAX(const _Tp& __a, const _Tp& __b) { - return __a < __b ? __b : __a; -} - -#ifdef _MSC_VER -// 4250: dominance -// 4660: explicitly instantiating a class that's already implicitly instantiated -// 4786: identifer was truncated in debug information -// 4355: 'this' : used in base member initializer list -// 4800: converting int to bool -#pragma warning(disable: 4250 4660 4786 4355 4800 4710) -#endif - -NAMESPACE_END - -#endif +// config.h - originally written and placed in the public domain by Wei Dai + +/// \file config.h +/// \brief Library configuration file +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +/// \file config.h +/// \brief Library configuration file + +#ifndef CRYPTOPP_CONFIG_H +#define CRYPTOPP_CONFIG_H + +#include "config_align.h" +#include "config_asm.h" +#include "config_cpu.h" +#include "config_cxx.h" +#include "config_dll.h" +#include "config_int.h" +#include "config_misc.h" +#include "config_ns.h" +#include "config_os.h" +#include "config_ver.h" + +#endif // CRYPTOPP_CONFIG_H diff --git a/external/ours/library/crypto/src/shared/original/config_align.h b/external/ours/library/crypto/src/shared/original/config_align.h new file mode 100755 index 000000000..6a6e9e041 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_align.h @@ -0,0 +1,72 @@ +// config_align.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_align.h +/// \brief Library configuration file +/// \details config_align.h provides defines for aligned memory +/// allocations. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_align.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_ALIGN_H +#define CRYPTOPP_CONFIG_ALIGN_H + +#include "config_asm.h" // CRYPTOPP_DISABLE_ASM +#include "config_cpu.h" // X86, X32, X64, ARM32, ARM64, etc +#include "config_cxx.h" // CRYPTOPP_CXX11_ALIGNAS +#include "config_ver.h" // Compiler versions + +// Nearly all Intel's and AMD's have SSE. Enable it independent of SSE ASM and intrinsics. +// ARM NEON and ARMv8 ASIMD only need natural alignment of an element in the vector. +// Altivec through POWER7 need vector alignment. POWER8 and POWER9 relax the requirement. +#if defined(CRYPTOPP_DISABLE_ASM) + #define CRYPTOPP_BOOL_ALIGN16 0 +#elif (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || \ + CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + #define CRYPTOPP_BOOL_ALIGN16 1 +#else + #define CRYPTOPP_BOOL_ALIGN16 0 +#endif + +// How to allocate 16-byte aligned memory (for SSE2) +// posix_memalign see https://forum.kde.org/viewtopic.php?p=66274 +#if defined(_MSC_VER) + #define CRYPTOPP_MM_MALLOC_AVAILABLE +#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) + #define CRYPTOPP_MEMALIGN_AVAILABLE +#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 +#elif (defined(_GNU_SOURCE) || ((_XOPEN_SOURCE + 0) >= 600)) && (_POSIX_ADVISORY_INFO > 0) + #define CRYPTOPP_POSIX_MEMALIGN_AVAILABLE +#else + #define CRYPTOPP_NO_ALIGNED_ALLOC +#endif + +// Sun Studio Express 3 (December 2006) provides GCC-style attributes. +// IBM XL C/C++ alignment modifier per Optimization Guide, pp. 19-20. +// __IBM_ATTRIBUTES per XLC 12.1 AIX Compiler Manual, p. 473. +// CRYPTOPP_ALIGN_DATA may not be reliable on AIX. +#if defined(CRYPTOPP_CXX11_ALIGNAS) + #define CRYPTOPP_ALIGN_DATA(x) alignas(x) +#elif defined(_MSC_VER) + #define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x)) +#elif defined(__GNUC__) || defined(__clang__) || (__SUNPRO_CC >= 0x5100) + #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x))) +#elif defined(__xlc__) || defined(__xlC__) + #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x))) +#else + #define CRYPTOPP_ALIGN_DATA(x) +#endif + +#endif // CRYPTOPP_CONFIG_ALIGN_H diff --git a/external/ours/library/crypto/src/shared/original/config_asm.h b/external/ours/library/crypto/src/shared/original/config_asm.h new file mode 100755 index 000000000..3202a2c37 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_asm.h @@ -0,0 +1,480 @@ +// config_asm.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_asm.h +/// \brief Library configuration file +/// \details config_asm.h provides defines for instruction set +/// architectures +/// and inline assembly. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_asm.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_ASM_H +#define CRYPTOPP_CONFIG_ASM_H + +#include "config_os.h" +#include "config_cpu.h" +#include "config_ver.h" + +// Define this to disable ASM, intrinsics and built-ins. The library will be +// compiled using C++ only. The library code will not include SSE2 (and +// above), NEON, Aarch32, Aarch64, or Altivec (and above). Note the compiler +// may use higher ISAs depending on compiler options, but the library will not +// explicitly use the ISAs. When disabling ASM, it is best to do it from +// config.h to ensure the library and all programs share the setting. +// #define CRYPTOPP_DISABLE_ASM 1 + +// https://github.com/weidai11/cryptopp/issues/719 +#if defined(__native_client__) +# undef CRYPTOPP_DISABLE_ASM +# define CRYPTOPP_DISABLE_ASM 1 +#endif + +// Some Clang and SunCC cannot handle mixed asm with positional arguments, +// where the body is Intel style with no prefix and the templates are +// AT&T style. Define this if the Makefile misdetects the configuration. +// Also see https://bugs.llvm.org/show_bug.cgi?id=39895 . +// #define CRYPTOPP_DISABLE_MIXED_ASM 1 + +#if defined(__clang__) || (defined(__APPLE__) && defined(__GNUC__)) || defined(__SUNPRO_CC) +# undef CRYPTOPP_DISABLE_MIXED_ASM +# define CRYPTOPP_DISABLE_MIXED_ASM 1 +#endif + +// Define this if you need to disable Android advanced ISAs. +// The problem is, Android-mk does not allow us to specify an +// ISA option, like -maes or -march=armv8-a+crypto for AES. +// Lack of an option results in a compile failure. To avoid +// the compile failure, set this define. Also see +// https://github.com/weidai11/cryptopp/issues/1015 +// CRYPTOPP_DISABLE_ANDROID_ADVANCED_ISA 1 + +// ***************** IA32 CPU features ******************** + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + +// Apple Clang prior to 5.0 cannot handle SSE2 +#if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000) +# define CRYPTOPP_DISABLE_ASM 1 +#endif + +// Sun Studio 12.1 provides GCC inline assembly +// http://blogs.oracle.com/x86be/entry/gcc_style_asm_inlining_support +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5100) +# define CRYPTOPP_DISABLE_ASM 1 +#endif + +// Guard everything in CRYPTOPP_DISABLE_ASM +#if !defined(CRYPTOPP_DISABLE_ASM) + +#if (defined(_MSC_VER) && defined(_M_IX86)) || ((defined(__GNUC__) && (defined(__i386__)) || defined(__x86_64__))) + // C++Builder 2010 does not allow "call label" where label is defined within inline assembly + #define CRYPTOPP_X86_ASM_AVAILABLE 1 + + #if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(_MSC_VER) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__)) + #define CRYPTOPP_SSE2_ASM_AVAILABLE 1 + #endif + + #if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1500 || CRYPTOPP_GCC_VERSION >= 40300 || defined(__SSSE3__)) + #define CRYPTOPP_SSSE3_ASM_AVAILABLE 1 + #endif +#endif + +#if defined(_MSC_VER) && defined(_M_X64) + #define CRYPTOPP_X64_MASM_AVAILABLE 1 +#endif + +#if defined(__GNUC__) && defined(__x86_64__) + #define CRYPTOPP_X64_ASM_AVAILABLE 1 +#endif + +// 32-bit SunCC does not enable SSE2 by default. +#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(_MSC_VER) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__) || (__SUNPRO_CC >= 0x5100)) + #define CRYPTOPP_SSE2_INTRIN_AVAILABLE 1 +#endif + +#if !defined(CRYPTOPP_DISABLE_SSSE3) +# if defined(__SSSE3__) || (_MSC_VER >= 1500) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) + #define CRYPTOPP_SSSE3_AVAILABLE 1 +# endif +#endif + +// Intrinsics available in GCC 4.3 (http://gcc.gnu.org/gcc-4.3/changes.html) and +// MSVC 2008 (http://msdn.microsoft.com/en-us/library/bb892950%28v=vs.90%29.aspx) +// SunCC could generate SSE4 at 12.1, but the intrinsics are missing until 12.4. +#if !defined(CRYPTOPP_DISABLE_SSE4) && defined(CRYPTOPP_SSSE3_AVAILABLE) && \ + (defined(__SSE4_1__) || (CRYPTOPP_MSC_VERSION >= 1500) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)) + #define CRYPTOPP_SSE41_AVAILABLE 1 +#endif + +#if !defined(CRYPTOPP_DISABLE_SSE4) && defined(CRYPTOPP_SSSE3_AVAILABLE) && \ + (defined(__SSE4_2__) || (CRYPTOPP_MSC_VERSION >= 1500) || (__SUNPRO_CC >= 0x5110) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)) + #define CRYPTOPP_SSE42_AVAILABLE 1 +#endif + +// Couple to CRYPTOPP_DISABLE_AESNI, but use CRYPTOPP_CLMUL_AVAILABLE so we can selectively +// disable for misbehaving platofrms and compilers, like Solaris or some Clang. +#if defined(CRYPTOPP_DISABLE_AESNI) + #define CRYPTOPP_DISABLE_CLMUL 1 +#endif + +// Requires Sun Studio 12.3 (SunCC 0x5120) in theory. +#if !defined(CRYPTOPP_DISABLE_CLMUL) && defined(CRYPTOPP_SSE42_AVAILABLE) && \ + (defined(__PCLMUL__) || (_MSC_FULL_VER >= 150030729) || (__SUNPRO_CC >= 0x5120) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1110) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300)) + #define CRYPTOPP_CLMUL_AVAILABLE 1 +#endif + +// Requires Sun Studio 12.3 (SunCC 0x5120) +#if !defined(CRYPTOPP_DISABLE_AESNI) && defined(CRYPTOPP_SSE42_AVAILABLE) && \ + (defined(__AES__) || (_MSC_FULL_VER >= 150030729) || (__SUNPRO_CC >= 0x5120) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1110) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300)) + #define CRYPTOPP_AESNI_AVAILABLE 1 +#endif + +// Requires Binutils 2.24 +#if !defined(CRYPTOPP_DISABLE_AVX) && defined(CRYPTOPP_SSE42_AVAILABLE) && \ + (defined(__AVX2__) || (CRYPTOPP_MSC_VERSION >= 1800) || (__SUNPRO_CC >= 0x5130) || \ + (CRYPTOPP_GCC_VERSION >= 40700) || (__INTEL_COMPILER >= 1400) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40600)) +#define CRYPTOPP_AVX_AVAILABLE 1 +#endif + +// Requires Binutils 2.24 +#if !defined(CRYPTOPP_DISABLE_AVX2) && defined(CRYPTOPP_AVX_AVAILABLE) && \ + (defined(__AVX2__) || (CRYPTOPP_MSC_VERSION >= 1800) || (__SUNPRO_CC >= 0x5130) || \ + (CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1400) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40600)) +#define CRYPTOPP_AVX2_AVAILABLE 1 +#endif + +// Guessing at SHA for SunCC. Its not in Sun Studio 12.6. Also see +// http://stackoverflow.com/questions/45872180/which-xarch-for-sha-extensions-on-solaris +// Guessing for Intel ICPC. A slide deck says SHA support is in version 16.0-beta +// https://www.alcf.anl.gov/files/ken_intel_compiler_optimization.pdf +#if !defined(CRYPTOPP_DISABLE_SHANI) && defined(CRYPTOPP_SSE42_AVAILABLE) && \ + (defined(__SHA__) || (CRYPTOPP_MSC_VERSION >= 1900) || (__SUNPRO_CC >= 0x5160) || \ + (CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1600) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50100)) + #define CRYPTOPP_SHANI_AVAILABLE 1 +#endif + +// RDRAND uses byte codes. All we need is x86 ASM for it. +// However tie it to AES-NI since SecureKey was available with it. +#if !defined(CRYPTOPP_DISABLE_RDRAND) && defined(CRYPTOPP_AESNI_AVAILABLE) + #define CRYPTOPP_RDRAND_AVAILABLE 1 +#endif + +// RDSEED uses byte codes. All we need is x86 ASM for it. +// However tie it to AES-NI since SecureKey was available with it. +#if !defined(CRYPTOPP_DISABLE_RDSEED) && defined(CRYPTOPP_AESNI_AVAILABLE) + #define CRYPTOPP_RDSEED_AVAILABLE 1 +#endif + +// PadlockRNG uses byte codes. All we need is x86 ASM for it. +#if !defined(CRYPTOPP_DISABLE_PADLOCK) && \ + !(defined(__ANDROID__) || defined(ANDROID) || defined(__APPLE__)) && \ + defined(CRYPTOPP_X86_ASM_AVAILABLE) + #define CRYPTOPP_PADLOCK_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_RNG_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_ACE_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_ACE2_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_PHE_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_PMM_AVAILABLE 1 +#endif + +// Fixup for SunCC 12.1-12.4. Bad code generation in AES_Encrypt and friends. +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5130) +# undef CRYPTOPP_AESNI_AVAILABLE +#endif + +// Fixup for SunCC 12.1-12.6. Compiler crash on GCM_Reduce_CLMUL. +// http://github.com/weidai11/cryptopp/issues/226 +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5150) +# undef CRYPTOPP_CLMUL_AVAILABLE +#endif + +// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670 +#define M128_CAST(x) ((__m128i *)(void *)(x)) +#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) +#define M256_CAST(x) ((__m256i *)(void *)(x)) +#define CONST_M256_CAST(x) ((const __m256i *)(const void *)(x)) + +#endif // CRYPTOPP_DISABLE_ASM + +#endif // X86, X32, X64 + +// ***************** ARM CPU features ******************** + +#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) + +// We don't have an ARM big endian test rig. Disable +// ARM-BE ASM and instrinsics until we can test it. +#if (CRYPTOPP_BIG_ENDIAN) +# define CRYPTOPP_DISABLE_ASM 1 +#endif + +// Guard everything in CRYPTOPP_DISABLE_ASM +#if !defined(CRYPTOPP_DISABLE_ASM) + +// Requires ACLE 1.0. -mfpu=neon or above must be present +// Requires GCC 4.3, Clang 2.8 or Visual Studio 2012 +// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead. +#if !defined(CRYPTOPP_ARM_NEON_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_NEON) +# if defined(__arm__) || defined(__ARM_NEON) || defined(__ARM_FEATURE_NEON) || defined(_M_ARM) +# if (CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 30200) || (CRYPTOPP_MSC_VERSION >= 1700) +# define CRYPTOPP_ARM_NEON_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and ASIMD. -march=armv8-a or above must be present +// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017 +// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead. +#if !defined(CRYPTOPP_ARM_ASIMD_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_ASIMD) +# if defined(__aarch32__) || defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) +# if defined(__ARM_NEON) || defined(__ARM_ASIMD) || defined(__ARM_FEATURE_NEON) || defined(__ARM_FEATURE_ASIMD) || \ + (CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || (CRYPTOPP_MSC_VERSION >= 1916) +# define CRYPTOPP_ARM_NEON_AVAILABLE 1 +# define CRYPTOPP_ARM_ASIMD_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and ASIMD. -march=armv8-a+crc or above must be present +// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017 +#if !defined(CRYPTOPP_ARM_CRC32_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_CRC32) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_CRC32) || (CRYPTOPP_GCC_VERSION >= 40800) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300) || \ + (CRYPTOPP_MSC_VERSION >= 1916) +# define CRYPTOPP_ARM_CRC32_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and AES. -march=armv8-a+crypto or above must be present +// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017 +#if !defined(CRYPTOPP_ARM_AES_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_AES) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300) || \ + (CRYPTOPP_MSC_VERSION >= 1916) +# define CRYPTOPP_ARM_AES_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and PMULL. -march=armv8-a+crypto or above must be present +// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017 +#if !defined(CRYPTOPP_ARM_PMULL_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_PMULL) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300) || \ + (CRYPTOPP_MSC_VERSION >= 1916) +# define CRYPTOPP_ARM_PMULL_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and SHA-1, SHA-256. -march=armv8-a+crypto or above must be present +// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017 +#if !defined(CRYPTOPP_ARM_SHA_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_SHA) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300) || \ + (CRYPTOPP_MSC_VERSION >= 1916) +# define CRYPTOPP_ARM_SHA1_AVAILABLE 1 +# define CRYPTOPP_ARM_SHA2_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and SHA-512, SHA-3. -march=armv8.2-a+crypto or above must be present +// Requires GCC 8.0, Clang 11.0, Apple Clang 12.0 or Visual Studio 20?? +#if !defined(CRYPTOPP_ARM_SHA3_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_SHA) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_SHA3) || (CRYPTOPP_GCC_VERSION >= 80000) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 120000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 110000) +# define CRYPTOPP_ARM_SHA512_AVAILABLE 1 +# define CRYPTOPP_ARM_SHA3_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// ARMv8 and SM3, SM4. -march=armv8.2-a+crypto or above must be present +// Requires GCC 8.0, Clang ??? or Visual Studio 20?? +// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead. +#if !defined(CRYPTOPP_ARM_SM3_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_SM3) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_SM3) || (CRYPTOPP_GCC_VERSION >= 80000) +# define CRYPTOPP_ARM_SM3_AVAILABLE 1 +# define CRYPTOPP_ARM_SM4_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + +// Limit the include. +#if !defined(CRYPTOPP_ARM_NEON_HEADER) +# if defined(CRYPTOPP_ARM_NEON_AVAILABLE) || defined (CRYPTOPP_ARM_ASIMD_AVAILABLE) +# if !defined(_M_ARM64) +# define CRYPTOPP_ARM_NEON_HEADER 1 +# endif +# endif +#endif + +// Limit the include. +#if !defined(CRYPTOPP_ARM_ACLE_HEADER) +# if defined(__aarch32__) || defined(__aarch64__) || (__ARM_ARCH >= 8) || defined(__ARM_ACLE) +# define CRYPTOPP_ARM_ACLE_HEADER 1 +# endif +#endif + +// Apple M1 hack. Xcode cross-compiles for iOS lack +// arm_acle.h. Apple M1 needs arm_acle.h. The problem +// in practice is, we can't get CRYPTOPP_ARM_ACLE_HEADER +// quite right based on ARM preprocessor macros. +#if defined(__APPLE__) && !defined(__ARM_FEATURE_CRC32) +# undef CRYPTOPP_ARM_ACLE_HEADER +#endif + +// Cryptogams offers an ARM asm implementations for AES and SHA. Crypto++ does +// not provide an asm implementation. The Cryptogams AES implementation is +// about 50% faster than C/C++, and SHA implementation is about 30% faster +// than C/C++. Define this to use the Cryptogams AES and SHA implementations +// on GNU Linux systems. When defined, Crypto++ will use aes_armv4.S, +// sha1_armv4.S and sha256_armv4.S. https://www.cryptopp.com/wiki/Cryptogams. +#if defined(__arm__) && defined(__linux__) +# if defined(__GNUC__) || defined(__clang__) +# define CRYPTOGAMS_ARM_AES 1 +# define CRYPTOGAMS_ARM_SHA1 1 +# define CRYPTOGAMS_ARM_SHA256 1 +# define CRYPTOGAMS_ARM_SHA512 1 +# endif +#endif + +// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670 +#define UINT64_CAST(x) ((uint64_t *)(void *)(x)) +#define CONST_UINT64_CAST(x) ((const uint64_t *)(const void *)(x)) + +#endif // CRYPTOPP_DISABLE_ASM + +#endif // ARM32, ARM64 + +// ***************** AltiVec and Power8 ******************** + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + +// Guard everything in CRYPTOPP_DISABLE_ASM +#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_ALTIVEC) + +// An old Apple G5 with GCC 4.01 has AltiVec, but its only Power4 or so. +#if !defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# if defined(_ARCH_PWR4) || defined(__ALTIVEC__) || \ + (CRYPTOPP_XLC_VERSION >= 100000) || (CRYPTOPP_GCC_VERSION >= 40001) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) +# define CRYPTOPP_ALTIVEC_AVAILABLE 1 +# endif +#endif + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) + +// We need Power7 for unaligned loads and stores +#if !defined(CRYPTOPP_POWER7_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER7) +# if defined(_ARCH_PWR7) || (CRYPTOPP_XLC_VERSION >= 100000) || \ + (CRYPTOPP_GCC_VERSION >= 40100) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30100) +# define CRYPTOPP_POWER7_AVAILABLE 1 +# endif +#endif + +#if defined(CRYPTOPP_POWER7_AVAILABLE) + +// We need Power8 for in-core crypto and 64-bit vector types +#if !defined(CRYPTOPP_POWER8_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER8) +# if defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || \ + (CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 70000) +# define CRYPTOPP_POWER8_AVAILABLE 1 +# endif +#endif + +#if !defined(CRYPTOPP_POWER8_AES_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER8_AES) && defined(CRYPTOPP_POWER8_AVAILABLE) +# if defined(__CRYPTO__) || defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || \ + (CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 70000) +//# define CRYPTOPP_POWER8_CRC_AVAILABLE 1 +# define CRYPTOPP_POWER8_AES_AVAILABLE 1 +# define CRYPTOPP_POWER8_VMULL_AVAILABLE 1 +# define CRYPTOPP_POWER8_SHA_AVAILABLE 1 +# endif +#endif + +#if defined(CRYPTOPP_POWER8_AVAILABLE) + +// Power9 for random numbers +#if !defined(CRYPTOPP_POWER9_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER9) +# if defined(_ARCH_PWR9) || (CRYPTOPP_XLC_VERSION >= 130200) || \ + (CRYPTOPP_GCC_VERSION >= 70000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 80000) +# define CRYPTOPP_POWER9_AVAILABLE 1 +# endif +#endif + +#endif // CRYPTOPP_POWER8_AVAILABLE +#endif // CRYPTOPP_POWER7_AVAILABLE +#endif // CRYPTOPP_ALTIVEC_AVAILABLE +#endif // CRYPTOPP_DISABLE_ASM +#endif // PPC32, PPC64 + +// https://github.com/weidai11/cryptopp/issues/1015 +#if defined(CRYPTOPP_DISABLE_ANDROID_ADVANCED_ISA) +# if defined(__ANDROID__) || defined(ANDROID) +# if (CRYPTOPP_BOOL_X86) +# undef CRYPTOPP_SSE41_AVAILABLE +# undef CRYPTOPP_SSE42_AVAILABLE +# undef CRYPTOPP_CLMUL_AVAILABLE +# undef CRYPTOPP_AESNI_AVAILABLE +# undef CRYPTOPP_SHANI_AVAILABLE +# undef CRYPTOPP_RDRAND_AVAILABLE +# undef CRYPTOPP_RDSEED_AVAILABLE +# undef CRYPTOPP_AVX_AVAILABLE +# undef CRYPTOPP_AVX2_AVAILABLE +# endif +# if (CRYPTOPP_BOOL_X64) +# undef CRYPTOPP_CLMUL_AVAILABLE +# undef CRYPTOPP_AESNI_AVAILABLE +# undef CRYPTOPP_SHANI_AVAILABLE +# undef CRYPTOPP_RDRAND_AVAILABLE +# undef CRYPTOPP_RDSEED_AVAILABLE +# undef CRYPTOPP_AVX_AVAILABLE +# undef CRYPTOPP_AVX2_AVAILABLE +# endif +# if (CRYPTOPP_BOOL_ARMV8) +# undef CRYPTOPP_ARM_CRC32_AVAILABLE +# undef CRYPTOPP_ARM_PMULL_AVAILABLE +# undef CRYPTOPP_ARM_AES_AVAILABLE +# undef CRYPTOPP_ARM_SHA1_AVAILABLE +# undef CRYPTOPP_ARM_SHA2_AVAILABLE +# endif +# endif // ANDROID +#endif // CRYPTOPP_DISABLE_ANDROID_ADVANCED_ISA + +#endif // CRYPTOPP_CONFIG_ASM_H diff --git a/external/ours/library/crypto/src/shared/original/config_cpu.h b/external/ours/library/crypto/src/shared/original/config_cpu.h new file mode 100755 index 000000000..3eeaf2341 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_cpu.h @@ -0,0 +1,211 @@ +// config_cpu.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_cpu.h +/// \brief Library configuration file +/// \details config_cpu.h provides defines for the cpu and machine +/// architecture. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_cpu.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki, +/// Sourceforge +/// Pre-defined Compiler Macros +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_CPU_H +#define CRYPTOPP_CONFIG_CPU_H + +#include "config_ver.h" + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief 32-bit x32 platform + /// \details CRYPTOPP_BOOL_X32 is defined to 1 when building the library + /// for a 32-bit x32 platform. Otherwise, the macro is not defined. + /// \details x32 is sometimes referred to as x86_32. x32 is the ILP32 data + /// model on a 64-bit cpu. Integers, longs and pointers are 32-bit but the + /// program runs on a 64-bit cpu. + /// \details The significance of x32 is, inline assembly must operate on + /// 64-bit registers, not 32-bit registers. That means, for example, + /// function prologues and epilogues must push and pop RSP, not ESP. + /// \note: Clang defines __ILP32__ on any 32-bit platform. Therefore, + /// CRYPTOPP_BOOL_X32 depends upon both __ILP32__ and __x86_64__. + /// \sa Debian X32 Port, + /// Gentoo + /// Multilib Concepts + #define CRYPTOPP_BOOL_X32 ... + /// \brief 32-bit x86 platform + /// \details CRYPTOPP_BOOL_X64 is defined to 1 when building the library + /// for a 64-bit x64 platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_X64 ... + /// \brief 32-bit x86 platform + /// \details CRYPTOPP_BOOL_X86 is defined to 1 when building the library + /// for a 32-bit x86 platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_X86 ... +#elif (defined(__ILP32__) || defined(_ILP32)) && defined(__x86_64__) + #define CRYPTOPP_BOOL_X32 1 +#elif (defined(_M_X64) || defined(__x86_64__)) + #define CRYPTOPP_BOOL_X64 1 +#elif (defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__)) + #define CRYPTOPP_BOOL_X86 1 +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief ARMv8 platform + /// \details CRYPTOPP_BOOL_ARMV8 is defined to 1 when building the library + /// for an ARMv8 platform. Otherwise, the macro is not defined. + /// \details ARMv8 includes both Aarch32 and Aarch64. Aarch32 is a 32-bit + /// execution environment on Aarch64. + #define CRYPTOPP_BOOL_ARMV8 ... + /// \brief 64-bit ARM platform + /// \details CRYPTOPP_BOOL_ARM64 is defined to 1 when building the library + /// for a 64-bit x64 platform. Otherwise, the macro is not defined. + /// \details Currently the macro indicates an ARM 64-bit architecture. + #define CRYPTOPP_BOOL_ARM64 ... + /// \brief 32-bit ARM platform + /// \details CRYPTOPP_BOOL_ARM32 is defined to 1 when building the library + /// for a 32-bit ARM platform. Otherwise, the macro is not defined. + /// \details Currently the macro indicates an ARM A-32 architecture. + #define CRYPTOPP_BOOL_ARM32 ... +#elif defined(__arm64__) || defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) + // Microsoft added ARM64 define December 2017. + #define CRYPTOPP_BOOL_ARMV8 1 +#endif +#if defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) + #define CRYPTOPP_BOOL_ARM64 1 +#elif defined(__arm__) || defined(_M_ARM) + #define CRYPTOPP_BOOL_ARM32 1 +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief 64-bit PowerPC platform + /// \details CRYPTOPP_BOOL_PPC64 is defined to 1 when building the library + /// for a 64-bit PowerPC platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_PPC64 ... + /// \brief 32-bit PowerPC platform + /// \details CRYPTOPP_BOOL_PPC32 is defined to 1 when building the library + /// for a 32-bit PowerPC platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_PPC32 ... +#elif defined(__ppc64__) || defined(__powerpc64__) || defined(__PPC64__) || defined(_ARCH_PPC64) + #define CRYPTOPP_BOOL_PPC64 1 +#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC) + #define CRYPTOPP_BOOL_PPC32 1 +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief 64-bit MIPS platform + /// \details CRYPTOPP_BOOL_MIPS64 is defined to 1 when building the library + /// for a 64-bit MIPS platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_MIPS64 ... + /// \brief 64-bit MIPS platform + /// \details CRYPTOPP_BOOL_MIPS32 is defined to 1 when building the library + /// for a 32-bit MIPS platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_MIPS32 ... +#elif defined(__mips64__) + #define CRYPTOPP_BOOL_MIPS64 1 +#elif defined(__mips__) + #define CRYPTOPP_BOOL_MIPS32 1 +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief 64-bit SPARC platform + /// \details CRYPTOPP_BOOL_SPARC64 is defined to 1 when building the library + /// for a 64-bit SPARC platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_SPARC64 ... + /// \brief 32-bit SPARC platform + /// \details CRYPTOPP_BOOL_SPARC32 is defined to 1 when building the library + /// for a 32-bit SPARC platform. Otherwise, the macro is not defined. + #define CRYPTOPP_BOOL_SPARC32 ... +#elif defined(__sparc64__) || defined(__sparc64) || defined(__sparcv9) || defined(__sparc_v9__) + #define CRYPTOPP_BOOL_SPARC64 1 +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) || defined(__sparc_v8__) + #define CRYPTOPP_BOOL_SPARC32 1 +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief L1 data cache line size + /// \details CRYPTOPP_L1_CACHE_LINE_SIZE should be a lower bound on the L1 + /// data cache line size. It is used for defense against some timing attacks. + /// \details CRYPTOPP_L1_CACHE_LINE_SIZE default value on 32-bit platforms + /// is 32, and the default value on 64-bit platforms is 64. On PowerPC the + /// default value is 128 since all PowerPC cpu's starting at PPC 970 provide + /// it. + /// \note The runtime library on some PowerPC platforms misreport the size + /// of the cache line size. The runtime library reports 64, while the cpu + /// has a cache line size of 128. + /// \sa CentOS Issue + /// 14599: sysconf(_SC_LEVEL1_DCACHE_LINESIZE) returns 0 instead of 128 + /// \since Crypto++ 5.3 + #define CRYPTOPP_L1_CACHE_LINE_SIZE ... +#else + #ifndef CRYPTOPP_L1_CACHE_LINE_SIZE + #if defined(CRYPTOPP_BOOL_X32) || defined(CRYPTOPP_BOOL_X64) || defined(CRYPTOPP_BOOL_ARMV8) || \ + defined(CRYPTOPP_BOOL_MIPS64) || defined(CRYPTOPP_BOOL_SPARC64) + #define CRYPTOPP_L1_CACHE_LINE_SIZE 64 + #elif defined(CRYPTOPP_BOOL_PPC32) || defined(CRYPTOPP_BOOL_PPC64) + // http://lists.llvm.org/pipermail/llvm-dev/2017-March/110982.html + #define CRYPTOPP_L1_CACHE_LINE_SIZE 128 + #else + // L1 cache line size is 32 on Pentium III and earlier + #define CRYPTOPP_L1_CACHE_LINE_SIZE 32 + #endif + #endif +#endif + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief Initialized data section + /// \details CRYPTOPP_SECTION_INIT is added to variables to place them in the + /// initialized data section (sometimes denoted .data). The placement + /// helps avoid "uninitialized variable" warnings from Valgrind and other tools. + #define CRYPTOPP_SECTION_INIT ... +#else + // The section attribute attempts to initialize CPU flags to avoid Valgrind findings above -O1 + #if ((defined(__MACH__) && defined(__APPLE__)) && ((CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 70100) || (CRYPTOPP_GCC_VERSION >= 40300))) + #define CRYPTOPP_SECTION_INIT __attribute__((section ("__DATA,__data"))) + #elif (defined(__ELF__) && (CRYPTOPP_GCC_VERSION >= 40300)) + #define CRYPTOPP_SECTION_INIT __attribute__((section ("nocommon"))) + #elif defined(__ELF__) && (defined(__xlC__) || defined(__ibmxl__)) + #define CRYPTOPP_SECTION_INIT __attribute__((section ("nocommon"))) + #else + #define CRYPTOPP_SECTION_INIT + #endif +#endif + +// How to disable CPU feature probing. We determine machine +// capabilities by performing an os/platform *query* first, +// like getauxv(). If the *query* fails, we move onto a +// cpu *probe*. The cpu *probe* tries to exeute an instruction +// and then catches a SIGILL on Linux or the exception +// EXCEPTION_ILLEGAL_INSTRUCTION on Windows. Some OSes +// fail to hangle a SIGILL gracefully, like Apple OSes. Apple +// machines corrupt memory and variables around the probe. +#if defined(__APPLE__) + #define CRYPTOPP_NO_CPU_FEATURE_PROBES 1 +#endif + +// Flavor of inline assembly language +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief Microsoft style inline assembly + /// \details CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY is defined when either + /// _MSC_VER or __BORLANDC__ are defined. + #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY ... + /// \brief GNU style inline assembly + /// \details CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY is defined when neither + /// _MSC_VER nor __BORLANDC__ are defined. + #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY ... +#elif defined(_MSC_VER) || defined(__BORLANDC__) + #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 1 +#else + #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY 1 +#endif + +#endif // CRYPTOPP_CONFIG_CPU_H diff --git a/external/ours/library/crypto/src/shared/original/config_cxx.h b/external/ours/library/crypto/src/shared/original/config_cxx.h new file mode 100755 index 000000000..95093de76 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_cxx.h @@ -0,0 +1,247 @@ +// config_cxx.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_cxx.h +/// \brief Library configuration file +/// \details config_cxx.h provides defines for C++ language and +/// runtime library +/// features. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_cxx.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +// Visual Studio began at VS2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx +// and https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance +// Intel, http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler +// GCC, http://gcc.gnu.org/projects/cxx0x.html +// Clang, http://clang.llvm.org/cxx_status.html + +#ifndef CRYPTOPP_CONFIG_CXX_H +#define CRYPTOPP_CONFIG_CXX_H + +#include "config_os.h" +#include "config_cpu.h" +#include "config_ver.h" + +// https://github.com/weidai11/cryptopp/issues/960 +#include +#include + +// You may need to force include a C++ header on Android when using STLPort +// to ensure _STLPORT_VERSION is defined +#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || (defined(_STLPORT_VERSION) && ((_STLPORT_VERSION < 0x450) || defined(_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT))) +#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION +#endif + +// Ancient Crypto++ define, dating back to C++98. +#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION +# define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE 1 +# define CRYPTOPP_CXX98_UNCAUGHT_EXCEPTION 1 +#endif + +// Compatibility with non-clang compilers. +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +// C++11 macro version, https://stackoverflow.com/q/7223991/608639 +#if ((_MSC_VER >= 1600) || (__cplusplus >= 201103L)) && !defined(_STLPORT_VERSION) +# define CRYPTOPP_CXX11 1 +#endif + +// Hack ahead. Apple's standard library does not have C++'s unique_ptr in C++11. +// We can't test for unique_ptr directly because some of the non-Apple Clangs +// on OS X fail the same way. However, modern standard libraries have +// , so we test for it instead. Thanks to Jonathan Wakely for +// devising the clever test for modern/ancient versions. TODO: test under +// Xcode 3, where g++ is really g++. +#if defined(__APPLE__) && defined(__clang__) +# if !(defined(__has_include) && __has_include()) +# undef CRYPTOPP_CXX11 +# endif +#endif + +// C++14 macro version, https://stackoverflow.com/q/26089319/608639 +#if defined(CRYPTOPP_CXX11) && !defined(CRYPTOPP_NO_CXX14) +# if ((_MSC_VER >= 1900) || (__cplusplus >= 201402L)) && !defined(_STLPORT_VERSION) +# define CRYPTOPP_CXX14 1 +# endif +#endif + +// C++17 macro version, https://stackoverflow.com/q/38456127/608639 +#if defined(CRYPTOPP_CXX14) && !defined(CRYPTOPP_NO_CXX17) +# if ((_MSC_VER >= 1900) || (__cplusplus >= 201703L)) && !defined(_STLPORT_VERSION) +# define CRYPTOPP_CXX17 1 +# endif +#endif + +// ***************** C++11 and above ******************** + +#if defined(CRYPTOPP_CXX11) + +// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 5.14. +#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_atomic) || \ + (__INTEL_COMPILER >= 1300) || (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5140) +# define CRYPTOPP_CXX11_ATOMIC 1 +#endif // atomics + +// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 5.13. +// TODO: verify Clang and Intel versions; find __has_feature(x) extension for Clang +#if (CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 50000) || (__INTEL_COMPILER >= 1200) || \ + (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5130) +// Hack ahead. New GCC compilers like GCC 6 on AIX 7.0 or earlier as well as original MinGW +// don't have the synchronization gear. However, Wakely's test used for Apple does not work +// on the GCC/AIX combination. Another twist is we need other stuff from C++11, +// like no-except destructors. Dumping preprocessors shows the following may +// apply: http://stackoverflow.com/q/14191566/608639. +# include +# if !defined(__GLIBCXX__) || defined(_GLIBCXX_HAS_GTHREADS) +# define CRYPTOPP_CXX11_SYNCHRONIZATION 1 +# endif +#endif // synchronization + +// Dynamic Initialization and Destruction with Concurrency ("Magic Statics") +// MS at VS2015 with Vista (19.00); GCC at 4.3; LLVM Clang at 2.9; Apple Clang at 4.0; Intel 11.1; SunCC 5.13. +// Microsoft's implementation only works for Vista and above, so its further +// limited. http://connect.microsoft.com/VisualStudio/feedback/details/1789709 +// Clang may not support this as early as we indicate. Also see https://bugs.llvm.org/show_bug.cgi?id=47012. +#if (__cpp_threadsafe_static_init >= 200806) || \ + (CRYPTOPP_MSC_VERSION >= 1900) && ((WINVER >= 0x0600) || (_WIN32_WINNT >= 0x0600)) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || \ + (__INTEL_COMPILER >= 1110) || (CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_STATIC_INIT 1 +#endif // Dynamic Initialization compilers + +// deleted functions: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13. +#if (CRYPTOPP_MSC_VERSION >= 1800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || (__INTEL_COMPILER >= 1210) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_DELETED_FUNCTIONS 1 +#endif // deleted functions + +// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.0; Intel 15.0; SunCC 5.13. +#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_alignas) || \ + (__INTEL_COMPILER >= 1500) || (CRYPTOPP_GCC_VERSION >= 40800) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_ALIGNAS 1 +#endif // alignas + +// alignof: MS at VS2015 (19.00); GCC at 4.5; Clang at 2.9; Intel 15.0; SunCC 5.13. +#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_alignof) || \ + (__INTEL_COMPILER >= 1500) || (CRYPTOPP_GCC_VERSION >= 40500) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_ALIGNOF 1 +#endif // alignof + +// initializer lists: MS at VS2013 (18.00); GCC at 4.4; Clang at 3.1; Intel 14.0; SunCC 5.13. +#if (CRYPTOPP_MSC_VERSION >= 1800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || (__INTEL_COMPILER >= 1400) || \ + (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_INITIALIZER_LIST 1 +#endif // alignas + +// lambdas: MS at VS2012 (17.00); GCC at 4.9; Clang at 3.3; Intel 12.0; SunCC 5.14. +#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_lambdas) || \ + (__INTEL_COMPILER >= 1200) || (CRYPTOPP_GCC_VERSION >= 40900) || (__SUNPRO_CC >= 0x5140) +# define CRYPTOPP_CXX11_LAMBDA 1 +#endif // lambdas + +// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 5.13. +#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_noexcept) || \ + (__INTEL_COMPILER >= 1400) || (CRYPTOPP_GCC_VERSION >= 40600) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_NOEXCEPT 1 +#endif // noexcept compilers + +// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13. +#if (__cpp_variadic_templates >= 200704) || __has_feature(cxx_variadic_templates) || \ + (CRYPTOPP_MSC_VERSION >= 1800) || (__INTEL_COMPILER >= 1210) || \ + (CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1 +#endif // variadic templates + +// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.1; Intel 16.0; SunCC 5.13. +// Intel has mis-supported the feature since at least ICPC 13.00 +#if (__cpp_constexpr >= 200704) || __has_feature(cxx_constexpr) || \ + (CRYPTOPP_MSC_VERSION >= 1900) || (__INTEL_COMPILER >= 1600) || \ + (CRYPTOPP_GCC_VERSION >= 40600) || (__SUNPRO_CC >= 0x5130) +# define CRYPTOPP_CXX11_CONSTEXPR 1 +#endif // constexpr compilers + +// strong typed enums: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Intel 14.0; SunCC 5.12. +// Mircorosft and Intel had partial support earlier, but we require full support. +#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_strong_enums) || \ + (__INTEL_COMPILER >= 1400) || (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5120) +# define CRYPTOPP_CXX11_STRONG_ENUM 1 +#endif // constexpr compilers + +// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 10.0; SunCC 5.13. +#if (CRYPTOPP_MSC_VERSION >= 1600) || __has_feature(cxx_nullptr) || \ + (__INTEL_COMPILER >= 1000) || (CRYPTOPP_GCC_VERSION >= 40600) || \ + (__SUNPRO_CC >= 0x5130) || defined(__IBMCPP_NULLPTR) +# define CRYPTOPP_CXX11_NULLPTR 1 +#endif // nullptr_t compilers + +#endif // CRYPTOPP_CXX11 + +// ***************** C++14 and above ******************** + +#if defined(CRYPTOPP_CXX14) + +// Extended static_assert with one argument +// Microsoft cannot handle the single argument static_assert as of VS2019 (cl.exe 19.00) +#if (__cpp_static_assert >= 201411) +# define CRYPTOPP_CXX17_STATIC_ASSERT 1 +#endif // static_assert + +#endif + +// ***************** C++17 and above ******************** + +// C++17 is available +#if defined(CRYPTOPP_CXX17) + +// C++17 uncaught_exceptions: MS at VS2015 (19.00); GCC at 6.0; Clang at 3.5; Intel 18.0. +// Clang and __EXCEPTIONS see http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html +// Also see https://github.com/weidai11/cryptopp/issues/980. I'm not sure what +// to do when the compiler defines __cpp_lib_uncaught_exceptions but the platform +// does not support std::uncaught_exceptions. What was Apple thinking??? +#if defined(__clang__) +# if __EXCEPTIONS && __has_feature(cxx_exceptions) +# if __cpp_lib_uncaught_exceptions >= 201411L +# define CRYPTOPP_CXX17_UNCAUGHT_EXCEPTIONS 1 +# endif +# endif +#elif (CRYPTOPP_MSC_VERSION >= 1900) || (__INTEL_COMPILER >= 1800) || \ + (CRYPTOPP_GCC_VERSION >= 60000) || (__cpp_lib_uncaught_exceptions >= 201411L) +# define CRYPTOPP_CXX17_UNCAUGHT_EXCEPTIONS 1 +#endif // uncaught_exceptions compilers + +#endif // CRYPTOPP_CXX17 + +// ***************** C++ fixups ******************** + +#if defined(CRYPTOPP_CXX11_NOEXCEPT) +# define CRYPTOPP_THROW noexcept(false) +# define CRYPTOPP_NO_THROW noexcept(true) +#else +# define CRYPTOPP_THROW +# define CRYPTOPP_NO_THROW +#endif // CRYPTOPP_CXX11_NOEXCEPT + +// Hack... C++11 nullptr_t type safety and analysis +#if defined(CRYPTOPP_CXX11_NULLPTR) && !defined(NULLPTR) +# define NULLPTR nullptr +#elif !defined(NULLPTR) +# define NULLPTR NULL +#endif // CRYPTOPP_CXX11_NULLPTR + +#endif // CRYPTOPP_CONFIG_CXX_H diff --git a/external/ours/library/crypto/src/shared/original/config_dll.h b/external/ours/library/crypto/src/shared/original/config_dll.h new file mode 100755 index 000000000..ab9c67afa --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_dll.h @@ -0,0 +1,178 @@ +// config_dll.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_dll.h +/// \brief Library configuration file +/// \details config_dll.h provides defines for shared objects and +/// dynamic libraries. Generally speaking the macros are used to export +/// classes and template classes from the Win32 dynamic link library. +/// When not building the Win32 dynamic link library they are mostly an extern +/// template declaration. +/// \details In practice they are a furball coughed up by a cat and then peed +/// on by a dog. They are awful to get just right because of inconsistent +/// compiler support for extern templates, manual instantiation and the FIPS DLL. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_dll.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script, +/// Visual Studio, +/// and FIPS DLL +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_DLL_H +#define CRYPTOPP_CONFIG_DLL_H + +#include "config_os.h" + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + + /// \brief Win32 define for dynamic link libraries + /// \details CRYPTOPP_IMPORTS is set in the Visual Studio project files. + /// When the macro is set, CRYPTOPP_DLL is defined to + /// __declspec(dllimport). + /// \details This macro has no effect on Unix & Linux. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_IMPORTS ... + + /// \brief Win32 define for dynamic link libraries + /// \details CRYPTOPP_EXPORTS is set in the Visual Studio project files. + /// When the macro is set, CRYPTOPP_DLL is defined to + /// __declspec(dllexport). + /// \details This macro has no effect on Unix & Linux. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_EXPORTS ... + + /// \brief Win32 define for dynamic link libraries + /// \details CRYPTOPP_IS_DLL is set in the Visual Studio project files. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_IS_DLL + + /// \brief Instantiate templates in a dynamic library + /// \details CRYPTOPP_DLL_TEMPLATE_CLASS decoration should be used + /// for classes intended to be exported from dynamic link libraries. + /// \details This macro is primarily used on Win32, but sees some + /// action on Unix & Linux due to the source file dll.cpp. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_DLL_TEMPLATE_CLASS ... + + /// \brief Instantiate templates in a dynamic library + /// \details CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS decoration should be used + /// for template classes intended to be exported from dynamic link libraries. + /// \details This macro is primarily used on Win32, but sees some + /// action on Unix & Linux due to the source file dll.cpp. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS ... + + /// \brief Instantiate templates in a dynamic library + /// \details CRYPTOPP_STATIC_TEMPLATE_CLASS decoration should be used + /// for template classes intended to be exported from dynamic link libraries. + /// \details This macro is primarily used on Win32, but sees some + /// action on Unix & Linux due to the source file dll.cpp. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_STATIC_TEMPLATE_CLASS ... + + /// \brief Instantiate templates in a dynamic library + /// \details CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS decoration should be used + /// for template classes intended to be exported from dynamic link libraries. + /// \details This macro is primarily used on Win32, but sees some + /// action on Unix & Linux due to the source file dll.cpp. + /// \sa Visual Studio, + /// and FIPS DLL + /// on the Crypto++ wiki + #define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS ... + + /// \brief Override for internal linkage + /// \details CRYPTOPP_TABLE can be used to override internal linkage + /// on tables with the const qualifier. According to C++ rules + /// a decalration with const qualifier is internal linkage. + /// \note The name CRYPTOPP_TABLE was chosen because it is often used to + /// export a table, like AES or SHA constants. The name avoids collisions + /// with the DLL gear macros, like CRYPTOPP_EXPORTS and CRYPTOPP_EXTERN. + #define CRYPTOPP_TABLE extern + + /// \brief Win32 calling convention + /// \details CRYPTOPP_API sets the calling convention on Win32. + /// On Win32 CRYPTOPP_API is __cedcl. On Unix & Linux + /// CRYPTOPP_API is defined to nothing. + /// \sa Visual Studio + /// on the Crypto++ wiki + #define CRYPTOPP_API ... + +#else // CRYPTOPP_DOXYGEN_PROCESSING + +#if defined(CRYPTOPP_WIN32_AVAILABLE) + + #if defined(CRYPTOPP_EXPORTS) + # define CRYPTOPP_IS_DLL + # define CRYPTOPP_DLL __declspec(dllexport) + #elif defined(CRYPTOPP_IMPORTS) + # define CRYPTOPP_IS_DLL + # define CRYPTOPP_DLL __declspec(dllimport) + #else + # define CRYPTOPP_DLL + #endif + + // C++ makes const internal linkage + #define CRYPTOPP_TABLE extern + #define CRYPTOPP_API __cdecl + +#else // not CRYPTOPP_WIN32_AVAILABLE + + // C++ makes const internal linkage + #define CRYPTOPP_TABLE extern + #define CRYPTOPP_DLL + #define CRYPTOPP_API + +#endif // CRYPTOPP_WIN32_AVAILABLE + +#if defined(__MWERKS__) +# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL +#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) +# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL +#else +# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL +#endif + +#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS) +# define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL +#else +# define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS +#endif + +#if defined(__MWERKS__) +# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class +#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) +# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class +#else +# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class +#endif + +#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS) +# define CRYPTOPP_STATIC_TEMPLATE_CLASS template class +#else +# define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS +#endif + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +#endif // CRYPTOPP_CONFIG_DLL_H diff --git a/external/ours/library/crypto/src/shared/original/config_int.h b/external/ours/library/crypto/src/shared/original/config_int.h new file mode 100755 index 000000000..2f74480fb --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_int.h @@ -0,0 +1,253 @@ +// config_int.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_int.h +/// \brief Library configuration file +/// \details config_int.h provides defines and typedefs for fixed +/// size integers. The library's choices for fixed size integers predates other +/// standard-based integers by about 5 years. After fixed sizes were +/// made standard, the library continued to use its own definitions for +/// compatibility with previous versions of the library. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_int.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_INT_H +#define CRYPTOPP_CONFIG_INT_H + +#include "config_ns.h" +#include "config_ver.h" + +/// \brief Library byte guard +/// \details CRYPTOPP_NO_GLOBAL_BYTE indicates byte is in the Crypto++ +/// namespace. +/// \details The Crypto++ byte was originally in global namespace to avoid +/// ambiguity with other byte typedefs. byte was moved to CryptoPP namespace +/// at Crypto++ 6.0 due to C++17, std::byte and potential compile problems. +/// \sa Issue 442, +/// std::byte on the +/// Crypto++ wiki +/// \since Crypto++ 6.0 +#define CRYPTOPP_NO_GLOBAL_BYTE 1 + +NAMESPACE_BEGIN(CryptoPP) + +// Signed words added at Issue 609 for early versions of and Visual Studio and +// the NaCl gear. Also see https://github.com/weidai11/cryptopp/issues/609. + +/// \brief 8-bit unsigned datatype +/// \details The Crypto++ byte was originally in global namespace to avoid +/// ambiguity with other byte typedefs. byte was moved to CryptoPP namespace +/// at Crypto++ 6.0 due to C++17, std::byte and potential compile problems. +/// \sa CRYPTOPP_NO_GLOBAL_BYTE, Issue 442, +/// std::byte on the +/// Crypto++ wiki +/// \since Crypto++ 1.0, CryptoPP namespace since Crypto++ 6.0 +typedef unsigned char byte; +/// \brief 16-bit unsigned datatype +/// \since Crypto++ 1.0 +typedef unsigned short word16; +/// \brief 32-bit unsigned datatype +/// \since Crypto++ 1.0 +typedef unsigned int word32; + +/// \brief 8-bit signed datatype +/// \details The 8-bit signed datatype was added to support constant time +/// implementations for curve25519, X25519 key agreement and ed25519 +/// signatures. +/// \since Crypto++ 8.0 +typedef signed char sbyte; +/// \brief 16-bit signed datatype +/// \details The 32-bit signed datatype was added to support constant time +/// implementations for curve25519, X25519 key agreement and ed25519 +/// signatures. +/// \since Crypto++ 8.0 +typedef signed short sword16; +/// \brief 32-bit signed datatype +/// \details The 32-bit signed datatype was added to support constant time +/// implementations for curve25519, X25519 key agreement and ed25519 +/// signatures. +/// \since Crypto++ 8.0 +typedef signed int sword32; + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + + /// \brief 64-bit unsigned datatype + /// \details The typedef for word64 varies depending on the platform. + /// On Microsoft platforms it is unsigned __int64. On Unix & Linux + /// with LP64 data model it is unsigned long. On Unix & Linux with ILP32 + /// data model it is unsigned long long. + /// \since Crypto++ 1.0 + typedef unsigned long long word64; + + /// \brief 64-bit signed datatype + /// \details The typedef for sword64 varies depending on the platform. + /// On Microsoft platforms it is signed __int64. On Unix & Linux + /// with LP64 data model it is signed long. On Unix & Linux with ILP32 + /// data model it is signed long long. + /// \since Crypto++ 8.0 + typedef signed long long sword64; + + /// \brief 128-bit unsigned datatype + /// \details The typedef for word128 varies depending on the platform. + /// word128 is only available on 64-bit machines when + /// CRYPTOPP_WORD128_AVAILABLE is defined. + /// On Unix & Linux with LP64 data model it is __uint128_t. + /// Microsoft platforms do not provide a 128-bit integer type. 32-bit platforms + /// do not provide a 128-bit integer type. + /// \since Crypto++ 5.6 + typedef __uint128_t word128; + + /// \brief Declare an unsigned word64 + /// \details W64LIT is used to portability declare or assign 64-bit literal values. + /// W64LIT will append the proper suffix to ensure the compiler accepts the literal. + /// \details Use the macro like shown below. + ///

+	///    word64 x = W64LIT(0xffffffffffffffff);
+	///  
+ /// \since Crypto++ 1.0 + #define W64LIT(x) ... + + /// \brief Declare a signed word64 + /// \details SW64LIT is used to portability declare or assign 64-bit literal values. + /// SW64LIT will append the proper suffix to ensure the compiler accepts the literal. + /// \details Use the macro like shown below. + ///
+	///    sword64 x = SW64LIT(0xffffffffffffffff);
+	///  
+ /// \since Crypto++ 8.0 + #define SW64LIT(x) ... + + /// \brief Declare ops on word64 are slow + /// \details CRYPTOPP_BOOL_SLOW_WORD64 is typically defined to 1 on platforms + /// that have a machine word smaller than 64-bits. That is, the define + /// is present on 32-bit platforms. The define is also present on platforms + /// where the cpu is slow even with a 64-bit cpu. + #define CRYPTOPP_BOOL_SLOW_WORD64 ... + +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef signed __int64 sword64; + typedef unsigned __int64 word64; + #define SW64LIT(x) x##i64 + #define W64LIT(x) x##ui64 +#elif (_LP64 || __LP64__) + typedef signed long sword64; + typedef unsigned long word64; + #define SW64LIT(x) x##L + #define W64LIT(x) x##UL +#else + typedef signed long long sword64; + typedef unsigned long long word64; + #define SW64LIT(x) x##LL + #define W64LIT(x) x##ULL +#endif + +/// \brief Large word type +/// \details lword is a typedef for large word types. It is used for file +/// offsets and such. +typedef word64 lword; + +/// \brief Large word type max value +/// \details LWORD_MAX is the maximum value for large word types. +/// Since an lword is an unsigned type, the value is +/// 0xffffffffffffffff. W64LIT will append the proper suffix. +const lword LWORD_MAX = W64LIT(0xffffffffffffffff); + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief Half word used for multiprecision integer arithmetic + /// \details hword is used for multiprecision integer arithmetic. + /// The typedef for hword varies depending on the platform. + /// On 32-bit platforms it is usually word16. On 64-bit platforms + /// it is usually word32. + /// \details Library users typically use byte, word16, word32 and word64. + /// \since Crypto++ 2.0 + typedef word32 hword; + /// \brief Full word used for multiprecision integer arithmetic + /// \details word is used for multiprecision integer arithmetic. + /// The typedef for word varies depending on the platform. + /// On 32-bit platforms it is usually word32. On 64-bit platforms + /// it is usually word64. + /// \details Library users typically use byte, word16, word32 and word64. + /// \since Crypto++ 2.0 + typedef word64 word; + /// \brief Double word used for multiprecision integer arithmetic + /// \details dword is used for multiprecision integer arithmetic. + /// The typedef for dword varies depending on the platform. + /// On 32-bit platforms it is usually word64. On 64-bit Unix & + /// Linux platforms it is usually word128. word128 is + /// not available on Microsoft platforms. word128 is only available + /// when CRYPTOPP_WORD128_AVAILABLE is defined. + /// \details Library users typically use byte, word16, word32 and word64. + /// \sa CRYPTOPP_WORD128_AVAILABLE + /// \since Crypto++ 2.0 + typedef word128 dword; + + /// \brief 128-bit word availability + /// \details CRYPTOPP_WORD128_AVAILABLE indicates a 128-bit word is + /// available from the platform. 128-bit words are usually available on + /// 64-bit platforms, but not available 32-bit platforms. + /// \details If CRYPTOPP_WORD128_AVAILABLE is not defined, then 128-bit + /// words are not available. + /// \details GCC and compatible compilers signal 128-bit word availability + /// with the preporcessor macro __SIZEOF_INT128__ >= 16. + /// \since Crypto++ 2.0 + #define CRYPTOPP_WORD128_AVAILABLE ... +#else + // define hword, word, and dword. these are used for multiprecision integer arithmetic + // Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx + #if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__)) + typedef word32 hword; + typedef word64 word; + #else + #define CRYPTOPP_NATIVE_DWORD_AVAILABLE 1 + #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__) || defined(__aarch64__) + #if ((CRYPTOPP_GCC_VERSION >= 30400) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30000) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300)) && (__SIZEOF_INT128__ >= 16) + // GCC 4.0.1 on MacOS X is missing __umodti3 and __udivti3 + // GCC 4.8.3 and bad uint128_t ops on PPC64/POWER7 (Issue 421) + // mode(TI) division broken on amd64 with GCC earlier than GCC 3.4 + typedef word32 hword; + typedef word64 word; + typedef __uint128_t dword; + typedef __uint128_t word128; + #define CRYPTOPP_WORD128_AVAILABLE 1 + #else + // if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results + typedef word16 hword; + typedef word32 word; + typedef word64 dword; + #endif + #else + // being here means the native register size is probably 32 bits or less + #define CRYPTOPP_BOOL_SLOW_WORD64 1 + typedef word16 hword; + typedef word32 word; + typedef word64 dword; + #endif + #endif +#endif + +#ifndef CRYPTOPP_BOOL_SLOW_WORD64 +# define CRYPTOPP_BOOL_SLOW_WORD64 0 +#endif + +/// \brief Size of a platform word in bytes +/// \details The size of a platform word, in bytes +const unsigned int WORD_SIZE = sizeof(word); + +/// \brief Size of a platform word in bits +/// \details The size of a platform word, in bits +const unsigned int WORD_BITS = WORD_SIZE * 8; + +NAMESPACE_END + +#endif // CRYPTOPP_CONFIG_INT_H diff --git a/external/ours/library/crypto/src/shared/original/config_misc.h b/external/ours/library/crypto/src/shared/original/config_misc.h new file mode 100755 index 000000000..67b2d4ab2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_misc.h @@ -0,0 +1,194 @@ +// config_misc.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_misc.h +/// \brief Library configuration file +/// \details config_misc.h provides miscellaneous defines. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_misc.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_MISC_H +#define CRYPTOPP_CONFIG_MISC_H + +#include "config_asm.h" +#include "config_cxx.h" +#include "config_os.h" +#include "config_ver.h" + +// Define this if running on a big-endian CPU +// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0 +#if !defined(CRYPTOPP_LITTLE_ENDIAN) && !defined(CRYPTOPP_BIG_ENDIAN) && (defined(__BIG_ENDIAN__) || (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || (defined(__m68k__) || defined(__MC68K__)) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__MIPSEB__) || defined(__ARMEB__) || (defined(__MWERKS__) && !defined(__INTEL__))) +# define CRYPTOPP_BIG_ENDIAN 1 +#endif + +// Define this if running on a little-endian CPU +// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0 +#if !defined(CRYPTOPP_BIG_ENDIAN) && !defined(CRYPTOPP_LITTLE_ENDIAN) +# define CRYPTOPP_LITTLE_ENDIAN 1 +#endif + +// Define this if you want to set a prefix for TestData/ and TestVectors/ +// Be sure to add the trailing slash since its simple concatenation. +// After https://github.com/weidai11/cryptopp/issues/760 the library +// should find the test vectors and data without much effort. It +// will search in "./" and "$ORIGIN/../share/cryptopp" automatically. +#ifndef CRYPTOPP_DATA_DIR +# define CRYPTOPP_DATA_DIR "" +#endif + +// Define this to disable the test suite from searching for test +// vectors and data in "./" and "$ORIGIN/../share/cryptopp". The +// library will still search in CRYPTOPP_DATA_DIR, regardless. +// Some distros may want to disable this feature. Also see +// https://github.com/weidai11/cryptopp/issues/760 +// #ifndef CRYPTOPP_DISABLE_DATA_DIR_SEARCH +// # define CRYPTOPP_DISABLE_DATA_DIR_SEARCH +// #endif + +// Define this if you want or need the library's memcpy_s and memmove_s. +// See http://github.com/weidai11/cryptopp/issues/28. +// #if !defined(CRYPTOPP_WANT_SECURE_LIB) +// # define CRYPTOPP_WANT_SECURE_LIB +// #endif + +// Define this if ARMv8 shifts are slow. ARM Cortex-A53 and Cortex-A57 shift +// operation perform poorly, so NEON and ASIMD code that relies on shifts +// or rotates often performs worse than C/C++ code. Also see +// http://github.com/weidai11/cryptopp/issues/367. +#define CRYPTOPP_SLOW_ARMV8_SHIFT 1 + +// CRYPTOPP_DEBUG enables the library's CRYPTOPP_ASSERT. CRYPTOPP_ASSERT +// raises a SIGTRAP (Unix) or calls DebugBreak() (Windows). CRYPTOPP_ASSERT +// is only in effect when CRYPTOPP_DEBUG, DEBUG or _DEBUG is defined. Unlike +// Posix assert, CRYPTOPP_ASSERT is not affected by NDEBUG (or failure to +// define it). According to the ndk-build docs, Android use NDK_DEBUG=1 to +// signal a DEBUG build (and NDK_DEBUG=0 to signal non-DEBUG build). +// Also see http://github.com/weidai11/cryptopp/issues/277, CVE-2016-7420 and +// https://developer.android.com/ndk/guides/ndk-build +#if (defined(DEBUG) || defined(_DEBUG)) || (defined(NDK_DEBUG) && (NDK_DEBUG > 0)) +# undef CRYPTOPP_DEBUG +# define CRYPTOPP_DEBUG 1 +#endif + +// File system code to use when creating GZIP archive. +// http://www.gzip.org/format.txt +#if !defined(GZIP_OS_CODE) +# if defined(__macintosh__) +# define GZIP_OS_CODE 7 +# elif defined(__unix__) || defined(__linux__) +# define GZIP_OS_CODE 3 +# else +# define GZIP_OS_CODE 0 +# endif +#endif + +// Try this if your CPU has 256K internal cache or a slow multiply instruction +// and you want a (possibly) faster IDEA implementation using log tables +// #define IDEA_LARGECACHE + +// Define this if, for the linear congruential RNG, you want to use +// the original constants as specified in S.K. Park and K.W. Miller's +// CACM paper. +// #define LCRNG_ORIGINAL_NUMBERS + +// Define this if you want Integer's operator<< to honor std::showbase (and +// std::noshowbase). If defined, Integer will use a suffix of 'b', 'o', 'h' +// or '.' (the last for decimal) when std::showbase is in effect. If +// std::noshowbase is set, then the suffix is not added to the Integer. If +// not defined, existing behavior is preserved and Integer will use a suffix +// of 'b', 'o', 'h' or '.' (the last for decimal). +// #define CRYPTOPP_USE_STD_SHOWBASE + +// Define this if you want to decouple AlgorithmParameters and Integer +// The decoupling should make it easier for the linker to remove Integer +// related code for those who do not need Integer, and avoid a potential +// race during AssignIntToInteger pointer initialization. Also +// see http://github.com/weidai11/cryptopp/issues/389. +// #define CRYPTOPP_NO_ASSIGN_TO_INTEGER + +// Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}" +#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || \ + (CRYPTOPP_APPLE_CLANG_VERSION >= 20000) + #define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1 +#endif + +// Portable way to suppress warnings. +// Moved from misc.h due to circular depenedencies. +#ifndef CRYPTOPP_UNUSED + #define CRYPTOPP_UNUSED(x) ((void)(x)) +#endif + +// how to disable inlining +#if defined(_MSC_VER) +# define CRYPTOPP_NOINLINE_DOTDOTDOT +# define CRYPTOPP_NOINLINE __declspec(noinline) +#elif defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__) +# define CRYPTOPP_NOINLINE_DOTDOTDOT ... +# define CRYPTOPP_NOINLINE __attribute__((noinline)) +#elif defined(__GNUC__) +# define CRYPTOPP_NOINLINE_DOTDOTDOT +# define CRYPTOPP_NOINLINE __attribute__((noinline)) +#else +# define CRYPTOPP_NOINLINE_DOTDOTDOT ... +# define CRYPTOPP_NOINLINE +#endif + +// http://stackoverflow.com/a/13867690/608639 +#if defined(CRYPTOPP_CXX11_CONSTEXPR) +# define CRYPTOPP_STATIC_CONSTEXPR static constexpr +# define CRYPTOPP_CONSTEXPR constexpr +#else +# define CRYPTOPP_STATIC_CONSTEXPR static +# define CRYPTOPP_CONSTEXPR +#endif // CRYPTOPP_CXX11_CONSTEXPR + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +# define CRYPTOPP_CONSTANT(x) static const int x +#elif defined(CRYPTOPP_CXX11_STRONG_ENUM) +# define CRYPTOPP_CONSTANT(x) enum : int { x } +#elif defined(CRYPTOPP_CXX11_CONSTEXPR) +# define CRYPTOPP_CONSTANT(x) constexpr static int x +#else +# define CRYPTOPP_CONSTANT(x) static const int x +#endif + +// Warnings +#ifdef _MSC_VER + // 4127: conditional expression is constant + // 4512: assignment operator not generated + // 4661: no suitable definition provided for explicit template instantiation request + // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation +# pragma warning(disable: 4127 4512 4661 4910) + // _MSC_VER 1920 is VS2019 +# if _MSC_VER >= 1920 + // 5054: operator '|': deprecated between enumerations of different types +# pragma warning(disable: 5054) +# endif + // Security related, possible defects + // http://blogs.msdn.com/b/vcblog/archive/2010/12/14/off-by-default-compiler-warnings-in-visual-c.aspx +# pragma warning(once: 4191 4242 4263 4264 4266 4302 4826 4905 4906 4928) +#endif + +#ifdef __BORLANDC__ +// 8037: non-const function called for const object. needed to work around BCB2006 bug +# pragma warn -8037 +#endif + +// [GCC Bug 53431] "C++ preprocessor ignores #pragma GCC diagnostic". Clang honors it. +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wunknown-pragmas" +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#endif // CRYPTOPP_CONFIG_MISC_H diff --git a/external/ours/library/crypto/src/shared/original/config_ns.h b/external/ours/library/crypto/src/shared/original/config_ns.h new file mode 100755 index 000000000..9fa3a3cb4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_ns.h @@ -0,0 +1,76 @@ +// config_ns.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_ns.h +/// \brief Library configuration file +/// \details config_ns.h provides defines for C++ and library +/// namespaces. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_ns.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_NAMESPACE_H +#define CRYPTOPP_CONFIG_NAMESPACE_H + +// namespace support is now required +#ifdef NO_NAMESPACE +# error namespace support is now required +#endif + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING + +/// \namespace CryptoPP +/// \brief Crypto++ library namespace +/// \details Nearly all classes are located in the CryptoPP namespace. Within +/// the namespace, there are four additional namespaces. +///
    +///
  • Name - namespace for names used with NameValuePairs and documented +/// in argnames.h +///
  • NaCl - namespace for NaCl test functions like crypto_box, +/// crypto_box_open, crypto_sign, and crypto_sign_open +///
  • Donna - namespace for curve25519 library operations. The name was +/// selected due to use of Langley and Moon's curve25519-donna. +///
  • Test - namespace for testing and benchmarks classes +///
  • Weak - namespace for weak and wounded algorithms, like ARC4, MD5 +/// and Pananma +///
+/// \since Crypto++ 3.0 +namespace CryptoPP { } + +// Bring in the symbols found in the weak namespace; and fold Weak1 into Weak +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#define Weak1 Weak +// Avoid putting "CryptoPP::" in front of everything in Doxygen output +#define CryptoPP +#define NAMESPACE_BEGIN(x) +#define NAMESPACE_END +// Get Doxygen to generate better documentation for these typedefs +#define DOCUMENTED_TYPEDEF(x, y) class y : public x {} +// Make "protected" "private" so the functions and members are not documented +#define protected private + +#else +// Not Doxygen +#define NAMESPACE_BEGIN(x) namespace x { +#define NAMESPACE_END } +#define DOCUMENTED_TYPEDEF(x, y) typedef x y + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +#define ANONYMOUS_NAMESPACE_BEGIN namespace { +#define ANONYMOUS_NAMESPACE_END } +#define USING_NAMESPACE(x) using namespace x; +#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x { +#define DOCUMENTED_NAMESPACE_END } + +#endif // CRYPTOPP_CONFIG_NAMESPACE_H diff --git a/external/ours/library/crypto/src/shared/original/config_os.h b/external/ours/library/crypto/src/shared/original/config_os.h new file mode 100755 index 000000000..107e44528 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_os.h @@ -0,0 +1,169 @@ +// config_os.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_os.h +/// \brief Library configuration file +/// \details config_os.h provides defines for platforms and operating +/// systems. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_os.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_OS_H +#define CRYPTOPP_CONFIG_OS_H + +#include "config_ver.h" + +// It is OK to remove the hard stop below, but you are on your own. +// After building the library be sure to run self tests described +// https://www.cryptopp.com/wiki/Release_Process#Self_Tests +// The problems with Clang pretending to be other compilers is +// discussed at http://github.com/weidai11/cryptopp/issues/147. +#if (defined(_MSC_VER) && defined(__clang__) && \ + !(defined( __clang_analyzer__)) && !defined(__INTEL_LLVM_COMPILER)) +# error: "Unsupported configuration" +#endif + +// Windows platform +#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) +#define CRYPTOPP_WIN32_AVAILABLE +#endif + +// Unix and Linux platforms +#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun) +#define CRYPTOPP_UNIX_AVAILABLE +#endif + +// BSD platforms +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#define CRYPTOPP_BSD_AVAILABLE +#endif + +// Microsoft compilers +#if defined(_MSC_VER) || defined(__fastcall) + #define CRYPTOPP_FASTCALL __fastcall +#else + #define CRYPTOPP_FASTCALL +#endif + +// Microsoft compilers +#if defined(_MSC_VER) + #define CRYPTOPP_NO_VTABLE __declspec(novtable) +#else + #define CRYPTOPP_NO_VTABLE +#endif + +// Define this if you want to disable all OS-dependent features, +// such as sockets and OS-provided random number generators +// #define NO_OS_DEPENDENCE + +// Define this to use features provided by Microsoft's CryptoAPI. +// Currently the only feature used is Windows random number generation. +// This macro will be ignored if NO_OS_DEPENDENCE is defined. +// #define USE_MS_CRYPTOAPI + +// Define this to use features provided by Microsoft's CryptoNG API. +// CryptoNG API is available in Vista and above and its cross platform, +// including desktop apps and store apps. Currently the only feature +// used is Windows random number generation. +// This macro will be ignored if NO_OS_DEPENDENCE is defined. +// #define USE_MS_CNGAPI + +// If the user did not make a choice, then select CryptoNG if +// targeting Windows 8 or above. +#if !defined(USE_MS_CRYPTOAPI) && !defined(USE_MS_CNGAPI) +# if !defined(_USING_V110_SDK71_) && ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || \ + (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)) +# define USE_MS_CNGAPI +# else +# define USE_MS_CRYPTOAPI +# endif +#endif + +// Begin OS features, like init priorities and random numbers +#ifndef NO_OS_DEPENDENCE + +// CRYPTOPP_INIT_PRIORITY attempts to manage initialization of C++ static objects. +// Under GCC, the library uses init_priority attribute in the range +// [CRYPTOPP_INIT_PRIORITY, CRYPTOPP_INIT_PRIORITY+100]. Under Windows, +// CRYPTOPP_INIT_PRIORITY enlists "#pragma init_seg(lib)". The platforms +// with gaps are Apple and Sun because they require linker scripts. Apple and +// Sun will use the library's Singletons to initialize and acquire resources. +// Also see http://cryptopp.com/wiki/Static_Initialization_Order_Fiasco +#ifndef CRYPTOPP_INIT_PRIORITY +# define CRYPTOPP_INIT_PRIORITY 250 +#endif + +// CRYPTOPP_USER_PRIORITY is for other libraries and user code that is using Crypto++ +// and managing C++ static object creation. It is guaranteed not to conflict with +// values used by (or would be used by) the Crypto++ library. +#ifndef CRYPTOPP_USER_PRIORITY +# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY+101) +#endif + +// Most platforms allow us to specify when to create C++ objects. Apple and Sun do not. +#if (CRYPTOPP_INIT_PRIORITY > 0) && !(defined(NO_OS_DEPENDENCE) || defined(__APPLE__) || defined(__sun__)) +# if (CRYPTOPP_GCC_VERSION >= 30000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 800) +# define HAVE_GCC_INIT_PRIORITY 1 +# elif (CRYPTOPP_MSC_VERSION >= 1310) +# define HAVE_MSC_INIT_PRIORITY 1 +# elif defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__) +# define HAVE_XLC_INIT_PRIORITY 1 +# endif +#endif // CRYPTOPP_INIT_PRIORITY, NO_OS_DEPENDENCE, Apple, Sun + +#if defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) +# define HIGHRES_TIMER_AVAILABLE +#endif + +#ifdef CRYPTOPP_WIN32_AVAILABLE +# if !defined(WINAPI_FAMILY) +# define THREAD_TIMER_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define THREAD_TIMER_AVAILABLE +# endif +# endif +#endif + +#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +# define NONBLOCKING_RNG_AVAILABLE +# define BLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +#endif + +// Cygwin/Newlib requires _XOPEN_SOURCE=600 +#if defined(CRYPTOPP_UNIX_AVAILABLE) +# define UNIX_SIGNALS_AVAILABLE 1 +#endif + +#ifdef CRYPTOPP_WIN32_AVAILABLE +# if !defined(WINAPI_FAMILY) +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# if ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)) +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# endif +# endif +# endif +#endif + +#endif // NO_OS_DEPENDENCE + +#endif // CRYPTOPP_CONFIG_OS_H diff --git a/external/ours/library/crypto/src/shared/original/config_ver.h b/external/ours/library/crypto/src/shared/original/config_ver.h new file mode 100755 index 000000000..178eafea4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/config_ver.h @@ -0,0 +1,90 @@ +// config_ver.h - written and placed in public domain by Jeffrey Walton +// the bits that make up this source file are from the +// library's monolithic config.h. + +/// \file config_ver.h +/// \brief Library configuration file +/// \details config_ver.h provides defines for library and compiler +/// versions. +/// \details config.h was split into components in May 2019 to better +/// integrate with Autoconf and its feature tests. The splitting occurred so +/// users could continue to include config.h while allowing Autoconf +/// to write new config_asm.h and new config_cxx.h using +/// its feature tests. +/// \note You should include config.h rather than config_ver.h +/// directly. +/// \sa Issue 835, +/// Make config.h more autoconf friendly, +/// Configure.sh script +/// on the Crypto++ wiki +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_CONFIG_VERSION_H +#define CRYPTOPP_CONFIG_VERSION_H + +/// \brief Library major version +/// \details CRYPTOPP_MAJOR reflects the major version of the library the +/// headers came from. It is not necessarily the version of the library built +/// as a shared object if versions are inadvertently mixed and matched. +/// \sa CRYPTOPP_VERSION, LibraryVersion(), HeaderVersion() +/// \since Crypto++ 8.2 +#define CRYPTOPP_MAJOR 8 +/// \brief Library minor version +/// \details CRYPTOPP_MINOR reflects the minor version of the library the +/// headers came from. It is not necessarily the version of the library built +/// as a shared object if versions are inadvertently mixed and matched. +/// \sa CRYPTOPP_VERSION, LibraryVersion(), HeaderVersion() +/// \since Crypto++ 8.2 +#define CRYPTOPP_MINOR 6 +/// \brief Library revision number +/// \details CRYPTOPP_REVISION reflects the revision number of the library the +/// headers came from. It is not necessarily the revision of the library built +/// as a shared object if versions are inadvertently mixed and matched. +/// \sa CRYPTOPP_VERSION, LibraryVersion(), HeaderVersion() +/// \since Crypto++ 8.2 +#define CRYPTOPP_REVISION 0 + +/// \brief Full library version +/// \details CRYPTOPP_VERSION reflects the version of the library the headers +/// came from. It is not necessarily the version of the library built as a +/// shared object if versions are inadvertently mixed and matched. +/// \sa CRYPTOPP_MAJOR, CRYPTOPP_MINOR, CRYPTOPP_REVISION, LibraryVersion(), HeaderVersion() +/// \since Crypto++ 5.6 +#define CRYPTOPP_VERSION 860 + +// Compiler version macros + +#if defined(__GNUC__) +# define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +// Apple and LLVM Clang versions. Apple Clang version 7.0 roughly equals +// LLVM Clang version 3.7. Also see https://gist.github.com/yamaya/2924292 +#if defined(__clang__) && defined(__apple_build_version__) +# undef CRYPTOPP_GCC_VERSION +# define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#elif defined(__clang__) +# undef CRYPTOPP_GCC_VERSION +# define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif + +// Clang pretends to be other compilers. The compiler gets into +// code paths that it cannot compile. Unset Clang to save the grief. +// Also see http://github.com/weidai11/cryptopp/issues/147. + +#if defined(__xlc__) || defined(__xlC__) +# undef CRYPTOPP_LLVM_CLANG_VERSION +# define CRYPTOPP_XLC_VERSION ((__xlC__ / 256) * 10000 + (__xlC__ % 256) * 100) +#endif + +#ifdef __INTEL_COMPILER +# undef CRYPTOPP_LLVM_CLANG_VERSION +# define CRYPTOPP_INTEL_VERSION (__INTEL_COMPILER) +#endif + +#ifdef _MSC_VER +# undef CRYPTOPP_LLVM_CLANG_VERSION +# define CRYPTOPP_MSC_VERSION (_MSC_VER) +#endif + +#endif // CRYPTOPP_CONFIG_VERSION_H diff --git a/external/ours/library/crypto/src/shared/original/cpu.cpp b/external/ours/library/crypto/src/shared/original/cpu.cpp new file mode 100755 index 000000000..0e8cd7df5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cpu.cpp @@ -0,0 +1,1459 @@ +// cpu.cpp - originally written and placed in the public domain by Wei Dai +// modified by Jeffrey Walton and the community over the years. + +#include "pch.h" +#include "config.h" + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +#ifndef CRYPTOPP_IMPORTS + +#include "cpu.h" +#include "misc.h" +#include "stdcpp.h" + +// For _xgetbv on Microsoft 32-bit and 64-bit Intel platforms +// https://github.com/weidai11/cryptopp/issues/972 +#if _MSC_VER >= 1600 && (defined(_M_IX86) || defined(_M_X64)) +# include +#endif + +// For IsProcessorFeaturePresent on Microsoft Arm64 platforms, +// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent +#if defined(_WIN32) && defined(_M_ARM64) +# include +# include +#endif + +#ifdef _AIX +# include +#endif + +#ifdef __linux__ +# include +#endif + +// Capability queries, requires Glibc 2.16, http://lwn.net/Articles/519085/ +// CRYPTOPP_GLIBC_VERSION not used because config.h is missing +#if (((__GLIBC__ * 100) + __GLIBC_MINOR__) >= 216) +# define CRYPTOPP_GETAUXV_AVAILABLE 1 +#endif + +#if CRYPTOPP_GETAUXV_AVAILABLE +# include +#else +#ifndef AT_HWCAP +# define AT_HWCAP 16 +#endif +#ifndef AT_HWCAP2 +# define AT_HWCAP2 26 +#endif +unsigned long int getauxval(unsigned long int) { return 0; } +#endif + +#if defined(__APPLE__) +# include +# include +#endif + +// FreeBSD headers are giving us trouble... +// https://github.com/weidai11/cryptopp/pull/1029 +#if defined(__FreeBSD__) +# include +# include +#endif + +// The cpu-features header and source file are located in +// "$ANDROID_NDK_ROOT/sources/android/cpufeatures". +// setenv-android.sh will copy the header and source file +// into PWD and the makefile will build it in place. +#if defined(__ANDROID__) +# include "cpu-features.h" +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +// Visual Studio 2008 and below are missing _xgetbv and _cpuidex. +// The 32-bit versions use inline ASM below. The 64-bit versions are in x64dll.asm. +#if defined(_MSC_VER) && defined(_M_X64) +extern "C" unsigned long long __fastcall XGETBV64(unsigned int); +extern "C" unsigned long long __fastcall CPUID64(unsigned int, unsigned int, unsigned int*); +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); +} + +extern "C" +{ + static jmp_buf s_jmpNoCPUID; + static void SigIllHandler(int) + { + longjmp(s_jmpNoCPUID, 1); + } +} +#endif // CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY + +ANONYMOUS_NAMESPACE_BEGIN + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + +using CryptoPP::word32; + +inline bool IsIntel(const word32 output[4]) +{ + // This is the "GenuineIntel" string + return (output[1] /*EBX*/ == 0x756e6547) && + (output[2] /*ECX*/ == 0x6c65746e) && + (output[3] /*EDX*/ == 0x49656e69); +} + +inline bool IsAMD(const word32 output[4]) +{ + // This is the "AuthenticAMD" string. + return ((output[1] /*EBX*/ == 0x68747541) && + (output[2] /*ECX*/ == 0x444D4163) && + (output[3] /*EDX*/ == 0x69746E65)) || + // Early K5's can return "AMDisbetter!" + ((output[1] /*EBX*/ == 0x69444d41) && + (output[2] /*ECX*/ == 0x74656273) && + (output[3] /*EDX*/ == 0x21726574)); +} + +inline bool IsHygon(const word32 output[4]) +{ + // This is the "HygonGenuine" string. + return (output[1] /*EBX*/ == 0x6f677948) && + (output[2] /*ECX*/ == 0x656e6975) && + (output[3] /*EDX*/ == 0x6e65476e); +} + +inline bool IsVIA(const word32 output[4]) +{ + // This is the "CentaurHauls" string. + return ((output[1] /*EBX*/ == 0x746e6543) && + (output[2] /*ECX*/ == 0x736c7561) && + (output[3] /*EDX*/ == 0x48727561)) || + // Some non-PadLock's return "VIA VIA VIA " + ((output[1] /*EBX*/ == 0x32414956) && + (output[2] /*ECX*/ == 0x32414956) && + (output[3] /*EDX*/ == 0x32414956)); +} + +#endif // X86, X32 and X64 + +#if defined(__APPLE__) + +// http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios +class AppleMachineInfo +{ +public: + enum { PowerMac=1, Mac, iPhone, iPod, iPad, AppleTV, AppleWatch }; + enum { PowerPC=1, I386, I686, X86_64, ARM32, ARMV8, ARMV82, ARMV83 }; + + AppleMachineInfo() : m_device(0), m_version(0), m_arch(0) + { + struct utsname systemInfo; + systemInfo.machine[0] = '\0'; + uname(&systemInfo); + + std::string machine(systemInfo.machine); + + std::string::size_type pos = machine.find_first_of("0123456789"); + if (pos != std::string::npos) + m_version = std::atoi(machine.substr(pos).c_str()); + + if (machine.find("iPhone") != std::string::npos) + { + m_device = iPhone; + if (m_version >= 6) { m_arch = ARMV8; } + else { m_arch = ARM32; } + } + else if (machine.find("iPod") != std::string::npos) + { + m_device = iPod; + if (m_version >= 6) { m_arch = ARMV8; } + else { m_arch = ARM32; } + } + else if (machine.find("iPad") != std::string::npos) + { + m_device = iPad; + if (m_version >= 5) { m_arch = ARMV8; } + else { m_arch = ARM32; } + } + else if (machine.find("PowerMac") != std::string::npos || + machine.find("Power Macintosh") != std::string::npos) + { + m_device = PowerMac; + m_arch = PowerPC; + } + else if (machine.find("Mac") != std::string::npos || + machine.find("Macintosh") != std::string::npos) + { +#if defined(__x86_64) || defined(__amd64) + m_device = Mac; + m_arch = X86_64; +#elif defined(__i386) + m_device = Mac; + m_arch = I386; +#elif defined(__i686) + m_device = Mac; + m_arch = I686; +#else + // Should never get here + m_device = Mac; + m_arch = 0; +#endif + } + else if (machine.find("AppleTV") != std::string::npos) + { + m_device = AppleTV; + if (m_version >= 4) { m_arch = ARMV8; } + else { m_arch = ARM32; } + } + else if (machine.find("AppleWatch") != std::string::npos) + { + m_device = AppleWatch; + if (m_version >= 4) { m_arch = ARMV8; } + else { m_arch = ARM32; } + } + else if (machine.find("arm64") != std::string::npos) + { + // M1 machine? + std::string brand; + size_t size = 32; + + // Supply an oversized buffer, and avoid + // an extra call to sysctlbyname. + brand.resize(size); + if (sysctlbyname("machdep.cpu.brand_string", &brand[0], &size, NULL, 0) == 0 && size > 0) + { + if (brand[size-1] == '\0') + size--; + brand.resize(size); + } + + if (brand == "Apple M1") + { + m_device = Mac; + m_arch = ARMV82; + } + else + { + // ??? + m_device = 0; + m_arch = ARMV8; + } + } + else + { + CRYPTOPP_ASSERT(0); + } + } + + unsigned int Device() const { + return m_device; + } + + unsigned int Version() const { + return m_version; + } + + unsigned int Arch() const { + return m_arch; + } + + bool IsARM32() const { + return m_arch == ARM32; + } + + bool IsARMv8() const { + return m_arch >= ARMV8; + } + + bool IsARMv82() const { + return m_arch >= ARMV82; + } + + bool IsARMv83() const { + return m_arch >= ARMV83; + } + +private: + unsigned int m_device, m_version, m_arch; +}; + +void GetAppleMachineInfo(unsigned int& device, unsigned int& version, unsigned int& arch) +{ +#if CRYPTOPP_CXX11_STATIC_INIT + static const AppleMachineInfo info; +#else + using CryptoPP::Singleton; + const AppleMachineInfo& info = Singleton().Ref(); +#endif + + device = info.Device(); + version = info.Version(); + arch = info.Arch(); +} + +inline bool IsAppleMachineARM32() +{ + static unsigned int arch; + if (arch == 0) + { + unsigned int unused; + GetAppleMachineInfo(unused, unused, arch); + } + return arch == AppleMachineInfo::ARM32; +} + +inline bool IsAppleMachineARMv8() +{ + static unsigned int arch; + if (arch == 0) + { + unsigned int unused; + GetAppleMachineInfo(unused, unused, arch); + } + return arch >= AppleMachineInfo::ARMV8; +} + +inline bool IsAppleMachineARMv82() +{ + static unsigned int arch; + if (arch == 0) + { + unsigned int unused; + GetAppleMachineInfo(unused, unused, arch); + } + return arch >= AppleMachineInfo::ARMV82; +} + +inline bool IsAppleMachineARMv83() +{ + static unsigned int arch; + if (arch == 0) + { + unsigned int unused; + GetAppleMachineInfo(unused, unused, arch); + } + return arch >= AppleMachineInfo::ARMV83; +} + +#endif // __APPLE__ + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +// *************************** IA-32 CPUs *************************** + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + +bool CRYPTOPP_SECTION_INIT g_x86DetectionDone = false; +bool CRYPTOPP_SECTION_INIT g_hasSSE2 = false; +bool CRYPTOPP_SECTION_INIT g_hasSSSE3 = false; +bool CRYPTOPP_SECTION_INIT g_hasSSE41 = false; +bool CRYPTOPP_SECTION_INIT g_hasSSE42 = false; +bool CRYPTOPP_SECTION_INIT g_hasAESNI = false; +bool CRYPTOPP_SECTION_INIT g_hasCLMUL = false; +bool CRYPTOPP_SECTION_INIT g_hasMOVBE = false; +bool CRYPTOPP_SECTION_INIT g_hasAVX = false; +bool CRYPTOPP_SECTION_INIT g_hasAVX2 = false; +bool CRYPTOPP_SECTION_INIT g_hasADX = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA = false; +bool CRYPTOPP_SECTION_INIT g_hasRDRAND = false; +bool CRYPTOPP_SECTION_INIT g_hasRDSEED = false; +bool CRYPTOPP_SECTION_INIT g_isP4 = false; +bool CRYPTOPP_SECTION_INIT g_hasPadlockRNG = false; +bool CRYPTOPP_SECTION_INIT g_hasPadlockACE = false; +bool CRYPTOPP_SECTION_INIT g_hasPadlockACE2 = false; +bool CRYPTOPP_SECTION_INIT g_hasPadlockPHE = false; +bool CRYPTOPP_SECTION_INIT g_hasPadlockPMM = false; +word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + +// For Solaris 11 +extern bool CPU_ProbeSSE2(); + +// xcr0 is available when xgetbv is present. +// The intrinsic is broke on GCC 8.1 and earlier. Also see +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684. +word64 XGetBV(word32 num) +{ +// Visual Studio 2010 SP1 and above, 32 and 64-bit +// https://github.com/weidai11/cryptopp/issues/972 +#if defined(_MSC_VER) && (_MSC_FULL_VER >= 160040219) + + return _xgetbv(num); + +// Visual Studio 2008 and below, 64-bit +#elif defined(_MSC_VER) && defined(_M_X64) + + return XGETBV64(num); + +// Visual Studio 2008 and below, 32-bit +#elif defined(_MSC_VER) && defined(_M_IX86) + + word32 a=0, d=0; + __asm { + push eax + push edx + push ecx + mov ecx, num + _emit 0x0f + _emit 0x01 + _emit 0xd0 + mov a, eax + mov d, edx + pop ecx + pop edx + pop eax + } + return (static_cast(d) << 32) | a; + +// GCC 4.4 and above +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + + word32 a=0, d=0; + __asm__ + ( + "xgetbv" : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + return (static_cast(d) << 32) | a; + +// Remainder of GCC and compatibles. +#elif defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC) + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71659 and + // http://www.agner.org/optimize/vectorclass/read.php?i=65 + word32 a=0, d=0; + __asm__ + ( + ".byte 0x0f, 0x01, 0xd0" "\n\t" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + return (static_cast(d) << 32) | a; +#else + # error "Need an xgetbv function" +#endif +} + +// No inline due to Borland/Embarcadero and Issue 498 +// cpu.cpp (131): E2211 Inline assembly not allowed in inline and template functions +bool CpuId(word32 func, word32 subfunc, word32 output[4]) +{ +// Visual Studio 2010 and above, 32 and 64-bit +#if defined(_MSC_VER) && (_MSC_VER >= 1600) + + __cpuidex((int *)output, func, subfunc); + return true; + +// Visual Studio 2008 and below, 64-bit +#elif defined(_MSC_VER) && defined(_M_X64) + + CPUID64(func, subfunc, output); + return true; + +// Visual Studio 2008 and below, 32-bit +#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__BORLANDC__) + + __try + { + // Borland/Embarcadero and Issue 500 + // Local variables for cpuid output + word32 a, b, c, d; + __asm + { + push ebx + mov eax, func + mov ecx, subfunc + cpuid + mov [a], eax + mov [b], ebx + mov [c], ecx + mov [d], edx + pop ebx + } + output[0] = a; + output[1] = b; + output[2] = c; + output[3] = d; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + + return true; + +// Linux, Unix, OS X, Solaris, Cygwin, MinGW +#else + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + +# ifndef __MINGW32__ + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask) != 0) + { + signal(SIGILL, oldHandler); + return false; + } +# endif + + if (setjmp(s_jmpNoCPUID)) + result = false; + else + { + asm volatile + ( + // save ebx in case -fPIC is being used +# if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" +# else + "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" +# endif + : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) + : "a" (func), "c" (subfunc) + : "cc" + ); + } + +# ifndef __MINGW32__ + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); +# endif + + signal(SIGILL, oldHandler); + return result; +#endif +} + +void DetectX86Features() +{ + // Coverity finding CID 171239. Initialize arrays. + // Indexes: EAX=0, EBX=1, ECX=2, EDX=3 + word32 cpuid0[4]={0}, cpuid1[4]={0}, cpuid2[4]={0}; + +#if defined(CRYPTOPP_DISABLE_ASM) + // Not available + goto done; +#else + if (!CpuId(0, 0, cpuid0)) + goto done; + if (!CpuId(1, 0, cpuid1)) + goto done; +#endif + + CRYPTOPP_CONSTANT(EAX_REG = 0); + CRYPTOPP_CONSTANT(EBX_REG = 1); + CRYPTOPP_CONSTANT(ECX_REG = 2); + CRYPTOPP_CONSTANT(EDX_REG = 3); + + CRYPTOPP_CONSTANT(MMX_FLAG = (1 << 24)); // EDX + CRYPTOPP_CONSTANT(SSE_FLAG = (1 << 25)); // EDX + CRYPTOPP_CONSTANT(SSE2_FLAG = (1 << 26)); // EDX + + CRYPTOPP_CONSTANT(SSE3_FLAG = (1 << 0)); // ECX + CRYPTOPP_CONSTANT(SSSE3_FLAG = (1 << 9)); // ECX + CRYPTOPP_CONSTANT(SSE41_FLAG = (1 << 19)); // ECX + CRYPTOPP_CONSTANT(SSE42_FLAG = (1 << 20)); // ECX + CRYPTOPP_CONSTANT(MOVBE_FLAG = (1 << 22)); // ECX + CRYPTOPP_CONSTANT(AESNI_FLAG = (1 << 25)); // ECX + CRYPTOPP_CONSTANT(CLMUL_FLAG = (1 << 1)); // ECX + + CRYPTOPP_CONSTANT(XSAVE_FLAG = (1 << 26)); // ECX + CRYPTOPP_CONSTANT(OSXSAVE_FLAG = (1 << 27)); // ECX + + CRYPTOPP_CONSTANT(AVX_FLAG = (3 << 27)); // ECX + CRYPTOPP_CONSTANT(YMM_FLAG = (3 << 1)); // CR0 + + // x86_64 machines don't check some flags because SSE2 + // is part of the core instruction set architecture + CRYPTOPP_UNUSED(MMX_FLAG); CRYPTOPP_UNUSED(SSE_FLAG); + CRYPTOPP_UNUSED(SSE2_FLAG); CRYPTOPP_UNUSED(SSE3_FLAG); + CRYPTOPP_UNUSED(XSAVE_FLAG); + +#if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + // 64-bit core instruction set includes SSE2. Just check + // the OS enabled SSE2 support using OSXSAVE. + g_hasSSE2 = (cpuid1[ECX_REG] & OSXSAVE_FLAG) != 0; +#else + // Check the processor supports SSE2. Then use OSXSAVE to + // signal OS support for SSE2 to avoid probes. + // Also see http://stackoverflow.com/a/22521619/608639 + // and http://github.com/weidai11/cryptopp/issues/511. + if ((cpuid1[EDX_REG] & SSE2_FLAG) == SSE2_FLAG) + g_hasSSE2 = (cpuid1[ECX_REG] & XSAVE_FLAG) != 0 && + (cpuid1[ECX_REG] & OSXSAVE_FLAG) != 0; +#endif + + // Solaris 11 i86pc does not signal SSE support using + // OSXSAVE. We need to probe for SSE support. + if (g_hasSSE2 == false) + g_hasSSE2 = CPU_ProbeSSE2(); + + if (g_hasSSE2 == false) + goto done; + + g_hasSSSE3 = (cpuid1[ECX_REG] & SSSE3_FLAG) != 0; + g_hasSSE41 = (cpuid1[ECX_REG] & SSE41_FLAG) != 0; + g_hasSSE42 = (cpuid1[ECX_REG] & SSE42_FLAG) != 0; + g_hasMOVBE = (cpuid1[ECX_REG] & MOVBE_FLAG) != 0; + g_hasAESNI = (cpuid1[ECX_REG] & AESNI_FLAG) != 0; + g_hasCLMUL = (cpuid1[ECX_REG] & CLMUL_FLAG) != 0; + + // AVX is similar to SSE. Check if AVX is available on the cpu, then + // check if the OS enabled XSAVE/XRESTORE for the extended registers. + // https://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled + if ((cpuid1[ECX_REG] & AVX_FLAG) == AVX_FLAG) + { + word64 xcr0 = XGetBV(0); + g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG; + } + + if (IsIntel(cpuid0)) + { + CRYPTOPP_CONSTANT(RDRAND_FLAG = (1 << 30)); + CRYPTOPP_CONSTANT(RDSEED_FLAG = (1 << 18)); + CRYPTOPP_CONSTANT( ADX_FLAG = (1 << 19)); + CRYPTOPP_CONSTANT( SHA_FLAG = (1 << 29)); + CRYPTOPP_CONSTANT( AVX2_FLAG = (1 << 5)); + + g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; + g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); + g_hasRDRAND = (cpuid1[ECX_REG] & RDRAND_FLAG) != 0; + + if (cpuid0[EAX_REG] >= 7) + { + if (CpuId(7, 0, cpuid2)) + { + g_hasRDSEED = (cpuid2[EBX_REG] & RDSEED_FLAG) != 0; + g_hasADX = (cpuid2[EBX_REG] & ADX_FLAG) != 0; + g_hasSHA = (cpuid2[EBX_REG] & SHA_FLAG) != 0; + g_hasAVX2 = (cpuid2[EBX_REG] & AVX2_FLAG) != 0; + } + } + } + else if (IsAMD(cpuid0) || IsHygon(cpuid0)) + { + CRYPTOPP_CONSTANT(RDRAND_FLAG = (1 << 30)); + CRYPTOPP_CONSTANT(RDSEED_FLAG = (1 << 18)); + CRYPTOPP_CONSTANT( ADX_FLAG = (1 << 19)); + CRYPTOPP_CONSTANT( SHA_FLAG = (1 << 29)); + CRYPTOPP_CONSTANT( AVX2_FLAG = (1 << 5)); + + CpuId(0x80000005, 0, cpuid2); + g_cacheLineSize = GETBYTE(cpuid2[ECX_REG], 0); + g_hasRDRAND = (cpuid1[ECX_REG] & RDRAND_FLAG) != 0; + + if (cpuid0[EAX_REG] >= 7) + { + if (CpuId(7, 0, cpuid2)) + { + g_hasRDSEED = (cpuid2[EBX_REG] & RDSEED_FLAG) != 0; + g_hasADX = (cpuid2[EBX_REG] & ADX_FLAG) != 0; + g_hasSHA = (cpuid2[EBX_REG] & SHA_FLAG) != 0; + g_hasAVX2 = (cpuid2[EBX_REG] & AVX2_FLAG) != 0; + } + } + + // Unconditionally disable RDRAND and RDSEED on AMD cpu's with family 15h or 16h. + // See Crypto++ Issue 924, https://github.com/weidai11/cryptopp/issues/924, + // Clear RDRAND CPUID bit on AMD family 15h/16h, https://lore.kernel.org/patchwork/patch/1115413/, + // and AMD CPUID Specification, https://www.amd.com/system/files/TechDocs/25481.pdf + { + CRYPTOPP_CONSTANT(FAMILY_BASE_FLAG = (0x0f << 8)); + CRYPTOPP_CONSTANT(FAMILY_EXT_FLAG = (0xff << 20)); + + word32 family = (cpuid1[0] & FAMILY_BASE_FLAG) >> 8; + if (family == 0xf) + family += (cpuid1[0] & FAMILY_EXT_FLAG) >> 20; + if (family == 0x15 || family == 0x16) + { + g_hasRDRAND = false; + g_hasRDSEED = false; + } + } + } + else if (IsVIA(cpuid0)) + { + // Two bits: available and enabled + CRYPTOPP_CONSTANT( RNG_FLAGS = (0x3 << 2)); + CRYPTOPP_CONSTANT( ACE_FLAGS = (0x3 << 6)); + CRYPTOPP_CONSTANT(ACE2_FLAGS = (0x3 << 8)); + CRYPTOPP_CONSTANT( PHE_FLAGS = (0x3 << 10)); + CRYPTOPP_CONSTANT( PMM_FLAGS = (0x3 << 12)); + + CpuId(0xC0000000, 0, cpuid2); + word32 extendedFeatures = cpuid2[0]; + + if (extendedFeatures >= 0xC0000001) + { + CpuId(0xC0000001, 0, cpuid2); + g_hasPadlockRNG = (cpuid2[EDX_REG] & RNG_FLAGS) != 0; + g_hasPadlockACE = (cpuid2[EDX_REG] & ACE_FLAGS) != 0; + g_hasPadlockACE2 = (cpuid2[EDX_REG] & ACE2_FLAGS) != 0; + g_hasPadlockPHE = (cpuid2[EDX_REG] & PHE_FLAGS) != 0; + g_hasPadlockPMM = (cpuid2[EDX_REG] & PMM_FLAGS) != 0; + } + + if (extendedFeatures >= 0xC0000005) + { + CpuId(0xC0000005, 0, cpuid2); + g_cacheLineSize = GETBYTE(cpuid2[ECX_REG], 0); + } + } + + // Keep AVX2 in sync with OS support for AVX. AVX tests both + // cpu support and OS support, while AVX2 only tests cpu support. + g_hasAVX2 &= g_hasAVX; + +done: + +#if defined(_SC_LEVEL1_DCACHE_LINESIZE) + // Glibc does not implement on some platforms. The runtime returns 0 instead of error. + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c + int cacheLineSize = (int)sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + if (g_cacheLineSize == 0 && cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; +#endif + + if (g_cacheLineSize == 0) + g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + + *const_cast(&g_x86DetectionDone) = true; +} + +// *************************** ARM-32, Aarch32 and Aarch64 *************************** + +#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) + +bool CRYPTOPP_SECTION_INIT g_ArmDetectionDone = false; +bool CRYPTOPP_SECTION_INIT g_hasARMv7 = false; +bool CRYPTOPP_SECTION_INIT g_hasNEON = false; +bool CRYPTOPP_SECTION_INIT g_hasPMULL = false; +bool CRYPTOPP_SECTION_INIT g_hasCRC32 = false; +bool CRYPTOPP_SECTION_INIT g_hasAES = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA1 = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA2 = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA512 = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA3 = false; +bool CRYPTOPP_SECTION_INIT g_hasSM3 = false; +bool CRYPTOPP_SECTION_INIT g_hasSM4 = false; +word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + +// ARM does not have an unprivileged equivalent to CPUID on IA-32. We have to +// jump through some hoops to detect features on a wide array of platforms. +// Our strategy is two part. First, attempt to *Query* the OS for a feature, +// like using getauxval on Linux. If that fails, then *Probe* the cpu +// executing an instruction and an observe a SIGILL if unsupported. The probes +// are in source files where compilation options like -march=armv8-a+crc make +// intrinsics available. They are expensive when compared to a standard OS +// feature query. Always perform the feature query first. For Linux see +// http://sourceware.org/ml/libc-help/2017-08/msg00012.html +// Avoid probes on Apple platforms because Apple's signal handling for SIGILLs +// appears broken. We are trying to figure out a way to feature test without +// probes. Also see http://stackoverflow.com/a/11197770/608639 and +// http://gist.github.com/erkanyildiz/390a480f27e86f8cd6ba. + +extern bool CPU_ProbeARMv7(); +extern bool CPU_ProbeNEON(); +extern bool CPU_ProbeCRC32(); +extern bool CPU_ProbeAES(); +extern bool CPU_ProbeSHA1(); +extern bool CPU_ProbeSHA256(); +extern bool CPU_ProbeSHA512(); +extern bool CPU_ProbeSHA3(); +extern bool CPU_ProbeSM3(); +extern bool CPU_ProbeSM4(); +extern bool CPU_ProbePMULL(); + +// https://github.com/torvalds/linux/blob/master/arch/arm/include/uapi/asm/hwcap.h +// https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h +#ifndef HWCAP_ARMv7 +# define HWCAP_ARMv7 (1 << 29) +#endif +#ifndef HWCAP_ASIMD +# define HWCAP_ASIMD (1 << 1) +#endif +#ifndef HWCAP_NEON +# define HWCAP_NEON (1 << 12) +#endif +#ifndef HWCAP_CRC32 +# define HWCAP_CRC32 (1 << 7) +#endif +#ifndef HWCAP2_CRC32 +# define HWCAP2_CRC32 (1 << 4) +#endif +#ifndef HWCAP_PMULL +# define HWCAP_PMULL (1 << 4) +#endif +#ifndef HWCAP2_PMULL +# define HWCAP2_PMULL (1 << 1) +#endif +#ifndef HWCAP_AES +# define HWCAP_AES (1 << 3) +#endif +#ifndef HWCAP2_AES +# define HWCAP2_AES (1 << 0) +#endif +#ifndef HWCAP_SHA1 +# define HWCAP_SHA1 (1 << 5) +#endif +#ifndef HWCAP_SHA2 +# define HWCAP_SHA2 (1 << 6) +#endif +#ifndef HWCAP2_SHA1 +# define HWCAP2_SHA1 (1 << 2) +#endif +#ifndef HWCAP2_SHA2 +# define HWCAP2_SHA2 (1 << 3) +#endif +#ifndef HWCAP_SHA3 +# define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SM3 +# define HWCAP_SM3 (1 << 18) +#endif +#ifndef HWCAP_SM4 +# define HWCAP_SM4 (1 << 19) +#endif +#ifndef HWCAP_SHA512 +# define HWCAP_SHA512 (1 << 21) +#endif + +inline bool CPU_QueryARMv7() +{ +#if defined(__ANDROID__) && defined(__arm__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0)) + return true; +#elif defined(__linux__) && defined(__arm__) + if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0 || + (getauxval(AT_HWCAP) & HWCAP_NEON) != 0) + return true; +#elif defined(__APPLE__) && defined(__arm__) + // Apple hardware is ARMv7 or above. + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + // Windows 10 ARM64 is only supported on Armv8a and above + return true; +#endif + return false; +} + +inline bool CPU_QueryNEON() +{ +#if defined(__ANDROID__) && defined(__aarch64__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__arm__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_ASIMD) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0) + return true; +#elif defined(__linux__) && defined(__arm__) + if ((getauxval(AT_HWCAP) & HWCAP_NEON) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // Core feature set for Aarch32 and Aarch64. + if (IsAppleMachineARMv8()) + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + // Windows 10 ARM64 is only supported on Armv8a and above + if (IsProcessorFeaturePresent(PF_ARM_V8_INSTRUCTIONS_AVAILABLE) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryCRC32() +{ +#if defined(__ANDROID__) && defined(__aarch64__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_CRC32) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryPMULL() +{ +#if defined(__ANDROID__) && defined(__aarch64__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_PMULL) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_PMULL) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryAES() +{ +#if defined(__ANDROID__) && defined(__aarch64__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_AES) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_AES) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QuerySHA1() +{ +#if defined(__ANDROID__) && defined(__aarch64__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SHA1) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_SHA1) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QuerySHA256() +{ +#if defined(__ANDROID__) && defined(__aarch64__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_SHA2) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#elif defined(_WIN32) && defined(_M_ARM64) + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return true; +#endif + return false; +} + +// Some ARMv8.2 features are disabled at the moment +inline bool CPU_QuerySHA3() +{ + // According to the ARM manual, SHA3 depends upon SHA1 and SHA2. + // If SHA1 and SHA2 are not present, then SHA3 and SHA512 are + // not present. Also see Arm A64 Instruction Set Architecture, + // https://developer.arm.com/documentation/ddi0596/2020-12/ + if (!g_hasSHA1 || !g_hasSHA2) { return false; } + +#if defined(__ANDROID__) && defined(__aarch64__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA3) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA3) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SHA3) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_SHA3) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#endif + return false; +} + +// Some ARMv8.2 features are disabled at the moment +inline bool CPU_QuerySHA512() +{ + // According to the ARM manual, SHA512 depends upon SHA1 and SHA2. + // If SHA1 and SHA2 are not present, then SHA3 and SHA512 are + // not present. Also see Arm A64 Instruction Set Architecture, + // https://developer.arm.com/documentation/ddi0596/2020-12/ + if (!g_hasSHA1 || !g_hasSHA2) { return false; } + +#if defined(__ANDROID__) && defined(__aarch64__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA512) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA512) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SHA512) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_SHA512) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) + // M1 processor + if (IsAppleMachineARMv82()) + return true; +#endif + return false; +} + +// Some ARMv8.2 features are disabled at the moment +inline bool CPU_QuerySM3() +{ +#if defined(__ANDROID__) && defined(__aarch64__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SM3) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SM3) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SM3) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_SM3) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) && 0 + // No Apple support yet. +#endif + return false; +} + +// Some ARMv8.2 features are disabled at the moment +inline bool CPU_QuerySM4() +{ +#if defined(__ANDROID__) && defined(__aarch64__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SM4) != 0)) + return true; +#elif defined(__ANDROID__) && defined(__aarch32__) && 0 + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SM4) != 0)) + return true; +#elif defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SM4) != 0) + return true; +#elif defined(__linux__) && defined(__aarch32__) + if ((getauxval(AT_HWCAP2) & HWCAP2_SM4) != 0) + return true; +#elif defined(__APPLE__) && defined(__aarch64__) && 0 + // No Apple support yet. +#endif + return false; +} + +void DetectArmFeatures() +{ + // The CPU_ProbeXXX's return false for OSes which + // can't tolerate SIGILL-based probes + g_hasARMv7 = CPU_QueryARMv7() || CPU_ProbeARMv7(); + g_hasNEON = CPU_QueryNEON() || CPU_ProbeNEON(); + g_hasCRC32 = CPU_QueryCRC32() || CPU_ProbeCRC32(); + g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL(); + g_hasAES = CPU_QueryAES() || CPU_ProbeAES(); + g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1(); + g_hasSHA2 = CPU_QuerySHA256() || CPU_ProbeSHA256(); + g_hasSHA512 = CPU_QuerySHA512(); // || CPU_ProbeSHA512(); + g_hasSHA3 = CPU_QuerySHA3(); // || CPU_ProbeSHA3(); + g_hasSM3 = CPU_QuerySM3(); // || CPU_ProbeSM3(); + g_hasSM4 = CPU_QuerySM4(); // || CPU_ProbeSM4(); + +#if defined(_SC_LEVEL1_DCACHE_LINESIZE) + // Glibc does not implement on some platforms. The runtime returns 0 instead of error. + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c + int cacheLineSize = (int)sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + if (cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; +#endif + + if (g_cacheLineSize == 0) + g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + + *const_cast(&g_ArmDetectionDone) = true; +} + +// *************************** PowerPC and PowerPC64 *************************** + +#elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + +bool CRYPTOPP_SECTION_INIT g_PowerpcDetectionDone = false; +bool CRYPTOPP_SECTION_INIT g_hasAltivec = false; +bool CRYPTOPP_SECTION_INIT g_hasPower7 = false; +bool CRYPTOPP_SECTION_INIT g_hasPower8 = false; +bool CRYPTOPP_SECTION_INIT g_hasPower9 = false; +bool CRYPTOPP_SECTION_INIT g_hasAES = false; +bool CRYPTOPP_SECTION_INIT g_hasPMULL = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA256 = false; +bool CRYPTOPP_SECTION_INIT g_hasSHA512 = false; +bool CRYPTOPP_SECTION_INIT g_hasDARN = false; +word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + +extern bool CPU_ProbeAltivec(); +extern bool CPU_ProbePower7(); +extern bool CPU_ProbePower8(); +extern bool CPU_ProbePower9(); +extern bool CPU_ProbeAES(); +extern bool CPU_ProbePMULL(); +extern bool CPU_ProbeSHA256(); +extern bool CPU_ProbeSHA512(); +extern bool CPU_ProbeDARN(); + +// AIX defines. We used to just call __power_7_andup() +// and friends but at Power9, too many compilers were +// missing __power_9_andup(). Instead we switched to +// a pattern similar to OpenSSL caps testing. +#ifndef __power_6_andup +# define __power_6_andup() __power_set(0xffffffffU<<14) +#endif +#ifndef __power_7_andup +# define __power_7_andup() __power_set(0xffffffffU<<15) +#endif +#ifndef __power_8_andup +# define __power_8_andup() __power_set(0xffffffffU<<16) +#endif +#ifndef __power_9_andup +# define __power_9_andup() __power_set(0xffffffffU<<17) +#endif + +// AIX first supported Altivec at Power6, though it +// was available much earlier for other vendors. +inline bool CPU_QueryAltivec() +{ +#if defined(__linux__) && defined(PPC_FEATURE_HAS_ALTIVEC) + if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0) + return true; +#elif defined(_AIX) + if (__power_6_andup() != 0) + return true; +#elif defined(__APPLE__) && defined(__POWERPC__) + unsigned int unused, arch; + GetAppleMachineInfo(unused, unused, arch); + return arch == AppleMachineInfo::PowerMac; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE_HAS_ALTIVEC) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE_HAS_ALTIVEC) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryPower7() +{ + // Power7 and ISA 2.06 +#if defined(__linux__) && defined(PPC_FEATURE_ARCH_2_06) + if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0) + return true; +#elif defined(_AIX) + if (__power_7_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE_ARCH_2_06) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE_ARCH_2_06) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryPower8() +{ + // Power8 and ISA 2.07 provide in-core crypto. +#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_2_07) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0) + return true; +#elif defined(_AIX) + if (__power_8_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_ARCH_2_07) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE_ARCH_2_07) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryPower9() +{ + // Power9 and ISA 3.0. +#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0) + return true; +#elif defined(_AIX) + if (__power_9_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_ARCH_3_00) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE_ARCH2_3_00) != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryAES() +{ + // Power8 and ISA 2.07 provide in-core crypto. Glibc + // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. +#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) + return true; +#elif defined(_AIX) + if (__power_8_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0) + return true; +#endif + return false; +} + +inline bool CPU_QueryPMULL() +{ + // Power8 and ISA 2.07 provide in-core crypto. Glibc + // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. +#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) + return true; +#elif defined(_AIX) + if (__power_8_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0) + return true; +#endif + return false; +} + +inline bool CPU_QuerySHA256() +{ + // Power8 and ISA 2.07 provide in-core crypto. Glibc + // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. +#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) + return true; +#elif defined(_AIX) + if (__power_8_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0) + return true; +#endif + return false; +} +inline bool CPU_QuerySHA512() +{ + // Power8 and ISA 2.07 provide in-core crypto. Glibc + // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. +#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) + return true; +#elif defined(_AIX) + if (__power_8_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_HAS_VEC_CRYPTO) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO != 0) + return true; +#endif + return false; +} + +// Power9 random number generator +inline bool CPU_QueryDARN() +{ + // Power9 and ISA 3.0 provide DARN. It looks like + // Glibc offers PPC_FEATURE2_DARN. +#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0) + return true; +#elif defined(_AIX) + if (__power_9_andup() != 0) + return true; +#elif defined(__FreeBSD__) && defined(PPC_FEATURE2_ARCH_3_00) + unsigned long cpufeatures; + if (elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures)) == 0) + if ((cpufeatures & PPC_FEATURE2_ARCH_3_00) != 0) + return true; +#endif + return false; +} + +void DetectPowerpcFeatures() +{ + // GCC 10 is giving us trouble in CPU_ProbePower9() and + // CPU_ProbeDARN(). GCC is generating POWER9 instructions + // on POWER8 for ppc_power9.cpp. The compiler idiots did + // not think through the consequences of requiring us to + // use -mcpu=power9 to unlock the ISA. Epic fail. + // https://github.com/weidai11/cryptopp/issues/986 + + // The CPU_ProbeXXX's return false for OSes which + // can't tolerate SIGILL-based probes, like Apple + g_hasAltivec = CPU_QueryAltivec() || CPU_ProbeAltivec(); + g_hasPower7 = CPU_QueryPower7() || CPU_ProbePower7(); + g_hasPower8 = CPU_QueryPower8() || CPU_ProbePower8(); + g_hasPower9 = CPU_QueryPower9() || CPU_ProbePower9(); + g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL(); + g_hasAES = CPU_QueryAES() || CPU_ProbeAES(); + g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256(); + g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512(); + g_hasDARN = CPU_QueryDARN() || CPU_ProbeDARN(); + +#if defined(_AIX) && defined(SC_L1C_DLS) + // /usr/include/sys/systemcfg.h + int cacheLineSize = getsystemcfg(SC_L1C_DLS); + if (cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; +#elif defined(_SC_LEVEL1_DCACHE_LINESIZE) + // Glibc does not implement on some platforms. The runtime returns 0 instead of error. + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c + int cacheLineSize = (int)sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + if (cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; +#endif + + if (g_cacheLineSize == 0) + g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + + *const_cast(&g_PowerpcDetectionDone) = true; +} + +#endif +NAMESPACE_END + +// *************************** C++ Static Initialization *************************** + +ANONYMOUS_NAMESPACE_BEGIN + +class InitCpu +{ +public: + InitCpu() + { +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + CryptoPP::DetectX86Features(); +#elif CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 + CryptoPP::DetectArmFeatures(); +#elif CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 + CryptoPP::DetectPowerpcFeatures(); +#endif + } +}; + +// This is not really needed because HasSSE() and friends can dynamically initialize. +// Everything depends on CPU features so we initialize it once at load time. +// Dynamic initialization will be used if init priorities are not available. + +#if HAVE_GCC_INIT_PRIORITY + const InitCpu s_init __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 10))) = InitCpu(); +#elif HAVE_MSC_INIT_PRIORITY + #pragma warning(disable: 4075) + #pragma init_seg(".CRT$XCU") + const InitCpu s_init; + #pragma warning(default: 4075) +#elif HAVE_XLC_INIT_PRIORITY + // XLC needs constant, not a define + #pragma priority(270) + const InitCpu s_init; +#else + const InitCpu s_init; +#endif + +ANONYMOUS_NAMESPACE_END + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/cpu.h b/external/ours/library/crypto/src/shared/original/cpu.h new file mode 100755 index 000000000..c6f836671 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cpu.h @@ -0,0 +1,1085 @@ +// cpu.h - originally written and placed in the public domain by Wei Dai +// updated for ARM and PowerPC by Jeffrey Walton. +// updated to split CPU_Query() and CPU_Probe() by Jeffrey Walton. + +/// \file cpu.h +/// \brief Functions for CPU features and intrinsics +/// \details The CPU functions are used in IA-32, ARM and PowerPC code paths. The +/// functions provide cpu specific feature testing on IA-32, ARM and PowerPC machines. +/// \details Feature detection uses CPUID on IA-32, like Intel and AMD. On other platforms +/// a two-part strategy is used. First, the library attempts to *Query* the OS for a feature, +/// like using Linux getauxval() or android_getCpuFeatures(). If that fails, then *Probe* +/// the cpu executing an instruction and an observe a SIGILL if unsupported. The general +/// pattern used by the library is: +///
+///    g_hasCRC32 = CPU_QueryCRC32() || CPU_ProbeCRC32();
+///    g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
+///    g_hasAES  = CPU_QueryAES() || CPU_ProbeAES();
+/// 
+/// \details Generally speaking, CPU_Query() is in the source file cpu.cpp because it +/// does not require special architectural flags. CPU_Probe() is in a source file that receives +/// architectural flags, like sse_simd.cpp, neon_simd.cpp and +/// ppc_simd.cpp. For example, compiling neon_simd.cpp on an ARM64 machine will +/// have -march=armv8-a applied during a compile to make the instruction set architecture +/// (ISA) available. +/// \details The cpu probes are expensive when compared to a standard OS feature query. The library +/// also avoids probes on Apple platforms because Apple's signal handling for SIGILLs appears to +/// corrupt memory. CPU_Probe() will unconditionally return false for Apple platforms. OpenSSL +/// experienced the same problem and moved away from SIGILL probes on Apple. + +#ifndef CRYPTOPP_CPU_H +#define CRYPTOPP_CPU_H + +#include "config.h" + +// Issue 340 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +// Applies to both X86/X32/X64 and ARM32/ARM64 +#if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) + #define NEW_LINE "\n" + #define INTEL_PREFIX ".intel_syntax;" + #define INTEL_NOPREFIX ".intel_syntax;" + #define ATT_PREFIX ".att_syntax;" + #define ATT_NOPREFIX ".att_syntax;" +#elif defined(__GNUC__) + #define NEW_LINE + #define INTEL_PREFIX ".intel_syntax prefix;" + #define INTEL_NOPREFIX ".intel_syntax noprefix;" + #define ATT_PREFIX ".att_syntax prefix;" + #define ATT_NOPREFIX ".att_syntax noprefix;" +#else + #define NEW_LINE + #define INTEL_PREFIX + #define INTEL_NOPREFIX + #define ATT_PREFIX + #define ATT_NOPREFIX +#endif + +#ifdef CRYPTOPP_GENERATE_X64_MASM + +#define CRYPTOPP_X86_ASM_AVAILABLE +#define CRYPTOPP_BOOL_X64 1 +#define CRYPTOPP_SSE2_ASM_AVAILABLE 1 +#define NAMESPACE_END + +#else + +NAMESPACE_BEGIN(CryptoPP) + +// ***************************** IA-32 ***************************** // + +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING + +#define CRYPTOPP_CPUID_AVAILABLE 1 + +// Hide from Doxygen +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +// These should not be used directly +extern CRYPTOPP_DLL bool g_x86DetectionDone; +extern CRYPTOPP_DLL bool g_hasSSE2; +extern CRYPTOPP_DLL bool g_hasSSSE3; +extern CRYPTOPP_DLL bool g_hasSSE41; +extern CRYPTOPP_DLL bool g_hasSSE42; +extern CRYPTOPP_DLL bool g_hasMOVBE; +extern CRYPTOPP_DLL bool g_hasAESNI; +extern CRYPTOPP_DLL bool g_hasCLMUL; +extern CRYPTOPP_DLL bool g_hasAVX; +extern CRYPTOPP_DLL bool g_hasAVX2; +extern CRYPTOPP_DLL bool g_hasSHA; +extern CRYPTOPP_DLL bool g_hasADX; +extern CRYPTOPP_DLL bool g_isP4; +extern CRYPTOPP_DLL bool g_hasRDRAND; +extern CRYPTOPP_DLL bool g_hasRDSEED; +extern CRYPTOPP_DLL bool g_hasPadlockRNG; +extern CRYPTOPP_DLL bool g_hasPadlockACE; +extern CRYPTOPP_DLL bool g_hasPadlockACE2; +extern CRYPTOPP_DLL bool g_hasPadlockPHE; +extern CRYPTOPP_DLL bool g_hasPadlockPMM; +extern CRYPTOPP_DLL word32 g_cacheLineSize; + +CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); +CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 func, word32 subfunc, word32 output[4]); +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +/// \name IA-32 CPU FEATURES +//@{ + +/// \brief Determine SSE2 availability +/// \return true if SSE2 is determined to be available, false otherwise +/// \details MMX, SSE and SSE2 are core processor features for x86_64, and +/// the function return value is based on OSXSAVE. On i386 both +/// SSE2 and OSXSAVE are used for the return value. +/// \note This function is only available on Intel IA-32 platforms +inline bool HasSSE2() +{ +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_SSE2_INTRIN_AVAILABLE) + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSSE2; +#else + return false; +#endif +} + +/// \brief Determine SSSE3 availability +/// \return true if SSSE3 is determined to be available, false otherwise +/// \details HasSSSE3() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasSSSE3() +{ +#if CRYPTOPP_SSSE3_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSSSE3; +#else + return false; +#endif +} + +/// \brief Determine SSE4.1 availability +/// \return true if SSE4.1 is determined to be available, false otherwise +/// \details HasSSE41() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasSSE41() +{ +#if CRYPTOPP_SSE41_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSSE41; +#else + return false; +#endif +} + +/// \brief Determine SSE4.2 availability +/// \return true if SSE4.2 is determined to be available, false otherwise +/// \details HasSSE42() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasSSE42() +{ +#if CRYPTOPP_SSE42_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSSE42; +#else + return false; +#endif +} + +/// \brief Determine MOVBE availability +/// \return true if MOVBE is determined to be available, false otherwise +/// \details HasMOVBE() is a runtime check performed using CPUID +/// \since Crypto++ 8.3 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasMOVBE() +{ +#if CRYPTOPP_SSE42_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasMOVBE; +#else + return false; +#endif +} + +/// \brief Determine AES-NI availability +/// \return true if AES-NI is determined to be available, false otherwise +/// \details HasAESNI() is a runtime check performed using CPUID +/// \since Crypto++ 5.6.1 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasAESNI() +{ +#if CRYPTOPP_AESNI_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasAESNI; +#else + return false; +#endif +} + +/// \brief Determine Carryless Multiply availability +/// \return true if pclmulqdq is determined to be available, false otherwise +/// \details HasCLMUL() is a runtime check performed using CPUID +/// \since Crypto++ 5.6.1 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasCLMUL() +{ +#if CRYPTOPP_CLMUL_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasCLMUL; +#else + return false; +#endif +} + +/// \brief Determine SHA availability +/// \return true if SHA is determined to be available, false otherwise +/// \details HasSHA() is a runtime check performed using CPUID +/// \since Crypto++ 6.0 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasSHA() +{ +#if CRYPTOPP_SHANI_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSHA; +#else + return false; +#endif +} + +/// \brief Determine ADX availability +/// \return true if ADX is determined to be available, false otherwise +/// \details HasADX() is a runtime check performed using CPUID +/// \since Crypto++ 7.0 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasADX() +{ +#if CRYPTOPP_ADX_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasADX; +#else + return false; +#endif +} + +/// \brief Determine AVX availability +/// \return true if AVX is determined to be available, false otherwise +/// \details HasAVX() is a runtime check performed using CPUID +/// \since Crypto++ 8.0 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasAVX() +{ +#if CRYPTOPP_AVX_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasAVX; +#else + return false; +#endif +} + +/// \brief Determine AVX2 availability +/// \return true if AVX2 is determined to be available, false otherwise +/// \details HasAVX2() is a runtime check performed using CPUID +/// \since Crypto++ 8.0 +/// \note This function is only available on Intel IA-32 platforms +inline bool HasAVX2() +{ +#if CRYPTOPP_AVX2_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasAVX2; +#else + return false; +#endif +} + +/// \brief Determine RDRAND availability +/// \return true if RDRAND is determined to be available, false otherwise +/// \details HasRDRAND() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasRDRAND() +{ +#if CRYPTOPP_RDRAND_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasRDRAND; +#else + return false; +#endif +} + +/// \brief Determine RDSEED availability +/// \return true if RDSEED is determined to be available, false otherwise +/// \details HasRDSEED() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasRDSEED() +{ +#if CRYPTOPP_RDSEED_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasRDSEED; +#else + return false; +#endif +} + +/// \brief Determine Padlock RNG availability +/// \return true if VIA Padlock RNG is determined to be available, false otherwise +/// \details HasPadlockRNG() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockRNG() +{ +#if CRYPTOPP_PADLOCK_RNG_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockRNG; +#else + return false; +#endif +} + +/// \brief Determine Padlock ACE availability +/// \return true if VIA Padlock ACE is determined to be available, false otherwise +/// \details HasPadlockACE() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockACE() +{ +#if CRYPTOPP_PADLOCK_ACE_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockACE; +#else + return false; +#endif +} + +/// \brief Determine Padlock ACE2 availability +/// \return true if VIA Padlock ACE2 is determined to be available, false otherwise +/// \details HasPadlockACE2() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockACE2() +{ +#if CRYPTOPP_PADLOCK_ACE2_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockACE2; +#else + return false; +#endif +} + +/// \brief Determine Padlock PHE availability +/// \return true if VIA Padlock PHE is determined to be available, false otherwise +/// \details HasPadlockPHE() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockPHE() +{ +#if CRYPTOPP_PADLOCK_PHE_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockPHE; +#else + return false; +#endif +} + +/// \brief Determine Padlock PMM availability +/// \return true if VIA Padlock PMM is determined to be available, false otherwise +/// \details HasPadlockPMM() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockPMM() +{ +#if CRYPTOPP_PADLOCK_PMM_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockPMM; +#else + return false; +#endif +} + +/// \brief Determine if the CPU is an Intel P4 +/// \return true if the CPU is a P4, false otherwise +/// \details IsP4() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool IsP4() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_isP4; +} + +/// \brief Provides the cache line size +/// \return lower bound on the size of a cache line in bytes, if available +/// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it +/// is available. If the value is not available at runtime, then 32 is returned for a 32-bit +/// processor and 64 is returned for a 64-bit processor. +/// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC +/// and AIX also makes the value available to user space and it is also usually accurate. The +/// ARM processor equivalent is a privileged instruction, so a compile time value is returned. +inline int GetCacheLineSize() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_cacheLineSize; +} +//@} + +#endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + +// ***************************** ARM-32, Aarch32 and Aarch64 ***************************** // + +#if CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 || CRYPTOPP_DOXYGEN_PROCESSING + +// Hide from Doxygen +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +extern bool g_ArmDetectionDone; +extern bool g_hasARMv7; +extern bool g_hasNEON; +extern bool g_hasPMULL; +extern bool g_hasCRC32; +extern bool g_hasAES; +extern bool g_hasSHA1; +extern bool g_hasSHA2; +extern bool g_hasSHA512; +extern bool g_hasSHA3; +extern bool g_hasSM3; +extern bool g_hasSM4; +void CRYPTOPP_API DetectArmFeatures(); +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +/// \name ARM A-32, Aarch32 and AArch64 CPU FEATURES +//@{ + +/// \brief Determine if an ARM processor is ARMv7 or above +/// \return true if the hardware is ARMv7 or above, false otherwise. +/// \details Some AES code requires ARMv7 or above +/// \since Crypto++ 8.0 +/// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms +inline bool HasARMv7() +{ + // ASIMD is a core feature on Aarch32 and Aarch64 like SSE2 is a core feature on x86_64 +#if defined(__aarch32__) || defined(__aarch64__) + return true; +#else + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasARMv7; +#endif +} + +/// \brief Determine if an ARM processor has Advanced SIMD available +/// \return true if the hardware is capable of Advanced SIMD at runtime, false otherwise. +/// \details Advanced SIMD instructions are available under most ARMv7, Aarch32 and Aarch64. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mfpu=neon (32-bit) or -march=armv8-a +/// (64-bit). Also see ARM's __ARM_NEON preprocessor macro. +/// \since Crypto++ 5.6.4 +/// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms +inline bool HasNEON() +{ + // ASIMD is a core feature on Aarch32 and Aarch64 like SSE2 is a core feature on x86_64 +#if defined(CRYPTOPP_ARM_ASIMD_AVAILABLE) + return true; +#elif defined(CRYPTOPP_ARM_NEON_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasNEON; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has CRC32 available +/// \return true if the hardware is capable of CRC32 at runtime, false otherwise. +/// \details CRC32 instructions provide access to the processor's CRC-32 and CRC-32C +/// instructions. They are provided by ARM C Language Extensions 2.0 (ACLE 2.0) and +/// available under Aarch32 and Aarch64. +/// \details Runtime support requires compile time support. When compiling with GCC, +/// you may need to compile with -march=armv8-a+crc; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRC32 preprocessor macro. +/// \since Crypto++ 5.6.4 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasCRC32() +{ +#if defined(CRYPTOPP_ARM_CRC32_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasCRC32; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has AES available +/// \return true if the hardware is capable of AES at runtime, false otherwise. +/// \details AES is part of the optional Crypto extensions on Aarch32 and Aarch64. They are +/// accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -march=armv8-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 5.6.4 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasAES() +{ +#if defined(CRYPTOPP_ARM_AES_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasAES; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor provides Polynomial Multiplication +/// \return true if the hardware is capable of polynomial multiplications at runtime, +/// false otherwise. +/// \details The multiplication instructions are available under Aarch32 and Aarch64. +/// \details Runtime support requires compile time support. When compiling with GCC, +/// you may need to compile with -march=armv8-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 5.6.4 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasPMULL() +{ +#if defined(CRYPTOPP_ARM_PMULL_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasPMULL; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has SHA1 available +/// \return true if the hardware is capable of SHA1 at runtime, false otherwise. +/// \details SHA1 is part of the optional Crypto extensions on Aarch32 and Aarch64. They are +/// accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -march=armv8-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 5.6.4 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasSHA1() +{ +#if defined(CRYPTOPP_ARM_SHA1_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasSHA1; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has SHA256 available +/// \return true if the hardware is capable of SHA256 at runtime, false otherwise. +/// \details SHA256 is part of the optional Crypto extensions on Aarch32 and Aarch64. They are +/// accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -march=armv8-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 5.6.4 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasSHA2() +{ +#if defined(CRYPTOPP_ARM_SHA2_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasSHA2; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has SHA3 available +/// \return true if the hardware is capable of SHA3 at runtime, false otherwise. +/// \details SHA3 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They +/// are accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you +/// may need to compile with -march=armv8.2-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 8.0 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasSHA3() +{ +#if defined(CRYPTOPP_ARM_SHA3_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasSHA3; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has SHA512 available +/// \return true if the hardware is capable of SHA512 at runtime, false otherwise. +/// \details SHA512 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They +/// are accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you +/// may need to compile with -march=armv8.2-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 8.0 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasSHA512() +{ +#if defined(CRYPTOPP_ARM_SHA512_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasSHA512; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has SM3 available +/// \return true if the hardware is capable of SM3 at runtime, false otherwise. +/// \details SM3 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They +/// are accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you +/// may need to compile with -march=armv8.2-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 8.0 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasSM3() +{ +#if defined(CRYPTOPP_ARM_SM3_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasSM3; +#else + return false; +#endif +} + +/// \brief Determine if an ARM processor has SM4 available +/// \return true if the hardware is capable of SM4 at runtime, false otherwise. +/// \details SM4 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They +/// are accessed using ARM C Language Extensions 2.0 (ACLE 2.0). +/// \details Runtime support requires compile time support. When compiling with GCC, you +/// may need to compile with -march=armv8.2-a+crypto; while Apple requires +/// -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +/// \since Crypto++ 8.0 +/// \note This function is only available on Aarch32 and Aarch64 platforms +inline bool HasSM4() +{ +#if defined(CRYPTOPP_ARM_SM4_AVAILABLE) + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasSM4; +#else + return false; +#endif +} + +//@} + +#endif // CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 + +// ***************************** PowerPC ***************************** // + +#if CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 || CRYPTOPP_DOXYGEN_PROCESSING + +// Hide from Doxygen +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +extern bool g_PowerpcDetectionDone; +extern bool g_hasAltivec; +extern bool g_hasPower7; +extern bool g_hasPower8; +extern bool g_hasPower9; +extern bool g_hasAES; +extern bool g_hasPMULL; +extern bool g_hasSHA256; +extern bool g_hasSHA512; +extern bool g_hasDARN; +extern word32 g_cacheLineSize; +void CRYPTOPP_API DetectPowerpcFeatures(); +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +/// \name POWERPC CPU FEATURES +//@{ + +/// \brief Determine if a PowerPC processor has Altivec available +/// \return true if the hardware is capable of Altivec at runtime, false otherwise. +/// \details Altivec instructions are available on modern PowerPCs. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power4; while IBM XL C/C++ compilers require +/// -qarch=pwr6 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasAltivec() +{ +#if CRYPTOPP_ALTIVEC_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasAltivec; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has Power7 available +/// \return true if the hardware is capable of Power7 at runtime, false otherwise. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power7; while IBM XL C/C++ compilers require +/// -qarch=pwr7 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasPower7() +{ +#if CRYPTOPP_POWER7_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasPower7; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has Power8 available +/// \return true if the hardware is capable of Power8 at runtime, false otherwise. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power8; while IBM XL C/C++ compilers require +/// -qarch=pwr8 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasPower8() +{ +#if CRYPTOPP_POWER8_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasPower8; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has Power9 available +/// \return true if the hardware is capable of Power9 at runtime, false otherwise. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power9; while IBM XL C/C++ compilers require +/// -qarch=pwr9 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasPower9() +{ +#if CRYPTOPP_POWER9_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasPower9; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has AES available +/// \return true if the hardware is capable of AES at runtime, false otherwise. +/// \details AES is part of the in-crypto extensions on Power8 and Power9. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power8; while IBM XL C/C++ compilers require +/// -qarch=pwr8 -qaltivec. Also see PowerPC's __CRYPTO preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasAES() +{ +#if CRYPTOPP_POWER8_AES_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasAES; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has Polynomial Multiply available +/// \return true if the hardware is capable of PMULL at runtime, false otherwise. +/// \details PMULL is part of the in-crypto extensions on Power8 and Power9. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power8; while IBM XL C/C++ compilers require +/// -qarch=pwr8 -qaltivec. Also see PowerPC's __CRYPTO preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasPMULL() +{ +#if CRYPTOPP_POWER8_VMULL_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasPMULL; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has SHA256 available +/// \return true if the hardware is capable of SHA256 at runtime, false otherwise. +/// \details SHA is part of the in-crypto extensions on Power8 and Power9. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power8; while IBM XL C/C++ compilers require +/// -qarch=pwr8 -qaltivec. Also see PowerPC's __CRYPTO preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasSHA256() +{ +#if CRYPTOPP_POWER8_SHA_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasSHA256; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has SHA512 available +/// \return true if the hardware is capable of SHA512 at runtime, false otherwise. +/// \details SHA is part of the in-crypto extensions on Power8 and Power9. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power8; while IBM XL C/C++ compilers require +/// -qarch=pwr8 -qaltivec. Also see PowerPC's __CRYPTO preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasSHA512() +{ +#if CRYPTOPP_POWER8_SHA_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasSHA512; +#else + return false; +#endif +} + +/// \brief Determine if a PowerPC processor has DARN available +/// \return true if the hardware is capable of DARN at runtime, false otherwise. +/// \details Runtime support requires compile time support. When compiling with GCC, you may +/// need to compile with -mcpu=power9; while IBM XL C/C++ compilers require +/// -qarch=pwr9 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +/// \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasDARN() +{ +#if CRYPTOPP_POWER9_AVAILABLE + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + // see comments in cpu.cpp +# if defined(__ibmxl__) && defined(__linux__) + return false; +# else + return g_hasDARN; +# endif +#else + return false; +#endif +} + +/// \brief Provides the cache line size +/// \return lower bound on the size of a cache line in bytes, if available +/// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it +/// is available. If the value is not available at runtime, then 32 is returned for a 32-bit +/// processor and 64 is returned for a 64-bit processor. +/// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC +/// and AIX also makes the value available to user space and it is also usually accurate. The +/// ARM processor equivalent is a privileged instruction, so a compile time value is returned. +inline int GetCacheLineSize() +{ + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_cacheLineSize; +} + +//@} + +#endif // CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 + +// ***************************** L1 cache line ***************************** // + +// Non-Intel systems +#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) +/// \brief Provides the cache line size +/// \return lower bound on the size of a cache line in bytes, if available +/// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it +/// is available. If the value is not available at runtime, then 32 is returned for a 32-bit +/// processor and 64 is returned for a 64-bit processor. +/// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC +/// and AIX also makes the value available to user space and it is also usually accurate. The +/// ARM processor equivalent is a privileged instruction, so a compile time value is returned. +inline int GetCacheLineSize() +{ + return CRYPTOPP_L1_CACHE_LINE_SIZE; +} +#endif // Non-Intel systems + +#endif // CRYPTOPP_GENERATE_X64_MASM + +// ***************************** Inline ASM Helper ***************************** // + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + +#ifdef CRYPTOPP_GENERATE_X64_MASM + #define AS1(x) x*newline* + #define AS2(x, y) x, y*newline* + #define AS3(x, y, z) x, y, z*newline* + #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline* + #define ASL(x) label##x:*newline* + #define ASJ(x, y, z) x label##y*newline* + #define ASC(x, y) x label##y*newline* + #define AS_HEX(y) 0##y##h +#elif defined(_MSC_VER) || defined(__BORLANDC__) + #define AS1(x) __asm {x} + #define AS2(x, y) __asm {x, y} + #define AS3(x, y, z) __asm {x, y, z} + #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)} + #define ASL(x) __asm {label##x:} + #define ASJ(x, y, z) __asm {x label##y} + #define ASC(x, y) __asm {x label##y} + #define CRYPTOPP_NAKED __declspec(naked) + #define AS_HEX(y) 0x##y +#else + // define these in two steps to allow arguments to be expanded + #define GNU_AS1(x) #x ";" NEW_LINE + #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE + #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" NEW_LINE + #define GNU_ASL(x) "\n" #x ":" NEW_LINE +// clang 5.0.0 and apple clang 9.0.0 don't support numerical backward jumps +#if (CRYPTOPP_LLVM_CLANG_VERSION >= 50000) || (CRYPTOPP_APPLE_CLANG_VERSION >= 90000) + #define GNU_ASJ(x, y, z) ATT_PREFIX ";" NEW_LINE #x " " #y #z ";" NEW_LINE INTEL_PREFIX ";" NEW_LINE +#else + #define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE +#endif + #define AS1(x) GNU_AS1(x) + #define AS2(x, y) GNU_AS2(x, y) + #define AS3(x, y, z) GNU_AS3(x, y, z) + #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";" + #define ASL(x) GNU_ASL(x) + #define ASJ(x, y, z) GNU_ASJ(x, y, z) + #define ASC(x, y) #x " " #y ";" + #define CRYPTOPP_NAKED + #define AS_HEX(y) 0x##y +#endif + +#define IF0(y) +#define IF1(y) y + +#ifdef CRYPTOPP_GENERATE_X64_MASM +#define ASM_MOD(x, y) ((x) MOD (y)) +#define XMMWORD_PTR XMMWORD PTR +#else +// GNU assembler doesn't seem to have mod operator +#define ASM_MOD(x, y) ((x)-((x)/(y))*(y)) +// GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM +#define XMMWORD_PTR +#endif + +#if CRYPTOPP_BOOL_X86 + #define AS_REG_1 ecx + #define AS_REG_2 edx + #define AS_REG_3 esi + #define AS_REG_4 edi + #define AS_REG_5 eax + #define AS_REG_6 ebx + #define AS_REG_7 ebp + #define AS_REG_1d ecx + #define AS_REG_2d edx + #define AS_REG_3d esi + #define AS_REG_4d edi + #define AS_REG_5d eax + #define AS_REG_6d ebx + #define AS_REG_7d ebp + #define WORD_SZ 4 + #define WORD_REG(x) e##x + #define WORD_PTR DWORD PTR + #define AS_PUSH_IF86(x) AS1(push e##x) + #define AS_POP_IF86(x) AS1(pop e##x) + #define AS_JCXZ jecxz +#elif CRYPTOPP_BOOL_X32 + #define AS_REG_1 ecx + #define AS_REG_2 edx + #define AS_REG_3 r8d + #define AS_REG_4 r9d + #define AS_REG_5 eax + #define AS_REG_6 r10d + #define AS_REG_7 r11d + #define AS_REG_1d ecx + #define AS_REG_2d edx + #define AS_REG_3d r8d + #define AS_REG_4d r9d + #define AS_REG_5d eax + #define AS_REG_6d r10d + #define AS_REG_7d r11d + #define WORD_SZ 4 + #define WORD_REG(x) e##x + #define WORD_PTR DWORD PTR + #define AS_PUSH_IF86(x) AS1(push r##x) + #define AS_POP_IF86(x) AS1(pop r##x) + #define AS_JCXZ jecxz +#elif CRYPTOPP_BOOL_X64 + #ifdef CRYPTOPP_GENERATE_X64_MASM + #define AS_REG_1 rcx + #define AS_REG_2 rdx + #define AS_REG_3 r8 + #define AS_REG_4 r9 + #define AS_REG_5 rax + #define AS_REG_6 r10 + #define AS_REG_7 r11 + #define AS_REG_1d ecx + #define AS_REG_2d edx + #define AS_REG_3d r8d + #define AS_REG_4d r9d + #define AS_REG_5d eax + #define AS_REG_6d r10d + #define AS_REG_7d r11d + #else + #define AS_REG_1 rdi + #define AS_REG_2 rsi + #define AS_REG_3 rdx + #define AS_REG_4 rcx + #define AS_REG_5 r8 + #define AS_REG_6 r9 + #define AS_REG_7 r10 + #define AS_REG_1d edi + #define AS_REG_2d esi + #define AS_REG_3d edx + #define AS_REG_4d ecx + #define AS_REG_5d r8d + #define AS_REG_6d r9d + #define AS_REG_7d r10d + #endif + #define WORD_SZ 8 + #define WORD_REG(x) r##x + #define WORD_PTR QWORD PTR + #define AS_PUSH_IF86(x) + #define AS_POP_IF86(x) + #define AS_JCXZ jrcxz +#endif + +// helper macro for stream cipher output +#define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\ + AS2( test inputPtr, inputPtr)\ + ASC( jz, labelPrefix##3)\ + AS2( test inputPtr, 15)\ + ASC( jnz, labelPrefix##7)\ + AS2( pxor xmm##x0, [inputPtr+p0*16])\ + AS2( pxor xmm##x1, [inputPtr+p1*16])\ + AS2( pxor xmm##x2, [inputPtr+p2*16])\ + AS2( pxor xmm##x3, [inputPtr+p3*16])\ + AS2( add inputPtr, increment*16)\ + ASC( jmp, labelPrefix##3)\ + ASL(labelPrefix##7)\ + AS2( movdqu xmm##t, [inputPtr+p0*16])\ + AS2( pxor xmm##x0, xmm##t)\ + AS2( movdqu xmm##t, [inputPtr+p1*16])\ + AS2( pxor xmm##x1, xmm##t)\ + AS2( movdqu xmm##t, [inputPtr+p2*16])\ + AS2( pxor xmm##x2, xmm##t)\ + AS2( movdqu xmm##t, [inputPtr+p3*16])\ + AS2( pxor xmm##x3, xmm##t)\ + AS2( add inputPtr, increment*16)\ + ASL(labelPrefix##3)\ + AS2( test outputPtr, 15)\ + ASC( jnz, labelPrefix##8)\ + AS2( movdqa [outputPtr+p0*16], xmm##x0)\ + AS2( movdqa [outputPtr+p1*16], xmm##x1)\ + AS2( movdqa [outputPtr+p2*16], xmm##x2)\ + AS2( movdqa [outputPtr+p3*16], xmm##x3)\ + ASC( jmp, labelPrefix##9)\ + ASL(labelPrefix##8)\ + AS2( movdqu [outputPtr+p0*16], xmm##x0)\ + AS2( movdqu [outputPtr+p1*16], xmm##x1)\ + AS2( movdqu [outputPtr+p2*16], xmm##x2)\ + AS2( movdqu [outputPtr+p3*16], xmm##x3)\ + ASL(labelPrefix##9)\ + AS2( add outputPtr, increment*16) + +#endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + +#endif // Not CRYPTOPP_DOXYGEN_PROCESSING + +NAMESPACE_END + +// Issue 340 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#endif // CRYPTOPP_CPU_H diff --git a/external/ours/library/crypto/src/shared/original/crc.cpp b/external/ours/library/crypto/src/shared/original/crc.cpp new file mode 100755 index 000000000..20addce6a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/crc.cpp @@ -0,0 +1,367 @@ +// crc.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" +#include "crc.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +// crc_simd.cpp +#if (CRYPTOPP_ARM_CRC32_AVAILABLE) +extern void CRC32_Update_ARMV8(const byte *s, size_t n, word32& c); +extern void CRC32C_Update_ARMV8(const byte *s, size_t n, word32& c); +#endif + +// crc_simd.cpp +#if (CRYPTOPP_SSE42_AVAILABLE) +extern void CRC32C_Update_SSE42(const byte *s, size_t n, word32& c); +#endif + +/* Table of CRC-32's of all single byte values (made by makecrc.c) */ +const word32 CRC32::m_tab[] = { +#if (CRYPTOPP_LITTLE_ENDIAN) + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +#else + 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, + 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, + 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, + 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L, + 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L, + 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L, + 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L, + 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L, + 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L, + 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L, + 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL, + 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L, + 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L, + 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L, + 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L, + 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L, + 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL, + 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L, + 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL, + 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L, + 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L, + 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L, + 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL, + 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL, + 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L, + 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL, + 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L, + 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL, + 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L, + 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L, + 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L, + 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L, + 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L, + 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL, + 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L, + 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L, + 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L, + 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L, + 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L, + 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L, + 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L, + 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L, + 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL, + 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L, + 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L, + 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L, + 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L, + 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L, + 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL, + 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L, + 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL, + 0x8def022dL +#endif +}; + +std::string CRC32::AlgorithmProvider() const +{ +#if (CRYPTOPP_ARM_CRC32_AVAILABLE) + if (HasCRC32()) + return "ARMv8"; +#endif + return "C++"; +} + +CRC32::CRC32() +{ + Reset(); +} + +void CRC32::Update(const byte *s, size_t n) +{ +#if (CRYPTOPP_ARM_CRC32_AVAILABLE) + if (HasCRC32()) + { + CRC32_Update_ARMV8(s, n, m_crc); + return; + } +#endif + + word32 crc = m_crc; + + for(; !IsAligned(s) && n > 0; n--) + crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); + + while (n >= 4) + { + crc ^= *(const word32 *)(void*)s; + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + n -= 4; s += 4; + } + + while (n--) + crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); + + m_crc = crc; +} + +void CRC32::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + m_crc ^= CRC32_NEGL; + for (size_t i=0; i(s) && n > 0; n--) + crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); + + while (n >= 4) + { + crc ^= *(const word32 *)(void*)s; + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + n -= 4; s += 4; + } + + while (n--) + crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); + + m_crc = crc; +} + +void CRC32C::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + m_crc ^= CRC32_NEGL; + for (size_t i=0; i> 8) +#else +#define CRC32_INDEX(c) (c >> 24) +#define CRC32_SHIFTED(c) (c << 8) +#endif + +/// \brief CRC-32 Checksum Calculation +/// \details Uses CRC polynomial 0xEDB88320 +class CRC32 : public HashTransformation +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 4); + CRC32(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "CRC32";} + std::string AlgorithmName() const {return StaticAlgorithmName();} + + void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);} + byte GetCrcByte(size_t i) const {return reinterpret_cast(&m_crc)[i];} + + std::string AlgorithmProvider() const; + +protected: + void Reset() {m_crc = CRC32_NEGL;} + +private: + static const word32 m_tab[256]; + word32 m_crc; +}; + +/// \brief CRC-32C Checksum Calculation +/// \details Uses CRC polynomial 0x82F63B78 +/// \since Crypto++ 5.6.4 +class CRC32C : public HashTransformation +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 4); + CRC32C(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "CRC32C";} + std::string AlgorithmName() const {return StaticAlgorithmName();} + + void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);} + byte GetCrcByte(size_t i) const {return reinterpret_cast(&m_crc)[i];} + + std::string AlgorithmProvider() const; + +protected: + void Reset() {m_crc = CRC32_NEGL;} + +private: + static const word32 m_tab[256]; + word32 m_crc; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/crc_simd.cpp b/external/ours/library/crypto/src/shared/original/crc_simd.cpp new file mode 100755 index 000000000..c1a0725f5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/crc_simd.cpp @@ -0,0 +1,172 @@ +// crc_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics to gain access to SSE4.2 and +// ARMv8a CRC-32 and CRC-32C instructions. A separate source file +// is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "misc.h" + +#if (CRYPTOPP_SSE42_AVAILABLE) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if (CRYPTOPP_ARM_CRC32_AVAILABLE) +# include "arm_simd.h" +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +#define CONST_WORD32_CAST(x) ((const word32 *)(void*)(x)) + +// Squash MS LNK4221 and libtool warnings +extern const char CRC_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) + +bool CPU_ProbeCRC32() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (CRYPTOPP_ARM_CRC32_AVAILABLE) +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + word32 w=0, x=1; byte z=3; + w = CRC32W(w,x); + w = CRC32B(w,z); + w = CRC32CW(w,x); + w = CRC32CB(w,z); + + result = !!w; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +#else + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + word32 w=0, x=1; byte z=3; + w = CRC32W(w,x); + w = CRC32B(w,z); + w = CRC32CW(w,x); + w = CRC32CB(w,z); + + // Hack... GCC optimizes away the code and returns true + result = !!w; + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_CRC32_AVAILABLE +} +#endif // ARM32 or ARM64 + +#if (CRYPTOPP_ARM_CRC32_AVAILABLE) +void CRC32_Update_ARMV8(const byte *s, size_t n, word32& c) +{ + for(; !IsAligned(s) && n > 0; s++, n--) + c = CRC32B(c, *s); + + for(; n >= 16; s+=16, n-=16) + c = CRC32Wx4(c, CONST_WORD32_CAST(s)); + + for(; n >= 4; s+=4, n-=4) + c = CRC32W(c, *CONST_WORD32_CAST(s)); + + for(; n > 0; s++, n--) + c = CRC32B(c, *s); +} + +void CRC32C_Update_ARMV8(const byte *s, size_t n, word32& c) +{ + for(; !IsAligned(s) && n > 0; s++, n--) + c = CRC32CB(c, *s); + + for(; n >= 16; s+=16, n-=16) + c = CRC32CWx4(c, CONST_WORD32_CAST(s)); + + for(; n >= 4; s+=4, n-=4) + c = CRC32CW(c, *CONST_WORD32_CAST(s)); + + for(; n > 0; s++, n--) + c = CRC32CB(c, *s); +} +#endif + +#if (CRYPTOPP_SSE42_AVAILABLE) +void CRC32C_Update_SSE42(const byte *s, size_t n, word32& c) +{ + for(; !IsAligned(s) && n > 0; s++, n--) + c = _mm_crc32_u8(c, *s); + + for(; n >= 16; s+=16, n-=16) + { + c = _mm_crc32_u32(_mm_crc32_u32(_mm_crc32_u32(_mm_crc32_u32(c, + *CONST_WORD32_CAST(s+ 0)), *CONST_WORD32_CAST(s+ 4)), + *CONST_WORD32_CAST(s+ 8)), *CONST_WORD32_CAST(s+12)); + } + + for(; n >= 4; s+=4, n-=4) + c = _mm_crc32_u32(c, *CONST_WORD32_CAST(s)); + + for(; n > 0; s++, n--) + c = _mm_crc32_u8(c, *s); +} +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/cryptest.nmake b/external/ours/library/crypto/src/shared/original/cryptest.nmake new file mode 100755 index 000000000..1164c25f2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/cryptest.nmake @@ -0,0 +1,363 @@ +# cryptest.nmake - written and placed in public domain by Jeffrey Walton. +# Copyright assigned to the Crypto++ project. + +# This makefile is used for testing and building cryptlib.lib and cryptest.exe +# under nmake. Open a Visual Studio Developer Prompt and then run +# "nmake /f cryptest.nmake". The build procedure will reveal not so readily +# apparent problems under Microsoft ARM and Metro UI apps. + +# The makefile is not intended for production use, though it may be used as a +# starting point. For example, you can add switches like /MD and /MDd for +# dynamic runtime linking against the Microsoft C++ Runtime libraries. If you +# are building for Windows Phone or Windows Store, then you probably want to +# remove /D_MBCS. The resulting cryptlib.lib may be suitable as a starting +# point for a DLL project using Crypto++. + +# You must also add /DCRYPTOPP_DEBUG or /DDEBUG if you want a debug build with +# the library's assert. The library moved from Posix NDEBUG and assert() to +# CRYPTOPP_ASSERT at 5.6.5 due to CVE-2016-7420. CRYPTOPP_ASSERT has the +# additional benefit of using DebugBreak(), and the program does not crash +# while you are debugging it like would happen with Posix assert(). + +# There is mention of cryptopp.dll, CRYPTOPP_IMPORTS and CRYPTOPP_EXPORTS +# below. They are for testing only. Attempting to produce a working DLL on +# Windows fails. Too many missing symbols because cryptest.exe exercises +# about 80% of the library, but CRYPTOPP_DLL is only used for FIPS algos. + +# The list of LIB_SRCS and TEST_SRCS was generated under Linux with +# "make sources | fold -w73 -s". The list of LIB_OBJS and TEST_OBJS was +# generated with "make sources | fold -w73 -s | sed 's|.cpp|.obj|g'". The +# order of the first three object files are significant. See C++ Static +# Initialization Order Fiasco on the Crypto++ wiki for details. + +# You are free to add and remove files to the list. For example, you can remove +# rdrand.asm build it using NASM, and then include the NASM object file +# rdrand_x86.obj or rdrand_x64.obj. + +########################################################################################### + +# To test debug builds, use the following CXXFLAGS: +# - /DDEBUG /D_DEBUG /Oi /Oy- /Od +# To test release builds, use the following CXXFLAGS: +# - /DNDEBUG /D_NDEBUG /Oi /Oy /O2 +# To test with static C++ runtime linking, use the following CXXFLAGS: +# - /MT (release) or /MTd (debug) +# To test with dynamic C++ runtime linking, use the following CXXFLAGS: +# - /MD (release) or /MDd (debug) +# To test Desktop app, use the following CXXFLAGS: +# - /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP +# To test Windows Store app, use the following CXXFLAGS: +# - /DWINAPI_FAMILY=WINAPI_FAMILY_APP +# To test Windows Phone, use the following CXXFLAGS: +# - /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP +# To test Surface RT (ARM tablet), use the following CXXFLAGS: +# - /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP + +########################################################################################### + +LIB_SRCS = \ + cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp \ + algparam.cpp allocate.cpp arc4.cpp aria.cpp aria_simd.cpp ariatab.cpp \ + asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp \ + blake2.cpp blake2b_simd.cpp blake2s_simd.cpp blowfish.cpp blumshub.cpp \ + camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp \ + chacha_avx.cpp chacha_simd.cpp chachapoly.cpp cham.cpp cham_simd.cpp \ + channels.cpp cmac.cpp crc.cpp crc_simd.cpp darn.cpp default.cpp des.cpp \ + dessp.cpp dh.cpp dh2.cpp dll.cpp donna_32.cpp donna_64.cpp donna_sse.cpp \ + dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp \ + eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp \ + gcm.cpp gcm_simd.cpp gf256.cpp gf2_32.cpp gf2n.cpp gf2n_simd.cpp \ + gfpcrypt.cpp gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp \ + hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp \ + kalynatab.cpp keccak.cpp keccak_core.cpp keccak_simd.cpp lea.cpp \ + lea_simd.cpp lsh256.cpp lsh256_avx.cpp lsh256_sse.cpp lsh512.cpp \ + lsh512_avx.cpp lsh512_sse.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp \ + md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp oaep.cpp \ + osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp \ + pssr.cpp pubkey.cpp queue.cpp rabbit.cpp rabin.cpp randpool.cpp rc2.cpp \ + rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael.cpp rijndael_simd.cpp \ + ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp scrypt.cpp \ + seal.cpp seed.cpp serpent.cpp sha.cpp sha3.cpp sha_simd.cpp shacal2.cpp \ + shacal2_simd.cpp shake.cpp shark.cpp sharkbox.cpp simeck.cpp simon.cpp \ + simon128_simd.cpp skipjack.cpp sm3.cpp sm4.cpp sm4_simd.cpp \ + sosemanuk.cpp speck.cpp speck128_simd.cpp square.cpp squaretb.cpp \ + sse_simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp \ + tigertab.cpp ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wake.cpp \ + whrlpool.cpp xed25519.cpp xtr.cpp xtrcrypt.cpp xts.cpp zdeflate.cpp \ + zinflate.cpp zlib.cpp + +LIB_OBJS = \ + cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj \ + algparam.obj allocate.obj arc4.obj aria.obj aria_simd.obj ariatab.obj \ + asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj \ + blake2.obj blake2b_simd.obj blake2s_simd.obj blowfish.obj blumshub.obj \ + camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj \ + chacha_avx.obj chacha_simd.obj chachapoly.obj cham.obj cham_simd.obj \ + channels.obj cmac.obj crc.obj crc_simd.obj darn.obj default.obj des.obj \ + dessp.obj dh.obj dh2.obj dll.obj donna_32.obj donna_64.obj donna_sse.obj \ + dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj \ + eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj \ + gcm.obj gcm_simd.obj gf256.obj gf2_32.obj gf2n.obj gf2n_simd.obj \ + gfpcrypt.obj gost.obj gzip.obj hc128.obj hc256.obj hex.obj hight.obj \ + hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj \ + kalynatab.obj keccak.obj keccak_core.obj keccak_simd.obj lea.obj \ + lea_simd.obj lsh256.obj lsh256_avx.obj lsh256_sse.obj lsh512.obj \ + lsh512_avx.obj lsh512_sse.obj luc.obj mars.obj marss.obj md2.obj md4.obj \ + md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj oaep.obj \ + osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj \ + pssr.obj pubkey.obj queue.obj rabbit.obj rabin.obj randpool.obj rc2.obj \ + rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael.obj rijndael_simd.obj \ + ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj scrypt.obj \ + seal.obj seed.obj serpent.obj sha.obj sha3.obj sha_simd.obj shacal2.obj \ + shacal2_simd.obj shake.obj shark.obj sharkbox.obj simeck.obj simon.obj \ + simon128_simd.obj skipjack.obj sm3.obj sm4.obj sm4_simd.obj \ + sosemanuk.obj speck.obj speck128_simd.obj square.obj squaretb.obj \ + sse_simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj \ + tigertab.obj ttmac.obj tweetnacl.obj twofish.obj vmac.obj wake.obj \ + whrlpool.obj xed25519.obj xtr.obj xtrcrypt.obj xts.obj zdeflate.obj \ + zinflate.obj zlib.obj + +ASM_OBJS = \ + rdrand-x86.obj rdrand-x64.obj rdseed-x86.obj rdseed-x64.obj x64masm.obj x64dll.obj + +TEST_SRCS = \ + test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \ + dlltest.cpp fipsalgt.cpp validat0.cpp validat1.cpp validat2.cpp \ + validat3.cpp validat4.cpp validat5.cpp validat6.cpp validat7.cpp \ + validat8.cpp validat9.cpp validat10.cpp regtest1.cpp regtest2.cpp \ + regtest3.cpp regtest4.cpp + +TEST_OBJS = \ + test.obj bench1.obj bench2.obj bench3.obj datatest.obj \ + dlltest.obj fipsalgt.obj validat0.obj validat1.obj validat2.obj \ + validat3.obj validat4.obj validat5.obj validat6.obj validat7.obj \ + validat8.obj validat9.obj validat10.obj regtest1.obj regtest2.obj \ + regtest3.obj regtest4.obj + +CXX = cl.exe +LD = link.exe +AR = lib.exe +RM = del +RMDIR = rd + +# We may misdetect the environment on VS2005 or so. Uncomment as +# needed to match the Developer Prompt environment. +# PLATFORM = x86 +# PLATFORM = x64 +# PLATFORM = arm +# PLATFORM = arm64 + +# C4231 is needed for VS2008 and below. Lots of noise... +CXXFLAGS = /nologo /W4 /wd4231 /wd4511 /wd4156 /D_MBCS /Zi /TP /GR /EHsc +LDFLAGS = /nologo /SUBSYSTEM:CONSOLE /DEBUG +ARFLAGS = /nologo +LDLIBS = + +# Compiler debug build. +# CXXFLAGS = $(CXXFLAGS) /DDEBUG /D_DEBUG /Oi /Oy- /Od /MTd +# Compiler release build. +CXXFLAGS = $(CXXFLAGS) /DNDEBUG /D_NDEBUG /Oi /Oy /O2 /MT +# Linker debug build. +# LDFLAGS = $(LDFLAGS) /DEBUG +# Linker release build. +LDFLAGS = $(LDFLAGS) /DEBUG /OPT:REF + +# Attempt to detect when and are available +# http://stackoverflow.com/q/40577415 ? +!IF "$(WINDOWSSDKDIR)" != "" || "$(WINDOWSSDKLIBVERSION)" != "" +CXXFLAGS = $(CXXFLAGS) /FI sdkddkver.h +!ENDIF +!IF "$(WINDOWSPHONEKITDIR)" != "" || "$(UNIVERSALCRTSDKDIR)" != "" || "$(UCRTVERSION)" != "" +CXXFLAGS = $(CXXFLAGS) /FI winapifamily.h +!ELSEIF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64" +CXXFLAGS = $(CXXFLAGS) /FI winapifamily.h +!ENDIF + +# Check for empty Platform and Processor +!IF "$(PLATFORM)" == "" +!IF "$(PROCESSOR_ARCHITECTURE)" == "x86" +PLATFORM = x86 +!ELSEIF "$(PROCESSOR_ARCHITECTURE)" == "x64" || "$(PROCESSOR_ARCHITECTURE)" == "AMD64" +PLATFORM = x64 +!ELSE +!ERROR "Unknown platform" +!ENDIF +!ENDIF + +!MESSAGE +!MESSAGE ****************************** +!MESSAGE Platform is $(PLATFORM) +!MESSAGE ****************************** +!MESSAGE + +!IF "$(PLATFORM)" == "x86" || "$(PLATFORM)" == "X86" +# CXXFLAGS = $(CXXFLAGS) /arch:SSE2 +# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP +# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP +AS = ml.exe +ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh +LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm +LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj rdseed-x86.obj +LDFLAGS = $(LDFLAGS) /MACHINE:X86 +LDLIBS = $(LDLIBS) kernel32.lib +RDRAND_OBJ = rdrand-x86.obj +RDSEED_OBJ = rdseed-x86.obj +!ENDIF + +# May need $(VCINSTALLDIR)\bin\amd64\ml64.exe +!IF "$(PLATFORM)" == "x64" || "$(PLATFORM)" == "X64" || "$(PLATFORM)" == "amd64" +# CXXFLAGS = $(CXXFLAGS) /arch:AVX2 +# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP +# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP +AS = ml64.exe +ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi +LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm +LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj rdseed-x64.obj x64masm.obj x64dll.obj +LDFLAGS = $(LDFLAGS) /MACHINE:X64 +LDLIBS = $(LDLIBS) kernel32.lib +RDRAND_OBJ = rdrand-x64.obj +RDSEED_OBJ = rdseed-x64.obj +!ENDIF + +!IF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64" +# CXXFLAGS = $(CXXFLAGS) /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP +CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP +LIB_SRCS = $(LIB_SRCS) neon_simd.cpp +LIB_OBJS = $(LIB_OBJS) neon_simd.obj +# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP +# LDLIBS = $(LDLIBS) +!ENDIF + +all: cryptest.exe + +# For testing cryptopp.dll and CRYPTOPP_IMPORTS +#cryptest.exe: pch.pch cryptopp.lib $(TEST_OBJS) +# $(LD) $(LDFLAGS) $(TEST_OBJS) cryptopp.lib $(LDLIBS) /out:$@ + +cryptest.exe: pch.pch cryptlib.lib $(TEST_OBJS) + $(LD) $(LDFLAGS) $(TEST_OBJS) cryptlib.lib $(LDLIBS) /out:$@ + +cryptlib.lib: $(LIB_OBJS) + $(AR) $(ARFLAGS) $(LIB_OBJS) /out:$@ + +cryptopp.dump: cryptlib.lib + dumpbin.exe /LINKERMEMBER cryptlib.lib /OUT:$@ + +cryptopp.map: $(LIB_OBJS) + $(LD) $(LDFLAGS) /DLL /MAP /MAPINFO:EXPORTS $(LIB_OBJS) + mv cryptlib.map cryptopp.map + +cryptopp.def: cryptopp.dump + dump2def.exe cryptopp.dump cryptopp.def + +# LD produces 3 output artifacts for cryptopp.dll +cryptopp.dll cryptopp.lib cryptopp.exp: $(LIB_OBJS) cryptopp.def + $(LD) $(LDFLAGS) /DLL /DEF:cryptopp.def /IGNORE:4102 $(LIB_OBJS) $(LDLIBS) /out:cryptopp.dll + +clean :: + $(RM) /F /Q cryptest.exe cryptest.lib cryptest.exp pch.pch 2>nul +clean :: + $(RM) /F /Q cryptlib.lib cryptlib.exp cryptlib.dll 2>nul +clean :: + $(RM) /F /Q cryptopp.dll cryptopp.lib cryptopp.exp cryptopp.def 2>nul +clean :: + $(RM) /F /Q pch.obj $(LIB_OBJS) $(ASM_OBJS) $(TEST_OBJS) *.pdb 2>nul + +distclean :: clean +!IF EXIST ("$(USERNAME).sdf") + attrib -r -a -s -h "$(USERNAME).sdf" 2>nul + $(RM) /F /Q "$(USERNAME).sdf" 2>nul +!ENDIF +!IF EXIST ("$(USERNAME).suo") + attrib -r -a -s -h $(USERNAME).suo" 2>nul + $(RM) /F /Q $(USERNAME).suo" 2>nul +!ENDIF +!IF EXIST (Win32\) + $(RMDIR) Win32\ /q /s 2>nul +!ENDIF +!IF EXIST (x64\) + $(RMDIR) x64\ /q /s 2>nul +!ENDIF +!IF EXIST (ipch\) + $(RMDIR) ipch\ /q /s 2>nul +!ENDIF + +# Precompiled header +pch.pch: pch.h pch.cpp + $(CXX) $(CXXFLAGS) /Yc"pch.h" /Fp"pch.pch" /c pch.cpp + +# No precompiled headers +iterhash.obj: iterhash.h iterhash.cpp + $(CXX) $(CXXFLAGS) /Y- /c iterhash.cpp +dll.obj: dll.h dll.cpp + $(CXX) $(CXXFLAGS) /Y- /c dll.cpp +rdrand.obj: rdrand.h rdrand.cpp + $(CXX) $(CXXFLAGS) /c rdrand.cpp + +# Built for x86/x64 +rdrand-x86.obj: rdrand.asm + $(AS) $(ASFLAGS) /Fo rdrand-x86.obj /c rdrand.asm +rdrand-x64.obj: rdrand.asm + $(AS) $(ASFLAGS) /Fo rdrand-x64.obj /c rdrand.asm +rdseed-x86.obj: rdseed.asm + $(AS) $(ASFLAGS) /Fo rdseed-x86.obj /c rdseed.asm +rdseed-x64.obj: rdseed.asm + $(AS) $(ASFLAGS) /Fo rdseed-x64.obj /c rdseed.asm +x64masm.obj: x64masm.asm + $(AS) $(ASFLAGS) /Fo x64masm.obj /c x64masm.asm +x64dll.obj: x64dll.asm + $(AS) $(ASFLAGS) /Fo x64dll.obj /c x64dll.asm + +# For testing cryptopp.dll and CRYPTOPP_IMPORTS +#CXXFLAGS_IMPORTS = /wd4275 /wd4251 /DCRYPTOPP_IMPORTS +#test.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#datatest.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#fipstest.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#bench1.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#bench2.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#bench3.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#regtest1.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#regtest2.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#regtest3.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#regtest4.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat1.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat2.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat3.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat4.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat5.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat6.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat7.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat8.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat9.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? +#validat10.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $? + +# For testing cryptopp.dll and CRYPTOPP_EXPORTS +#CXXFLAGS_EXPORTS = /wd4275 /wd4251 /DCXXFLAGS_EXPORTS +#.cpp.obj: +# $(CXX) $(CXXFLAGS) $(CXXFLAGS_EXPORTS) /c $< + +.cpp.obj: + $(CXX) $(CXXFLAGS) /c $< + +.asm.obj: + $(AS) $(ASFLAGS) /c $< diff --git a/external/ours/library/crypto/src/shared/original/cryptlib.cpp b/external/ours/library/crypto/src/shared/original/cryptlib.cpp index 174cea86d..80f452695 100755 --- a/external/ours/library/crypto/src/shared/original/cryptlib.cpp +++ b/external/ours/library/crypto/src/shared/original/cryptlib.cpp @@ -1,488 +1,1054 @@ -// cryptlib.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "cryptlib.h" -#include "misc.h" -#include "filters.h" - -#include - -NAMESPACE_BEGIN(CryptoPP) - -const std::string BufferedTransformation::NULL_CHANNEL; - -unsigned int RandomNumberGenerator::GenerateBit() -{ - return Parity(GetByte()); -} - -void RandomNumberGenerator::GenerateBlock(byte *output, unsigned int size) -{ - while (size--) - *output++ = GetByte(); -} - -word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) -{ - word32 range = max-min; - const int maxBytes = BytePrecision(range); - const int maxBits = BitPrecision(range); - - word32 value; - - do - { - value = 0; - for (int i=0; i range); - - return value+min; -} - -void StreamCipher::ProcessString(byte *outString, const byte *inString, unsigned int length) -{ - while(length--) - *outString++ = ProcessByte(*inString++); -} - -void StreamCipher::ProcessString(byte *inoutString, unsigned int length) -{ - while(length--) { - (*inoutString)++; - *inoutString = ProcessByte(*inoutString); - } -} - -bool HashModule::Verify(const byte *digestIn) -{ - SecByteBlock digest(DigestSize()); - Final(digest); - return memcmp(digest, digestIn, DigestSize()) == 0; -} - -BufferedTransformation::Err::Err(ErrorType errorType, const std::string &s) - : Exception(s), m_errorType(errorType) -{ - if (GetWhat().empty()) - { - switch (errorType) - { - case CANNOT_FLUSH: - SetWhat("BufferedTransformation: cannot flush buffer"); - break; - case DATA_INTEGRITY_CHECK_FAILED: - SetWhat("BufferedTransformation: data integrity check failed"); - break; - case INVALID_DATA_FORMAT: - SetWhat("BufferedTransformation: invalid data format"); - break; - case OUTPUT_ERROR: - SetWhat("BufferedTransformation: cannot write to output device"); - break; - case OTHER_ERROR: - SetWhat("BufferedTransformation: unknown error"); - break; - default: - assert(false); - break; - } - } -} - -void BufferedTransformation::Put(byte b) -{ - if (AttachedTransformation()) - AttachedTransformation()->Put(b); -} - -void BufferedTransformation::Put(const byte *inString, unsigned int length) -{ - if (AttachedTransformation()) - AttachedTransformation()->Put(inString, length); -} - -void BufferedTransformation::Flush(bool completeFlush, int propagation) -{ - if (AttachedTransformation() && propagation) - AttachedTransformation()->Flush(completeFlush, propagation-1); -} - -void BufferedTransformation::MessageEnd(int propagation) -{ - if (AttachedTransformation() && propagation) - AttachedTransformation()->MessageEnd(propagation-1); -} - -void BufferedTransformation::MessageSeriesEnd(int propagation) -{ - if (AttachedTransformation() && propagation) - AttachedTransformation()->MessageSeriesEnd(propagation-1); -} - -void BufferedTransformation::PutMessageEnd(const byte *inString, unsigned int length, int propagation) -{ - Put(inString, length); - MessageEnd(propagation); -} - -void BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation) -{ - if (channel.empty()) - Flush(completeFlush, propagation); - else if (AttachedTransformation() && propagation) - AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation-1); -} - -void BufferedTransformation::ChannelMessageEnd(const std::string &channel, int propagation) -{ - if (channel.empty()) - MessageEnd(propagation); - else if (AttachedTransformation() && propagation) - AttachedTransformation()->ChannelMessageEnd(channel, propagation-1); -} - -void BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation) -{ - if (channel.empty()) - MessageSeriesEnd(propagation); - else if (AttachedTransformation() && propagation) - AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1); -} - -void BufferedTransformation::ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation) -{ - if (channel.empty()) - PutMessageEnd(inString, length, propagation); - else - { - ChannelPut(channel, inString, length); - ChannelMessageEnd(channel, propagation); - } -} - -unsigned long BufferedTransformation::MaxRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->MaxRetrievable(); - else - return CopyTo(g_bitBucket); -} - -bool BufferedTransformation::AnyRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->AnyRetrievable(); - else - { - byte b; - return Peek(b) != 0; - } -} - -unsigned int BufferedTransformation::Get(byte &outByte) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Get(outByte); - else - return Get(&outByte, 1); -} - -unsigned int BufferedTransformation::Get(byte *outString, unsigned int getMax) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Get(outString, getMax); - else - { - ArraySink arraySink(outString, getMax); - return TransferTo(arraySink, getMax); - } -} - -unsigned int BufferedTransformation::Peek(byte &outByte) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->Peek(outByte); - else - return Peek(&outByte, 1); -} - -unsigned int BufferedTransformation::Peek(byte *outString, unsigned int peekMax) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->Peek(outString, peekMax); - else - { - ArraySink arraySink(outString, peekMax); - return CopyTo(arraySink, peekMax); - } -} - -unsigned long BufferedTransformation::Skip(unsigned long skipMax) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Skip(skipMax); - else - return TransferTo(g_bitBucket, skipMax); -} - -unsigned long BufferedTransformation::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->CopyTo(target, copyMax); - else - return 0; -} - -unsigned long BufferedTransformation::TransferTo(BufferedTransformation &target, unsigned long size) -{ - if (AttachedTransformation()) - return AttachedTransformation()->TransferTo(target, size); - else - return 0; -} - -unsigned long BufferedTransformation::TotalBytesRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->TotalBytesRetrievable(); - else - return MaxRetrievable(); -} - -unsigned int BufferedTransformation::NumberOfMessages() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->NumberOfMessages(); - else - return CopyMessagesTo(g_bitBucket); -} - -bool BufferedTransformation::AnyMessages() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->NumberOfMessages(); - else - return NumberOfMessages() != 0; -} - -bool BufferedTransformation::GetNextMessage() -{ - if (AttachedTransformation()) - return AttachedTransformation()->GetNextMessage(); - else - return false; -} - -unsigned int BufferedTransformation::SkipMessages(unsigned int count) -{ - if (AttachedTransformation()) - return AttachedTransformation()->SkipMessages(count); - else - return TransferMessagesTo(g_bitBucket, count); -} - -unsigned int BufferedTransformation::TransferMessagesTo(BufferedTransformation &target, unsigned int count) -{ - if (AttachedTransformation()) - return AttachedTransformation()->TransferMessagesTo(target, count); - else - { - unsigned int i; - for (i=0; i (result); - target.MessageEnd(GetAutoSignalPropagation()); - } - return i; - } -} - -unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->CopyMessagesTo(target, count); - else - return 0; -} - -void BufferedTransformation::SkipAll() -{ - if (AttachedTransformation()) - AttachedTransformation()->SkipAll(); - else - { - while (SkipMessages()) {} - while (Skip()) {} - } -} - -void BufferedTransformation::TransferAllTo(BufferedTransformation &target) -{ - if (AttachedTransformation()) - AttachedTransformation()->TransferAllTo(target); - else - { - while (TransferMessagesTo(target)) {} - while (TransferTo(target)) {} - } -} - -void BufferedTransformation::CopyAllTo(BufferedTransformation &target) const -{ - if (AttachedTransformation()) - AttachedTransformation()->CopyAllTo(target); - else - { - CopyMessagesTo(target); - CopyTo(target); - } -} - -void BufferedTransformation::SetRetrievalChannel(const std::string &channel) -{ - if (AttachedTransformation()) - AttachedTransformation()->SetRetrievalChannel(channel); -} - -void BufferedTransformation::ChannelPut(const std::string &channel, byte inByte) -{ - if (channel.empty()) - Put(inByte); -} - -void BufferedTransformation::ChannelPut(const std::string &channel, const byte *inString, unsigned int length) -{ - if (channel.empty()) - Put(inString, length); -} - -void BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, bool highFirst) -{ - if (highFirst) - { - ChannelPut(channel, value>>8); - ChannelPut(channel, byte(value)); - } - else - { - ChannelPut(channel, byte(value)); - ChannelPut(channel, value>>8); - } -} - -void BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, bool highFirst) -{ - if (highFirst) - { - for (int i=0; i<4; i++) - ChannelPut(channel, byte(value>>((3-i)*8))); - } - else - { - for (int i=0; i<4; i++) - ChannelPut(channel, byte(value>>(i*8))); - } -} - -void BufferedTransformation::PutWord16(word16 value, bool highFirst) -{ - ChannelPutWord16(NULL_CHANNEL, value, highFirst); -} - -void BufferedTransformation::PutWord32(word32 value, bool highFirst) -{ - ChannelPutWord32(NULL_CHANNEL, value, highFirst); -} - -unsigned int BufferedTransformation::PeekWord16(word16 &value, bool highFirst) -{ - byte buf[2] = {0, 0}; - unsigned int len = Peek(buf, 2); - - if (highFirst) - value = (buf[0] << 8) | buf[1]; - else - value = (buf[1] << 8) | buf[0]; - - return len; -} - -unsigned int BufferedTransformation::PeekWord32(word32 &value, bool highFirst) -{ - byte buf[4] = {0, 0, 0, 0}; - unsigned int len = Peek(buf, 4); - - if (highFirst) - value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; - else - value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; - - return len; -} - -unsigned int BufferedTransformation::GetWord16(word16 &value, bool highFirst) -{ - return Skip(PeekWord16(value, highFirst)); -} - -unsigned int BufferedTransformation::GetWord32(word32 &value, bool highFirst) -{ - return Skip(PeekWord32(value, highFirst)); -} - -void BufferedTransformation::Attach(BufferedTransformation *newOut) -{ - if (!Attachable()) - return; - - if (AttachedTransformation() && AttachedTransformation()->Attachable()) - AttachedTransformation()->Attach(newOut); - else - Detach(newOut); -} - -unsigned int PK_FixedLengthCryptoSystem::MaxPlainTextLength(unsigned int cipherTextLength) const -{ - if (cipherTextLength == CipherTextLength()) - return MaxPlainTextLength(); - else - return 0; -} - -unsigned int PK_FixedLengthCryptoSystem::CipherTextLength(unsigned int plainTextLength) const -{ - if (plainTextLength <= MaxPlainTextLength()) - return CipherTextLength(); - else - return 0; -} - -unsigned int PK_FixedLengthDecryptor::Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) -{ - if (cipherTextLength != CipherTextLength()) - return 0; - - return Decrypt(cipherText, plainText); -} - -void PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const -{ - std::unique_ptr accumulator(NewMessageAccumulator()); - accumulator->Update(message, messageLen); - Sign(rng, accumulator.release(), signature); -} - -bool PK_Verifier::VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const -{ - std::unique_ptr accumulator(NewMessageAccumulator()); - accumulator->Update(message, messageLen); - return Verify(accumulator.release(), sig); -} - -NAMESPACE_END +// cryptlib.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4127 4189 4459) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wunused-value" +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#ifndef CRYPTOPP_IMPORTS + +#include "cryptlib.h" +#include "filters.h" +#include "algparam.h" +#include "fips140.h" +#include "argnames.h" +#include "fltrimpl.h" +#include "osrng.h" +#include "secblock.h" +#include "smartptr.h" +#include "stdcpp.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1); +CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2); +CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4); +CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8); +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE +CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word)); +#endif + +BufferedTransformation & TheBitBucket() +{ + static BitBucket bitBucket; + return bitBucket; +} + +Algorithm::Algorithm(bool checkSelfTestStatus) +{ + if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled()) + { + if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread()) + throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed."); + + if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED) + throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed."); + } +} + +void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms) +{ + this->ThrowIfInvalidKeyLength(length); + this->UncheckedSetKey(key, static_cast(length), params); +} + +void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds) +{ + SetKey(key, length, MakeParameters(Name::Rounds(), rounds)); +} + +void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength) +{ + SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength))); +} + +void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length) +{ + if (!IsValidKeyLength(length)) + throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length); +} + +void SimpleKeyingInterface::ThrowIfResynchronizable() +{ + if (IsResynchronizable()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV"); +} + +void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) +{ + if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV"); +} + +size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int length) +{ + size_t size = 0; + if (length < 0) + size = static_cast(IVSize()); + else if ((size_t)length < MinIVLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " is less than the minimum of " + IntToString(MinIVLength())); + else if ((size_t)length > MaxIVLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(length) + " exceeds the maximum of " + IntToString(MaxIVLength())); + else + size = static_cast(length); + + return size; +} + +const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size) +{ + ConstByteArrayParameter ivWithLength; + const byte *iv = NULLPTR; + bool found = false; + + try {found = params.GetValue(Name::IV(), ivWithLength);} + catch (const NameValuePairs::ValueTypeMismatch &) {} + + if (found) + { + iv = ivWithLength.begin(); + ThrowIfInvalidIV(iv); + size = ThrowIfInvalidIVLength(static_cast(ivWithLength.size())); + } + else if (params.GetValue(Name::IV(), iv)) + { + ThrowIfInvalidIV(iv); + size = static_cast(IVSize()); + } + else + { + ThrowIfResynchronizable(); + size = 0; + } + + return iv; +} + +void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *iv) +{ + rng.GenerateBlock(iv, IVSize()); +} + +size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const +{ + CRYPTOPP_ASSERT(inBlocks); + CRYPTOPP_ASSERT(outBlocks); + CRYPTOPP_ASSERT(length); + + const unsigned int blockSize = BlockSize(); + size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; + size_t xorIncrement = xorBlocks ? blockSize : 0; + size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; + + if (flags & BT_ReverseDirection) + { + inBlocks = PtrAdd(inBlocks, length - blockSize); + xorBlocks = PtrAdd(xorBlocks, length - blockSize); + outBlocks = PtrAdd(outBlocks, length - blockSize); + inIncrement = 0-inIncrement; + xorIncrement = 0-xorIncrement; + outIncrement = 0-outIncrement; + } + + // Coverity finding. + const bool xorFlag = xorBlocks && (flags & BT_XorInput); + while (length >= blockSize) + { + if (xorFlag) + { + // xorBlocks non-NULL and with BT_XorInput. + xorbuf(outBlocks, xorBlocks, inBlocks, blockSize); + ProcessBlock(outBlocks); + } + else + { + // xorBlocks may be non-NULL and without BT_XorInput. + ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); + } + + if (flags & BT_InBlockIsCounter) + const_cast(inBlocks)[blockSize-1]++; + + inBlocks = PtrAdd(inBlocks, inIncrement); + outBlocks = PtrAdd(outBlocks, outIncrement); + xorBlocks = PtrAdd(xorBlocks, xorIncrement); + length -= blockSize; + } + + return length; +} + +unsigned int BlockTransformation::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +unsigned int StreamTransformation::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +unsigned int HashTransformation::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +#if 0 +void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(MinLastBlockSize() == 0); // this function should be overridden otherwise + + if (length == MandatoryBlockSize()) + ProcessData(outString, inString, length); + else if (length != 0) + throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block"); +} +#endif + +size_t StreamTransformation::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) +{ + // this function should be overridden otherwise + CRYPTOPP_ASSERT(MinLastBlockSize() == 0); + + if (inLength == MandatoryBlockSize()) + { + outLength = inLength; // squash unused warning + ProcessData(outString, inString, inLength); + } + else if (inLength != 0) + throw NotImplemented(AlgorithmName() + ": this object doesn't support a special last block"); + + return outLength; +} + +void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) +{ + if (headerLength > MaxHeaderLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength())); + + if (messageLength > MaxMessageLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength())); + + if (footerLength > MaxFooterLength()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength())); + + UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength); +} + +void AuthenticatedSymmetricCipher::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength) +{ + Resynchronize(iv, ivLength); + SpecifyDataLengths(headerLength, messageLength); + Update(header, headerLength); + ProcessString(ciphertext, message, messageLength); + TruncatedFinal(mac, macSize); +} + +bool AuthenticatedSymmetricCipher::DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength) +{ + Resynchronize(iv, ivLength); + SpecifyDataLengths(headerLength, ciphertextLength); + Update(header, headerLength); + ProcessString(message, ciphertext, ciphertextLength); + return TruncatedVerify(mac, macLength); +} + +std::string AuthenticatedSymmetricCipher::AlgorithmName() const +{ + // Squash C4505 on Visual Studio 2008 and friends + return "Unknown"; +} + +unsigned int RandomNumberGenerator::GenerateBit() +{ + return GenerateByte() & 1; +} + +byte RandomNumberGenerator::GenerateByte() +{ + byte b; + GenerateBlock(&b, 1); + return b; +} + +word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) +{ + const word32 range = max-min; + const unsigned int maxBits = BitPrecision(range); + + word32 value; + + do + { + GenerateBlock((byte *)&value, sizeof(value)); + value = Crop(value, maxBits); + } while (value > range); + + return value+min; +} + +// Stack recursion below... GenerateIntoBufferedTransformation calls GenerateBlock, +// and GenerateBlock calls GenerateIntoBufferedTransformation. Ad infinitum. Also +// see http://github.com/weidai11/cryptopp/issues/38. +// +// According to Wei, RandomNumberGenerator is an interface, and it should not +// be instantiable. Its now spilt milk, and we are going to CRYPTOPP_ASSERT it in Debug +// builds to alert the programmer and throw in Release builds. Developers have +// a reference implementation in case its needed. If a programmer +// unintentionally lands here, then they should ensure use of a +// RandomNumberGenerator pointer or reference so polymorphism can provide the +// proper runtime dispatching. + +void RandomNumberGenerator::GenerateBlock(byte *output, size_t size) +{ + CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size); + + ArraySink s(output, size); + GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size); +} + +void RandomNumberGenerator::DiscardBytes(size_t n) +{ + GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n); +} + +void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) +{ + FixedSizeSecBlock buffer; + while (length) + { + size_t len = UnsignedMin(buffer.size(), length); + GenerateBlock(buffer, len); + (void)target.ChannelPut(channel, buffer, len); + length -= len; + } +} + +size_t KeyDerivationFunction::MinDerivedKeyLength() const +{ + return 0; +} + +size_t KeyDerivationFunction::MaxDerivedKeyLength() const +{ + return static_cast(-1); +} + +void KeyDerivationFunction::ThrowIfInvalidDerivedKeyLength(size_t length) const +{ + if (!IsValidDerivedLength(length)) + throw InvalidDerivedKeyLength(GetAlgorithm().AlgorithmName(), length); +} + +void KeyDerivationFunction::SetParameters(const NameValuePairs& params) { + CRYPTOPP_UNUSED(params); +} + +/// \brief Random Number Generator that does not produce random numbers +/// \details ClassNullRNG can be used for functions that require a RandomNumberGenerator +/// but don't actually use it. The class throws NotImplemented when a generation function is called. +/// \sa NullRNG() +class ClassNullRNG : public RandomNumberGenerator +{ +public: + /// \brief The name of the generator + /// \returns the string \a NullRNGs + std::string AlgorithmName() const {return "NullRNG";} + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief An implementation that throws NotImplemented + byte GenerateByte () {} + /// \brief An implementation that throws NotImplemented + unsigned int GenerateBit () {} + /// \brief An implementation that throws NotImplemented + word32 GenerateWord32 (word32 min, word32 max) {} +#endif + + /// \brief An implementation that throws NotImplemented + void GenerateBlock(byte *output, size_t size) + { + CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size); + throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes"); + } + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + /// \brief An implementation that throws NotImplemented + void GenerateIntoBufferedTransformation (BufferedTransformation &target, const std::string &channel, lword length) {} + /// \brief An implementation that throws NotImplemented + void IncorporateEntropy (const byte *input, size_t length) {} + /// \brief An implementation that returns \p false + bool CanIncorporateEntropy () const {} + /// \brief An implementation that does nothing + void DiscardBytes (size_t n) {} + /// \brief An implementation that does nothing + void Shuffle (IT begin, IT end) {} + +private: + Clonable* Clone () const { return NULLPTR; } +#endif +}; + +RandomNumberGenerator & NullRNG() +{ + static ClassNullRNG s_nullRNG; + return s_nullRNG; +} + +bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength) +{ + // Allocate at least 1 for calculated to avoid triggering diagnostics + ThrowIfInvalidTruncatedSize(digestLength); + SecByteBlock calculated(digestLength ? digestLength : 1); + TruncatedFinal(calculated, digestLength); + return VerifyBufsEqual(calculated, digest, digestLength); +} + +void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const +{ + if (size > DigestSize()) + throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes"); +} + +unsigned int BufferedTransformation::GetMaxWaitObjectCount() const +{ + const BufferedTransformation *t = AttachedTransformation(); + return t ? t->GetMaxWaitObjectCount() : 0; +} + +void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + BufferedTransformation *t = AttachedTransformation(); + if (t) + t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here +} + +void BufferedTransformation::Initialize(const NameValuePairs ¶meters, int propagation) +{ + CRYPTOPP_UNUSED(propagation); + CRYPTOPP_ASSERT(!AttachedTransformation()); + IsolatedInitialize(parameters); +} + +bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking) +{ + CRYPTOPP_UNUSED(propagation); + CRYPTOPP_ASSERT(!AttachedTransformation()); + return IsolatedFlush(hardFlush, blocking); +} + +bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking) +{ + CRYPTOPP_UNUSED(propagation); + CRYPTOPP_ASSERT(!AttachedTransformation()); + return IsolatedMessageSeriesEnd(blocking); +} + +byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size) +{ + byte* space = NULLPTR; + if (channel.empty()) + space = CreatePutSpace(size); + else + throw NoChannelSupport(AlgorithmName()); + return space; +} + +size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking) +{ + size_t size = 0; + if (channel.empty()) + size = Put2(inString, length, messageEnd, blocking); + else + throw NoChannelSupport(AlgorithmName()); + return size; +} + +size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) +{ + size_t size = 0; + if (channel.empty()) + size = PutModifiable2(inString, length, messageEnd, blocking); + else + size = ChannelPut2(channel, inString, length, messageEnd, blocking); + return size; +} + +bool BufferedTransformation::ChannelFlush(const std::string &channel, bool hardFlush, int propagation, bool blocking) +{ + bool result = 0; + if (channel.empty()) + result = Flush(hardFlush, propagation, blocking); + else + throw NoChannelSupport(AlgorithmName()); + return result; +} + +bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) +{ + bool result = false; + if (channel.empty()) + result = MessageSeriesEnd(propagation, blocking); + else + throw NoChannelSupport(AlgorithmName()); + return result; +} + +lword BufferedTransformation::MaxRetrievable() const +{ + lword size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->MaxRetrievable(); + else + size = CopyTo(TheBitBucket()); + return size; +} + +bool BufferedTransformation::AnyRetrievable() const +{ + bool result = false; + if (AttachedTransformation()) + result = AttachedTransformation()->AnyRetrievable(); + else + { + byte b; + result = Peek(b) != 0; + } + return result; +} + +size_t BufferedTransformation::Get(byte &outByte) +{ + size_t size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->Get(outByte); + else + size = Get(&outByte, 1); + return size; +} + +size_t BufferedTransformation::Get(byte *outString, size_t getMax) +{ + size_t size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->Get(outString, getMax); + else + { + ArraySink arraySink(outString, getMax); + size = (size_t)TransferTo(arraySink, getMax); + } + return size; +} + +size_t BufferedTransformation::Peek(byte &outByte) const +{ + size_t size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->Peek(outByte); + else + size = Peek(&outByte, 1); + return size; +} + +size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const +{ + size_t size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->Peek(outString, peekMax); + else + { + ArraySink arraySink(outString, peekMax); + size = (size_t)CopyTo(arraySink, peekMax); + } + return size; +} + +lword BufferedTransformation::Skip(lword skipMax) +{ + lword size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->Skip(skipMax); + else + size = TransferTo(TheBitBucket(), skipMax); + return size; +} + +lword BufferedTransformation::TotalBytesRetrievable() const +{ + lword size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->TotalBytesRetrievable(); + else + size = MaxRetrievable(); + return size; +} + +unsigned int BufferedTransformation::NumberOfMessages() const +{ + unsigned int size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->NumberOfMessages(); + else + size = CopyMessagesTo(TheBitBucket()); + return size; +} + +bool BufferedTransformation::AnyMessages() const +{ + bool result = false; + if (AttachedTransformation()) + result = AttachedTransformation()->AnyMessages(); + else + result = NumberOfMessages() != 0; + return result; +} + +bool BufferedTransformation::GetNextMessage() +{ + bool result = false; + if (AttachedTransformation()) + result = AttachedTransformation()->GetNextMessage(); + else + { + CRYPTOPP_ASSERT(!AnyMessages()); + } + return result; +} + +unsigned int BufferedTransformation::SkipMessages(unsigned int count) +{ + unsigned int size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->SkipMessages(count); + else + size = TransferMessagesTo(TheBitBucket(), count); + return size; +} + +size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking) +{ + if (AttachedTransformation()) + return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking); + else + { + unsigned int maxMessages = messageCount; + for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++) + { + size_t blockedBytes; + lword transferredBytes; + + while (AnyRetrievable()) + { + // MaxRetrievable() instead of LWORD_MAX due to GH #962. If + // the target calls CreatePutSpace(), then the allocation + // size will be LWORD_MAX. That happens when target is a + // ByteQueue. Maybe ByteQueue should check the size, and if + // it is LWORD_MAX or -1, then use a default like 4096. + transferredBytes = MaxRetrievable(); + blockedBytes = TransferTo2(target, transferredBytes, channel, blocking); + if (blockedBytes > 0) + return blockedBytes; + } + + if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking)) + return 1; + + bool result = GetNextMessage(); + CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result); + } + return 0; + } +} + +unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const +{ + unsigned int size = 0; + if (AttachedTransformation()) + size = AttachedTransformation()->CopyMessagesTo(target, count, channel); + return size; +} + +void BufferedTransformation::SkipAll() +{ + if (AttachedTransformation()) + AttachedTransformation()->SkipAll(); + else + { + while (SkipMessages()) {} + while (Skip()) {} + } +} + +size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking) +{ + if (AttachedTransformation()) + return AttachedTransformation()->TransferAllTo2(target, channel, blocking); + else + { + CRYPTOPP_ASSERT(!NumberOfMessageSeries()); + + unsigned int messageCount; + do + { + messageCount = UINT_MAX; + size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking); + if (blockedBytes) + return blockedBytes; + } + while (messageCount != 0); + + lword byteCount; + do + { + byteCount = ULONG_MAX; + size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking); + if (blockedBytes) + return blockedBytes; + } + while (byteCount != 0); + + return 0; + } +} + +void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const +{ + if (AttachedTransformation()) + AttachedTransformation()->CopyAllTo(target, channel); + else + { + CRYPTOPP_ASSERT(!NumberOfMessageSeries()); + while (CopyMessagesTo(target, UINT_MAX, channel)) {} + } +} + +void BufferedTransformation::SetRetrievalChannel(const std::string &channel) +{ + if (AttachedTransformation()) + AttachedTransformation()->SetRetrievalChannel(channel); +} + +size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking) +{ + PutWord(false, order, m_buf, value); + return ChannelPut(channel, m_buf, 2, blocking); +} + +size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking) +{ + PutWord(false, order, m_buf, value); + return ChannelPut(channel, m_buf, 4, blocking); +} + +size_t BufferedTransformation::ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order, bool blocking) +{ + PutWord(false, order, m_buf, value); + return ChannelPut(channel, m_buf, 8, blocking); +} + +size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking) +{ + return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking); +} + +size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking) +{ + return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking); +} + +size_t BufferedTransformation::PutWord64(word64 value, ByteOrder order, bool blocking) +{ + return ChannelPutWord64(DEFAULT_CHANNEL, value, order, blocking); +} + +size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const +{ + byte buf[2] = {0, 0}; + size_t len = Peek(buf, 2); + + if (order == BIG_ENDIAN_ORDER) + value = word16((buf[0] << 8) | buf[1]); + else + value = word16((buf[1] << 8) | buf[0]); + + return len; +} + +size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const +{ + byte buf[4] = {0, 0, 0, 0}; + size_t len = Peek(buf, 4); + + if (order == BIG_ENDIAN_ORDER) + value = word32((buf[0] << 24) | (buf[1] << 16) | + (buf[2] << 8) | (buf[3] << 0)); + else + value = word32((buf[3] << 24) | (buf[2] << 16) | + (buf[1] << 8) | (buf[0] << 0)); + + return len; +} + +size_t BufferedTransformation::PeekWord64(word64 &value, ByteOrder order) const +{ + byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + size_t len = Peek(buf, 8); + + if (order == BIG_ENDIAN_ORDER) + value = ((word64)buf[0] << 56) | ((word64)buf[1] << 48) | ((word64)buf[2] << 40) | + ((word64)buf[3] << 32) | ((word64)buf[4] << 24) | ((word64)buf[5] << 16) | + ((word64)buf[6] << 8) | (word64)buf[7]; + else + value = ((word64)buf[7] << 56) | ((word64)buf[6] << 48) | ((word64)buf[5] << 40) | + ((word64)buf[4] << 32) | ((word64)buf[3] << 24) | ((word64)buf[2] << 16) | + ((word64)buf[1] << 8) | (word64)buf[0]; + + return len; +} + +size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order) +{ + return (size_t)Skip(PeekWord16(value, order)); +} + +size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order) +{ + return (size_t)Skip(PeekWord32(value, order)); +} + +size_t BufferedTransformation::GetWord64(word64 &value, ByteOrder order) +{ + return (size_t)Skip(PeekWord64(value, order)); +} + +void BufferedTransformation::Attach(BufferedTransformation *newAttachment) +{ + if (AttachedTransformation() && AttachedTransformation()->Attachable()) + AttachedTransformation()->Attach(newAttachment); + else + Detach(newAttachment); +} + +void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize) +{ + GenerateRandom(rng, MakeParameters("KeySize", (int)keySize)); +} + +class PK_DefaultEncryptionFilter : public Unflushable +{ +public: + PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) + : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters) + { + Detach(attachment); + } + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + FILTER_BEGIN; + m_plaintextQueue.Put(inString, length); + + if (messageEnd) + { + { + size_t plaintextLength; + if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength)) + throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long"); + size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength); + + SecByteBlock plaintext(plaintextLength); + m_plaintextQueue.Get(plaintext, plaintextLength); + m_ciphertext.resize(ciphertextLength); + m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters); + } + + FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd); + } + FILTER_END_NO_MESSAGE_END; + } + + RandomNumberGenerator &m_rng; + const PK_Encryptor &m_encryptor; + const NameValuePairs &m_parameters; + ByteQueue m_plaintextQueue; + SecByteBlock m_ciphertext; +}; + +BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const +{ + return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters); +} + +class PK_DefaultDecryptionFilter : public Unflushable +{ +public: + PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) + : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters) + { + Detach(attachment); + } + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + FILTER_BEGIN; + m_ciphertextQueue.Put(inString, length); + + if (messageEnd) + { + { + size_t ciphertextLength; + if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength)) + throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long"); + size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength); + + SecByteBlock ciphertext(ciphertextLength); + m_ciphertextQueue.Get(ciphertext, ciphertextLength); + m_plaintext.resize(maxPlaintextLength); + m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters); + if (!m_result.isValidCoding) + throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext"); + } + + FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd); + } + FILTER_END_NO_MESSAGE_END; + } + + RandomNumberGenerator &m_rng; + const PK_Decryptor &m_decryptor; + const NameValuePairs &m_parameters; + ByteQueue m_ciphertextQueue; + SecByteBlock m_plaintext; + DecodingResult m_result; +}; + +BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const +{ + return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters); +} + +size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const +{ + member_ptr m(messageAccumulator); + return SignAndRestart(rng, *m, signature, false); +} + +size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const +{ + member_ptr m(NewSignatureAccumulator(rng)); + m->Update(message, messageLen); + return SignAndRestart(rng, *m, signature, false); +} + +size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const +{ + member_ptr m(NewSignatureAccumulator(rng)); + InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength); + m->Update(nonrecoverableMessage, nonrecoverableMessageLength); + return SignAndRestart(rng, *m, signature, false); +} + +bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const +{ + member_ptr m(messageAccumulator); + return VerifyAndRestart(*m); +} + +bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLen) const +{ + member_ptr m(NewVerificationAccumulator()); + InputSignature(*m, signature, signatureLen); + m->Update(message, messageLen); + return VerifyAndRestart(*m); +} + +DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const +{ + member_ptr m(messageAccumulator); + return RecoverAndRestart(recoveredMessage, *m); +} + +DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, + const byte *signature, size_t signatureLength) const +{ + member_ptr m(NewVerificationAccumulator()); + InputSignature(*m, signature, signatureLength); + m->Update(nonrecoverableMessage, nonrecoverableMessageLength); + return RecoverAndRestart(recoveredMessage, *m); +} + +void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const +{ + GeneratePrivateKey(rng, privateKey); + GeneratePublicKey(rng, privateKey, publicKey); +} + +void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const +{ + GenerateStaticPrivateKey(rng, privateKey); + GenerateStaticPublicKey(rng, privateKey, publicKey); +} + +void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const +{ + GenerateEphemeralPrivateKey(rng, privateKey); + GenerateEphemeralPublicKey(rng, privateKey, publicKey); +} + +// Allow a distro or packager to override the build-time version +// http://github.com/weidai11/cryptopp/issues/371 +#ifndef CRYPTOPP_BUILD_VERSION +# define CRYPTOPP_BUILD_VERSION CRYPTOPP_VERSION +#endif +int LibraryVersion(CRYPTOPP_NOINLINE_DOTDOTDOT) +{ + return CRYPTOPP_BUILD_VERSION; +} + +class NullNameValuePairs : public NameValuePairs +{ +public: + NullNameValuePairs() {} // Clang complains a default ctor must be available + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + {CRYPTOPP_UNUSED(name); CRYPTOPP_UNUSED(valueType); CRYPTOPP_UNUSED(pValue); return false;} +}; + +#if HAVE_GCC_INIT_PRIORITY + const std::string DEFAULT_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 25))) = ""; + const std::string AAD_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 26))) = "AAD"; + const NullNameValuePairs s_nullNameValuePairs __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 27))); + const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs; +#elif HAVE_MSC_INIT_PRIORITY + #pragma warning(disable: 4073) + #pragma init_seg(lib) + const std::string DEFAULT_CHANNEL = ""; + const std::string AAD_CHANNEL = "AAD"; + const NullNameValuePairs s_nullNameValuePairs; + const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs; + #pragma warning(default: 4073) +#elif HAVE_XLC_INIT_PRIORITY + #pragma priority(260) + const std::string DEFAULT_CHANNEL = ""; + const std::string AAD_CHANNEL = "AAD"; + const NullNameValuePairs s_nullNameValuePairs; + const NameValuePairs& g_nullNameValuePairs = s_nullNameValuePairs; +#else + const std::string DEFAULT_CHANNEL = ""; + const std::string AAD_CHANNEL = "AAD"; + const simple_ptr s_pNullNameValuePairs(new NullNameValuePairs); + const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p; +#endif + +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/cryptlib.h b/external/ours/library/crypto/src/shared/original/cryptlib.h index fd2587063..6fe6b2bbc 100755 --- a/external/ours/library/crypto/src/shared/original/cryptlib.h +++ b/external/ours/library/crypto/src/shared/original/cryptlib.h @@ -1,818 +1,3379 @@ -// cryptlib.h - written and placed in the public domain by Wei Dai -/*! \file - This file contains the declarations for the abstract base - classes that provide a uniform interface to this library. -*/ - -/*! \mainpage Crypto++ Reference Manual -
-
Abstract Base Classes
- cryptlib.h -
Algebraic Structures
- Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, - ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, - GF2NP, GF256, GF2_32, EC2N, ECP -
Block Ciphers (in ECB mode)
- 3way.h, blowfish.h, cast.h, des.h, diamond.h, gost.h, - idea.h, lubyrack.h, mars.h, mdc.h, - rc2.h, rc5.h, rc6.h, rijndael.h, safer.h, serpent.h, shark.h, skipjack.h, - square.h, tea.h, twofish.h -
Block Cipher Modes
- modes.h, cbc.h -
Compression
- Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor -
Secret Sharing and Information Dispersal
- SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery -
Stream Ciphers
- ARC4, PanamaCipher, BlumBlumShub, SEAL, SapphireEncryption, WAKEEncryption -
Hash Functions
- HAVAL, MD2, MD5, PanamaHash, RIPEMD160, SHA, SHA256, SHA384, SHA512, Tiger -
Non-Cryptographic Checksums
- CRC32, Adler32 -
Message Authentication Codes
- MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC -
Random Number Generators
- NullRNG, LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool -
Public Key Cryptography
- blumgold.h, dh.h, dh2.h, dsa.h, eccrypto.h, luc.h, mqv.h, - nr.h, rsa.h, rabin.h, rw.h, xtrcrypt.h -
Input Source Classes
- StringSource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource -
Output Sink Classes
- StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink -
Filter Wrappers
- StreamCipherFilter, HashFilter, HashVerifier, SignerFilter, VerifierFilter -
Binary to Text Encoders and Decoders
- HexEncoder, HexDecoder, Base64Encoder, Base64Decoder -
Wrappers for OS features
- Timer, Socket, WindowsHandle, WindowsReadPipe, WindowsWritePipe -
- -

This reference manual is very much a work in progress. Many classes are still lacking detailed descriptions. -

Click here to download a zip archive containing this manual. -

Thanks to Ryan Phillips for providing the Doxygen configuration file -and getting me started with this manual. -*/ - -#ifndef CRYPTOPP_CRYPTLIB_H -#define CRYPTOPP_CRYPTLIB_H - -#include "config.h" -#include -#include -#include - -NAMESPACE_BEGIN(CryptoPP) - -//! base class for all exceptions thrown by Crypto++ - -class Exception : public std::exception -{ -public: - explicit Exception(const std::string &s) : m_what(s) {} - virtual ~Exception() throw() {} - const char *what() const throw() {return (m_what.c_str());} - const std::string &GetWhat() const {return m_what;} - void SetWhat(const std::string &s) {m_what = s;} - -private: - std::string m_what; -}; - -//! used to specify a direction for a cipher to operate in (encrypt or decrypt) -enum CipherDir { - //! - ENCRYPTION, - //! - DECRYPTION}; - - -//! abstract base class for block ciphers - -/*! All classes derived from BlockTransformation are block ciphers - in ECB mode (for example the DESEncryption class), which are stateless. - These classes should not be used directly, but only in combination with - a mode class (see CipherMode). - - Note: BlockTransformation objects may assume that pointers to input and - output blocks are aligned on 32-bit word boundaries. -*/ -class BlockTransformation -{ -public: - //! - virtual ~BlockTransformation() {} - - //! encrypt or decrypt one block in place - /*! \pre size of inoutBlock == BlockSize() */ - virtual void ProcessBlock(byte *inoutBlock) const =0; - - //! encrypt or decrypt one block, may assume inBlock != outBlock - /*! \pre size of inBlock and outBlock == BlockSize() */ - virtual void ProcessBlock(const byte *inBlock, byte *outBlock) const =0; - - //! block size of the cipher in bytes - virtual unsigned int BlockSize() const =0; -}; - -//! provides an implementation of BlockSize() -template -class FixedBlockSize : public BlockTransformation -{ -public: - enum {BLOCKSIZE = N}; - virtual unsigned int BlockSize() const {return BLOCKSIZE;} -}; - -//! abstract base class for stream ciphers - -class StreamCipher -{ -public: - //! - virtual ~StreamCipher() {} - - //! encrypt or decrypt one byte - virtual byte ProcessByte(byte input) =0; - - //! encrypt or decrypt an array of bytes of specified length in place - virtual void ProcessString(byte *inoutString, unsigned int length); - //! encrypt or decrypt an array of bytes of specified length, may assume inString != outString - virtual void ProcessString(byte *outString, const byte *inString, unsigned int length); -}; - -//! abstract base class for random access stream ciphers - -class RandomAccessStreamCipher : public virtual StreamCipher -{ -public: - //! - virtual ~RandomAccessStreamCipher() {} - /*/ specify that the next byte to be processed is at absolute position n - in the plaintext/ciphertext stream */ - virtual void Seek(unsigned long n) =0; -}; - -//! abstract base class for random number generators - -/*! All return values are uniformly distributed over the range specified. -*/ -class RandomNumberGenerator -{ -public: - //! - virtual ~RandomNumberGenerator() {} - - //! generate new random byte and return it - virtual byte GenerateByte() =0; - - //! generate new random bit and return it - /*! Default implementation is to call GenerateByte() and return its parity. */ - virtual unsigned int GenerateBit(); - - //! generate a random 32 bit word in the range min to max, inclusive - virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); - - //! generate random array of bytes - //* Default implementation is to call GenerateByte() size times. - virtual void GenerateBlock(byte *output, unsigned int size); - - //! randomly shuffle the specified array, resulting permutation is uniformly distributed - template void Shuffle(IT begin, IT end) - { - for (; begin != end; ++begin) - std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); - } - - // for backwards compatibility, maybe be remove later - byte GetByte() {return GenerateByte();} - unsigned int GetBit() {return GenerateBit();} - word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} - word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} - void GetBlock(byte *output, unsigned int size) {GenerateBlock(output, size);} -}; - -//! abstract base class for hash functions - -/*! HashModule objects are stateful. They are created in an initial state, - change state as Update() is called, and return to the initial - state when Final() is called. This interface allows a large message to - be hashed in pieces by calling Update() on each piece followed by - calling Final(). -*/ -class HashModule -{ -public: - //! - virtual ~HashModule() {} - - //! process more input - virtual void Update(const byte *input, unsigned int length) =0; - - /*/ calculate hash for the current message (the concatenation of all - inputs passed in via Update()), then reinitialize the object */ - //* Precondition: size of digest == DigestSize(). - virtual void Final(byte *digest) =0; - - //! size of the hash returned by Final() - virtual unsigned int DigestSize() const =0; - - //! use this if your input is short and you don't want to call Update() and Final() seperately - virtual void CalculateDigest(byte *digest, const byte *input, int length) - {Update(input, length); Final(digest);} - - //! verify that digest is a valid digest for the current message, then reinitialize the object - /*! Default implementation is to call Final() and do a bitwise comparison - between its output and digest. */ - virtual bool Verify(const byte *digest); - - //! use this if your input is short and you don't want to call Update() and Verify() seperately - virtual bool VerifyDigest(const byte *digest, const byte *input, int length) - {Update(input, length); return Verify(digest);} -}; - -//! abstract base class for message authentication codes - -/*! The main differences between a MAC and an hash function (in terms of - programmatic interface) is that a MAC is keyed, and that calculating - a MAC for the same message twice may produce two different results so - verifying a MAC may not be simply recalculating it and doing a bitwise - comparison. -*/ -class MessageAuthenticationCode : public virtual HashModule -{ -public: - //! - virtual ~MessageAuthenticationCode() {} -}; - -//! abstract base class for buffered transformations - -/*! BufferedTransformation is a generalization of BlockTransformation, - StreamCipher, and HashModule. - - A buffered transformation is an object that takes a stream of bytes - as input (this may be done in stages), does some computation on them, and - then places the result into an internal buffer for later retrieval. Any - partial result already in the output buffer is not modified by further - input. - - Computation is generally done as soon as possible, but some buffering - on the input may be done for performance reasons. - \nosubgrouping -*/ -class BufferedTransformation -{ -public: - //! - virtual ~BufferedTransformation() {} - - //! \name INPUT - //@{ - //! input a byte for processing - virtual void Put(byte inByte) =0; - //! input multiple bytes - virtual void Put(const byte *inString, unsigned int length) =0; - - //! input a 16-bit word, big-endian or little-endian depending on highFirst - void PutWord16(word16 value, bool highFirst=true); - //! input a 32-bit word - void PutWord32(word32 value, bool highFirst=true); - //@} - - //! \name SIGNALS - //@{ - //! process everything in internal buffers and output them - /*! throws exception if completeFlush == true and it's - not possible to flush everything */ - virtual void Flush(bool completeFlush, int propagation=-1); - //! mark end of an input segment, message, or packet - /*! propagation != 0 means pass on the signal to attached - BufferedTransformation objects, with propagation - decremented at each step until it reaches 0. - -1 means unlimited propagation. */ - virtual void MessageEnd(int propagation=-1); - //! same as Put() followed by MessageEnd() but may be more efficient - virtual void PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); - //! mark end of a series of messages - /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ - virtual void MessageSeriesEnd(int propagation=-1); - - //! set propagation of automatically generated and transfered signals - /*! propagation == 0 means do not automaticly generate signals */ - virtual void SetAutoSignalPropagation(int propagation) {} - - //! - virtual int GetAutoSignalPropagation() const {return 0;} - - // for backwards compatibility - void Close() {MessageEnd();} - //@} - - //! \name ERRORS - //@{ - //! error types - enum ErrorType { - //! received a Flush(true) signal but can't flush buffers - CANNOT_FLUSH, - //! data integerity check (such as CRC or MAC) failed - DATA_INTEGRITY_CHECK_FAILED, - //! received input data that doesn't conform to expected format - INVALID_DATA_FORMAT, - //! error reading from input device - INPUT_ERROR, - //! error writing to output device - OUTPUT_ERROR, - //! some error not belong to any of the above categories - OTHER_ERROR - }; - - //! exception thrown by BufferedTransformation - class Err : public Exception - { - public: - Err(ErrorType errorType, const std::string &s=""); - ErrorType GetErrorType() const {return m_errorType;} - void SetErrorType(ErrorType errorType) {m_errorType = errorType;} - private: - ErrorType m_errorType; - }; - //@} - - //! \name RETRIEVAL OF ONE MESSAGE - //@{ - //! returns number of bytes that is currently ready for retrieval - /*! All retrieval functions return the actual number of bytes - retrieved, which is the lesser of the request number and - MaxRetrievable(). */ - virtual unsigned long MaxRetrievable() const; - - // old mispelled name - unsigned long MaxRetrieveable() const {return MaxRetrievable();} - - //! returns whether any bytes are currently ready for retrieval - virtual bool AnyRetrievable() const; - - //! try to retrieve a single byte - virtual unsigned int Get(byte &outByte); - //! try to retrieve multiple bytes - virtual unsigned int Get(byte *outString, unsigned int getMax); - - //! peek at the next byte without removing it from the output buffer - virtual unsigned int Peek(byte &outByte) const; - //! peek at multiple bytes without removing them from the output buffer - virtual unsigned int Peek(byte *outString, unsigned int peekMax) const; - - //! try to retrieve a 16-bit word, big-endian or little-endian depending on highFirst - unsigned int GetWord16(word16 &value, bool highFirst=true); - //! try to retrieve a 32-bit word - unsigned int GetWord32(word32 &value, bool highFirst=true); - - //! try to peek at a 16-bit word, big-endian or little-endian depending on highFirst - unsigned int PeekWord16(word16 &value, bool highFirst=true); - //! try to peek at a 32-bit word - unsigned int PeekWord32(word32 &value, bool highFirst=true); - - //! move transferMax bytes of the buffered output to target as input - virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - - //! discard skipMax bytes from the output buffer - virtual unsigned long Skip(unsigned long skipMax=ULONG_MAX); - - //! copy copyMax bytes of the buffered output to target as input - virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - //@} - - //! \name RETRIEVAL OF MULTIPLE MESSAGES - //@{ - //! - virtual unsigned long TotalBytesRetrievable() const; - //! number of times MessageEnd() has been received minus messages retrieved or skipped - virtual unsigned int NumberOfMessages() const; - //! returns true if NumberOfMessages() > 0 - virtual bool AnyMessages() const; - //! start retrieving the next message - /*! - Returns false if no more messages exist or this message - is not completely retrieved. - */ - virtual bool GetNextMessage(); - //! skip count number of messages - virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); - //! - virtual unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX); - //! - virtual unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; - - //! - virtual void SkipAll(); - //! - virtual void TransferAllTo(BufferedTransformation &target); - //! - virtual void CopyAllTo(BufferedTransformation &target) const; - //@} - - //! \name CHANNELS - //@{ - virtual void ChannelPut(const std::string &channel, byte inByte); - virtual void ChannelPut(const std::string &channel, const byte *inString, unsigned int length); - - void ChannelPutWord16(const std::string &channel, word16 value, bool highFirst=true); - void ChannelPutWord32(const std::string &channel, word32 value, bool highFirst=true); - - virtual void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1); - virtual void ChannelMessageEnd(const std::string &channel, int propagation=-1); - virtual void ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation=-1); - virtual void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1); - - virtual void SetRetrievalChannel(const std::string &channel); - - static const std::string NULL_CHANNEL; - //@} - - /*! \name ATTACHMENT - Some BufferedTransformation objects (e.g. Filter objects) - allow other BufferedTransformation objects to be attached. When - this is done, the first object instead of buffering its output, - sents that output to the attached object as input. The entire - attachment chain is deleted when the anchor object is destructed. - */ - //@{ - //! returns whether this object allows attachment - virtual bool Attachable() {return false;} - //! returns the object immediately attached to this object or nullptr for no attachment - virtual BufferedTransformation *AttachedTransformation() {return 0;} - //! - virtual const BufferedTransformation *AttachedTransformation() const - {return const_cast(this)->AttachedTransformation();} - //! delete the current attachment chain and replace it with newAttachment - virtual void Detach(BufferedTransformation *newAttachment = 0) {} - //! add newAttachment to the end of attachment chain - virtual void Attach(BufferedTransformation *newAttachment); - //@} -}; - -//! abstract base class for public-key encryptors and decryptors - -/*! This class provides an interface common to encryptors and decryptors - for querying their plaintext and ciphertext lengths. -*/ -class PK_CryptoSystem -{ -public: - //! - virtual ~PK_CryptoSystem() {} - - //! maximum length of plaintext for a given ciphertext length - //* This function returns 0 if cipherTextLength is not valid (too long or too short). - virtual unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const =0; - - //! calculate length of ciphertext given length of plaintext - //* This function returns 0 if plainTextLength is not valid (too long). - virtual unsigned int CipherTextLength(unsigned int plainTextLength) const =0; -}; - -//! abstract base class for public-key encryptors - -/*! An encryptor is also a public encryption key. It contains both the - key and the algorithm to perform the encryption. -*/ -class PK_Encryptor : public virtual PK_CryptoSystem -{ -public: - //! encrypt a byte string - /*! Preconditions: - \begin{itemize} - \item CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long) - \item size of cipherText == CipherTextLength(plainTextLength) - \end{itemize} - */ - virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) =0; -}; - -//! abstract base class for public-key decryptors - -/*! An decryptor is also a private decryption key. It contains both the - key and the algorithm to perform the decryption. -*/ -class PK_Decryptor : public virtual PK_CryptoSystem -{ -public: - //! decrypt a byte string, and return the length of plaintext - /*! Precondition: size of plainText == MaxPlainTextLength(cipherTextLength) - bytes. - - The function returns the actual length of the plaintext, or 0 - if decryption fails. - */ - virtual unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) =0; -}; - -//! abstract base class for encryptors and decryptors with fixed length ciphertext - -/*! A simplified interface (as embodied in this - class and its subclasses) is provided for crypto systems (such - as RSA) whose ciphertext length depend only on the key, not on the length - of the plaintext. The maximum plaintext length also depend only on - the key. -*/ -class PK_FixedLengthCryptoSystem : public virtual PK_CryptoSystem -{ -public: - //! - virtual unsigned int MaxPlainTextLength() const =0; - //! - virtual unsigned int CipherTextLength() const =0; - - unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const; - unsigned int CipherTextLength(unsigned int plainTextLength) const; -}; - -//! abstract base class for encryptors with fixed length ciphertext - -class PK_FixedLengthEncryptor : public virtual PK_Encryptor, public virtual PK_FixedLengthCryptoSystem -{ -}; - -//! abstract base class for decryptors with fixed length ciphertext - -class PK_FixedLengthDecryptor : public virtual PK_Decryptor, public virtual PK_FixedLengthCryptoSystem -{ -public: - //! decrypt a byte string, and return the length of plaintext - /*! Preconditions: - \begin{itemize} - \item length of cipherText == CipherTextLength() - \item size of plainText == MaxPlainTextLength() - \end{itemize} - - The function returns the actual length of the plaintext, or 0 - if decryption fails. - */ - virtual unsigned int Decrypt(const byte *cipherText, byte *plainText) =0; - - unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText); -}; - -//! abstract base class for public-key signers and verifiers - -/*! This class provides an interface common to signers and verifiers - for querying their signature lengths and creating message - accumulators. -*/ -class PK_SignatureSystem -{ -public: - //! - virtual ~PK_SignatureSystem() {}; - - //! signature length support by this object (as either input or output) - virtual unsigned int SignatureLength() const =0; - - //! create a new HashModule to accumulate the message to be signed or verified - virtual HashModule * NewMessageAccumulator() const =0; -}; - -//! abstract base class for public-key signers - -/*! A signer is also a private signature key. It contains both the - key and the algorithm to perform the signature. -*/ -class PK_Signer : public virtual PK_SignatureSystem -{ -public: - //! key too short exception, may be thrown by Sign() or SignMessage() - class KeyTooShort : public Exception - { - public: - KeyTooShort() : Exception("PK_Signer: key too short") {} - }; - - //! sign and delete messageAccumulator - /*! Preconditions: - \begin{itemize} - \item messageAccumulator was obtained by calling NewMessageAccumulator() - \item HashModule::Final() has not been called on messageAccumulator - \item size of signature == SignatureLength() - \end{itemize} - */ - virtual void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const =0; - - //! sign a message - /*! Precondition: size of signature == SignatureLength() */ - virtual void SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const; -}; - -//! abstract base class for public-key verifiers - -/*! A verifier is also a public verification key. It contains both the - key and the algorithm to perform the verification. -*/ -class PK_Verifier : public virtual PK_SignatureSystem -{ -public: - //! check whether sig is a valid signature for messageAccumulator, and delete messageAccumulator - /*! Preconditions: - \begin{itemize} - \item messageAccumulator was obtained by calling NewMessageAccumulator() - \item HashModule::Final() has not been called on messageAccumulator - \item length of signature == SignatureLength() - \end{itemize} - */ - virtual bool Verify(HashModule *messageAccumulator, const byte *sig) const =0; - - //! check whether sig is a valid signature for message - /*! Precondition: size of signature == SignatureLength() */ - virtual bool VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const; -}; - -//! abstract base class for public-key signers and verifiers with recovery - -/*! In a signature scheme with recovery, a verifier is able to extract - a message from its valid signature. -*/ -class PK_SignatureSystemWithRecovery : public virtual PK_SignatureSystem -{ -public: - //! length of longest message that can be fully recovered - virtual unsigned int MaximumRecoverableLength() const =0; - - //! whether or not messages longer than MaximumRecoverableLength() can be signed - /*! If this function returns false, any message longer than - MaximumRecoverableLength() will be truncated for signature - and will fail verification. - */ - virtual bool AllowLeftoverMessage() const =0; -}; - -//! abstract base class for public-key signers with recovery - -class PK_SignerWithRecovery : public virtual PK_SignatureSystemWithRecovery, public PK_Signer -{ -}; - -//! abstract base class for public-key verifiers with recovery - -/*! A PK_VerifierWithRecovery can also be used the same way as a PK_Verifier, - where the signature and the entire message is given to Verify() or - VerifyMessage() as input. -*/ -class PK_VerifierWithRecovery : public virtual PK_SignatureSystemWithRecovery, public PK_Verifier -{ -public: - //! create a new HashModule to accumulate leftover message - virtual HashModule * NewLeftoverMessageAccumulator(const byte *signature) const =0; - - //! partially recover a message from its signature, return length of recoverd message, or 0 if signature is invalid - /*! Preconditions: - \begin{itemize} - \item leftoverMessageAccumulator was obtained by calling NewLeftoverMessageAccumulator(signature) - \item HashModule::Final() has not been called on leftoverMessageAccumulator - \item length of signature == SignatureLength() - \item size of recoveredMessage == MaximumRecoverableLength() - \end{itemize} - */ - virtual unsigned int PartialRecover(HashModule *leftoverMessageAccumulator, byte *recoveredMessage) const =0; - - //! recover a message from its signature, return length of message, or 0 if signature is invalid - /*! This function should be equivalent to PartialRecover(NewLeftoverMessageAccumulator(signature), recoveredMessage). - Preconditions: - \begin{itemize} - \item length of signature == SignatureLength() - \item size of recoveredMessage == MaximumRecoverableLength() - \end{itemize} - */ - virtual unsigned int Recover(const byte *signature, byte *recoveredMessage) const =0; -}; - -//! abstract base class for domains of simple key agreement protocols - -/*! A key agreement domain is a set of parameters that must be shared - by two parties in a key agreement protocol, along with the algorithms - for generating key pairs and deriving agreed values. -*/ -class PK_SimpleKeyAgreementDomain -{ -public: - virtual ~PK_SimpleKeyAgreementDomain() {} - - //! return whether the domain parameters stored in this object are valid - virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const =0; - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - //! return length of private keys in this domain - virtual unsigned int PrivateKeyLength() const =0; - //! return length of public keys in this domain - virtual unsigned int PublicKeyLength() const =0; - //! generate private/public key pair - /*! Preconditions: - \begin{itemize} - \item size of privateKey == PrivateKeyLength() - \item size of publicKey == PublicKeyLength() - \end{itemize} - */ - virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; - /*! derive agreed value from your private key and couterparty's public key, return false in case of failure - //! Note: If you have previously validated the public key, use validateOtherPublicKey=false to save time. - //! Preconditions: - \begin{itemize} - \item size of agreedValue == AgreedValueLength() - \item length of privateKey == PrivateKeyLength() - \item length of otherPublicKey == PublicKeyLength() - \end{itemize} - */ - virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; -}; - -//! abstract base class for domains of authenticated key agreement protocols - -/*! In an authenticated key agreement protocol, each party has two - key pairs. The long-lived key pair is called the static key pair, - and the short-lived key pair is called the ephemeral key pair. -*/ -class PK_AuthenticatedKeyAgreementDomain -{ -public: - virtual ~PK_AuthenticatedKeyAgreementDomain() {} - - //! return whether the domain parameters stored in this object are valid - virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const =0; - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - - //! return length of static private keys in this domain - virtual unsigned int StaticPrivateKeyLength() const =0; - //! return length of static public keys in this domain - virtual unsigned int StaticPublicKeyLength() const =0; - //! generate static private/public key pair - /*! Preconditions: - \begin{itemize} - \item size of privateKey == StaticPrivateKeyLength() - \item size of publicKey == StaticPublicKeyLength() - \end{itemize} - */ - virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; - - //! return length of ephemeral private keys in this domain - virtual unsigned int EphemeralPrivateKeyLength() const =0; - //! return length of ephemeral public keys in this domain - virtual unsigned int EphemeralPublicKeyLength() const =0; - //! generate ephemeral private/public key pair - /*! Preconditions: - \begin{itemize} - \item size of privateKey == EphemeralPrivateKeyLength() - \item size of publicKey == EphemeralPublicKeyLength() - \end{itemize} - */ - virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! Note: The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - Preconditions: - \begin{itemize} - \item size of agreedValue == AgreedValueLength() - \item length of staticPrivateKey == StaticPrivateKeyLength() - \item length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \item length of staticOtherPublicKey == StaticPublicKeyLength() - \item length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - \end{itemize} - */ - virtual bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const =0; -}; - -//! abstract base class for all objects that support precomputation - -/*! The class defines a common interface for doing precomputation, - and loading and saving precomputation. -*/ -class PK_Precomputation -{ -public: - //! - virtual ~PK_Precomputation() {} - - //! - /*! The exact semantics of Precompute() is varies, but - typically it means calculate a table of n objects - that can be used later to speed up computation. - */ - virtual void Precompute(unsigned int n) =0; - - //! retrieve previously saved precomputation - virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) =0; - //! save precomputation for later use - virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const =0; -}; - -//! . -template class PK_WithPrecomputation : public virtual T, public virtual PK_Precomputation -{ -}; - -NAMESPACE_END - -#endif +// cryptlib.h - originally written and placed in the public domain by Wei Dai + +/// \file cryptlib.h +/// \brief Abstract base classes that provide a uniform interface to this library. + +/*! \mainpage Crypto++ Library 8.6 API Reference +

+
Abstract Base Classes
+ cryptlib.h +
Authenticated Encryption Modes
+ CCM, EAX, \ref GCM "GCM (2K tables)", \ref GCM "GCM (64K tables)" +
Block Ciphers
+ \ref Rijndael "AES", ARIA, Weak::ARC4, Blowfish, BTEA, \ref CHAM128 "CHAM (64/128)", Camellia, + \ref CAST128 "CAST (128/256)", DES, \ref DES_EDE2 "2-key Triple-DES", \ref DES_EDE3 "3-key Triple-DES", + \ref DES_XEX3 "DESX", GOST, HIGHT, IDEA, LEA, \ref LR "Luby-Rackoff", \ref Kalyna128 "Kalyna (128/256/512)", + MARS, RC2, RC5, RC6, \ref SAFER_K "SAFER-K", \ref SAFER_SK "SAFER-SK", SEED, Serpent, + \ref SHACAL2 "SHACAL-2", SHARK, \ref SIMECK64 "SIMECK (32/64)" SKIPJACK, SM4, Square, TEA, + \ref ThreeWay "3-Way", \ref Threefish256 "Threefish (256/512/1024)", Twofish, XTEA +
Stream Ciphers
+ \ref ChaCha "ChaCha (8/12/20)", \ref HC128 "HC-128/256", \ref Panama "Panama-LE", \ref Panama "Panama-BE", + Rabbit, Salsa20, \ref SEAL "SEAL-LE", \ref SEAL "SEAL-BE", WAKE, XSalsa20 +
Hash Functions
+ BLAKE2s, BLAKE2b, \ref Keccak "Keccak (F1600)", SHA1, SHA224, SHA256, SHA384, SHA512, + \ref SHA3 "SHA-3", SM3, Tiger, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, SipHash, Whirlpool, + Weak::MD2, Weak::MD4, Weak::MD5 +
Non-Cryptographic Checksums
+ CRC32, CRC32C, Adler32 +
Message Authentication Codes
+ BLAKE2b, BLAKE2s, CBC_MAC, CMAC, DMAC, \ref GCM "GCM (GMAC)", HMAC, Poly1305, TTMAC, VMAC +
Random Number Generators
+ NullRNG, LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, + NIST Hash_DRBG and HMAC_DRBG, \ref MersenneTwister "MersenneTwister (MT19937 and MT19937-AR)", + DARN, RDRAND, RDSEED +
Key Derivation and Password-based Cryptography
+ HKDF, \ref PKCS12_PBKDF "PBKDF (PKCS #12)", \ref PKCS5_PBKDF1 "PBKDF-1 (PKCS #5)", + \ref PKCS5_PBKDF2_HMAC "PBKDF-2/HMAC (PKCS #5)" +
Public Key Cryptosystems
+ DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES +
Public Key Signature Schemes
+ DSA, DSA2, \ref ed25519 "Ed25519", GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, + RabinSS, RWSS, ESIGN +
Key Agreement
+ DH, DH2, \ref x25519 "X25519", \ref MQV_Domain "MQV", \ref HMQV_Domain "HMQV", + \ref FHMQV_Domain "FHMQV", ECDH, x25519, ECMQV, ECHMQV, ECFHMQV, XTR_DH +
Algebraic Structures
+ Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, + ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, GF2NP, GF256, GF2_32, EC2N, ECP +
Secret Sharing and Information Dispersal
+ SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery +
Compression
+ Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor +
Input Source Classes
+ StringSource, ArraySource, VectorSource, FileSource, RandomNumberSource +
Output Sink Classes
+ StringSinkTemplate, StringSink, VectorSink, ArraySink, FileSink, RandomNumberSink +
Filter Wrappers
+ StreamTransformationFilter, AuthenticatedEncryptionFilter, AuthenticatedDecryptionFilter, HashFilter, + HashVerificationFilter, SignerFilter, SignatureVerificationFilter +
Binary to Text Encoders and Decoders
+ HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base64URLEncoder, Base64URLDecoder, Base32Encoder, + Base32Decoder +
Wrappers for OS features
+ Timer, ThreadUserTimer + +
+ + + +

This reference manual is a work in progress. Some classes lack detailed descriptions. +

Click here to download a zip archive containing this manual. +

Thanks to Ryan Phillips for providing the Doxygen configuration file +and getting us started on the manual. +*/ + +#ifndef CRYPTOPP_CRYPTLIB_H +#define CRYPTOPP_CRYPTLIB_H + +#include "config.h" +#include "stdcpp.h" +#include "trap.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4127 4189 4505 4702) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// forward declarations +class Integer; +class RandomNumberGenerator; +class BufferedTransformation; + +/// \brief Specifies a direction for a cipher to operate +/// \sa BlockTransformation::IsForwardTransformation(), BlockTransformation::IsPermutation(), BlockTransformation::GetCipherDirection() +enum CipherDir { + /// \brief the cipher is performing encryption + ENCRYPTION, + /// \brief the cipher is performing decryption + DECRYPTION}; + +/// \brief Represents infinite time +const unsigned long INFINITE_TIME = ULONG_MAX; + +// VC60 workaround: using enums as template parameters causes problems +/// \brief Converts an enumeration to a type suitable for use as a template parameter +template +struct EnumToType +{ + static ENUM_TYPE ToEnum() {return static_cast(VALUE);} +}; + +/// \brief Provides the byte ordering +/// \details Big-endian and little-endian modes are supported. Bi-endian and PDP-endian modes +/// are not supported. +enum ByteOrder { + /// \brief byte order is little-endian + LITTLE_ENDIAN_ORDER = 0, + /// \brief byte order is big-endian + BIG_ENDIAN_ORDER = 1}; + +/// \brief Provides a constant for LittleEndian +typedef EnumToType LittleEndian; +/// \brief Provides a constant for BigEndian +typedef EnumToType BigEndian; + +/// \brief Base class for all exceptions thrown by the library +/// \details All library exceptions directly or indirectly inherit from the Exception class. +/// The Exception class itself inherits from std::exception. The library does not use +/// std::runtime_error derived classes. +class CRYPTOPP_DLL Exception : public std::exception +{ +public: + /// \enum ErrorType + /// \brief Error types or categories + enum ErrorType { + /// \brief A method was called which was not implemented + NOT_IMPLEMENTED, + /// \brief An invalid argument was detected + INVALID_ARGUMENT, + /// \brief BufferedTransformation received a Flush(true) signal but can't flush buffers + CANNOT_FLUSH, + /// \brief Data integerity check, such as CRC or MAC, failed + DATA_INTEGRITY_CHECK_FAILED, + /// \brief Input data was received that did not conform to expected format + INVALID_DATA_FORMAT, + /// \brief Error reading from input device or writing to output device + IO_ERROR, + /// \brief Some other error occurred not belonging to other categories + OTHER_ERROR + }; + + virtual ~Exception() throw() {} + + /// \brief Construct a new Exception + explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {} + + /// \brief Retrieves a C-string describing the exception + const char *what() const throw() {return (m_what.c_str());} + /// \brief Retrieves a string describing the exception + const std::string &GetWhat() const {return m_what;} + /// \brief Sets the error string for the exception + void SetWhat(const std::string &s) {m_what = s;} + /// \brief Retrieves the error type for the exception + ErrorType GetErrorType() const {return m_errorType;} + /// \brief Sets the error type for the exceptions + void SetErrorType(ErrorType errorType) {m_errorType = errorType;} + +private: + ErrorType m_errorType; + std::string m_what; +}; + +/// \brief An invalid argument was detected +class CRYPTOPP_DLL InvalidArgument : public Exception +{ +public: + /// \brief Construct an InvalidArgument + /// \param s the message for the exception + /// \details The member function what() returns s. + explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {} +}; + +/// \brief Input data was received that did not conform to expected format +class CRYPTOPP_DLL InvalidDataFormat : public Exception +{ +public: + /// \brief Construct an InvalidDataFormat + /// \param s the message for the exception + /// \details The member function what() returns s. + explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} +}; + +/// \brief A decryption filter encountered invalid ciphertext +class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat +{ +public: + /// \brief Construct an InvalidCiphertext + /// \param s the message for the exception + /// \details The member function what() returns s. + explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {} +}; + +/// \brief A method was called which was not implemented +class CRYPTOPP_DLL NotImplemented : public Exception +{ +public: + /// \brief Construct an NotImplemented + /// \param s the message for the exception + /// \details The member function what() returns s. + explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {} +}; + +/// \brief Flush(true) was called but it can't completely flush its buffers +class CRYPTOPP_DLL CannotFlush : public Exception +{ +public: + /// \brief Construct an CannotFlush + /// \param s the message for the exception + /// \details The member function what() returns s. + explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {} +}; + +/// \brief The operating system reported an error +class CRYPTOPP_DLL OS_Error : public Exception +{ +public: + virtual ~OS_Error() throw() {} + + /// \brief Construct an OS_Error + /// \param errorType the error type + /// \param s the message for the exception + /// \param operation the operation for the exception + /// \param errorCode the error code + /// \details The member function what() returns s. + OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode) + : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} + + /// \brief Retrieve the operating system API that reported the error + const std::string & GetOperation() const {return m_operation;} + /// \brief Retrieve the error code returned by the operating system + int GetErrorCode() const {return m_errorCode;} + +protected: + std::string m_operation; + int m_errorCode; +}; + +/// \brief Returns a decoding results +struct CRYPTOPP_DLL DecodingResult +{ + /// \brief Constructs a DecodingResult + /// \details isValidCoding is initialized to false and messageLength is + /// initialized to 0. + explicit DecodingResult() : isValidCoding(false), messageLength(0) {} + /// \brief Constructs a DecodingResult + /// \param len the message length + /// \details isValidCoding is initialized to true. + explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {} + + /// \brief Compare two DecodingResult + /// \param rhs the other DecodingResult + /// \return true if either isValidCoding or messageLength is \a not equal, + /// false otherwise + bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;} + /// \brief Compare two DecodingResult + /// \param rhs the other DecodingResult + /// \return true if either isValidCoding or messageLength is \a not equal, + /// false otherwise + /// \details Returns !operator==(rhs). + bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);} + + /// \brief Flag to indicate the decoding is valid + bool isValidCoding; + /// \brief Recovered message length if isValidCoding is true, undefined otherwise + size_t messageLength; +}; + +/// \brief Interface for retrieving values given their names +/// \details This class is used to safely pass a variable number of arbitrarily +/// typed arguments to functions and to read values from keys and crypto parameters. +/// \details To obtain an object that implements NameValuePairs for the purpose of +/// parameter passing, use the MakeParameters() function. +/// \details To get a value from NameValuePairs, you need to know the name and the +/// type of the value. Call GetValueNames() on a NameValuePairs object to obtain a +/// list of value names that it supports. then look at the Name namespace +/// documentation to see what the type of each value is, or alternatively, call +/// GetIntValue() with the value name, and if the type is not int, a +/// ValueTypeMismatch exception will be thrown and you can get the actual type from +/// the exception object. +/// \sa NullNameValuePairs, g_nullNameValuePairs, +/// NameValuePairs on the +/// Crypto++ wiki +class NameValuePairs +{ +public: + virtual ~NameValuePairs() {} + + /// \brief Thrown when an unexpected type is encountered + /// \details Exception thrown when trying to retrieve a value using a different + /// type than expected + class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument + { + public: + /// \brief Construct a ValueTypeMismatch + /// \param name the name of the value + /// \param stored the \a actual type of the value stored + /// \param retrieving the \a presumed type of the value retrieved + ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving) + : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'") + , m_stored(stored), m_retrieving(retrieving) {} + + /// \brief Provides the stored type + /// \return the C++ mangled name of the type + const std::type_info & GetStoredTypeInfo() const {return m_stored;} + + /// \brief Provides the retrieveing type + /// \return the C++ mangled name of the type + const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;} + + private: + const std::type_info &m_stored; + const std::type_info &m_retrieving; + }; + + /// \brief Get a copy of this object or subobject + /// \tparam T class or type + /// \param object reference to a variable that receives the value + template + bool GetThisObject(T &object) const + { + return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object); + } + + /// \brief Get a pointer to this object + /// \tparam T class or type + /// \param ptr reference to a pointer to a variable that receives the value + template + bool GetThisPointer(T *&ptr) const + { + return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), ptr); + } + + /// \brief Get a named value + /// \tparam T class or type + /// \param name the name of the object or value to retrieve + /// \param value reference to a variable that receives the value + /// \return true if the value was retrieved, false otherwise + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + template + bool GetValue(const char *name, T &value) const + { + return GetVoidValue(name, typeid(T), &value); + } + + /// \brief Get a named value + /// \tparam T class or type + /// \param name the name of the object or value to retrieve + /// \param defaultValue the default value of the class or type if it does not exist + /// \return the object or value + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + template + T GetValueWithDefault(const char *name, T defaultValue) const + { + T value; + bool result = GetValue(name, value); + // No assert... this recovers from failure + if (result) {return value;} + return defaultValue; + } + + /// \brief Get a list of value names that can be retrieved + /// \return a list of names available to retrieve + /// \details the items in the list are delimited with a colon. + CRYPTOPP_DLL std::string GetValueNames() const + {std::string result; GetValue("ValueNames", result); return result;} + + /// \brief Get a named value with type int + /// \param name the name of the value to retrieve + /// \param value the value retrieved upon success + /// \return true if an int value was retrieved, false otherwise + /// \details GetIntValue() is used to ensure we don't accidentally try to get an + /// unsigned int or some other type when we mean int (which is the most common case) + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const + {return GetValue(name, value);} + + /// \brief Get a named value with type int, with default + /// \param name the name of the value to retrieve + /// \param defaultValue the default value if the name does not exist + /// \return the value retrieved on success or the default value + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const + {return GetValueWithDefault(name, defaultValue);} + + /// \brief Get a named value with type word64 + /// \param name the name of the value to retrieve + /// \param value the value retrieved upon success + /// \return true if an word64 value was retrieved, false otherwise + /// \sa GetValue(), GetValueWithDefault(), GetWord64ValueWithDefault(), GetIntValue(), + /// GetIntValueWithDefault(), GetRequiredParameter() and GetRequiredIntParameter() + CRYPTOPP_DLL bool GetWord64Value(const char *name, word64 &value) const + {return GetValue(name, value);} + + /// \brief Get a named value with type word64, with default + /// \param name the name of the value to retrieve + /// \param defaultValue the default value if the name does not exist + /// \return the value retrieved on success or the default value + /// \sa GetValue(), GetValueWithDefault(), GetWord64Value(), GetIntValue(), + /// GetIntValueWithDefault(), GetRequiredParameter() and GetRequiredWord64Parameter() + CRYPTOPP_DLL word64 GetWord64ValueWithDefault(const char *name, word64 defaultValue) const + {return GetValueWithDefault(name, defaultValue);} + + /// \brief Ensures an expected name and type is present + /// \param name the name of the value + /// \param stored the type that was stored for the name + /// \param retrieving the type that is being retrieved for the name + /// \throw ValueTypeMismatch + /// \details ThrowIfTypeMismatch() effectively performs a type safety check. + /// stored and retrieving are C++ mangled names for the type. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) + {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);} + + /// \brief Retrieves a required name/value pair + /// \tparam T class or type + /// \param className the name of the class + /// \param name the name of the value + /// \param value reference to a variable to receive the value + /// \throw InvalidArgument + /// \details GetRequiredParameter() throws InvalidArgument if the name + /// is not present or not of the expected type T. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + template + void GetRequiredParameter(const char *className, const char *name, T &value) const + { + if (!GetValue(name, value)) + throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); + } + + /// \brief Retrieves a required name/value pair + /// \param className the name of the class + /// \param name the name of the value + /// \param value reference to a variable to receive the value + /// \throw InvalidArgument + /// \details GetRequiredParameter() throws InvalidArgument if the name + /// is not present or not of the expected type T. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const + { + if (!GetIntValue(name, value)) + throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); + } + + /// \brief Get a named value + /// \param name the name of the object or value to retrieve + /// \param valueType reference to a variable that receives the value + /// \param pValue void pointer to a variable that receives the value + /// \return true if the value was retrieved, false otherwise + /// \details GetVoidValue() retrieves the value of name if it exists. + /// \note GetVoidValue() is an internal function and should be implemented + /// by derived classes. Users should use one of the other functions instead. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0; +}; + +// Doxygen cannot handle initialization +#if CRYPTOPP_DOXYGEN_PROCESSING +/// \brief Default channel for BufferedTransformation +/// \details DEFAULT_CHANNEL is equal to an empty string +/// \details The definition for DEFAULT_CHANNEL is in cryptlib.cpp. +/// It can be subject to Static +/// Initialization Order Fiasco. If you experience a crash in +/// DEFAULT_CHANNEL where the string object is NULL, then you probably have +/// a global object using DEFAULT_CHANNEL before it has been constructed. +const std::string DEFAULT_CHANNEL; + +/// \brief Channel for additional authenticated data +/// \details AAD_CHANNEL is equal to "AAD" +/// \details The definition for AAD_CHANNEL is in cryptlib.cpp. +/// It can be subject to Static +/// Initialization Order Fiasco. If you experience a crash in +/// AAD_CHANNEL where the string object is NULL, then you probably have a +/// global object using AAD_CHANNEL before it has been constructed. +const std::string AAD_CHANNEL; + +/// \brief An empty set of name-value pairs +/// \details The definition for g_nullNameValuePairs is in cryptlib.cpp. +/// It can be subject to Static +/// Initialization Order Fiasco. If you experience a crash in +/// g_nullNameValuePairs where the string object is NULL, then you probably +/// have a global object using g_nullNameValuePairs before it has been +/// constructed. +const NameValuePairs& g_nullNameValuePairs; + +#else +extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL; +extern CRYPTOPP_DLL const std::string AAD_CHANNEL; +extern CRYPTOPP_DLL const NameValuePairs& g_nullNameValuePairs; +#endif + +// Document additional name spaces which show up elsewhere in the sources. +#if CRYPTOPP_DOXYGEN_PROCESSING +/// \brief Namespace containing value name definitions. +/// \details Name is part of the CryptoPP namespace. +/// \details The semantics of value names, types are: +///

+///     ThisObject:ClassName (ClassName, copy of this object or a subobject)
+///     ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)
+/// 
+DOCUMENTED_NAMESPACE_BEGIN(Name) +// more names defined in argnames.h +DOCUMENTED_NAMESPACE_END + +/// \brief Namespace containing weak and wounded algorithms. +/// \details Weak is part of the CryptoPP namespace. Schemes and algorithms are moved into Weak +/// when their security level is reduced to an unacceptable level by contemporary standards. +/// \details To use an algorithm in the Weak namespace, you must \c \#define +/// CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 before including a header for a weak or wounded +/// algorithm. For example: +///
  \c \#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
+///   \c \#include 
+///   ...
+///   CryptoPP::Weak::MD5 md5;
+///   
+DOCUMENTED_NAMESPACE_BEGIN(Weak) +// weak and wounded algorithms +DOCUMENTED_NAMESPACE_END +#endif + +/// \brief Namespace containing NaCl library functions +/// \details TweetNaCl is a compact and portable reimplementation of the NaCl library. +DOCUMENTED_NAMESPACE_BEGIN(NaCl) +// crypto_box, crypto_box_open, crypto_sign, and crypto_sign_open (and friends) +DOCUMENTED_NAMESPACE_END + +/// \brief Namespace containing testing and benchmark classes. +/// \details Source files for classes in the Test namespaces include +/// test.cpp, validat#.cpp and bench#.cpp. +DOCUMENTED_NAMESPACE_BEGIN(Test) +// testing and benchmark classes +DOCUMENTED_NAMESPACE_END + +// ******************************************************** + +/// \brief Interface for cloning objects +/// \note this is \a not implemented by most classes +/// \sa ClonableImpl, NotCopyable +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable +{ +public: + virtual ~Clonable() {} + + /// \brief Copies this object + /// \return a copy of this object + /// \throw NotImplemented + /// \note this is \a not implemented by most classes + /// \sa NotCopyable + virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");} // TODO: make this =0 +}; + +/// \brief Interface for all crypto algorithms +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable +{ +public: + virtual ~Algorithm() {} + + /// \brief Interface for all crypto algorithms + /// \param checkSelfTestStatus determines whether the object can proceed if the self + /// tests have not been run or failed. + /// \details When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true, + /// this constructor throws SelfTestFailure if the self test hasn't been run or fails. + /// \details FIPS 140-2 compliance is disabled by default. It is only used by certain + /// versions of the library when the library is built as a DLL on Windows. Also see + /// CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 in config.h. + Algorithm(bool checkSelfTestStatus = true); + + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like AES or AES/GCM. + /// Some algorithms do not have standard names yet. For example, there is no standard + /// algorithm name for Shoup's ECIES. + /// \note AlgorithmName is not universally implemented yet. + virtual std::string AlgorithmName() const {return "unknown";} + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2". + /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics + /// instead of ASM. + /// \details Algorithms which combine different instructions or ISAs provide the + /// dominant one. For example on x86 AES/GCM returns "AESNI" rather than + /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". + /// \note Provider is not universally implemented yet. + /// \since Crypto++ 8.0 + virtual std::string AlgorithmProvider() const {return "C++";} +}; + +/// \brief Interface for algorithms that take byte strings as keys +/// \sa FixedKeyLength(), VariableKeyLength(), SameKeyLengthAs(), SimpleKeyingInterfaceImpl() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface +{ +public: + virtual ~SimpleKeyingInterface() {} + + /// \brief Returns smallest valid key length + /// \return the minimum key length, in bytes + virtual size_t MinKeyLength() const =0; + + /// \brief Returns largest valid key length + /// \return the maximum key length, in bytes + virtual size_t MaxKeyLength() const =0; + + /// \brief Returns default key length + /// \return the default key length, in bytes + virtual size_t DefaultKeyLength() const =0; + + /// \brief Returns a valid key length for the algorithm + /// \param keylength the size of the key, in bytes + /// \return the valid key length, in bytes + /// \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH, + /// then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, + /// then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE, + /// then keylength is returned. Otherwise, the function returns a \a lower multiple of + /// KEYLENGTH_MULTIPLE. + virtual size_t GetValidKeyLength(size_t keylength) const =0; + + /// \brief Returns whether keylength is a valid key length + /// \param keylength the requested keylength + /// \return true if keylength is valid, false otherwise + /// \details Internally the function calls GetValidKeyLength() + virtual bool IsValidKeyLength(size_t keylength) const + {return keylength == GetValidKeyLength(keylength);} + + /// \brief Sets or reset the key of this object + /// \param key the key to use when keying the object + /// \param length the size of the key, in bytes + /// \param params additional initialization parameters to configure this object + virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); + + /// \brief Sets or reset the key of this object + /// \param key the key to use when keying the object + /// \param length the size of the key, in bytes + /// \param rounds the number of rounds to apply the transformation function, + /// if applicable + /// \details SetKeyWithRounds() calls SetKey() with a NameValuePairs + /// object that only specifies rounds. rounds is an integer parameter, + /// and -1 means use the default number of rounds. + void SetKeyWithRounds(const byte *key, size_t length, int rounds); + + /// \brief Sets or reset the key of this object + /// \param key the key to use when keying the object + /// \param length the size of the key, in bytes + /// \param iv the initialization vector to use when keying the object + /// \param ivLength the size of the iv, in bytes + /// \details SetKeyWithIV() calls SetKey() with a NameValuePairs + /// that only specifies IV. The IV is a byte buffer with size ivLength. + /// ivLength is an integer parameter, and -1 means use IVSize(). + void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength); + + /// \brief Sets or reset the key of this object + /// \param key the key to use when keying the object + /// \param length the size of the key, in bytes + /// \param iv the initialization vector to use when keying the object + /// \details SetKeyWithIV() calls SetKey() with a NameValuePairs() object + /// that only specifies iv. iv is a byte buffer, and it must have + /// a size IVSize(). + void SetKeyWithIV(const byte *key, size_t length, const byte *iv) + {SetKeyWithIV(key, length, iv, IVSize());} + + /// \brief Secure IVs requirements as enumerated values. + /// \details Provides secure IV requirements as a monotonically increasing enumerated values. + /// Requirements can be compared using less than (<) and greater than (>). For example, + /// UNIQUE_IV < RANDOM_IV and UNPREDICTABLE_RANDOM_IV > RANDOM_IV. + /// \details Objects that use SimpleKeyingInterface do not support an optional IV. That is, + /// an IV must be present or it must be absent. If you wish to support an optional IV then + /// provide two classes - one with an IV and one without an IV. + /// \sa IsResynchronizable(), CanUseRandomIVs(), CanUsePredictableIVs(), CanUseStructuredIVs() + enum IV_Requirement { + /// \brief The IV must be unique + UNIQUE_IV = 0, + /// \brief The IV must be random and possibly predictable + RANDOM_IV, + /// \brief The IV must be random and unpredictable + UNPREDICTABLE_RANDOM_IV, + /// \brief The IV is set by the object + INTERNALLY_GENERATED_IV, + /// \brief The object does not use an IV + NOT_RESYNCHRONIZABLE + }; + + /// \brief Minimal requirement for secure IVs + /// \return the secure IV requirement of the algorithm + virtual IV_Requirement IVRequirement() const =0; + + /// \brief Determines if the object can be resynchronized + /// \return true if the object can be resynchronized (i.e. supports initialization vectors), false otherwise + /// \note If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, + /// an IV of all 0's will be assumed. + bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;} + + /// \brief Determines if the object can use random IVs + /// \return true if the object can use random IVs (in addition to ones returned by GetNextIV), false otherwise + bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;} + + /// \brief Determines if the object can use random but possibly predictable IVs + /// \return true if the object can use random but possibly predictable IVs (in addition to ones returned by + /// GetNextIV), false otherwise + bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;} + + /// \brief Determines if the object can use structured IVs + /// \return true if the object can use structured IVs, false otherwise + /// \details CanUseStructuredIVs() indicates whether the object can use structured IVs; for example a counter + /// (in addition to ones returned by GetNextIV). + bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;} + + /// \brief Returns length of the IV accepted by this object + /// \return the size of an IV, in bytes + /// \throw NotImplemented() if the object does not support resynchronization + /// \details The default implementation throws NotImplemented + virtual unsigned int IVSize() const + {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} + + /// \brief Provides the default size of an IV + /// \return default length of IVs accepted by this object, in bytes + unsigned int DefaultIVLength() const {return IVSize();} + + /// \brief Provides the minimum size of an IV + /// \return minimal length of IVs accepted by this object, in bytes + /// \throw NotImplemented() if the object does not support resynchronization + virtual unsigned int MinIVLength() const {return IVSize();} + + /// \brief Provides the maximum size of an IV + /// \return maximal length of IVs accepted by this object, in bytes + /// \throw NotImplemented() if the object does not support resynchronization + virtual unsigned int MaxIVLength() const {return IVSize();} + + /// \brief Resynchronize with an IV + /// \param iv the initialization vector + /// \param ivLength the size of the initialization vector, in bytes + /// \details Resynchronize() resynchronizes with an IV provided by the caller. ivLength=-1 means use IVSize(). + /// \throw NotImplemented() if the object does not support resynchronization + virtual void Resynchronize(const byte *iv, int ivLength=-1) { + CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(ivLength); + throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization"); + } + + /// \brief Retrieves a secure IV for the next message + /// \param rng a RandomNumberGenerator to produce keying material + /// \param iv a block of bytes to receive the IV + /// \details The IV must be at least IVSize() in length. + /// \details This method should be called after you finish encrypting one message and are ready + /// to start the next one. After calling it, you must call SetKey() or Resynchronize(). + /// before using this object again. + /// \details Internally, the base class implementation calls RandomNumberGenerator's GenerateBlock() + /// \note This method is not implemented on decryption objects. + virtual void GetNextIV(RandomNumberGenerator &rng, byte *iv); + +protected: + /// \brief Returns the base class Algorithm + /// \return the base class Algorithm + virtual const Algorithm & GetAlgorithm() const =0; + + /// \brief Sets the key for this object without performing parameter validation + /// \param key a byte buffer used to key the cipher + /// \param length the length of the byte buffer + /// \param params additional parameters passed as NameValuePairs + /// \details key must be at least DEFAULT_KEYLENGTH in length. + virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) =0; + + /// \brief Validates the key length + /// \param length the size of the keying material, in bytes + /// \throw InvalidKeyLength if the key length is invalid + void ThrowIfInvalidKeyLength(size_t length); + + /// \brief Validates the object + /// \throw InvalidArgument if the IV is present + /// \details Internally, the default implementation calls IsResynchronizable() and throws + /// InvalidArgument if the function returns true. + /// \note called when no IV is passed + void ThrowIfResynchronizable(); + + /// \brief Validates the IV + /// \param iv the IV with a length of IVSize, in bytes + /// \throw InvalidArgument on failure + /// \details Internally, the default implementation checks the iv. If iv is not NULL or nullptr, + /// then the function succeeds. If iv is NULL, then IVRequirement is checked against + /// UNPREDICTABLE_RANDOM_IV. If IVRequirement is UNPREDICTABLE_RANDOM_IV, then + /// then the function succeeds. Otherwise, an exception is thrown. + void ThrowIfInvalidIV(const byte *iv); + + /// \brief Validates the IV length + /// \param length the size of an IV, in bytes + /// \throw InvalidArgument if the IV length is invalid + size_t ThrowIfInvalidIVLength(int length); + + /// \brief Retrieves and validates the IV + /// \param params NameValuePairs with the IV supplied as a ConstByteArrayParameter + /// \param size the length of the IV, in bytes + /// \return a pointer to the first byte of the IV + /// \throw InvalidArgument if the number of rounds are invalid + const byte * GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size); + + /// \brief Validates the key length + /// \param length the size of the keying material, in bytes + inline void AssertValidKeyLength(size_t length) const + {CRYPTOPP_UNUSED(length); CRYPTOPP_ASSERT(IsValidKeyLength(length));} +}; + +/// \brief Interface for the data processing part of block ciphers +/// \details Classes derived from BlockTransformation are block ciphers +/// in ECB mode (for example the DES::Encryption class), which are stateless. +/// These classes should not be used directly, but only in combination with +/// a mode class (see CipherModeDocumentation in modes.h). +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm +{ +public: + virtual ~BlockTransformation() {} + + /// \brief Encrypt or decrypt a block + /// \param inBlock the input message before processing + /// \param outBlock the output message after processing + /// \param xorBlock an optional XOR mask + /// \details ProcessAndXorBlock encrypts or decrypts inBlock, xor with xorBlock, and write to outBlock. + /// \details The size of the block is determined by the block cipher and its documentation. Use + /// BLOCKSIZE at compile time, or BlockSize() at runtime. + /// \note The message can be transformed in-place, or the buffers must \a not overlap + /// \sa FixedBlockSize, BlockCipherFinal from seckey.h and BlockSize() + virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0; + + /// \brief Encrypt or decrypt a block + /// \param inBlock the input message before processing + /// \param outBlock the output message after processing + /// \details ProcessBlock encrypts or decrypts inBlock and write to outBlock. + /// \details The size of the block is determined by the block cipher and its documentation. + /// Use BLOCKSIZE at compile time, or BlockSize() at runtime. + /// \sa FixedBlockSize, BlockCipherFinal from seckey.h and BlockSize() + /// \note The message can be transformed in-place, or the buffers must \a not overlap + void ProcessBlock(const byte *inBlock, byte *outBlock) const + {ProcessAndXorBlock(inBlock, NULLPTR, outBlock);} + + /// \brief Encrypt or decrypt a block in place + /// \param inoutBlock the input message before processing + /// \details ProcessBlock encrypts or decrypts inoutBlock in-place. + /// \details The size of the block is determined by the block cipher and its documentation. + /// Use BLOCKSIZE at compile time, or BlockSize() at runtime. + /// \sa FixedBlockSize, BlockCipherFinal from seckey.h and BlockSize() + void ProcessBlock(byte *inoutBlock) const + {ProcessAndXorBlock(inoutBlock, NULLPTR, inoutBlock);} + + /// Provides the block size of the cipher + /// \return the block size of the cipher, in bytes + virtual unsigned int BlockSize() const =0; + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + virtual unsigned int OptimalDataAlignment() const; + + /// \brief Determines if the transformation is a permutation + /// \return true if this is a permutation (i.e. there is an inverse transformation) + virtual bool IsPermutation() const {return true;} + + /// \brief Determines if the cipher is being operated in its forward direction + /// \return true if DIR is ENCRYPTION, false otherwise + /// \sa IsForwardTransformation(), IsPermutation(), GetCipherDirection() + virtual bool IsForwardTransformation() const =0; + + /// \brief Determines the number of blocks that can be processed in parallel + /// \return the number of blocks that can be processed in parallel, for bit-slicing implementations + /// \details Bit-slicing is often used to improve throughput and minimize timing attacks. + virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;} + + /// \brief Bit flags that control AdvancedProcessBlocks() behavior + enum FlagsForAdvancedProcessBlocks { + /// \brief inBlock is a counter + BT_InBlockIsCounter=1, + /// \brief should not modify block pointers + BT_DontIncrementInOutPointers=2, + /// \brief Xor inputs before transformation + BT_XorInput=4, + /// \brief perform the transformation in reverse + BT_ReverseDirection=8, + /// \brief Allow parallel transformations + BT_AllowParallel=16}; + + /// \brief Encrypt and xor multiple blocks using additional flags + /// \param inBlocks the input message before processing + /// \param xorBlocks an optional XOR mask + /// \param outBlocks the output message after processing + /// \param length the size of the blocks, in bytes + /// \param flags additional flags to control processing + /// \details Encrypt and xor multiple blocks according to FlagsForAdvancedProcessBlocks flags. + /// \note If BT_InBlockIsCounter is set, then the last byte of inBlocks may be modified. + virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; + + /// \brief Provides the direction of the cipher + /// \return ENCRYPTION if IsForwardTransformation() is true, DECRYPTION otherwise + /// \sa IsForwardTransformation(), IsPermutation() + inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;} +}; + +/// \brief Interface for the data processing portion of stream ciphers +/// \sa StreamTransformationFilter() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm +{ +public: + virtual ~StreamTransformation() {} + + /// \brief Provides a reference to this object + /// \return A reference to this object + /// \details Useful for passing a temporary object to a function that takes a non-const reference + StreamTransformation& Ref() {return *this;} + + /// \brief Provides the mandatory block size of the cipher + /// \return The block size of the cipher if input must be processed in blocks, 1 otherwise + /// \details Stream ciphers and some block ciphers modes of operation return 1. Modes that + /// return 1 must be able to process a single byte at a time, like counter mode. If a + /// mode of operation or block cipher cannot stream then it must not return 1. + /// \details When filters operate the mode or cipher, ProcessData will be called with a + /// string of bytes that is determined by MandatoryBlockSize and OptimalBlockSize. When a + /// policy is set, like 16-byte strings for a 16-byte block cipher, the filter will buffer + /// bytes until the specified number of bytes is available to the object. + /// \sa ProcessData, ProcessLastBlock, MandatoryBlockSize, MinLastBlockSize, BlockPaddingSchemeDef, IsLastBlockSpecial + virtual unsigned int MandatoryBlockSize() const {return 1;} + + /// \brief Provides the input block size most efficient for this cipher + /// \return The input block size that is most efficient for the cipher + /// \details The base class implementation returns MandatoryBlockSize(). + /// \note Optimal input length is + /// n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n \> 0. + virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();} + + /// \brief Provides the number of bytes used in the current block when processing at optimal block size. + /// \return the number of bytes used in the current block when processing at the optimal block size + virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;} + + /// \brief Provides input and output data alignment for optimal performance + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + virtual unsigned int OptimalDataAlignment() const; + + /// \brief Encrypt or decrypt an array of bytes + /// \param outString the output byte buffer + /// \param inString the input byte buffer + /// \param length the size of the input and output byte buffers, in bytes + /// \details ProcessData is called with a string of bytes whose size depends on MandatoryBlockSize. + /// Either inString == outString, or they must not overlap. + /// \sa ProcessData, ProcessLastBlock, MandatoryBlockSize, MinLastBlockSize, BlockPaddingSchemeDef, IsLastBlockSpecial + virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0; + + /// \brief Encrypt or decrypt the last block of data + /// \param outString the output byte buffer + /// \param outLength the size of the output byte buffer, in bytes + /// \param inString the input byte buffer + /// \param inLength the size of the input byte buffer, in bytes + /// \return the number of bytes used in outString + /// \details ProcessLastBlock is used when the last block of data is special and requires handling + /// by the cipher. The current implementation provides an output buffer with a size + /// inLength+2*MandatoryBlockSize(). The return value allows the cipher to expand cipher + /// text during encryption or shrink plain text during decryption. + /// \details This member function is used by CBC-CTS and OCB modes. + /// \sa ProcessData, ProcessLastBlock, MandatoryBlockSize, MinLastBlockSize, BlockPaddingSchemeDef, IsLastBlockSpecial + virtual size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); + + /// \brief Provides the size of the last block + /// \return the minimum size of the last block + /// \details MinLastBlockSize() returns the minimum size of the last block. 0 indicates the last + /// block is not special. + /// \details MandatoryBlockSize() enlists one of two behaviors. First, if MandatoryBlockSize() + /// returns 1, then the cipher can be streamed and ProcessData() is called with the tail bytes. + /// Second, if MandatoryBlockSize() returns non-0, then the string of bytes is padded to + /// MandatoryBlockSize() according to the padding mode. Then, ProcessData() is called with the + /// padded string of bytes. + /// \details Some authenticated encryption modes are not expressed well with MandatoryBlockSize() + /// and MinLastBlockSize(). For example, AES/OCB uses 16-byte blocks (MandatoryBlockSize = 16) + /// and the last block requires special processing (MinLastBlockSize = 0). However, 0 is a valid + /// last block size for OCB and the special processing is custom padding, and not standard PKCS + /// padding. In response an unambiguous IsLastBlockSpecial() was added. + /// \sa ProcessData, ProcessLastBlock, MandatoryBlockSize, MinLastBlockSize, BlockPaddingSchemeDef, IsLastBlockSpecial + virtual unsigned int MinLastBlockSize() const {return 0;} + + /// \brief Determines if the last block receives special processing + /// \return true if the last block reveives special processing, false otherwise. + /// \details Some authenticated encryption modes are not expressed well with + /// MandatoryBlockSize() and MinLastBlockSize(). For example, AES/OCB uses + /// 16-byte blocks (MandatoryBlockSize = 16) and the last block requires special processing + /// (MinLastBlockSize = 0). However, 0 is a valid last block size for OCB and the special + /// processing is custom padding, and not standard PKCS padding. In response an + /// unambiguous IsLastBlockSpecial() was added. + /// \details When IsLastBlockSpecial() returns false nothing special happens. All the former + /// rules and behaviors apply. This is the default behavior of IsLastBlockSpecial(). + /// \details When IsLastBlockSpecial() returns true four things happen. First, MinLastBlockSize = 0 + /// means 0 is a valid block size that should be processed. Second, standard block cipher padding is + /// \a not \a applied. Third, the caller supplies an outString is larger than inString by + /// 2*MandatoryBlockSize(). That is, there's a reserve available when processing the last block. + /// Fourth, the cipher is responsible for finalization like custom padding. The cipher will tell + /// the library how many bytes were processed or used by returning the appropriate value from + /// ProcessLastBlock(). + /// \details The return value of ProcessLastBlock() indicates how many bytes were written to + /// outString. A filter pipelining data will send outString and up to outLength + /// to an AttachedTransformation() for additional processing. Below is an example of the code + /// used in StreamTransformationFilter::LastPut. + ///
  if (m_cipher.IsLastBlockSpecial())
+	///   {
+	///     size_t reserve = 2*m_cipher.MandatoryBlockSize();
+	///     space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length+reserve);
+	///     length = m_cipher.ProcessLastBlock(space, length+reserve, inString, length);
+	///     AttachedTransformation()->Put(space, length);
+	///     return;
+	///   }
+ /// \sa ProcessData, ProcessLastBlock, MandatoryBlockSize, MinLastBlockSize, BlockPaddingSchemeDef, IsLastBlockSpecial + /// \since Crypto++ 6.0 + virtual bool IsLastBlockSpecial() const {return false;} + + /// \brief Encrypt or decrypt a string of bytes + /// \param inoutString the string to process + /// \param length the size of the inoutString, in bytes + /// \details Internally, the base class implementation calls ProcessData(). + inline void ProcessString(byte *inoutString, size_t length) + {ProcessData(inoutString, inoutString, length);} + + /// \brief Encrypt or decrypt a string of bytes + /// \param outString the output string to process + /// \param inString the input string to process + /// \param length the size of the input and output strings, in bytes + /// \details Internally, the base class implementation calls ProcessData(). + inline void ProcessString(byte *outString, const byte *inString, size_t length) + {ProcessData(outString, inString, length);} + + /// \brief Encrypt or decrypt a byte + /// \param input the input byte to process + /// \details Internally, the base class implementation calls ProcessData() with a size of 1. + inline byte ProcessByte(byte input) + {ProcessData(&input, &input, 1); return input;} + + /// \brief Determines whether the cipher supports random access + /// \return true if the cipher supports random access, false otherwise + virtual bool IsRandomAccess() const =0; + + /// \brief Seek to an absolute position + /// \param pos position to seek + /// \throw NotImplemented + /// \details The base class implementation throws NotImplemented. The function + /// \ref CRYPTOPP_ASSERT "asserts" IsRandomAccess() in debug builds. + virtual void Seek(lword pos) + { + CRYPTOPP_UNUSED(pos); + CRYPTOPP_ASSERT(!IsRandomAccess()); + throw NotImplemented("StreamTransformation: this object doesn't support random access"); + } + + /// \brief Determines whether the cipher is self-inverting + /// \return true if the cipher is self-inverting, false otherwise + /// \details IsSelfInverting determines whether this transformation is + /// self-inverting (e.g. xor with a keystream). + virtual bool IsSelfInverting() const =0; + + /// \brief Determines if the cipher is being operated in its forward direction + /// \return true if DIR is ENCRYPTION, false otherwise + /// \sa IsForwardTransformation(), IsPermutation(), GetCipherDirection() + virtual bool IsForwardTransformation() const =0; +}; + +/// \brief Interface for hash functions and data processing part of MACs +/// \details HashTransformation objects are stateful. They are created in an initial state, +/// change state as Update() is called, and return to the initial +/// state when Final() is called. This interface allows a large message to +/// be hashed in pieces by calling Update() on each piece followed by +/// calling Final(). +/// \sa HashFilter(), HashVerificationFilter() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm +{ +public: + virtual ~HashTransformation() {} + + /// \brief Provides a reference to this object + /// \return A reference to this object + /// \details Useful for passing a temporary object to a function that takes a non-const reference + HashTransformation& Ref() {return *this;} + + /// \brief Updates a hash with additional input + /// \param input the additional input as a buffer + /// \param length the size of the buffer, in bytes + virtual void Update(const byte *input, size_t length) =0; + + /// \brief Request space which can be written into by the caller + /// \param size the requested size of the buffer + /// \details The purpose of this method is to help avoid extra memory allocations. + /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, + /// size is the requested size of the buffer. When the call returns, size is the size of + /// the array returned to the caller. + /// \details The base class implementation sets size to 0 and returns NULL or nullptr. + /// \note Some objects, like ArraySink, cannot create a space because its fixed. + virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULLPTR;} + + /// \brief Computes the hash of the current message + /// \param digest a pointer to the buffer to receive the hash + /// \details Final() restarts the hash for a new message. + /// \pre COUNTOF(digest) <= DigestSize() or COUNTOF(digest) <= HASH::DIGESTSIZE ensures + /// the output byte buffer is large enough for the digest. + virtual void Final(byte *digest) + {TruncatedFinal(digest, DigestSize());} + + /// \brief Restart the hash + /// \details Discards the current state, and restart for a new message + virtual void Restart() + {TruncatedFinal(NULLPTR, 0);} + + /// Provides the digest size of the hash + /// \return the digest size of the hash. + virtual unsigned int DigestSize() const =0; + + /// Provides the tag size of the hash + /// \return the tag size of the hash. + /// \details Same as DigestSize(). + unsigned int TagSize() const {return DigestSize();} + + /// \brief Provides the block size of the compression function + /// \return block size of the compression function, in bytes + /// \details BlockSize() will return 0 if the hash is not block based + /// or does not have an equivalent block size. For example, Keccak + /// and SHA-3 do not have a block size, but they do have an equivalent + /// block size called rate expressed as r. + virtual unsigned int BlockSize() const {return 0;} + + /// \brief Provides the input block size most efficient for this hash. + /// \return The input block size that is most efficient for the cipher + /// \details The base class implementation returns MandatoryBlockSize(). + /// \details Optimal input length is + /// n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n \> 0. + virtual unsigned int OptimalBlockSize() const {return 1;} + + /// \brief Provides input and output data alignment for optimal performance + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + virtual unsigned int OptimalDataAlignment() const; + + /// \brief Updates the hash with additional input and computes the hash of the current message + /// \param digest a pointer to the buffer to receive the hash + /// \param input the additional input as a buffer + /// \param length the size of the buffer, in bytes + /// \details Use this if your input is in one piece and you don't want to call Update() + /// and Final() separately + /// \details CalculateDigest() restarts the hash for the next message. + /// \pre COUNTOF(digest) == DigestSize() or COUNTOF(digest) == HASH::DIGESTSIZE ensures + /// the output byte buffer is a valid size. + virtual void CalculateDigest(byte *digest, const byte *input, size_t length) + {Update(input, length); Final(digest);} + + /// \brief Verifies the hash of the current message + /// \param digest a pointer to the buffer of an \a existing hash + /// \return \p true if the existing hash matches the computed hash, \p false otherwise + /// \throw InvalidArgument() if the existing hash's size exceeds DigestSize() + /// \details Verify() performs a bitwise compare on the buffers using VerifyBufsEqual(), which is + /// a constant time comparison function. digestLength cannot exceed DigestSize(). + /// \details Verify() restarts the hash for the next message. + /// \pre COUNTOF(digest) == DigestSize() or COUNTOF(digest) == HASH::DIGESTSIZE ensures + /// the input byte buffer is a valid size. + virtual bool Verify(const byte *digest) + {return TruncatedVerify(digest, DigestSize());} + + /// \brief Updates the hash with additional input and verifies the hash of the current message + /// \param digest a pointer to the buffer of an \a existing hash + /// \param input the additional input as a buffer + /// \param length the size of the buffer, in bytes + /// \return \p true if the existing hash matches the computed hash, \p false otherwise + /// \throw InvalidArgument() if the existing hash's size exceeds DigestSize() + /// \details Use this if your input is in one piece and you don't want to call Update() + /// and Verify() separately + /// \details VerifyDigest() performs a bitwise compare on the buffers using VerifyBufsEqual(), + /// which is a constant time comparison function. + /// \details VerifyDigest() restarts the hash for the next message. + /// \pre COUNTOF(digest) == DigestSize() or COUNTOF(digest) == HASH::DIGESTSIZE ensures + /// the output byte buffer is a valid size. + virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length) + {Update(input, length); return Verify(digest);} + + /// \brief Computes the hash of the current message + /// \param digest a pointer to the buffer to receive the hash + /// \param digestSize the size of the truncated digest, in bytes + /// \details TruncatedFinal() calls Final() and then copies digestSize bytes to digest. + /// The hash is restarted the hash for the next message. + /// \pre COUNTOF(digest) <= DigestSize() or COUNTOF(digest) <= HASH::DIGESTSIZE ensures + /// the output byte buffer is a valid size. + virtual void TruncatedFinal(byte *digest, size_t digestSize) =0; + + /// \brief Updates the hash with additional input and computes the hash of the current message + /// \param digest a pointer to the buffer to receive the hash + /// \param digestSize the length of the truncated hash, in bytes + /// \param input the additional input as a buffer + /// \param length the size of the buffer, in bytes + /// \details Use this if your input is in one piece and you don't want to call Update() + /// and CalculateDigest() separately. + /// \details CalculateTruncatedDigest() restarts the hash for the next message. + /// \pre digestSize <= DigestSize() or digestSize <= HASH::DIGESTSIZE ensures + /// the output byte buffer is a valid size. + virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length) + {Update(input, length); TruncatedFinal(digest, digestSize);} + + /// \brief Verifies the hash of the current message + /// \param digest a pointer to the buffer of an \a existing hash + /// \param digestLength the size of the truncated hash, in bytes + /// \return \p true if the existing hash matches the computed hash, \p false otherwise + /// \throw InvalidArgument() if digestLength exceeds DigestSize() + /// \details TruncatedVerify() is a truncated version of Verify(). It can operate on a + /// buffer smaller than DigestSize(). However, digestLength cannot exceed DigestSize(). + /// \details Verify() performs a bitwise compare on the buffers using VerifyBufsEqual(), which is + /// a constant time comparison function. digestLength cannot exceed DigestSize(). + /// \details TruncatedVerify() restarts the hash for the next message. + /// \pre digestLength <= DigestSize() or digestLength <= HASH::DIGESTSIZE ensures + /// the input byte buffer is a valid size. + virtual bool TruncatedVerify(const byte *digest, size_t digestLength); + + /// \brief Updates the hash with additional input and verifies the hash of the current message + /// \param digest a pointer to the buffer of an \a existing hash + /// \param digestLength the size of the truncated hash, in bytes + /// \param input the additional input as a buffer + /// \param length the size of the buffer, in bytes + /// \return \p true if the existing hash matches the computed hash, \p false otherwise + /// \throw InvalidArgument() if digestLength exceeds DigestSize() + /// \details Use this if your input is in one piece and you don't want to call Update() + /// and TruncatedVerify() separately. + /// \details VerifyTruncatedDigest() is a truncated version of VerifyDigest(). It can operate + /// on a buffer smaller than DigestSize(). However, digestLength cannot exceed DigestSize(). + /// \details VerifyTruncatedDigest() restarts the hash for the next message. + /// \pre digestLength <= DigestSize() or digestLength <= HASH::DIGESTSIZE ensures + /// the input byte buffer is a valid size. + virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length) + {Update(input, length); return TruncatedVerify(digest, digestLength);} + +protected: + /// \brief Validates a truncated digest size + /// \param size the requested digest size + /// \throw InvalidArgument if the algorithm's digest size cannot be truncated to the requested size + /// \details Throws an exception when the truncated digest size is greater than DigestSize() + void ThrowIfInvalidTruncatedSize(size_t size) const; +}; + +/// \brief Interface for one direction (encryption or decryption) of a block cipher +/// \details These objects usually should not be used directly. See BlockTransformation for more details. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockCipher : public SimpleKeyingInterface, public BlockTransformation +{ +protected: + const Algorithm & GetAlgorithm() const {return *this;} +}; + +/// \brief Interface for one direction (encryption or decryption) of a stream cipher or cipher mode +/// \details These objects usually should not be used directly. See StreamTransformation for more details. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SymmetricCipher : public SimpleKeyingInterface, public StreamTransformation +{ +protected: + const Algorithm & GetAlgorithm() const {return *this;} +}; + +/// \brief Interface for message authentication codes +/// \details These objects usually should not be used directly. See HashTransformation for more details. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE MessageAuthenticationCode : public SimpleKeyingInterface, public HashTransformation +{ +protected: + const Algorithm & GetAlgorithm() const {return *this;} +}; + +/// \brief Interface for authenticated encryption modes of operation +/// \details AuthenticatedSymmetricCipher() provides the interface for one direction +/// (encryption or decryption) of a stream cipher or block cipher mode with authentication. The +/// StreamTransformation() part of this interface is used to encrypt or decrypt the data. The +/// MessageAuthenticationCode() part of the interface is used to input additional authenticated +/// data (AAD), which is MAC'ed but not encrypted. The MessageAuthenticationCode() part is also +/// used to generate and verify the MAC. +/// \details Crypto++ provides four authenticated encryption modes of operation - CCM, EAX, GCM +/// and OCB mode. All modes implement AuthenticatedSymmetricCipher() and the motivation for +/// the API, like calling AAD a "header", can be found in Bellare, Rogaway and +/// Wagner's The EAX Mode of +/// Operation. The EAX paper suggested a basic API to help standardize AEAD schemes in +/// software and promote adoption of the modes. +/// \sa Authenticated +/// Encryption on the Crypto++ wiki. +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipher : public MessageAuthenticationCode, public StreamTransformation +{ +public: + virtual ~AuthenticatedSymmetricCipher() {} + + /// \brief Exception thrown when the object is in the wrong state for the operation + /// \details this indicates that a member function was called in the wrong state, for example trying to encrypt + /// a message before having set the key or IV + class BadState : public Exception + { + public: + explicit BadState(const std::string &name, const char *message) : Exception(OTHER_ERROR, name + ": " + message) {} + explicit BadState(const std::string &name, const char *function, const char *state) : Exception(OTHER_ERROR, name + ": " + function + " was called before " + state) {} + }; + + /// \brief Provides the maximum length of AAD that can be input + /// \return the maximum length of AAD that can be input before the encrypted data + virtual lword MaxHeaderLength() const =0; + + /// \brief Provides the maximum length of encrypted data + /// \return the maximum length of encrypted data + virtual lword MaxMessageLength() const =0; + + /// \brief Provides the maximum length of AAD + /// \return the maximum length of AAD that can be input after the encrypted data + virtual lword MaxFooterLength() const {return 0;} + + /// \brief Determines if data lengths must be specified prior to inputting data + /// \return true if the data lengths are required before inputting data, false otherwise + /// \details if this function returns true, SpecifyDataLengths() must be called before attempting to input data. + /// This is the case for some schemes, such as CCM. + /// \sa SpecifyDataLengths() + virtual bool NeedsPrespecifiedDataLengths() const {return false;} + + /// \brief Prescribes the data lengths + /// \param headerLength size of data before message is input, in bytes + /// \param messageLength size of the message, in bytes + /// \param footerLength size of data after message is input, in bytes + /// \details SpecifyDataLengths() only needs to be called if NeedsPrespecifiedDataLengths() returns true. + /// If true, then headerLength will be validated against MaxHeaderLength(), + /// messageLength will be validated against MaxMessageLength(), and + /// footerLength will be validated against MaxFooterLength(). + /// \sa NeedsPrespecifiedDataLengths() + void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0); + + /// \brief Encrypts and calculates a MAC in one call + /// \param ciphertext the encryption buffer + /// \param mac the mac buffer + /// \param macSize the size of the MAC buffer, in bytes + /// \param iv the iv buffer + /// \param ivLength the size of the IV buffer, in bytes + /// \param header the AAD buffer + /// \param headerLength the size of the AAD buffer, in bytes + /// \param message the message buffer + /// \param messageLength the size of the messagetext buffer, in bytes + /// \details EncryptAndAuthenticate() encrypts and generates the MAC in one call. The function + /// truncates the MAC if macSize < TagSize(). + virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength); + + /// \brief Decrypts and verifies a MAC in one call + /// \param message the decryption buffer + /// \param mac the mac buffer + /// \param macSize the size of the MAC buffer, in bytes + /// \param iv the iv buffer + /// \param ivLength the size of the IV buffer, in bytes + /// \param header the AAD buffer + /// \param headerLength the size of the AAD buffer, in bytes + /// \param ciphertext the ciphertext buffer + /// \param ciphertextLength the size of the ciphertext buffer, in bytes + /// \return true if the MAC is valid and the decoding succeeded, false otherwise + /// \details DecryptAndVerify() decrypts and verifies the MAC in one call. + /// message is a decryption buffer and should be at least as large as the ciphertext buffer. + /// \details The function returns true iff MAC is valid. DecryptAndVerify() assumes the MAC + /// is truncated if macLength < TagSize(). + virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength); + + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like \a AES or \a AES/GCM. Some algorithms + /// do not have standard names yet. For example, there is no standard algorithm name for + /// Shoup's ECIES. + virtual std::string AlgorithmName() const; + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2". + /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics + /// instead of ASM. + /// \details Algorithms which combine different instructions or ISAs provide the + /// dominant one. For example on x86 AES/GCM returns "AESNI" rather than + /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". + /// \note Provider is not universally implemented yet. + /// \since Crypto++ 8.0 + virtual std::string AlgorithmProvider() const {return "C++";} + +protected: + const Algorithm & GetAlgorithm() const + {return *static_cast(this);} + virtual void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) + {CRYPTOPP_UNUSED(headerLength); CRYPTOPP_UNUSED(messageLength); CRYPTOPP_UNUSED(footerLength);} +}; + +/// \brief Interface for random number generators +/// \details The library provides a number of random number generators, from software based +/// to hardware based generators. +/// \details All generated values are uniformly distributed over the range specified. +/// \since Crypto++ 3.1 +/// \sa RandomNumberGenerator +/// on the Crypto++ wiki +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm +{ +public: + virtual ~RandomNumberGenerator() {} + + /// \brief Update RNG state with additional unpredictable values + /// \param input the entropy to add to the generator + /// \param length the size of the input buffer + /// \throw NotImplemented + /// \details A generator may or may not accept additional entropy. Call CanIncorporateEntropy() + /// to test for the ability to use additional entropy. + /// \details If a derived class does not override IncorporateEntropy(), then the base class + /// throws NotImplemented. + virtual void IncorporateEntropy(const byte *input, size_t length) + { + CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); + throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented"); + } + + /// \brief Determines if a generator can accept additional entropy + /// \return true if IncorporateEntropy() is implemented + virtual bool CanIncorporateEntropy() const {return false;} + + /// \brief Generate new random byte and return it + /// \return a random 8-bit byte + /// \details Default implementation calls GenerateBlock() with one byte. + /// \details All generated values are uniformly distributed over the range specified within the + /// the constraints of a particular generator. + virtual byte GenerateByte(); + + /// \brief Generate new random bit and return it + /// \return a random bit + /// \details The default implementation calls GenerateByte() and return its lowest bit. + /// \details All generated values are uniformly distributed over the range specified within the + /// the constraints of a particular generator. + virtual unsigned int GenerateBit(); + + /// \brief Generate a random 32 bit word in the range min to max, inclusive + /// \param min the lower bound of the range + /// \param max the upper bound of the range + /// \return a random 32-bit word + /// \details The default implementation calls Crop() on the difference between max and + /// min, and then returns the result added to min. + /// \details All generated values are uniformly distributed over the range specified within the + /// the constraints of a particular generator. + virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + /// \details All generated values are uniformly distributed over the range specified within the + /// the constraints of a particular generator. + /// \note A derived generator \a must override either GenerateBlock() or + /// GenerateIntoBufferedTransformation(). They can override both, or have one call the other. + virtual void GenerateBlock(byte *output, size_t size); + + /// \brief Generate random bytes into a BufferedTransformation + /// \param target the BufferedTransformation object which receives the bytes + /// \param channel the channel on which the bytes should be pumped + /// \param length the number of bytes to generate + /// \details The default implementation calls GenerateBlock() and pumps the result into + /// the DEFAULT_CHANNEL of the target. + /// \details All generated values are uniformly distributed over the range specified within the + /// the constraints of a particular generator. + /// \note A derived generator \a must override either GenerateBlock() or + /// GenerateIntoBufferedTransformation(). They can override both, or have one call the other. + virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length); + + /// \brief Generate and discard n bytes + /// \param n the number of bytes to generate and discard + virtual void DiscardBytes(size_t n); + + /// \brief Randomly shuffle the specified array + /// \param begin an iterator to the first element in the array + /// \param end an iterator beyond the last element in the array + /// \details The resulting permutation is uniformly distributed. + template void Shuffle(IT begin, IT end) + { + // TODO: What happens if there are more than 2^32 elements? + for (; begin != end; ++begin) + std::iter_swap(begin, begin + GenerateWord32(0, static_cast(end-begin-1))); + } +}; + +/// \brief Interface for key derivation functions +/// \since Crypto++ 7.0 +/// \sa KeyDerivationFunction +/// on the Crypto++ wiki +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyDerivationFunction : public Algorithm +{ +public: + virtual ~KeyDerivationFunction() {} + + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + virtual std::string AlgorithmName() const =0; + + /// \brief Determine minimum number of bytes + /// \return Minimum number of bytes which can be derived + virtual size_t MinDerivedKeyLength() const; + + /// \brief Determine maximum number of bytes + /// \return Maximum number of bytes which can be derived + virtual size_t MaxDerivedKeyLength() const; + + /// \brief Returns a valid key length for the derivation function + /// \param keylength the size of the derived key, in bytes + /// \return the valid key length, in bytes + virtual size_t GetValidDerivedLength(size_t keylength) const =0; + + /// \brief Returns whether keylength is a valid key length + /// \param keylength the requested keylength + /// \return true if the derived keylength is valid, false otherwise + /// \details Internally the function calls GetValidKeyLength() + virtual bool IsValidDerivedLength(size_t keylength) const { + return keylength == GetValidDerivedLength(keylength); + } + + /// \brief Derive a key from a seed + /// \param derived the derived output buffer + /// \param derivedLen the size of the derived buffer, in bytes + /// \param secret the seed input buffer + /// \param secretLen the size of the secret buffer, in bytes + /// \param params additional initialization parameters to configure this object + /// \return the number of iterations performed + /// \throw InvalidDerivedKeyLength if derivedLen is invalid for the scheme + /// \details DeriveKey() provides a standard interface to derive a key from + /// a secret seed and other parameters. Each class that derives from KeyDerivationFunction + /// provides an overload that accepts most parameters used by the derivation function. + /// \details the number of iterations performed by DeriveKey() may be 1. For example, a + /// scheme like HKDF does not use the iteration count so it returns 1. + virtual size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const NameValuePairs& params = g_nullNameValuePairs) const =0; + + /// \brief Set or change parameters + /// \param params additional initialization parameters to configure this object + /// \details SetParameters() is useful for setting common parameters when an object is + /// reused. Some derivation function classes may choose to implement it. + virtual void SetParameters(const NameValuePairs& params); + +protected: + /// \brief Returns the base class Algorithm + /// \return the base class Algorithm + virtual const Algorithm & GetAlgorithm() const =0; + + /// \brief Validates the derived key length + /// \param length the size of the derived key material, in bytes + /// \throw InvalidKeyLength if the key length is invalid + void ThrowIfInvalidDerivedKeyLength(size_t length) const; +}; + +/// \brief Interface for password based key derivation functions +/// \since Crypto++ 7.0 +struct PasswordBasedKeyDerivationFunction : public KeyDerivationFunction +{ +}; + +/// \brief Random Number Generator that does not produce random numbers +/// \return reference that can be passed to functions that require a RandomNumberGenerator +/// \details NullRNG() returns a reference that can be passed to functions that require a +/// RandomNumberGenerator but don't actually use it. The NullRNG() throws NotImplemented +/// when a generation function is called. +/// \sa ClassNullRNG, PK_SignatureScheme::IsProbabilistic() +CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG(); + +class WaitObjectContainer; +class CallStack; + +/// \brief Interface for objects that can be waited on. +class CRYPTOPP_NO_VTABLE Waitable +{ +public: + virtual ~Waitable() {} + + /// \brief Maximum number of wait objects that this object can return + /// \return the maximum number of wait objects + virtual unsigned int GetMaxWaitObjectCount() const =0; + + /// \brief Retrieves waitable objects + /// \param container the wait container to receive the references to the objects. + /// \param callStack CallStack() object used to select waitable objects + /// \details GetWaitObjects() is usually called in one of two ways. First, it can + /// be called like something.GetWaitObjects(c, CallStack("my func after X", 0));. + /// Second, if in an outer GetWaitObjects() method that itself takes a callStack + /// parameter, it can be called like + /// innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack));. + virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0; + + /// \brief Wait on this object + /// \return true if the wait succeeded, false otherwise + /// \details Wait() is the same as creating an empty container, calling GetWaitObjects(), and then calling + /// Wait() on the container. + bool Wait(unsigned long milliseconds, CallStack const& callStack); +}; + +/// \brief Interface for buffered transformations +/// \details BufferedTransformation is a generalization of BlockTransformation, +/// StreamTransformation and HashTransformation. +/// \details A buffered transformation is an object that takes a stream of bytes as input (this may +/// be done in stages), does some computation on them, and then places the result into an internal +/// buffer for later retrieval. Any partial result already in the output buffer is not modified +/// by further input. +/// \details If a method takes a "blocking" parameter, and you pass false for it, then the method +/// will return before all input has been processed if the input cannot be processed without waiting +/// (for network buffers to become available, for example). In this case the method will return true +/// or a non-zero integer value. When this happens you must continue to call the method with the same +/// parameters until it returns false or zero, before calling any other method on it or attached +/// BufferedTransformation. The integer return value in this case is approximately +/// the number of bytes left to be processed, and can be used to implement a progress bar. +/// \details For functions that take a "propagation" parameter, propagation != 0 means pass on +/// the signal to attached BufferedTransformation objects, with propagation decremented at each +/// step until it reaches 0. -1 means unlimited propagation. +/// \details \a All of the retrieval functions, like Get() and GetWord32(), return the actual +/// number of bytes retrieved, which is the lesser of the request number and MaxRetrievable(). +/// \details \a Most of the input functions, like Put() and PutWord32(), return the number of +/// bytes remaining to be processed. A 0 value means all bytes were processed, and a non-0 value +/// means bytes remain to be processed. +/// \nosubgrouping +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable +{ +public: + virtual ~BufferedTransformation() {} + + /// \brief Construct a BufferedTransformation + BufferedTransformation() : Algorithm(false) {} + + /// \brief Provides a reference to this object + /// \return A reference to this object + /// \details Useful for passing a temporary object to a function that takes a non-const reference + BufferedTransformation& Ref() {return *this;} + + /// \name INPUT + //@{ + + /// \brief Input a byte for processing + /// \param inByte the 8-bit byte (octet) to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + /// \details Put(byte) calls Put(byte*, size_t). + size_t Put(byte inByte, bool blocking=true) + {return Put(&inByte, 1, blocking);} + + /// \brief Input a byte buffer for processing + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + /// \details Internally, Put() calls Put2(). + size_t Put(const byte *inString, size_t length, bool blocking=true) + {return Put2(inString, length, 0, blocking);} + + /// Input a 16-bit word for processing. + /// \param value the 16-bit value to be processed + /// \param order the ByteOrder of the value to be processed. + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + /// Input a 32-bit word for processing. + /// \param value the 32-bit value to be processed. + /// \param order the ByteOrder of the value to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + /// Input a 64-bit word for processing. + /// \param value the 64-bit value to be processed. + /// \param order the ByteOrder of the value to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + size_t PutWord64(word64 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + /// \brief Request space which can be written into by the caller + /// \param size the requested size of the buffer + /// \return byte pointer to the space to input data + /// \details The purpose of this method is to help avoid extra memory allocations. + /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, + /// size is the requested size of the buffer. When the call returns, size is the size of + /// the array returned to the caller. + /// \details The base class implementation sets size to 0 and returns NULL. + /// \note Some objects, like ArraySink, cannot create a space because its fixed. In the case of + /// an ArraySink, the pointer to the array is returned and the size is remaining size. + virtual byte * CreatePutSpace(size_t &size) + {size=0; return NULLPTR;} + + /// \brief Determines whether input can be modified by the callee + /// \return true if input can be modified, false otherwise + /// \details The base class implementation returns false. + virtual bool CanModifyInput() const + {return false;} + + /// \brief Input multiple bytes that may be modified by callee. + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). 0 indicates all + /// bytes were processed. + size_t PutModifiable(byte *inString, size_t length, bool blocking=true) + {return PutModifiable2(inString, length, 0, blocking);} + + /// \brief Signals the end of messages to the object + /// \param propagation the number of attached transformations the MessageEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + bool MessageEnd(int propagation=-1, bool blocking=true) + {return !!Put2(NULLPTR, 0, propagation < 0 ? -1 : propagation+1, blocking);} + + /// \brief Input multiple bytes for processing and signal the end of a message + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param propagation the number of attached transformations the MessageEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). 0 indicates all + /// bytes were processed. + /// \details Internally, PutMessageEnd() calls Put2() with a modified propagation to + /// ensure all attached transformations finish processing the message. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true) + {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);} + + /// \brief Input multiple bytes for processing + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). 0 indicates all + /// bytes were processed. + /// \details Derived classes must implement Put2(). + virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0; + + /// \brief Input multiple bytes that may be modified by callee. + /// \param inString the byte buffer to process. + /// \param length the size of the string, in bytes. + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). 0 indicates all + /// bytes were processed. + /// \details Internally, PutModifiable2() calls Put2(). + virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) + {return Put2(inString, length, messageEnd, blocking);} + + /// \brief Exception thrown by objects that have \a not implemented nonblocking input processing + /// \details BlockingInputOnly inherits from NotImplemented + struct BlockingInputOnly : public NotImplemented + {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}}; + //@} + + /// \name WAITING + //@{ + /// \brief Retrieves the maximum number of waitable objects + unsigned int GetMaxWaitObjectCount() const; + + /// \brief Retrieves waitable objects + /// \param container the wait container to receive the references to the objects + /// \param callStack CallStack() object used to select waitable objects + /// \details GetWaitObjects is usually called in one of two ways. First, it can + /// be called like something.GetWaitObjects(c, CallStack("my func after X", 0));. + /// Second, if in an outer GetWaitObjects() method that itself takes a callStack + /// parameter, it can be called like + /// innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack));. + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + //@} // WAITING + + /// \name SIGNALS + //@{ + + /// \brief Initialize or reinitialize this object, without signal propagation + /// \param parameters a set of NameValuePairs to initialize this object + /// \throw NotImplemented + /// \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable + /// number of arbitrarily typed arguments. The function avoids the need for multiple constructors providing + /// all possible combintations of configurable parameters. + /// \details IsolatedInitialize() does not call Initialize() on attached transformations. If initialization + /// should be propagated, then use the Initialize() function. + /// \details If a derived class does not override IsolatedInitialize(), then the base class throws + /// NotImplemented. + virtual void IsolatedInitialize(const NameValuePairs ¶meters) { + CRYPTOPP_UNUSED(parameters); + throw NotImplemented("BufferedTransformation: this object can't be reinitialized"); + } + + /// \brief Flushes data buffered by this object, without signal propagation + /// \param hardFlush indicates whether all data should be flushed + /// \param blocking specifies whether the object should block when processing input + /// \return true if the flush was successful, false otherwise + /// \note hardFlush must be used with care + virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0; + + /// \brief Marks the end of a series of messages, without signal propagation + /// \param blocking specifies whether the object should block when completing the processing on + /// the current series of messages + /// \return true if the message was successful, false otherwise + virtual bool IsolatedMessageSeriesEnd(bool blocking) + {CRYPTOPP_UNUSED(blocking); return false;} + + /// \brief Initialize or reinitialize this object, with signal propagation + /// \param parameters a set of NameValuePairs to initialize or reinitialize this object + /// \param propagation the number of attached transformations the Initialize() signal should be passed + /// \details Initialize() is used to initialize or reinitialize an object using a variable number of + /// arbitrarily typed arguments. The function avoids the need for multiple constructors providing + /// all possible combintations of configurable parameters. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); + + /// \brief Flush buffered input and/or output, with signal propagation + /// \param hardFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the Flush() + /// signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true if the flush was successful, false otherwise + /// \details propagation count includes this object. Setting propagation to + /// 1 means this object only. Setting propagation to -1 + /// means unlimited propagation. + /// \note Hard flushes must be used with care. It means try to process and + /// output everything, even if there may not be enough data to complete the + /// action. For example, hard flushing a HexDecoder would cause an error if + /// you do it after inputing an odd number of hex encoded characters. + /// \note For some types of filters, like ZlibDecompressor, hard flushes can + /// only be done at "synchronization points". These synchronization points + /// are positions in the data stream that are created by hard flushes on the + /// corresponding reverse filters, in this example ZlibCompressor. This is + /// useful when zlib compressed data is moved across a network in packets + /// and compression state is preserved across packets, as in the SSH2 protocol. + virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); + + /// \brief Marks the end of a series of messages, with signal propagation + /// \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true if the message was successful, false otherwise + /// \details Each object that receives the signal will perform its processing, decrement + /// propagation, and then pass the signal on to attached transformations if the value is not 0. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note There should be a MessageEnd() immediately before MessageSeriesEnd(). + virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true); + + /// \brief Set propagation of automatically generated and transferred signals + /// \param propagation then new value + /// \details Setting propagation to 0 means do not automatically generate signals. Setting + /// propagation to -1 means unlimited propagation. + virtual void SetAutoSignalPropagation(int propagation) + {CRYPTOPP_UNUSED(propagation);} + + /// \brief Retrieve automatic signal propagation value + /// \return the number of attached transformations the signal is propagated to. 0 indicates + /// the signal is only witnessed by this object + virtual int GetAutoSignalPropagation() const {return 0;} +public: + + /// \name RETRIEVAL OF ONE MESSAGE + //@{ + + /// \brief Provides the number of bytes ready for retrieval + /// \return the number of bytes ready for retrieval + /// \details The number of bytes available are dependent on the source. If an exact value is + /// available, then the exact value is returned. The exact value can include 0 if the source + /// is exhausted. + /// \details Some stream-based sources do not allow seeking() on the underlying stream, such + /// as some FileSource(). If the stream does not allow seeking() then MaxRetrievable() + /// returns LWORD_MAX to indicate there are still bytes to be retrieved. + virtual lword MaxRetrievable() const; + + /// \brief Determines whether bytes are ready for retrieval + /// \return true if bytes are available for retrieval, false otherwise + virtual bool AnyRetrievable() const; + + /// \brief Retrieve a 8-bit byte + /// \param outByte the 8-bit value to be retrieved + /// \return the number of bytes consumed during the call. + /// \details Use the return value of Get to detect short reads. + virtual size_t Get(byte &outByte); + + /// \brief Retrieve a block of bytes + /// \param outString a block of bytes + /// \param getMax the number of bytes to Get + /// \return the number of bytes consumed during the call. + /// \details Use the return value of Get to detect short reads. + virtual size_t Get(byte *outString, size_t getMax); + + /// \brief Peek a 8-bit byte + /// \param outByte the 8-bit value to be retrieved + /// \return the number of bytes read during the call. + /// \details Peek does not remove bytes from the object. Use the return value of + /// Get() to detect short reads. + virtual size_t Peek(byte &outByte) const; + + /// \brief Peek a block of bytes + /// \param outString a block of bytes + /// \param peekMax the number of bytes to Peek + /// \return the number of bytes read during the call. + /// \details Peek does not remove bytes from the object. Use the return value of + /// Peek() to detect short reads. + virtual size_t Peek(byte *outString, size_t peekMax) const; + + /// \brief Retrieve a 16-bit word + /// \param value the 16-bit value to be retrieved + /// \param order the ByteOrder of the value to be processed. + /// \return the number of bytes consumed during the call. + /// \details Use the return value of GetWord16() to detect short reads. + size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER); + + /// \brief Retrieve a 32-bit word + /// \param value the 32-bit value to be retrieved + /// \param order the ByteOrder of the value to be processed. + /// \return the number of bytes consumed during the call. + /// \details Use the return value of GetWord32() to detect short reads. + size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); + + /// \brief Retrieve a 64-bit word + /// \param value the 64-bit value to be retrieved + /// \param order the ByteOrder of the value to be processed. + /// \return the number of bytes consumed during the call. + /// \details Use the return value of GetWord64() to detect short reads. + /// \since Crypto++ 8.3 + size_t GetWord64(word64 &value, ByteOrder order=BIG_ENDIAN_ORDER); + + /// \brief Peek a 16-bit word + /// \param value the 16-bit value to be retrieved + /// \param order the ByteOrder of the value to be processed. + /// \return the number of bytes consumed during the call. + /// \details Peek does not consume bytes in the stream. Use the return value + /// of PeekWord16() to detect short reads. + size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; + + /// \brief Peek a 32-bit word + /// \param value the 32-bit value to be retrieved + /// \param order the ByteOrder of the value to be processed. + /// \return the number of bytes consumed during the call. + /// \details Peek does not consume bytes in the stream. Use the return value + /// of PeekWord32() to detect short reads. + size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; + + /// \brief Peek a 64-bit word + /// \param value the 64-bit value to be retrieved + /// \param order the ByteOrder of the value to be processed. + /// \return the number of bytes consumed during the call. + /// \details Peek does not consume bytes in the stream. Use the return value + /// of PeekWord64() to detect short reads. + /// \since Crypto++ 8.3 + size_t PeekWord64(word64 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; + + /// move transferMax bytes of the buffered output to target as input + + /// \brief Transfer bytes from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param transferMax the number of bytes to transfer + /// \param channel the channel on which the transfer should occur + /// \return the number of bytes transferred during the call. + /// \details TransferTo removes bytes from this object and moves them to the destination. + /// \details The function always returns transferMax. If an accurate count is needed, then use TransferTo2(). + lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) + {TransferTo2(target, transferMax, channel); return transferMax;} + + /// \brief Discard skipMax bytes from the output buffer + /// \param skipMax the number of bytes to discard + /// \details Skip() discards bytes from the output buffer, which is the AttachedTransformation(), if present. + /// The function always returns the parameter skipMax. + /// \details If you want to skip bytes from a Source, then perform the following. + ///
  StringSource ss(str, false, new Redirector(TheBitBucket()));
+		///   ss.Pump(10);    // Skip 10 bytes from Source
+		///   ss.Detach(new FilterChain(...));
+		///   ss.PumpAll();
+		/// 
+ virtual lword Skip(lword skipMax=LWORD_MAX); + + /// \brief Copy bytes from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param copyMax the number of bytes to copy + /// \param channel the channel on which the transfer should occur + /// \return the number of bytes copied during the call. + /// \details CopyTo copies bytes from this object to the destination. The bytes are not removed from this object. + /// \details The function always returns copyMax. If an accurate count is needed, then use CopyRangeTo2(). + lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const + {return CopyRangeTo(target, 0, copyMax, channel);} + + /// \brief Copy bytes from this object using an index to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param position the 0-based index of the byte stream to begin the copying + /// \param copyMax the number of bytes to copy + /// \param channel the channel on which the transfer should occur + /// \return the number of bytes copied during the call. + /// \details CopyTo copies bytes from this object to the destination. The bytes remain in this + /// object. Copying begins at the index position in the current stream, and not from an absolute + /// position in the stream. + /// \details The function returns the new position in the stream after transferring the bytes starting at the index. + lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const + {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;} + //@} + + /// \name RETRIEVAL OF MULTIPLE MESSAGES + //@{ + + /// \brief Provides the number of bytes ready for retrieval + /// \return the number of bytes ready for retrieval + virtual lword TotalBytesRetrievable() const; + + /// \brief Provides the number of meesages processed by this object + /// \return the number of meesages processed by this object + /// \details NumberOfMessages returns number of times MessageEnd() has been + /// received minus messages retrieved or skipped + virtual unsigned int NumberOfMessages() const; + + /// \brief Determines if any messages are available for retrieval + /// \return true if NumberOfMessages() > 0, false otherwise + /// \details AnyMessages returns true if NumberOfMessages() > 0 + virtual bool AnyMessages() const; + + /// \brief Start retrieving the next message + /// \return true if a message is ready for retrieval + /// \details GetNextMessage() returns true if a message is ready for retrieval; false + /// if no more messages exist or this message is not completely retrieved. + virtual bool GetNextMessage(); + + /// \brief Skip a number of meessages + /// \param count number of messages to skip + /// \return 0 if the requested number of messages was skipped, non-0 otherwise + /// \details SkipMessages() skips count number of messages. If there is an AttachedTransformation() + /// then SkipMessages() is called on the attached transformation. If there is no attached + /// transformation, then count number of messages are sent to TheBitBucket() using TransferMessagesTo(). + virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); + + /// \brief Transfer messages from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param count the number of messages to transfer + /// \param channel the channel on which the transfer should occur + /// \return the number of bytes that remain in the current transfer block (i.e., bytes not transferred) + /// \details TransferMessagesTo2() removes messages from this object and moves them to the destination. + /// If all bytes are not transferred for a message, then processing stops and the number of remaining + /// bytes is returned. TransferMessagesTo() does not proceed to the next message. + /// \details A return value of 0 indicates all messages were successfully transferred. + unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) + {TransferMessagesTo2(target, count, channel); return count;} + + /// \brief Copy messages from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param count the number of messages to copy + /// \param channel the channel on which the copy should occur + /// \return the number of bytes that remain in the current transfer block (i.e., bytes not transferred) + /// \details CopyMessagesTo copies messages from this object to the destination. + /// If all bytes are not transferred for a message, then processing stops and the number of remaining + /// bytes is returned. CopyMessagesTo() does not proceed to the next message. + /// \details A return value of 0 indicates all messages were successfully copied. + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; + + /// \brief Skip all messages in the series + virtual void SkipAll(); + + /// \brief Transfer all bytes from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param channel the channel on which the transfer should occur + /// \details TransferMessagesTo2() removes messages from this object and moves them to the destination. + /// Internally TransferAllTo() calls TransferAllTo2(). + void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) + {TransferAllTo2(target, channel);} + + /// \brief Copy messages from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param channel the channel on which the transfer should occur + /// \details CopyAllTo copies messages from this object and copies them to the destination. + void CopyAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const; + + /// \brief Retrieve the next message in a series + /// \return true if a message was retreved, false otherwise + /// \details Internally, the base class implementation returns false. + virtual bool GetNextMessageSeries() {return false;} + /// \brief Provides the number of messages in a series + /// \return the number of messages in this series + virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();} + /// \brief Provides the number of messages in a series + /// \return the number of messages in this series + virtual unsigned int NumberOfMessageSeries() const {return 0;} + //@} + + /// \name NON-BLOCKING TRANSFER OF OUTPUT + //@{ + + // upon return, byteCount contains number of bytes that have finished being transferred, + // and returns the number of bytes left in the current transfer block + + /// \brief Transfer bytes from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param byteCount the number of bytes to transfer + /// \param channel the channel on which the transfer should occur + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain in the transfer block (i.e., bytes not transferred) + /// \details TransferTo2() removes bytes from this object and moves them to the destination. + /// Transfer begins at the index position in the current stream, and not from an absolute + /// position in the stream. + /// \details byteCount is an \a IN and \a OUT parameter. When the call is made, + /// byteCount is the requested size of the transfer. When the call returns, byteCount is + /// the number of bytes that were transferred. + virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0; + + // upon return, begin contains the start position of data yet to be finished copying, + // and returns the number of bytes left in the current transfer block + + /// \brief Copy bytes from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param begin the 0-based index of the first byte to copy in the stream + /// \param end the 0-based index of the last byte to copy in the stream + /// \param channel the channel on which the transfer should occur + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain in the copy block (i.e., bytes not copied) + /// \details CopyRangeTo2 copies bytes from this object to the destination. The bytes are not + /// removed from this object. Copying begins at the index position in the current stream, and + /// not from an absolute position in the stream. + /// \details begin is an \a IN and \a OUT parameter. When the call is made, begin is the + /// starting position of the copy. When the call returns, begin is the position of the first + /// byte that was \a not copied (which may be different than end). begin can be used for + /// subsequent calls to CopyRangeTo2(). + virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0; + + // upon return, messageCount contains number of messages that have finished being transferred, + // and returns the number of bytes left in the current transfer block + + /// \brief Transfer messages from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param messageCount the number of messages to transfer + /// \param channel the channel on which the transfer should occur + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain in the current transfer block (i.e., bytes not transferred) + /// \details TransferMessagesTo2() removes messages from this object and moves them to the destination. + /// \details messageCount is an \a IN and \a OUT parameter. When the call is made, messageCount is the + /// the number of messages requested to be transferred. When the call returns, messageCount is the + /// number of messages actually transferred. + size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + + // returns the number of bytes left in the current transfer block + + /// \brief Transfer all bytes from this object to another BufferedTransformation + /// \param target the destination BufferedTransformation + /// \param channel the channel on which the transfer should occur + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain in the current transfer block (i.e., bytes not transferred) + /// \details TransferMessagesTo2() removes messages from this object and moves them to the destination. + size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + //@} + + /// \name CHANNELS + //@{ + /// \brief Exception thrown when a filter does not support named channels + struct NoChannelSupport : public NotImplemented + {NoChannelSupport(const std::string &name) : NotImplemented(name + ": this object doesn't support multiple channels") {}}; + /// \brief Exception thrown when a filter does not recognize a named channel + struct InvalidChannelName : public InvalidArgument + {InvalidChannelName(const std::string &name, const std::string &channel) : InvalidArgument(name + ": unexpected channel name \"" + channel + "\"") {}}; + + /// \brief Input a byte for processing on a channel + /// \param channel the channel to process the data. + /// \param inByte the 8-bit byte (octet) to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true) + {return ChannelPut(channel, &inByte, 1, blocking);} + + /// \brief Input a byte buffer for processing on a channel + /// \param channel the channel to process the data + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param blocking specifies whether the object should block when processing input + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true) + {return ChannelPut2(channel, inString, length, 0, blocking);} + + /// \brief Input multiple bytes that may be modified by callee on a channel + /// \param channel the channel to process the data. + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param blocking specifies whether the object should block when processing input + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true) + {return ChannelPutModifiable2(channel, inString, length, 0, blocking);} + + /// \brief Input a 16-bit word for processing on a channel. + /// \param channel the channel to process the data. + /// \param value the 16-bit value to be processed. + /// \param order the ByteOrder of the value to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + /// \brief Input a 32-bit word for processing on a channel. + /// \param channel the channel to process the data. + /// \param value the 32-bit value to be processed. + /// \param order the ByteOrder of the value to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + /// \brief Input a 64-bit word for processing on a channel. + /// \param channel the channel to process the data. + /// \param value the 64-bit value to be processed. + /// \param order the ByteOrder of the value to be processed. + /// \param blocking specifies whether the object should block when processing input. + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + size_t ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + /// \brief Signal the end of a message + /// \param channel the channel to process the data. + /// \param propagation the number of attached transformations the ChannelMessageEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return 0 indicates all bytes were processed during the call. Non-0 indicates the + /// number of bytes that were not processed. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true) + {return !!ChannelPut2(channel, NULLPTR, 0, propagation < 0 ? -1 : propagation+1, blocking);} + + /// \brief Input multiple bytes for processing and signal the end of a message + /// \param channel the channel to process the data. + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param propagation the number of attached transformations the ChannelPutMessageEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true) + {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);} + + /// \brief Request space which can be written into by the caller + /// \param channel the channel to process the data + /// \param size the requested size of the buffer + /// \return a pointer to a memory block with length size + /// \details The purpose of this method is to help avoid extra memory allocations. + /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, + /// size is the requested size of the buffer. When the call returns, size is the size of + /// the array returned to the caller. + /// \details The base class implementation sets size to 0 and returns NULL. + /// \note Some objects, like ArraySink(), cannot create a space because its fixed. In the case of + /// an ArraySink(), the pointer to the array is returned and the size is remaining size. + virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); + + /// \brief Input multiple bytes for processing on a channel. + /// \param channel the channel to process the data. + /// \param inString the byte buffer to process. + /// \param length the size of the string, in bytes. + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + virtual size_t ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking); + + /// \brief Input multiple bytes that may be modified by callee on a channel + /// \param channel the channel to process the data + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + virtual size_t ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking); + + /// \brief Flush buffered input and/or output on a channel + /// \param channel the channel to flush the data + /// \param hardFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the ChannelFlush() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true of the Flush was successful + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true); + + /// \brief Marks the end of a series of messages on a channel + /// \param channel the channel to signal the end of a series of messages + /// \param propagation the number of attached transformations the ChannelMessageSeriesEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true if the message was successful, false otherwise + /// \details Each object that receives the signal will perform its processing, decrement + /// propagation, and then pass the signal on to attached transformations if the value is not 0. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note There should be a MessageEnd() immediately before MessageSeriesEnd(). + virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); + + /// \brief Sets the default retrieval channel + /// \param channel the channel to signal the end of a series of messages + /// \note this function may not be implemented in all objects that should support it. + virtual void SetRetrievalChannel(const std::string &channel); + //@} + + /// \name ATTACHMENT + /// \details Some BufferedTransformation objects (e.g. Filter objects) allow other BufferedTransformation objects to be + /// attached. When this is done, the first object instead of buffering its output, sends that output to the attached + /// object as input. The entire attachment chain is deleted when the anchor object is destructed. + + //@{ + /// \brief Determines whether the object allows attachment + /// \return true if the object allows an attachment, false otherwise + /// \details Sources and Filters will returns true, while Sinks and other objects will return false. + virtual bool Attachable() {return false;} + + /// \brief Returns the object immediately attached to this object + /// \return the attached transformation + /// \details AttachedTransformation() returns NULL if there is no attachment. The non-const + /// version of AttachedTransformation() always returns NULL. + virtual BufferedTransformation *AttachedTransformation() {CRYPTOPP_ASSERT(!Attachable()); return NULLPTR;} + + /// \brief Returns the object immediately attached to this object + /// \return the attached transformation + /// \details AttachedTransformation() returns NULL if there is no attachment. The non-const + /// version of AttachedTransformation() always returns NULL. + virtual const BufferedTransformation *AttachedTransformation() const + {return const_cast(this)->AttachedTransformation();} + + /// \brief Delete the current attachment chain and attach a new one + /// \param newAttachment the new BufferedTransformation to attach + /// \throw NotImplemented + /// \details Detach() deletes the current attachment chain and replace it with an optional newAttachment + /// \details If a derived class does not override Detach(), then the base class throws + /// NotImplemented. + virtual void Detach(BufferedTransformation *newAttachment = NULLPTR) { + CRYPTOPP_UNUSED(newAttachment); CRYPTOPP_ASSERT(!Attachable()); + throw NotImplemented("BufferedTransformation: this object is not attachable"); + } + + /// \brief Add newAttachment to the end of attachment chain + /// \param newAttachment the attachment to add to the end of the chain + virtual void Attach(BufferedTransformation *newAttachment); + //@} + +protected: + /// \brief Decrements the propagation count while clamping at 0 + /// \return the decremented propagation or 0 + static int DecrementPropagation(int propagation) + {return propagation != 0 ? propagation - 1 : 0;} + +private: + // for ChannelPutWord16, ChannelPutWord32 and ChannelPutWord64, + // to ensure the buffer isn't deallocated before non-blocking + // operation completes + byte m_buf[8]; +}; + +/// \brief An input discarding BufferedTransformation +/// \return a reference to a BufferedTransformation object that discards all input +CRYPTOPP_DLL BufferedTransformation & TheBitBucket(); + +/// \brief Interface for crypto material +/// \details CryptoMaterial() is an interface for crypto material, such as +/// public keys, private keys and crypto parameters. Derived classes generally +/// do not offer public methods such as GenerateRandom() and +/// GenerateRandomWithKeySize(). +/// \sa GeneratableCryptoMaterial() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs +{ +public: + /// Exception thrown when invalid crypto material is detected + class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat + { + public: + explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {} + }; + + virtual ~CryptoMaterial() {} + + /// \brief Assign values to this object + /// \details This function can be used to create a public key from a private key. + virtual void AssignFrom(const NameValuePairs &source) =0; + + /// \brief Check this object for errors + /// \param rng a RandomNumberGenerator for objects which use randomized testing + /// \param level the level of thoroughness + /// \return true if the tests succeed, false otherwise + /// \details There are four levels of thoroughness: + ///
    + ///
  • 0 - using this object won't cause a crash or exception + ///
  • 1 - this object will probably function, and encrypt, sign, other operations correctly + ///
  • 2 - ensure this object will function correctly, and perform reasonable security checks + ///
  • 3 - perform reasonable security checks, and do checks that may take a long time + ///
+ /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0. + /// Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended. + /// \sa ThrowIfInvalid() + virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0; + + /// \brief Check this object for errors + /// \param rng a RandomNumberGenerator for objects which use randomized testing + /// \param level the level of thoroughness + /// \throw InvalidMaterial + /// \details Internally, ThrowIfInvalid() calls Validate() and throws InvalidMaterial() if validation fails. + /// \sa Validate() + virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const + {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");} + + /// \brief Saves a key to a BufferedTransformation + /// \param bt the destination BufferedTransformation + /// \throw NotImplemented + /// \details Save() writes the material to a BufferedTransformation. + /// \details If the material is a key, then the key is written with ASN.1 DER encoding. The key + /// includes an object identifier with an algorthm id, like a subjectPublicKeyInfo. + /// \details A "raw" key without the "key info" can be saved using a key's DEREncode() method. + /// \details If a derived class does not override Save(), then the base class throws + /// NotImplemented(). + virtual void Save(BufferedTransformation &bt) const + {CRYPTOPP_UNUSED(bt); throw NotImplemented("CryptoMaterial: this object does not support saving");} + + /// \brief Loads a key from a BufferedTransformation + /// \param bt the source BufferedTransformation + /// \throw KeyingErr + /// \details Load() attempts to read material from a BufferedTransformation. If the + /// material is a key that was generated outside the library, then the following + /// usually applies: + ///
    + ///
  • the key should be ASN.1 BER encoded + ///
  • the key should be a "key info" + ///
+ /// \details "key info" means the key should have an object identifier with an algorthm id, + /// like a subjectPublicKeyInfo. + /// \details To read a "raw" key without the "key info", then call the key's BERDecode() method. + /// \note Load() generally does not check that the key is valid. Call Validate(), if needed. + virtual void Load(BufferedTransformation &bt) + {CRYPTOPP_UNUSED(bt); throw NotImplemented("CryptoMaterial: this object does not support loading");} + + /// \brief Determines whether the object supports precomputation + /// \return true if the object supports precomputation, false otherwise + /// \sa Precompute() + virtual bool SupportsPrecomputation() const {return false;} + + /// \brief Perform precomputation + /// \param precomputationStorage the suggested number of objects for the precompute table + /// \throw NotImplemented + /// \details The exact semantics of Precompute() varies, but it typically means calculate + /// a table of n objects that can be used later to speed up computation. + /// \details If a derived class does not override Precompute(), then the base class throws + /// NotImplemented. + /// \sa SupportsPrecomputation(), LoadPrecomputation(), SavePrecomputation() + virtual void Precompute(unsigned int precomputationStorage) { + CRYPTOPP_UNUSED(precomputationStorage); CRYPTOPP_ASSERT(!SupportsPrecomputation()); + throw NotImplemented("CryptoMaterial: this object does not support precomputation"); + } + + /// \brief Retrieve previously saved precomputation + /// \param storedPrecomputation BufferedTransformation with the saved precomputation + /// \throw NotImplemented + /// \sa SupportsPrecomputation(), Precompute() + virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + {CRYPTOPP_UNUSED(storedPrecomputation); CRYPTOPP_ASSERT(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} + + /// \brief Save precomputation for later use + /// \param storedPrecomputation BufferedTransformation to write the precomputation + /// \throw NotImplemented + /// \sa SupportsPrecomputation(), Precompute() + virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + {CRYPTOPP_UNUSED(storedPrecomputation); CRYPTOPP_ASSERT(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} + + /// \brief Perform a quick sanity check + /// \details DoQuickSanityCheck() is for internal library use, and it should not be called by library users. + void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);} + +#if defined(__SUNPRO_CC) + // Sun Studio 11/CC 5.8 workaround: it generates incorrect code + // when casting to an empty virtual base class. JW, 2018: It is + // still a problem in Sun Studio 12.6/CC 5.15 on i386. Just enable + // it everywhere in case it affects SPARC (which we don't test). + char m_sunCCworkaround; +#endif +}; + +/// \brief Interface for crypto material +/// \details GeneratableCryptoMaterial() is an interface for crypto material, +/// such as private keys and crypto parameters. Derived classes offer public +/// methods such as GenerateRandom() and GenerateRandomWithKeySize(). +/// \sa CryptoMaterial() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial +{ +public: + virtual ~GeneratableCryptoMaterial() {} + + /// \brief Generate a random key or crypto parameters + /// \param rng a RandomNumberGenerator to produce keying material + /// \param params additional initialization parameters + /// \throw KeyingErr if a key can't be generated or algorithm parameters are invalid + /// \details If a derived class does not override GenerateRandom(), then the base class throws + /// NotImplemented. + virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) { + CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(params); + throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation"); + } + + /// \brief Generate a random key or crypto parameters + /// \param rng a RandomNumberGenerator to produce keying material + /// \param keySize the size of the key, in bits + /// \throw KeyingErr if a key can't be generated or algorithm parameters are invalid + /// \details GenerateRandomWithKeySize calls GenerateRandom() with a NameValuePairs + /// object with only "KeySize" + void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize); +}; + +/// \brief Interface for public keys +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial +{ +}; + +/// \brief Interface for private keys +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial +{ +}; + +/// \brief Interface for crypto prameters +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial +{ +}; + +/// \brief Interface for certificates +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Certificate : virtual public CryptoMaterial +{ +}; + +/// \brief Interface for asymmetric algorithms +/// \details BERDecode() and DEREncode() were removed under Issue 569 +/// and Commit 9b174e84de7a. Programs should use AccessMaterial().Load(bt) +/// or GetMaterial().Save(bt) instead. +/// \sa Issue 569 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm +{ +public: + virtual ~AsymmetricAlgorithm() {} + + /// \brief Retrieves a reference to CryptoMaterial + /// \return a reference to the crypto material + virtual CryptoMaterial & AccessMaterial() =0; + + /// \brief Retrieves a reference to CryptoMaterial + /// \return a const reference to the crypto material + virtual const CryptoMaterial & GetMaterial() const =0; + +#if 0 + /// \brief Loads this object from a BufferedTransformation + /// \param bt a BufferedTransformation object + /// \details Use of BERDecode() changed to Load() at Issue 569. + /// \deprecated for backwards compatibility, calls AccessMaterial().Load(bt) + void BERDecode(BufferedTransformation &bt) + {AccessMaterial().Load(bt);} + + /// \brief Saves this object to a BufferedTransformation + /// \param bt a BufferedTransformation object + /// \details Use of DEREncode() changed to Save() at Issue 569. + /// \deprecated for backwards compatibility, calls GetMaterial().Save(bt) + void DEREncode(BufferedTransformation &bt) const + {GetMaterial().Save(bt);} +#endif +}; + +/// \brief Interface for asymmetric algorithms using public keys +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm +{ +public: + virtual ~PublicKeyAlgorithm() {} + + // VC60 workaround: no co-variant return type + + /// \brief Retrieves a reference to a Public Key + /// \return a reference to the public key + CryptoMaterial & AccessMaterial() + {return AccessPublicKey();} + /// \brief Retrieves a reference to a Public Key + /// \return a const reference the public key + const CryptoMaterial & GetMaterial() const + {return GetPublicKey();} + + /// \brief Retrieves a reference to a Public Key + /// \return a reference to the public key + virtual PublicKey & AccessPublicKey() =0; + /// \brief Retrieves a reference to a Public Key + /// \return a const reference the public key + virtual const PublicKey & GetPublicKey() const + {return const_cast(this)->AccessPublicKey();} +}; + +/// \brief Interface for asymmetric algorithms using private keys +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm +{ +public: + virtual ~PrivateKeyAlgorithm() {} + + /// \brief Retrieves a reference to a Private Key + /// \return a reference the private key + CryptoMaterial & AccessMaterial() {return AccessPrivateKey();} + /// \brief Retrieves a reference to a Private Key + /// \return a const reference the private key + const CryptoMaterial & GetMaterial() const {return GetPrivateKey();} + + /// \brief Retrieves a reference to a Private Key + /// \return a reference the private key + virtual PrivateKey & AccessPrivateKey() =0; + /// \brief Retrieves a reference to a Private Key + /// \return a const reference the private key + virtual const PrivateKey & GetPrivateKey() const {return const_cast(this)->AccessPrivateKey();} +}; + +/// \brief Interface for key agreement algorithms +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm +{ +public: + virtual ~KeyAgreementAlgorithm() {} + + /// \brief Retrieves a reference to Crypto Parameters + /// \return a reference the crypto parameters + CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();} + /// \brief Retrieves a reference to Crypto Parameters + /// \return a const reference the crypto parameters + const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();} + + /// \brief Retrieves a reference to Crypto Parameters + /// \return a reference the crypto parameters + virtual CryptoParameters & AccessCryptoParameters() =0; + /// \brief Retrieves a reference to Crypto Parameters + /// \return a const reference the crypto parameters + virtual const CryptoParameters & GetCryptoParameters() const {return const_cast(this)->AccessCryptoParameters();} +}; + +/// \brief Interface for public-key encryptors and decryptors +/// \details This class provides an interface common to encryptors and decryptors +/// for querying their plaintext and ciphertext lengths. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem +{ +public: + virtual ~PK_CryptoSystem() {} + + /// \brief Provides the maximum length of plaintext for a given ciphertext length + /// \return the maximum size of the plaintext, in bytes + /// \details This function returns 0 if ciphertextLength is not valid (too long or too short). + virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0; + + /// \brief Calculate the length of ciphertext given length of plaintext + /// \return the maximum size of the ciphertext, in bytes + /// \details This function returns 0 if plaintextLength is not valid (too long). + virtual size_t CiphertextLength(size_t plaintextLength) const =0; + + /// \brief Determines whether this object supports the use of a named parameter + /// \param name the name of the parameter + /// \return true if the parameter name is supported, false otherwise + /// \details Some possible parameter names: EncodingParameters(), KeyDerivationParameters() + /// and others Parameters listed in argnames.h + virtual bool ParameterSupported(const char *name) const =0; + + /// \brief Provides the fixed ciphertext length, if one exists + /// \return the fixed ciphertext length if one exists, otherwise 0 + /// \details "Fixed" here means length of ciphertext does not depend on length of plaintext. + /// In this case, it usually does depend on the key length. + virtual size_t FixedCiphertextLength() const {return 0;} + + /// \brief Provides the maximum plaintext length given a fixed ciphertext length + /// \return maximum plaintext length given the fixed ciphertext length, if one exists, + /// otherwise return 0. + /// \details FixedMaxPlaintextLength(0 returns the maximum plaintext length given the fixed ciphertext + /// length, if one exists, otherwise return 0. + virtual size_t FixedMaxPlaintextLength() const {return 0;} +}; + +/// \brief Interface for public-key encryptors +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm +{ +public: + /// \brief Exception thrown when trying to encrypt plaintext of invalid length + class CRYPTOPP_DLL InvalidPlaintextLength : public Exception + { + public: + InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {} + }; + + /// \brief Encrypt a byte string + /// \param rng a RandomNumberGenerator derived class + /// \param plaintext the plaintext byte buffer + /// \param plaintextLength the size of the plaintext byte buffer + /// \param ciphertext a byte buffer to hold the encrypted string + /// \param parameters a set of NameValuePairs to initialize this object + /// \pre CiphertextLength(plaintextLength) != 0 ensures the plaintext isn't too large + /// \pre COUNTOF(ciphertext) == CiphertextLength(plaintextLength) ensures the output + /// byte buffer is large enough. + /// \sa PK_Decryptor + virtual void Encrypt(RandomNumberGenerator &rng, + const byte *plaintext, size_t plaintextLength, + byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; + + /// \brief Create a new encryption filter + /// \param rng a RandomNumberGenerator derived class + /// \param attachment an attached transformation + /// \param parameters a set of NameValuePairs to initialize this object + /// \details \p attachment can be \p NULL. The caller is responsible for deleting the returned pointer. + /// Encoding parameters should be passed in the "EP" channel. + virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, + BufferedTransformation *attachment=NULLPTR, const NameValuePairs ¶meters = g_nullNameValuePairs) const; +}; + +/// \brief Interface for public-key decryptors +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm +{ +public: + virtual ~PK_Decryptor() {} + + /// \brief Decrypt a byte string + /// \param rng a RandomNumberGenerator derived class + /// \param ciphertext the encrypted byte buffer + /// \param ciphertextLength the size of the encrypted byte buffer + /// \param plaintext a byte buffer to hold the decrypted string + /// \param parameters a set of NameValuePairs to initialize this object + /// \return the result of the decryption operation + /// \details If DecodingResult::isValidCoding is true, then DecodingResult::messageLength + /// is valid and holds the actual length of the plaintext recovered. The result is undefined + /// if decryption failed. If DecodingResult::isValidCoding is false, then DecodingResult::messageLength + /// is undefined. + /// \pre COUNTOF(plaintext) == MaxPlaintextLength(ciphertextLength) ensures the output + /// byte buffer is large enough + /// \sa PK_Encryptor + virtual DecodingResult Decrypt(RandomNumberGenerator &rng, + const byte *ciphertext, size_t ciphertextLength, + byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; + + /// \brief Create a new decryption filter + /// \param rng a RandomNumberGenerator derived class + /// \param attachment an attached transformation + /// \param parameters a set of NameValuePairs to initialize this object + /// \return the newly created decryption filter + /// \note the caller is responsible for deleting the returned pointer + virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, + BufferedTransformation *attachment=NULLPTR, const NameValuePairs ¶meters = g_nullNameValuePairs) const; + + /// \brief Decrypt a fixed size ciphertext + /// \param rng a RandomNumberGenerator derived class + /// \param ciphertext the encrypted byte buffer + /// \param plaintext a byte buffer to hold the decrypted string + /// \param parameters a set of NameValuePairs to initialize this object + /// \return the result of the decryption operation + /// \details If DecodingResult::isValidCoding is true, then DecodingResult::messageLength + /// is valid and holds the actual length of the plaintext recovered. The result is undefined + /// if decryption failed. If DecodingResult::isValidCoding is false, then DecodingResult::messageLength + /// is undefined. + /// \pre COUNTOF(plaintext) == MaxPlaintextLength(ciphertextLength) ensures the output + /// byte buffer is large enough + /// \sa PK_Encryptor + DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const + {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);} +}; + +/// \brief Interface for public-key signers and verifiers +/// \details This class provides an interface common to signers and verifiers for querying scheme properties +/// \sa DL_SignatureSchemeBase, TF_SignatureSchemeBase, DL_SignerBase, TF_SignerBase +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme +{ +public: + /// \brief Exception throw when the private or public key has a length that can't be used + /// \details InvalidKeyLength() may be thrown by any function in this class if the private + /// or public key has a length that can't be used + class CRYPTOPP_DLL InvalidKeyLength : public Exception + { + public: + InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {} + }; + + /// \brief Exception throw when the private or public key is too short to sign or verify + /// \details KeyTooShort() may be thrown by any function in this class if the private or public + /// key is too short to sign or verify anything + class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength + { + public: + KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {} + }; + + virtual ~PK_SignatureScheme() {} + + /// \brief Provides the signature length if it only depends on the key + /// \return the signature length if it only depends on the key, in bytes + /// \details SignatureLength() returns the signature length if it only depends on the key, otherwise 0. + virtual size_t SignatureLength() const =0; + + /// \brief Provides the maximum signature length produced given the length of the recoverable message part + /// \param recoverablePartLength the length of the recoverable message part, in bytes + /// \return the maximum signature length produced for a given length of recoverable message part, in bytes + /// \details MaxSignatureLength() returns the maximum signature length produced given the length of the + /// recoverable message part. + virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const + {CRYPTOPP_UNUSED(recoverablePartLength); return SignatureLength();} + + /// \brief Provides the length of longest message that can be recovered + /// \return the length of longest message that can be recovered, in bytes + /// \details MaxRecoverableLength() returns the length of longest message that can be recovered, or 0 if + /// this signature scheme does not support message recovery. + virtual size_t MaxRecoverableLength() const =0; + + /// \brief Provides the length of longest message that can be recovered from a signature of given length + /// \param signatureLength the length of the signature, in bytes + /// \return the length of longest message that can be recovered from a signature of given length, in bytes + /// \details MaxRecoverableLengthFromSignatureLength() returns the length of longest message that can be + /// recovered from a signature of given length, or 0 if this signature scheme does not support message + /// recovery. + virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0; + + /// \brief Determines whether a signature scheme requires a random number generator + /// \return true if the signature scheme requires a RandomNumberGenerator() to sign + /// \details if IsProbabilistic() returns false, then NullRNG() can be passed to functions that take + /// RandomNumberGenerator(). + virtual bool IsProbabilistic() const =0; + + /// \brief Determines whether the non-recoverable message part can be signed + /// \return true if the non-recoverable message part can be signed + virtual bool AllowNonrecoverablePart() const =0; + + /// \brief Determines whether the signature must be input before the message + /// \return true if the signature must be input before the message during verifcation + /// \details if SignatureUpfront() returns true, then you must input the signature before the message + /// during verification. Otherwise you can input the signature at anytime. + virtual bool SignatureUpfront() const {return false;} + + /// \brief Determines whether the recoverable part must be input before the non-recoverable part + /// \return true if the recoverable part must be input before the non-recoverable part during signing + /// \details RecoverablePartFirst() determines whether you must input the recoverable part before the + /// non-recoverable part during signing + virtual bool RecoverablePartFirst() const =0; +}; + +/// \brief Interface for accumulating messages to be signed or verified +/// \details Only Update() should be called from the PK_MessageAccumulator() class. No other functions +/// inherited from HashTransformation, like DigestSize() and TruncatedFinal(), should be called. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation +{ +public: + /// \warning DigestSize() should not be called on PK_MessageAccumulator + unsigned int DigestSize() const + {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");} + + /// \warning TruncatedFinal() should not be called on PK_MessageAccumulator + void TruncatedFinal(byte *digest, size_t digestSize) + { + CRYPTOPP_UNUSED(digest); CRYPTOPP_UNUSED(digestSize); + throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called"); + } +}; + +/// \brief Interface for public-key signers +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm +{ +public: + virtual ~PK_Signer() {} + + /// \brief Create a new HashTransformation to accumulate the message to be signed + /// \param rng a RandomNumberGenerator derived class + /// \return a pointer to a PK_MessageAccumulator + /// \details NewSignatureAccumulator() can be used with all signing methods. Sign() will autimatically delete the + /// accumulator pointer. The caller is responsible for deletion if a method is called that takes a reference. + virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0; + + /// \brief Input a recoverable message to an accumulator + /// \param messageAccumulator a reference to a PK_MessageAccumulator + /// \param recoverableMessage a pointer to the recoverable message part to be signed + /// \param recoverableMessageLength the size of the recoverable message part + virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0; + + /// \brief Sign and delete the messageAccumulator + /// \param rng a RandomNumberGenerator derived class + /// \param messageAccumulator a pointer to a PK_MessageAccumulator derived class + /// \param signature a block of bytes for the signature + /// \return actual signature length + /// \details Sign() deletes the messageAccumulator, even if an exception is thrown. + /// \pre COUNTOF(signature) == MaxSignatureLength() + virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const; + + /// \brief Sign and restart messageAccumulator + /// \param rng a RandomNumberGenerator derived class + /// \param messageAccumulator a pointer to a PK_MessageAccumulator derived class + /// \param signature a block of bytes for the signature + /// \param restart flag indicating whether the messageAccumulator should be restarted + /// \return actual signature length + /// \pre COUNTOF(signature) == MaxSignatureLength() + virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0; + + /// \brief Sign a message + /// \param rng a RandomNumberGenerator derived class + /// \param message a pointer to the message + /// \param messageLen the size of the message to be signed + /// \param signature a block of bytes for the signature + /// \return actual signature length + /// \pre COUNTOF(signature) == MaxSignatureLength() + virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const; + + /// \brief Sign a recoverable message + /// \param rng a RandomNumberGenerator derived class + /// \param recoverableMessage a pointer to the recoverable message part to be signed + /// \param recoverableMessageLength the size of the recoverable message part + /// \param nonrecoverableMessage a pointer to the non-recoverable message part to be signed + /// \param nonrecoverableMessageLength the size of the non-recoverable message part + /// \param signature a block of bytes for the signature + /// \return actual signature length + /// \pre COUNTOF(signature) == MaxSignatureLength(recoverableMessageLength) + virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const; +}; + +/// \brief Interface for public-key signature verifiers +/// \details The Recover* functions throw NotImplemented if the signature scheme does not support +/// message recovery. +/// \details The Verify* functions throw InvalidDataFormat if the scheme does support message +/// recovery and the signature contains a non-empty recoverable message part. The +/// Recover* functions should be used in that case. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm +{ +public: + virtual ~PK_Verifier() {} + + /// \brief Create a new HashTransformation to accumulate the message to be verified + /// \return a pointer to a PK_MessageAccumulator + /// \details NewVerificationAccumulator() can be used with all verification methods. Verify() will autimatically delete + /// the accumulator pointer. The caller is responsible for deletion if a method is called that takes a reference. + virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0; + + /// \brief Input signature into a message accumulator + /// \param messageAccumulator a pointer to a PK_MessageAccumulator derived class + /// \param signature the signature on the message + /// \param signatureLength the size of the signature + virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0; + + /// \brief Check whether messageAccumulator contains a valid signature and message + /// \param messageAccumulator a pointer to a PK_MessageAccumulator derived class + /// \return true if the signature is valid, false otherwise + /// \details Verify() deletes the messageAccumulator, even if an exception is thrown. + virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const; + + /// \brief Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator + /// \param messageAccumulator a reference to a PK_MessageAccumulator derived class + /// \return true if the signature is valid, false otherwise + /// \details VerifyAndRestart() restarts the messageAccumulator + virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0; + + /// \brief Check whether input signature is a valid signature for input message + /// \param message a pointer to the message to be verified + /// \param messageLen the size of the message + /// \param signature a pointer to the signature over the message + /// \param signatureLen the size of the signature + /// \return true if the signature is valid, false otherwise + virtual bool VerifyMessage(const byte *message, size_t messageLen, + const byte *signature, size_t signatureLen) const; + + /// \brief Recover a message from its signature + /// \param recoveredMessage a pointer to the recoverable message part to be verified + /// \param messageAccumulator a pointer to a PK_MessageAccumulator derived class + /// \return the result of the verification operation + /// \details Recover() deletes the messageAccumulator, even if an exception is thrown. + /// \pre COUNTOF(recoveredMessage) == MaxRecoverableLengthFromSignatureLength(signatureLength) + virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const; + + /// \brief Recover a message from its signature + /// \param recoveredMessage a pointer to the recoverable message part to be verified + /// \param messageAccumulator a pointer to a PK_MessageAccumulator derived class + /// \return the result of the verification operation + /// \details RecoverAndRestart() restarts the messageAccumulator + /// \pre COUNTOF(recoveredMessage) == MaxRecoverableLengthFromSignatureLength(signatureLength) + virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0; + + /// \brief Recover a message from its signature + /// \param recoveredMessage a pointer for the recovered message + /// \param nonrecoverableMessage a pointer to the non-recoverable message part to be signed + /// \param nonrecoverableMessageLength the size of the non-recoverable message part + /// \param signature the signature on the message + /// \param signatureLength the size of the signature + /// \return the result of the verification operation + /// \pre COUNTOF(recoveredMessage) == MaxRecoverableLengthFromSignatureLength(signatureLength) + virtual DecodingResult RecoverMessage(byte *recoveredMessage, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, + const byte *signature, size_t signatureLength) const; +}; + +/// \brief Interface for domains of simple key agreement protocols +/// \details A key agreement domain is a set of parameters that must be shared +/// by two parties in a key agreement protocol, along with the algorithms +/// for generating key pairs and deriving agreed values. +/// \since Crypto++ 3.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm +{ +public: + virtual ~SimpleKeyAgreementDomain() {} + + /// \brief Provides the size of the agreed value + /// \return size of agreed value produced in this domain + virtual unsigned int AgreedValueLength() const =0; + + /// \brief Provides the size of the private key + /// \return size of private keys in this domain + virtual unsigned int PrivateKeyLength() const =0; + + /// \brief Provides the size of the public key + /// \return size of public keys in this domain + virtual unsigned int PublicKeyLength() const =0; + + /// \brief Generate private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \pre COUNTOF(privateKey) == PrivateKeyLength() + virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; + + /// \brief Generate a public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \pre COUNTOF(publicKey) == PublicKeyLength() + virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; + + /// \brief Generate a private/public key pair + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details GenerateKeyPair() is equivalent to calling GeneratePrivateKey() and then GeneratePublicKey(). + /// \pre COUNTOF(privateKey) == PrivateKeyLength() + /// \pre COUNTOF(publicKey) == PublicKeyLength() + virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; + + /// \brief Derive agreed value + /// \param agreedValue a byte buffer for the shared secret + /// \param privateKey a byte buffer with your private key in this domain + /// \param otherPublicKey a byte buffer with the other party's public key in this domain + /// \param validateOtherPublicKey a flag indicating if the other party's public key should be validated + /// \return true upon success, false in case of failure + /// \details Agree() derives an agreed value from your private keys and couterparty's public keys. + /// \details The other party's public key is validated by default. If you have previously validated the + /// static public key, use validateStaticOtherPublicKey=false to save time. + /// \pre COUNTOF(agreedValue) == AgreedValueLength() + /// \pre COUNTOF(privateKey) == PrivateKeyLength() + /// \pre COUNTOF(otherPublicKey) == PublicKeyLength() + virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; +}; + +/// \brief Interface for domains of authenticated key agreement protocols +/// \details In an authenticated key agreement protocol, each party has two +/// key pairs. The long-lived key pair is called the static key pair, +/// and the short-lived key pair is called the ephemeral key pair. +/// \since Crypto++ 3.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm +{ +public: + virtual ~AuthenticatedKeyAgreementDomain() {} + + /// \brief Provides the size of the agreed value + /// \return size of agreed value produced in this domain + virtual unsigned int AgreedValueLength() const =0; + + /// \brief Provides the size of the static private key + /// \return size of static private keys in this domain + virtual unsigned int StaticPrivateKeyLength() const =0; + + /// \brief Provides the size of the static public key + /// \return size of static public keys in this domain + virtual unsigned int StaticPublicKeyLength() const =0; + + /// \brief Generate static private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \pre COUNTOF(privateKey) == PrivateStaticKeyLength() + virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; + + /// \brief Generate a static public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \pre COUNTOF(publicKey) == PublicStaticKeyLength() + virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; + + /// \brief Generate a static private/public key pair + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details GenerateStaticKeyPair() is equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey(). + /// \pre COUNTOF(privateKey) == PrivateStaticKeyLength() + /// \pre COUNTOF(publicKey) == PublicStaticKeyLength() + virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; + + /// \brief Provides the size of ephemeral private key + /// \return the size of ephemeral private key in this domain + virtual unsigned int EphemeralPrivateKeyLength() const =0; + + /// \brief Provides the size of ephemeral public key + /// \return the size of ephemeral public key in this domain + virtual unsigned int EphemeralPublicKeyLength() const =0; + + /// \brief Generate ephemeral private key + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \pre COUNTOF(privateKey) == PrivateEphemeralKeyLength() + virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; + + /// \brief Generate ephemeral public key + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \param publicKey a byte buffer for the generated public key in this domain + /// \pre COUNTOF(publicKey) == PublicEphemeralKeyLength() + virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; + + /// \brief Generate private/public key pair + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details GenerateEphemeralKeyPair() is equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() + virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; + + /// \brief Derive agreed value + /// \param agreedValue a byte buffer for the shared secret + /// \param staticPrivateKey a byte buffer with your static private key in this domain + /// \param ephemeralPrivateKey a byte buffer with your ephemeral private key in this domain + /// \param staticOtherPublicKey a byte buffer with the other party's static public key in this domain + /// \param ephemeralOtherPublicKey a byte buffer with the other party's ephemeral public key in this domain + /// \param validateStaticOtherPublicKey a flag indicating if the other party's public key should be validated + /// \return true upon success, false in case of failure + /// \details Agree() derives an agreed value from your private keys and couterparty's public keys. + /// \details The other party's ephemeral public key is validated by default. If you have previously validated + /// the static public key, use validateStaticOtherPublicKey=false to save time. + /// \pre COUNTOF(agreedValue) == AgreedValueLength() + /// \pre COUNTOF(staticPrivateKey) == StaticPrivateKeyLength() + /// \pre COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength() + /// \pre COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength() + /// \pre COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength() + virtual bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const =0; +}; + +// interface for password authenticated key agreement protocols, not implemented yet +#if 0 +/// \brief Interface for protocol sessions +/*! The methods should be called in the following order: + + InitializeSession(rng, parameters); // or call initialize method in derived class + while (true) + { + if (OutgoingMessageAvailable()) + { + length = GetOutgoingMessageLength(); + GetOutgoingMessage(message); + ; // send outgoing message + } + + if (LastMessageProcessed()) + break; + + ; // receive incoming message + ProcessIncomingMessage(message); + } + ; // call methods in derived class to obtain result of protocol session +*/ +class ProtocolSession +{ +public: + /// Exception thrown when an invalid protocol message is processed + class ProtocolError : public Exception + { + public: + ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {} + }; + + /// Exception thrown when a function is called unexpectedly + /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */ + class UnexpectedMethodCall : public Exception + { + public: + UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {} + }; + + virtual ~ProtocolSession() {} + + ProtocolSession() : m_rng(NULLPTR), m_throwOnProtocolError(true), m_validState(false) {} + + virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs ¶meters) =0; + + bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;} + void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;} + + bool HasValidState() const {return m_validState;} + + virtual bool OutgoingMessageAvailable() const =0; + virtual unsigned int GetOutgoingMessageLength() const =0; + virtual void GetOutgoingMessage(byte *message) =0; + + virtual bool LastMessageProcessed() const =0; + virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0; + +protected: + void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const; + void CheckAndHandleInvalidState() const; + void SetValidState(bool valid) {m_validState = valid;} + + RandomNumberGenerator *m_rng; + +private: + bool m_throwOnProtocolError, m_validState; +}; + +class KeyAgreementSession : public ProtocolSession +{ +public: + virtual ~KeyAgreementSession() {} + + virtual unsigned int GetAgreedValueLength() const =0; + virtual void GetAgreedValue(byte *agreedValue) const =0; +}; + +class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession +{ +public: + virtual ~PasswordAuthenticatedKeyAgreementSession() {} + + void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, + const byte *myId, unsigned int myIdLength, + const byte *counterPartyId, unsigned int counterPartyIdLength, + const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength); +}; + +/// \brief Password based key agreement domain +/// \since Crypto++ 3.0 +class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm +{ +public: + virtual ~PasswordAuthenticatedKeyAgreementDomain() {} + + /// return whether the domain parameters stored in this object are valid + virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const + {return GetCryptoParameters().Validate(rng, 2);} + + virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0; + virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0; + + enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8}; + + virtual bool IsValidRole(unsigned int role) =0; + virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0; +}; +#endif + +/// \brief Exception thrown when an ASN.1 BER decoing error is encountered +class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument +{ +public: + BERDecodeErr() : InvalidArgument("BER decode error") {} + BERDecodeErr(const std::string &s) : InvalidArgument(s) {} +}; + +/// \brief Interface for encoding and decoding ASN1 objects +/// \details Each class that derives from ASN1Object should provide a serialization format +/// that controls subobject layout. Most of the time the serialization format is +/// taken from a standard, like P1363 or an RFC. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object +{ +public: + virtual ~ASN1Object() {} + + /// \brief Decode this object from a BufferedTransformation + /// \param bt BufferedTransformation object + /// \details Uses Basic Encoding Rules (BER) + virtual void BERDecode(BufferedTransformation &bt) =0; + + /// \brief Encode this object into a BufferedTransformation + /// \param bt BufferedTransformation object + /// \details Uses Distinguished Encoding Rules (DER) + virtual void DEREncode(BufferedTransformation &bt) const =0; + + /// \brief Encode this object into a BufferedTransformation + /// \param bt BufferedTransformation object + /// \details Uses Basic Encoding Rules (BER). + /// \details This may be useful if DEREncode() would be too inefficient. + virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);} +}; + +/// \brief Specifies the build-time version of the library +/// \return integer representing the build-time version +/// \details LibraryVersion can help detect inadvertent mixing and matching of library +/// versions. When using Crypto++ distributed by a third party, LibraryVersion() +/// records the version of the shared object that was built by the third party. +/// The LibraryVersion() record resides in cryptlib.o on Unix compatibles +/// and cryptlib.obj on Windows. It does not change when an app links +/// to the library. +/// \details LibraryVersion() is declared with C linkage (extern "C") within the +/// CryptoPP namespace to help programs locate the symbol. If the symbol is present, then +/// the library version is 5.7 or above. If it is missing, then the library version is +/// 5.6.5 or below. +/// \details The function could be used as shown below. +///
  if (LibraryVersion() != HeaderVersion())
+///   {
+///      cout << "Potential version mismatch" << endl;
+///
+///      const int lmaj = (LibraryVersion() / 100U) % 10;
+///      const int lmin = (LibraryVersion() / 10U) % 10;
+///      const int hmaj = (HeaderVersion() / 100U) % 10;
+///      const int hmin = (HeaderVersion() / 10U) % 10;
+///
+///      if(lmaj != hmaj)
+///         cout << "Major version mismatch" << endl;
+///      else if(lmin != hmin)
+///         cout << "Minor version mismatch" << endl;
+///   }
+/// 
+/// \sa HeaderVersion(), GitHub Issue 371. +/// \since Crypto++ 6.0 +extern "C" { + int LibraryVersion(CRYPTOPP_NOINLINE_DOTDOTDOT); +} // C linkage + +/// \brief Specifies the runtime version of the library +/// \return integer representing the runtime version +/// \details HeaderVersion() can help detect inadvertent mixing and matching of library +/// versions. When using Crypto++ distributed by a third party, HeaderVersion() +/// records the version of the headers used by the app when the app is compiled. +/// \details HeaderVersion() is declared with C linkage (extern "C") within the +/// CryptoPP namespace to help programs locate the symbol. If the symbol is present, then +/// the library version is 5.7 or above. If it is missing, then the library version is +/// 5.6.5 or below. +/// \details The function could be used as shown below. +///
  if (LibraryVersion() != HeaderVersion())
+///   {
+///      cout << "Potential version mismatch" << endl;
+///
+///      const int lmaj = (LibraryVersion() / 100U) % 10;
+///      const int lmin = (LibraryVersion() / 10U) % 10;
+///      const int hmaj = (HeaderVersion() / 100U) % 10;
+///      const int hmin = (HeaderVersion() / 10U) % 10;
+///
+///      if(lmaj != hmaj)
+///         cout << "Major version mismatch" << endl;
+///      else if(lmin != hmin)
+///         cout << "Minor version mismatch" << endl;
+///   }
+/// 
+/// \sa LibraryVersion(), GitHub Issue 371. +/// \since Crypto++ 6.0 +extern "C" { +inline int HeaderVersion() +{ + return CRYPTOPP_VERSION; +} +} // C linkage + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/darn.cpp b/external/ours/library/crypto/src/shared/original/darn.cpp new file mode 100755 index 000000000..7f586beae --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/darn.cpp @@ -0,0 +1,236 @@ +// darn.cpp - written and placed in public domain by Jeffrey Walton + +#include "pch.h" +#include "config.h" +#include "cryptlib.h" +#include "secblock.h" +#include "darn.h" +#include "cpu.h" + +// At the moment only GCC 7.0 (and above) seems to support __builtin_darn() +// and __builtin_darn_32(). Clang 7.0 does not provide them, but it does +// support assembly instructions. XLC is unknown, but there are no hits when +// searching IBM's site. To cover more platforms we provide GCC inline +// assembly like we do with RDRAND and RDSEED. Platforms that don't support +// GCC inline assembly or the builtin will fail the compile. + +// Inline assembler available in GCC 3.2 or above. For practical +// purposes we check for GCC 4.0 or above. GCC impostors claim +// to be GCC 4.2.1 so it will capture them, too. We exclude the +// Apple machines because they are not Power9 and use a slightly +// different syntax in their assembler. +#if ((__GNUC__ >= 4) || defined(__IBM_GCC_ASM)) && !defined(__APPLE__) +# define GCC_DARN_ASM_AVAILABLE 1 +#endif + +// warning C4702: unreachable code +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4702) +#endif + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + +// *************************** 32-bit *************************** // + +#if (CRYPTOPP_BOOL_PPC32) + +// Fills 4 bytes, buffer must be aligned +inline void DARN32(void* output) +{ + CRYPTOPP_ASSERT(IsAlignedOn(output, GetAlignmentOf())); + word32* ptr = reinterpret_cast(output); + +#if defined(GCC_DARN_ASM_AVAILABLE) + // This is "darn r3, 0". When L=0 a 32-bit conditioned word + // is returned. On failure 0xffffffffffffffff is returned. + // The Power manual recommends only checking the low 32-bit + // word for this case. See Power ISA 3.0 specification, p. 78. + do + { + __asm__ __volatile__ ( + #if (CRYPTOPP_BIG_ENDIAN) + ".byte 0x7c, 0x60, 0x05, 0xe6 \n\t" // r3 = darn 3, 0 + "mr %0, 3 \n\t" // val = r3 + #else + ".byte 0xe6, 0x05, 0x60, 0x7c \n\t" // r3 = darn 3, 0 + "mr %0, 3 \n\t" // val = r3 + #endif + : "=r" (*ptr) : : "r3" + ); + } while (*ptr == 0xFFFFFFFFu); +#elif defined(_ARCH_PWR9) + // This is probably going to break some platforms. + // We will deal with them as we encounter them. + *ptr = __builtin_darn_32(); +#elif defined(__APPLE__) + // Nop. Apple G4 and G5 machines are too old. They will + // avoid this code path because HasPower9() returns false. + CRYPTOPP_ASSERT(0); +#else + // Catch other compile breaks + int XXX[-1]; +#endif +} +#endif // PPC32 + +// *************************** 64-bit *************************** // + +#if (CRYPTOPP_BOOL_PPC64) + +// Fills 8 bytes, buffer must be aligned +inline void DARN64(void* output) +{ + CRYPTOPP_ASSERT(IsAlignedOn(output, GetAlignmentOf())); + word64* ptr = reinterpret_cast(output); + +#if defined(GCC_DARN_ASM_AVAILABLE) + // This is "darn r3, 1". When L=1 a 64-bit conditioned word + // is returned. On failure 0xffffffffffffffff is returned. + // See Power ISA 3.0 specification, p. 78. + do + { + __asm__ __volatile__ ( + #if (CRYPTOPP_BIG_ENDIAN) + ".byte 0x7c, 0x61, 0x05, 0xe6 \n\t" // r3 = darn 3, 1 + "mr %0, 3 \n\t" // val = r3 + #else + ".byte 0xe6, 0x05, 0x61, 0x7c \n\t" // r3 = darn 3, 1 + "mr %0, 3 \n\t" // val = r3 + #endif + : "=r" (*ptr) : : "r3" + ); + } while (*ptr == 0xFFFFFFFFFFFFFFFFull); +#elif defined(_ARCH_PWR9) + // This is probably going to break some platforms. + // We will deal with them as we encounter them. + *ptr = __builtin_darn(); +#elif defined(__APPLE__) + // Nop. Apple G4 and G5 machines are too old. They will + // avoid this code path because HasPower9() returns false. + CRYPTOPP_ASSERT(0); +#else + // Catch other compile breaks + int XXX[-1]; +#endif +} +#endif // PPC64 + +// ************************ Standard C++ ************************ // + +DARN::DARN() +{ + if (!HasDARN()) + throw DARN_Err("HasDARN"); + + // Scratch buffer in case user buffers are unaligned. + m_temp.New(8); +} + +void DARN::GenerateBlock(byte *output, size_t size) +{ + CRYPTOPP_ASSERT((output && size) || !(output || size)); + if (size == 0) return; + size_t i = 0; + +#if (CRYPTOPP_BOOL_PPC64) + + // Check alignment + i = reinterpret_cast(output) & 0x7; + if (i != 0) + { + DARN64(m_temp); + std::memcpy(output, m_temp, i); + + output += i; + size -= i; + } + + // Output is aligned + for (i = 0; i < size/8; i++) + DARN64(output+i*8); + + output += i*8; + size -= i*8; + + if (size) + { + DARN64(m_temp); + std::memcpy(output, m_temp, size); + } + +#elif (CRYPTOPP_BOOL_PPC32) + + // Check alignment + i = reinterpret_cast(output) & 0x3; + if (i != 0) + { + DARN32(m_temp); + std::memcpy(output, m_temp, i); + + output += i; + size -= i; + } + + // Output is aligned + for (i = 0; i < size/4; i++) + DARN32(output+i*4); + + output += i*4; + size -= i*4; + + if (size) + { + DARN32(m_temp); + std::memcpy(output, m_temp, size); + } + +#else + // No suitable compiler found + CRYPTOPP_UNUSED(output); + throw NotImplemented("DARN: failed to find a suitable implementation"); +#endif +} + +void DARN::DiscardBytes(size_t n) +{ + // RoundUpToMultipleOf is used because a full word is read, and its cheaper + // to discard full words. There's no sense in dealing with tail bytes. + FixedSizeSecBlock discard; + n = RoundUpToMultipleOf(n, sizeof(word64)); + + size_t count = STDMIN(n, discard.SizeInBytes()); + while (count) + { + GenerateBlock(discard.BytePtr(), count); + n -= count; + count = STDMIN(n, discard.SizeInBytes()); + } +} + +#else // not PPC32 or PPC64 + +DARN::DARN() +{ + throw DARN_Err("HasDARN"); +} + +void DARN::GenerateBlock(byte *output, size_t size) +{ + // Constructor will throw, should not get here + CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size); +} + +void DARN::DiscardBytes(size_t n) +{ + // Constructor will throw, should not get here + CRYPTOPP_UNUSED(n); +} + +#endif // PPC32 or PPC64 + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/darn.h b/external/ours/library/crypto/src/shared/original/darn.h new file mode 100755 index 000000000..8965fd04e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/darn.h @@ -0,0 +1,95 @@ +// darn.h - written and placed in public domain by Jeffrey Walton +// DARN requires POWER9/ISA 3.0. + +// At the moment only GCC 7.0 (and above) seems to support __builtin_darn() +// and __builtin_darn_32(). However, GCC generates incorrect code. Clang 7.0 +// does not provide them, but it does support assembly instructions. XLC is +// unknown, but there are no hits when searching IBM's site. To cover more +// platforms we provide GCC inline assembly like we do with RDRAND and RDSEED. +// Platforms that don't support GCC inline assembly or the builtin will fail +// to compile. Also see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91481 and +// https://gcc.gnu.org/onlinedocs/gcc/Basic-PowerPC-Built-in-Functions-Available-on-ISA-3_002e0.html + +/// \file darn.h +/// \brief Classes for DARN RNG +/// \sa Power +/// ISA Version 3.0B +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_DARN_H +#define CRYPTOPP_DARN_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Exception thrown when a DARN generator encounters +/// a generator related error. +/// \since Crypto++ 8.0 +class DARN_Err : public Exception +{ +public: + DARN_Err(const std::string &operation) + : Exception(OTHER_ERROR, "DARN: " + operation + " operation failed") {} +}; + +/// \brief Hardware generated random numbers using DARN instruction +/// \details DARN() provides access to Power9's random number generator. The +/// Crypto++ implementation provides conditioned random numbers from the +/// generator as opposed to raw random numbers. According to Power ISA 3.0B +/// manual, a conditioned random number has been processed by hardware to +/// reduce bias. A raw random number is unconditioned noise source output. +/// \details According to Power ISA 3.0B manual, the random number generator +/// provided by the darn instruction is NIST SP800-90B and SP800-90C +/// compliant to the extent possible given the completeness of the standards +/// at the time the hardware is designed. The random number generator provides +/// a minimum of 0.5 bits of entropy per bit. +/// \par Wraps +/// darn instruction +/// \sa Power +/// ISA Version 3.0B, MaurerRandomnessTest() for random bit generators +/// \since Crypto++ 8.0 +class DARN : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "DARN"; } + + virtual ~DARN() {} + + /// \brief Construct a DARN generator + /// \throw DARN_Err if the random number generator is not available + DARN(); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + virtual void GenerateBlock(byte *output, size_t size); + + /// \brief Generate and discard n bytes + /// \param n the number of bytes to generate and discard + /// \details the RDSEED generator discards words, not bytes. If n is + /// not a multiple of a machine word, then it is rounded up to + /// that size. + virtual void DiscardBytes(size_t n); + + /// \brief Update RNG state with additional unpredictable values + /// \param input unused + /// \param length unused + /// \details The operation is a nop for this generator. + virtual void IncorporateEntropy(const byte *input, size_t length) + { + // Override to avoid the base class' throw. + CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); + } + + std::string AlgorithmProvider() const { + return "Power9"; + } + +private: + SecBlock > m_temp; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_DARN_H diff --git a/external/ours/library/crypto/src/shared/original/datatest.cpp b/external/ours/library/crypto/src/shared/original/datatest.cpp new file mode 100755 index 000000000..f3a8766f4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/datatest.cpp @@ -0,0 +1,1358 @@ +// datatest.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#define CRYPTOPP_DEFAULT_NO_DLL +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "factory.h" +#include "integer.h" +#include "filters.h" +#include "randpool.h" +#include "files.h" +#include "trunhash.h" +#include "queue.h" +#include "smartptr.h" +#include "validate.h" +#include "stdcpp.h" +#include "misc.h" +#include "hex.h" +#include "trap.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +#ifdef _MSC_VER +# define STRTOUL64 _strtoui64 +#else +# define STRTOUL64 strtoull +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +ANONYMOUS_NAMESPACE_BEGIN + +bool s_thorough = false; +typedef std::map TestData; +const TestData *s_currentTestData = NULLPTR; +const std::string testDataFilename = "cryptest.dat"; + +// Handles CR, LF, and CRLF properly +// For istream.fail() see https://stackoverflow.com/q/34395801/608639. +bool Readline(std::istream& stream, std::string& line) +{ + // Ensure old data is cleared + line.clear(); + + std::string temp; + temp.reserve(64); + + while (!stream.fail()) + { + int ch = stream.get(); + if (ch == '\r') + { + int next = stream.peek(); + if (next == '\n') + (void)stream.get(); + + break; + } + else if (ch == '\n') + { + break; + } + + // Let string class manage its own capacity. + // The string will grow as needed. + temp.push_back(static_cast(ch)); + } + +#if defined(CRYPTOPP_CXX11) + temp.shrink_to_fit(); +#else + // Non-binding shrink to fit + temp.reserve(0); +#endif + + std::swap(line, temp); + + return !stream.fail(); +} + +std::string TrimSpace(const std::string& str) +{ + if (str.empty()) return ""; + + const std::string whitespace(" \r\t\n"); + std::string::size_type beg = str.find_first_not_of(whitespace); + std::string::size_type end = str.find_last_not_of(whitespace); + + if (beg != std::string::npos && end != std::string::npos) + return str.substr(beg, end+1); + else if (beg != std::string::npos) + return str.substr(beg); + else + return ""; +} + +std::string TrimComment(const std::string& str) +{ + if (str.empty()) return ""; + + std::string::size_type first = str.find("#"); + + if (first != std::string::npos) + return TrimSpace(str.substr(0, first)); + else + return TrimSpace(str); +} + +class TestFailure : public Exception +{ +public: + TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {} +}; + +void OutputTestData(const TestData &v) +{ + std::cerr << "\n"; + for (TestData::const_iterator i = v.begin(); i != v.end(); ++i) + { + std::cerr << i->first << ": " << i->second << std::endl; + } +} + +void SignalTestFailure() +{ + OutputTestData(*s_currentTestData); + throw TestFailure(); +} + +void SignalUnknownAlgorithmError(const std::string& algType) +{ + OutputTestData(*s_currentTestData); + throw Exception(Exception::OTHER_ERROR, "Unknown algorithm " + algType + " during validation test"); +} + +void SignalTestError(const char* msg = NULLPTR) +{ + OutputTestData(*s_currentTestData); + + if (msg) + throw Exception(Exception::OTHER_ERROR, msg); + else + throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test"); +} + +bool DataExists(const TestData &data, const char *name) +{ + TestData::const_iterator i = data.find(name); + return (i != data.end()); +} + +const std::string & GetRequiredDatum(const TestData &data, const char *name) +{ + TestData::const_iterator i = data.find(name); + if (i == data.end()) + { + std::string msg("Required datum \"" + std::string(name) + "\" missing"); + SignalTestError(msg.c_str()); + } + return i->second; +} + +void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DEFAULT_CHANNEL) +{ + while (source.MaxRetrievable() > (finish ? 0 : 4096)) + { + byte buf[4096+64]; + size_t start = Test::GlobalRNG().GenerateWord32(0, 63); + size_t len = Test::GlobalRNG().GenerateWord32(1, UnsignedMin(4096U, 3*source.MaxRetrievable()/2)); + len = source.Get(buf+start, len); + target.ChannelPut(channel, buf+start, len); + } +} + +void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target) +{ + std::string s1 = GetRequiredDatum(data, name), s2; + ByteQueue q; + + while (!s1.empty()) + { + std::string::size_type pos = s1.find_first_not_of(" "); + if (pos != std::string::npos) + s1.erase(0, pos); + + if (s1.empty()) + goto end; + + int repeat = 1; + if (s1[0] == 'r') + { + s1 = s1.erase(0, 1); + repeat = std::atoi(s1.c_str()); + s1 = s1.substr(s1.find(' ')+1); + } + + // Convert word32 or word64 to little endian order. Some algorithm test vectors are + // presented in the format. We probably should have named them word32le and word64le. + if (s1.length() >= 6 && (s1.substr(0,6) == "word32" || s1.substr(0,6) == "word64")) + { + std::istringstream iss(s1.substr(6)); + if (s1.substr(0,6) == "word64") + { + word64 value; + while (iss >> std::skipws >> std::hex >> value) + { + value = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, value); + q.Put(reinterpret_cast(&value), 8); + } + } + else + { + word32 value; + while (iss >> std::skipws >> std::hex >> value) + { + value = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, value); + q.Put(reinterpret_cast(&value), 4); + } + } + goto end; + } + + s2.clear(); + if (s1[0] == '\"') + { + s2 = s1.substr(1, s1.find('\"', 1)-1); + s1 = s1.substr(s2.length() + 2); + } + else if (s1.substr(0, 2) == "0x") + { + std::string::size_type n = s1.find(' '); + StringSource(s1.substr(2, n), true, new HexDecoder(new StringSink(s2))); + s1 = s1.substr(STDMIN(n, s1.length())); + } + else + { + std::string::size_type n = s1.find(' '); + StringSource(s1.substr(0, n), true, new HexDecoder(new StringSink(s2))); + s1 = s1.substr(STDMIN(n, s1.length())); + } + + while (repeat--) + { + q.Put(ConstBytePtr(s2), BytePtrSize(s2)); + RandomizedTransfer(q, target, false); + } + } + +end: + RandomizedTransfer(q, target, true); +} + +std::string GetDecodedDatum(const TestData &data, const char *name) +{ + std::string s; + PutDecodedDatumInto(data, name, StringSink(s).Ref()); + return s; +} + +std::string GetOptionalDecodedDatum(const TestData &data, const char *name) +{ + std::string s; + if (DataExists(data, name)) + PutDecodedDatumInto(data, name, StringSink(s).Ref()); + return s; +} + +class TestDataNameValuePairs : public NameValuePairs +{ +public: + TestDataNameValuePairs(const TestData &data) : m_data(data) {} + + virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + TestData::const_iterator i = m_data.find(name); + if (i == m_data.end()) + { + if (std::string(name) == Name::DigestSize() && valueType == typeid(int)) + { + i = m_data.find("MAC"); + if (i == m_data.end()) + i = m_data.find("Digest"); + if (i == m_data.end()) + return false; + + m_temp.clear(); + PutDecodedDatumInto(m_data, i->first.c_str(), StringSink(m_temp).Ref()); + *reinterpret_cast(pValue) = (int)m_temp.size(); + return true; + } + else + return false; + } + + const std::string &value = i->second; + + if (valueType == typeid(int)) + *reinterpret_cast(pValue) = atoi(value.c_str()); + else if (valueType == typeid(word64)) + { + std::string x(value.empty() ? "0" : value); + const char* beg = &x[0]; + char* end = &x[0] + value.size(); + + errno = 0; + *reinterpret_cast(pValue) = STRTOUL64(beg, &end, 0); + if (errno != 0) + return false; + } + else if (valueType == typeid(Integer)) + *reinterpret_cast(pValue) = Integer((std::string(value) + "h").c_str()); + else if (valueType == typeid(ConstByteArrayParameter)) + { + m_temp.clear(); + PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref()); + reinterpret_cast(pValue)->Assign(ConstBytePtr(m_temp), BytePtrSize(m_temp), false); + } + else + throw ValueTypeMismatch(name, typeid(std::string), valueType); + + return true; + } + +private: + const TestData &m_data; + mutable std::string m_temp; +}; + +void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv, unsigned int &totalTests) +{ + totalTests++; + + if (!pub.Validate(Test::GlobalRNG(), 2U+!!s_thorough)) + SignalTestFailure(); + if (!priv.Validate(Test::GlobalRNG(), 2U+!!s_thorough)) + SignalTestFailure(); + + ByteQueue bq1, bq2; + pub.Save(bq1); + pub.AssignFrom(priv); + pub.Save(bq2); + if (bq1 != bq2) + SignalTestFailure(); +} + +void TestSignatureScheme(TestData &v, unsigned int &totalTests) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + static member_ptr signer; + static member_ptr verifier; + static std::string lastName; + + if (name != lastName) + { + signer.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + verifier.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + lastName = name; + + // Code coverage + (void)signer->AlgorithmName(); + (void)verifier->AlgorithmName(); + (void)signer->AlgorithmProvider(); + (void)verifier->AlgorithmProvider(); + } + + TestDataNameValuePairs pairs(v); + + if (test == "GenerateKey") + { + totalTests++; + + signer->AccessPrivateKey().GenerateRandom(Test::GlobalRNG(), pairs); + verifier->AccessPublicKey().AssignFrom(signer->AccessPrivateKey()); + } + else + { + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + totalTests++; // key format + if (keyFormat == "DER") + verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + else if (keyFormat == "Component") + verifier->AccessMaterial().AssignFrom(pairs); + + if (test == "Verify" || test == "NotVerify") + { + totalTests++; + + SignatureVerificationFilter verifierFilter(*verifier, NULLPTR, SignatureVerificationFilter::SIGNATURE_AT_BEGIN); + PutDecodedDatumInto(v, "Signature", verifierFilter); + PutDecodedDatumInto(v, "Message", verifierFilter); + verifierFilter.MessageEnd(); + if (verifierFilter.GetLastResult() == (test == "NotVerify")) + SignalTestFailure(); + return; + } + else if (test == "PublicKeyValid") + { + totalTests++; + + if (!verifier->GetMaterial().Validate(Test::GlobalRNG(), 3)) + SignalTestFailure(); + return; + } + + totalTests++; // key format + if (keyFormat == "DER") + signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + else if (keyFormat == "Component") + signer->AccessMaterial().AssignFrom(pairs); + } + + if (test == "GenerateKey" || test == "KeyPairValidAndConsistent") + { + totalTests++; + + TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial(),totalTests); + SignatureVerificationFilter verifierFilter(*verifier, NULLPTR, SignatureVerificationFilter::THROW_EXCEPTION); + const byte msg[3] = {'a', 'b', 'c'}; + verifierFilter.Put(msg, sizeof(msg)); + StringSource ss(msg, sizeof(msg), true, new SignerFilter(Test::GlobalRNG(), *signer, new Redirector(verifierFilter))); + } + else if (test == "Sign") + { + totalTests++; + + SignerFilter f(Test::GlobalRNG(), *signer, new HexEncoder(new FileSink(std::cout))); + StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); + SignalTestFailure(); + } + else if (test == "DeterministicSign") + { + totalTests++; + + // This test is specialized for RFC 6979. The RFC is a drop-in replacement + // for DSA and ECDSA, and access to the seed or secret is not needed. If + // additional deterministic signatures are added, then the test harness will + // likely need to be extended. + std::string signature; + SignerFilter f(Test::GlobalRNG(), *signer, new StringSink(signature)); + StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); + + if (GetDecodedDatum(v, "Signature") != signature) + SignalTestFailure(); + } + else + { + std::string msg("Unknown signature test \"" + test + "\""); + SignalTestError(msg.c_str()); + CRYPTOPP_ASSERT(false); + } +} + +// Subset of TestSignatureScheme. We picked the tests that have data that is easy to write to a file. +// Also see https://github.com/weidai11/cryptopp/issues/1010, where HIGHT broke when using FileSource. +void TestSignatureSchemeWithFileSource(TestData &v, unsigned int &totalTests) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + if (test != "Sign" && test != "DeterministicSign") { return; } + + static member_ptr signer; + static member_ptr verifier; + static std::string lastName; + + if (name != lastName) + { + signer.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + verifier.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + name = lastName; + + // Code coverage + (void)signer->AlgorithmName(); + (void)verifier->AlgorithmName(); + (void)signer->AlgorithmProvider(); + (void)verifier->AlgorithmProvider(); + } + + TestDataNameValuePairs pairs(v); + + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + totalTests++; // key format + if (keyFormat == "DER") + verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + else if (keyFormat == "Component") + verifier->AccessMaterial().AssignFrom(pairs); + + totalTests++; // key format + if (keyFormat == "DER") + signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + else if (keyFormat == "Component") + signer->AccessMaterial().AssignFrom(pairs); + + if (test == "Sign") + { + totalTests++; + + SignerFilter f(Test::GlobalRNG(), *signer, new HexEncoder(new FileSink(std::cout))); + StringSource ss(GetDecodedDatum(v, "Message"), true, new FileSink(testDataFilename.c_str())); + FileSource fs(testDataFilename.c_str(), true, new Redirector(f)); + SignalTestFailure(); + } + else if (test == "DeterministicSign") + { + totalTests++; + + // This test is specialized for RFC 6979. The RFC is a drop-in replacement + // for DSA and ECDSA, and access to the seed or secret is not needed. If + // additional deterministic signatures are added, then the test harness will + // likely need to be extended. + std::string signature; + SignerFilter f(Test::GlobalRNG(), *signer, new StringSink(signature)); + StringSource ss(GetDecodedDatum(v, "Message"), true, new FileSink(testDataFilename.c_str())); + FileSource fs(testDataFilename.c_str(), true, new Redirector(f)); + + if (GetDecodedDatum(v, "Signature") != signature) + SignalTestFailure(); + } +} + +void TestAsymmetricCipher(TestData &v, unsigned int &totalTests) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + static member_ptr encryptor; + static member_ptr decryptor; + static std::string lastName; + + if (name != lastName) + { + encryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + decryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + lastName = name; + + // Code coverage + (void)encryptor->AlgorithmName(); + (void)decryptor->AlgorithmName(); + (void)encryptor->AlgorithmProvider(); + (void)decryptor->AlgorithmProvider(); + } + + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + if (keyFormat == "DER") + { + totalTests++; + + decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + } + else if (keyFormat == "Component") + { + totalTests++; + + TestDataNameValuePairs pairs(v); + decryptor->AccessMaterial().AssignFrom(pairs); + encryptor->AccessMaterial().AssignFrom(pairs); + } + + if (test == "DecryptMatch") + { + totalTests++; + + std::string decrypted, expected = GetDecodedDatum(v, "Plaintext"); + StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(Test::GlobalRNG(), *decryptor, new StringSink(decrypted))); + if (decrypted != expected) + SignalTestFailure(); + } + else if (test == "KeyPairValidAndConsistent") + { + totalTests++; + + TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial(), totalTests); + } + else + { + std::string msg("Unknown asymmetric cipher test \"" + test + "\""); + SignalTestError(msg.c_str()); + CRYPTOPP_ASSERT(false); + } +} + +void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters, unsigned int &totalTests) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::string key = GetDecodedDatum(v, "Key"); + std::string plaintext = GetDecodedDatum(v, "Plaintext"); + + TestDataNameValuePairs testDataPairs(v); + CombinedNameValuePairs pairs(overrideParameters, testDataPairs); + + if (test == "Encrypt" || test == "EncryptXorDigest" || test == "Resync" || test == "EncryptionMCT" || test == "DecryptionMCT") + { + static member_ptr encryptor, decryptor; + static std::string lastName; + + totalTests++; + + if (name != lastName) + { + encryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + decryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + lastName = name; + + // Code coverage + (void)encryptor->AlgorithmName(); + (void)decryptor->AlgorithmName(); + (void)encryptor->AlgorithmProvider(); + (void)decryptor->AlgorithmProvider(); + (void)encryptor->IsRandomAccess(); + (void)decryptor->IsRandomAccess(); + (void)encryptor->MinKeyLength(); + (void)decryptor->MinKeyLength(); + (void)encryptor->MaxKeyLength(); + (void)decryptor->MaxKeyLength(); + (void)encryptor->DefaultKeyLength(); + (void)decryptor->DefaultKeyLength(); + } + + ConstByteArrayParameter iv; + if (pairs.GetValue(Name::IV(), iv) && iv.size() != encryptor->IVSize()) + SignalTestFailure(); + + if (test == "Resync") + { + encryptor->Resynchronize(iv.begin(), (int)iv.size()); + decryptor->Resynchronize(iv.begin(), (int)iv.size()); + } + else + { + encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + } + + word64 seek64 = pairs.GetWord64ValueWithDefault("Seek64", 0); + if (seek64) + { + encryptor->Seek(seek64); + decryptor->Seek(seek64); + } + else + { + int seek = pairs.GetIntValueWithDefault("Seek", 0); + if (seek) + { + encryptor->Seek(seek); + decryptor->Seek(seek); + } + } + + // Most block ciphers don't specify BlockPaddingScheme. Kalyna uses it + // in test vectors. 0 is NoPadding, 1 is ZerosPadding, 2 is PkcsPadding, + // 3 is OneAndZerosPadding, etc. Note: The machinery is wired such that + // paddingScheme is effectively latched. An old paddingScheme may be + // unintentionally used in a subsequent test. + int paddingScheme = pairs.GetIntValueWithDefault(Name::BlockPaddingScheme(), 0); + + std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest; + if (test == "EncryptionMCT" || test == "DecryptionMCT") + { + SymmetricCipher *cipher = encryptor.get(); + std::string buf(plaintext), keybuf(key); + + if (test == "DecryptionMCT") + { + cipher = decryptor.get(); + ciphertext = GetDecodedDatum(v, "Ciphertext"); + buf.assign(ciphertext.begin(), ciphertext.end()); + } + + for (int i=0; i<400; i++) + { + encrypted.reserve(10000 * plaintext.size()); + for (int j=0; j<10000; j++) + { + cipher->ProcessString(BytePtr(buf), BytePtrSize(buf)); + encrypted.append(buf.begin(), buf.end()); + } + + encrypted.erase(0, encrypted.size() - keybuf.size()); + xorbuf(BytePtr(keybuf), BytePtr(encrypted), BytePtrSize(keybuf)); + cipher->SetKey(BytePtr(keybuf), BytePtrSize(keybuf)); + } + + encrypted.assign(buf.begin(), buf.end()); + ciphertext = GetDecodedDatum(v, test == "EncryptionMCT" ? "Ciphertext" : "Plaintext"); + if (encrypted != ciphertext) + { + std::cout << "\nincorrectly encrypted: "; + StringSource ss(encrypted, false, new HexEncoder(new FileSink(std::cout))); + ss.Pump(256); ss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } + return; + } + + StreamTransformationFilter encFilter(*encryptor, new StringSink(encrypted), + static_cast(paddingScheme)); + + StringStore pstore(plaintext); + RandomizedTransfer(pstore, encFilter, true); + encFilter.MessageEnd(); + + if (test != "EncryptXorDigest") + { + ciphertext = GetDecodedDatum(v, "Ciphertext"); + } + else + { + ciphertextXorDigest = GetDecodedDatum(v, "CiphertextXorDigest"); + xorDigest.append(encrypted, 0, 64); + for (size_t i=64; i(xorDigest[i%64] ^ encrypted[i]); + } + if (test != "EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest) + { + std::cout << "\nincorrectly encrypted: "; + StringSource ss(encrypted, false, new HexEncoder(new FileSink(std::cout))); + ss.Pump(2048); ss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } + + std::string decrypted; + StreamTransformationFilter decFilter(*decryptor, new StringSink(decrypted), + static_cast(paddingScheme)); + + StringStore cstore(encrypted); + RandomizedTransfer(cstore, decFilter, true); + decFilter.MessageEnd(); + + if (decrypted != plaintext) + { + std::cout << "\nincorrectly decrypted: "; + StringSource ss(decrypted, false, new HexEncoder(new FileSink(std::cout))); + ss.Pump(256); ss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } + } + else + { + std::string msg("Unknown symmetric cipher test \"" + test + "\""); + SignalTestError(msg.c_str()); + } +} + +// Subset of TestSymmetricCipher. We picked the tests that have data that is easy to write to a file. +// Also see https://github.com/weidai11/cryptopp/issues/1010, where HIGHT broke when using FileSource. +void TestSymmetricCipherWithFileSource(TestData &v, const NameValuePairs &overrideParameters, unsigned int &totalTests) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + // Limit FileSource tests to Encrypt only. + if (test != "Encrypt") { return; } + + totalTests++; + + std::string key = GetDecodedDatum(v, "Key"); + std::string plaintext = GetDecodedDatum(v, "Plaintext"); + + TestDataNameValuePairs testDataPairs(v); + CombinedNameValuePairs pairs(overrideParameters, testDataPairs); + + static member_ptr encryptor, decryptor; + static std::string lastName; + + if (name != lastName) + { + encryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + decryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + lastName = name; + + // Code coverage + (void)encryptor->AlgorithmName(); + (void)decryptor->AlgorithmName(); + (void)encryptor->AlgorithmProvider(); + (void)decryptor->AlgorithmProvider(); + (void)encryptor->MinKeyLength(); + (void)decryptor->MinKeyLength(); + (void)encryptor->MaxKeyLength(); + (void)decryptor->MaxKeyLength(); + (void)encryptor->DefaultKeyLength(); + (void)decryptor->DefaultKeyLength(); + } + + ConstByteArrayParameter iv; + if (pairs.GetValue(Name::IV(), iv) && iv.size() != encryptor->IVSize()) + SignalTestFailure(); + + encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + + word64 seek64 = pairs.GetWord64ValueWithDefault("Seek64", 0); + if (seek64) + { + encryptor->Seek(seek64); + decryptor->Seek(seek64); + } + else + { + int seek = pairs.GetIntValueWithDefault("Seek", 0); + if (seek) + { + encryptor->Seek(seek); + decryptor->Seek(seek); + } + } + + // Most block ciphers don't specify BlockPaddingScheme. Kalyna uses it + // in test vectors. 0 is NoPadding, 1 is ZerosPadding, 2 is PkcsPadding, + // 3 is OneAndZerosPadding, etc. Note: The machinery is wired such that + // paddingScheme is effectively latched. An old paddingScheme may be + // unintentionally used in a subsequent test. + int paddingScheme = pairs.GetIntValueWithDefault(Name::BlockPaddingScheme(), 0); + + std::string encrypted, ciphertext; + StreamTransformationFilter encFilter(*encryptor, new StringSink(encrypted), + static_cast(paddingScheme)); + + StringSource ss(plaintext, true, new FileSink(testDataFilename.c_str())); + FileSource pstore(testDataFilename.c_str(), true); + RandomizedTransfer(pstore, encFilter, true); + encFilter.MessageEnd(); + + ciphertext = GetDecodedDatum(v, "Ciphertext"); + + if (encrypted != ciphertext) + { + std::cout << "\nincorrectly encrypted: "; + StringSource sss(encrypted, false, new HexEncoder(new FileSink(std::cout))); + sss.Pump(2048); sss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } + + std::string decrypted; + StreamTransformationFilter decFilter(*decryptor, new StringSink(decrypted), + static_cast(paddingScheme)); + + StringStore cstore(encrypted); + RandomizedTransfer(cstore, decFilter, true); + decFilter.MessageEnd(); + + if (decrypted != plaintext) + { + std::cout << "\nincorrectly decrypted: "; + StringSource sss(decrypted, false, new HexEncoder(new FileSink(std::cout))); + sss.Pump(256); sss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } +} + +void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters, unsigned int &totalTests) +{ + std::string type = GetRequiredDatum(v, "AlgorithmType"); + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + std::string key = GetDecodedDatum(v, "Key"); + + std::string plaintext = GetOptionalDecodedDatum(v, "Plaintext"); + std::string ciphertext = GetOptionalDecodedDatum(v, "Ciphertext"); + std::string header = GetOptionalDecodedDatum(v, "Header"); + std::string footer = GetOptionalDecodedDatum(v, "Footer"); + std::string mac = GetOptionalDecodedDatum(v, "MAC"); + + TestDataNameValuePairs testDataPairs(v); + CombinedNameValuePairs pairs(overrideParameters, testDataPairs); + + if (test == "Encrypt" || test == "EncryptXorDigest" || test == "NotVerify") + { + totalTests++; + + static member_ptr encryptor; + static member_ptr decryptor; + static std::string lastName; + + if (name != lastName) + { + encryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + decryptor.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + name = lastName; + + // Code coverage + (void)encryptor->AlgorithmName(); + (void)decryptor->AlgorithmName(); + (void)encryptor->AlgorithmProvider(); + (void)decryptor->AlgorithmProvider(); + (void)encryptor->MinKeyLength(); + (void)decryptor->MinKeyLength(); + (void)encryptor->MaxKeyLength(); + (void)decryptor->MaxKeyLength(); + (void)encryptor->DefaultKeyLength(); + (void)decryptor->DefaultKeyLength(); + (void)encryptor->IsRandomAccess(); + (void)decryptor->IsRandomAccess(); + (void)encryptor->IsSelfInverting(); + (void)decryptor->IsSelfInverting(); + (void)encryptor->MaxHeaderLength(); + (void)decryptor->MaxHeaderLength(); + (void)encryptor->MaxMessageLength(); + (void)decryptor->MaxMessageLength(); + (void)encryptor->MaxFooterLength(); + (void)decryptor->MaxFooterLength(); + (void)encryptor->NeedsPrespecifiedDataLengths(); + (void)decryptor->NeedsPrespecifiedDataLengths(); + } + + encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + + std::string encrypted, decrypted; + AuthenticatedEncryptionFilter ef(*encryptor, new StringSink(encrypted)); + bool macAtBegin = !mac.empty() && !Test::GlobalRNG().GenerateBit(); // test both ways randomly + AuthenticatedDecryptionFilter df(*decryptor, new StringSink(decrypted), macAtBegin ? AuthenticatedDecryptionFilter::MAC_AT_BEGIN : 0); + + if (encryptor->NeedsPrespecifiedDataLengths()) + { + encryptor->SpecifyDataLengths(header.size(), plaintext.size(), footer.size()); + decryptor->SpecifyDataLengths(header.size(), plaintext.size(), footer.size()); + } + + StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac); + + if (macAtBegin) + RandomizedTransfer(sm, df, true); + sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL); + RandomizedTransfer(sc, df, true); + sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL); + if (!macAtBegin) + RandomizedTransfer(sm, df, true); + df.MessageEnd(); + + RandomizedTransfer(sh, ef, true, AAD_CHANNEL); + RandomizedTransfer(sp, ef, true); + RandomizedTransfer(sf, ef, true, AAD_CHANNEL); + ef.MessageEnd(); + + if (test == "Encrypt" && encrypted != ciphertext+mac) + { + std::cout << "\nincorrectly encrypted: "; + StringSource ss(encrypted, false, new HexEncoder(new FileSink(std::cout))); + ss.Pump(2048); ss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } + if (test == "Encrypt" && decrypted != plaintext) + { + std::cout << "\nincorrectly decrypted: "; + StringSource ss(decrypted, false, new HexEncoder(new FileSink(std::cout))); + ss.Pump(256); ss.Flush(false); + std::cout << "\n"; + SignalTestFailure(); + } + + if (ciphertext.size()+mac.size()-plaintext.size() != encryptor->DigestSize()) + { + std::cout << "\nbad MAC size\n"; + SignalTestFailure(); + } + if (df.GetLastResult() != (test == "Encrypt")) + { + std::cout << "\nMAC incorrectly verified\n"; + SignalTestFailure(); + } + } + else + { + std::string msg("Unknown authenticated symmetric cipher test \"" + test + "\""); + SignalTestError(msg.c_str()); + } +} + +void TestDigestOrMAC(TestData &v, bool testDigest, unsigned int &totalTests) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + const char *digestName = testDigest ? "Digest" : "MAC"; + + member_ptr mac; + member_ptr hash; + HashTransformation *pHash = NULLPTR; + + TestDataNameValuePairs pairs(v); + + if (testDigest) + { + hash.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + pHash = hash.get(); + + // Code coverage + (void)hash->AlgorithmName(); + (void)hash->AlgorithmProvider(); + (void)hash->TagSize(); + (void)hash->DigestSize(); + (void)hash->Restart(); + } + else + { + mac.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + pHash = mac.get(); + std::string key = GetDecodedDatum(v, "Key"); + mac->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs); + + // Code coverage + (void)mac->AlgorithmName(); + (void)mac->AlgorithmProvider(); + (void)mac->TagSize(); + (void)mac->DigestSize(); + (void)mac->Restart(); + (void)mac->MinKeyLength(); + (void)mac->MaxKeyLength(); + (void)mac->DefaultKeyLength(); + } + + if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify") + { + totalTests++; + + int digestSize = -1; + if (test == "VerifyTruncated") + digestSize = pairs.GetIntValueWithDefault(Name::DigestSize(), digestSize); + HashVerificationFilter verifierFilter(*pHash, NULLPTR, HashVerificationFilter::HASH_AT_BEGIN, digestSize); + PutDecodedDatumInto(v, digestName, verifierFilter); + PutDecodedDatumInto(v, "Message", verifierFilter); + verifierFilter.MessageEnd(); + if (verifierFilter.GetLastResult() == (test == "NotVerify")) + SignalTestFailure(); + } + else + { + std::string msg("Unknown digest or mac test \"" + test + "\""); + SignalTestError(msg.c_str()); + } +} + +void TestKeyDerivationFunction(TestData &v, unsigned int &totalTests) +{ + totalTests++; + + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + if(test == "Skip") return; + + std::string secret = GetDecodedDatum(v, "Secret"); + std::string expected = GetDecodedDatum(v, "DerivedKey"); + + TestDataNameValuePairs pairs(v); + + static member_ptr kdf; + static std::string lastName; + + if (name != lastName) + { + kdf.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + name = lastName; + + // Code coverage + (void)kdf->AlgorithmName(); + (void)kdf->AlgorithmProvider(); + (void)kdf->MinDerivedKeyLength(); + (void)kdf->MaxDerivedKeyLength(); + } + + std::string calculated; calculated.resize(expected.size()); + kdf->DeriveKey(BytePtr(calculated), BytePtrSize(calculated), BytePtr(secret), BytePtrSize(secret), pairs); + + if(calculated != expected) + { + std::cerr << "Calculated: "; + StringSource(calculated, true, new HexEncoder(new FileSink(std::cerr))); + std::cerr << std::endl; + + SignalTestFailure(); + } +} + +inline char FirstChar(const std::string& str) { + if (str.empty()) return 0; + return str[0]; +} + +inline char LastChar(const std::string& str) { + if (str.empty()) return 0; + return str[str.length()-1]; +} + +// GetField parses the name/value pairs. If this function is modified, +// then run 'cryptest.exe tv all' to ensure parsing still works. +bool GetField(std::istream &is, std::string &name, std::string &value) +{ + std::string line; + name.clear(); value.clear(); + + // ***** Name ***** + while (Readline(is, line)) + { + // Eat empty lines and comments gracefully + line = TrimSpace(line); + if (line.empty() || line[0] == '#') + continue; + + std::string::size_type pos = line.find(':'); + if (pos == std::string::npos) + SignalTestError("Unable to parse name/value pair"); + + name = TrimSpace(line.substr(0, pos)); + line = TrimSpace(line.substr(pos +1)); + + // Empty name is bad + if (name.empty()) + return false; + + // Empty value is ok + if (line.empty()) + return true; + + break; + } + + // ***** Value ***** + bool continueLine = true; + + do + { + continueLine = false; + + // Trim leading and trailing whitespace. Don't parse comments + // here because there may be a line continuation at the end. + line = TrimSpace(line); + + if (line.empty()) + continue; + + // Check for continuation. The slash must be the last character. + if (LastChar(line) == '\\') { + continueLine = true; + line.erase(line.end()-1); + } + + // Re-trim after parsing + line = TrimComment(line); + line = TrimSpace(line); + + if (line.empty()) + continue; + + // Finally... the value + value += line; + + if (continueLine) + value += ' '; + } + while (continueLine && Readline(is, line)); + + return true; +} + +void OutputPair(const NameValuePairs &v, const char *name) +{ + Integer x; + bool b = v.GetValue(name, x); + CRYPTOPP_UNUSED(b); CRYPTOPP_ASSERT(b); + std::cout << name << ": \\\n "; + x.Encode(HexEncoder(new FileSink(std::cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize()); + std::cout << std::endl; +} + +void OutputNameValuePairs(const NameValuePairs &v) +{ + std::string names = v.GetValueNames(); + std::string::size_type i = 0; + while (i < names.size()) + { + std::string::size_type j = names.find_first_of (';', i); + + if (j == std::string::npos) + return; + else + { + std::string name = names.substr(i, j-i); + if (name.find(':') == std::string::npos) + OutputPair(v, name.c_str()); + } + + i = j + 1; + } +} + +void TestDataFile(std::string filename, const NameValuePairs &overrideParameters, unsigned int &totalTests, unsigned int &failedTests) +{ + std::ifstream file(DataDir(filename).c_str()); + if (!file.good()) + throw Exception(Exception::OTHER_ERROR, "Can not open file " + DataDir(filename) + " for reading"); + + TestData v; + s_currentTestData = &v; + std::string name, value, lastAlgName; + + while (file) + { + if (!GetField(file, name, value)) + break; + + if (name == "AlgorithmType") + v.clear(); + + // Can't assert value. Plaintext is sometimes empty. + // CRYPTOPP_ASSERT(!value.empty()); + v[name] = value; + + // The name "Test" is special. It tells the framework + // to run the test. Otherwise, name/value pairs are + // parsed and added to TestData 'v'. + if (name == "Test" && (s_thorough || v["SlowTest"] != "1")) + { + bool failed = false; + std::string algType = GetRequiredDatum(v, "AlgorithmType"); + std::string algName = GetRequiredDatum(v, "Name"); + + if (lastAlgName != algName) + { + std::cout << "\nTesting " << algType << " algorithm " << algName << ".\n"; + lastAlgName = algName; + } + + // In the old days each loop ran one test. Later, things were modified to run the + // the same test twice. Some tests are run with both a StringSource and a FileSource + // to catch FileSource specific errors. currentTests and deltaTests (below) keep + // the book keeping in order. + unsigned int currentTests = totalTests; + + try + { + if (algType == "Signature") + { + TestSignatureScheme(v, totalTests); + TestSignatureSchemeWithFileSource(v, totalTests); + } + else if (algType == "SymmetricCipher") + { + TestSymmetricCipher(v, overrideParameters, totalTests); + TestSymmetricCipherWithFileSource(v, overrideParameters, totalTests); + } + else if (algType == "AuthenticatedSymmetricCipher") + TestAuthenticatedSymmetricCipher(v, overrideParameters, totalTests); + else if (algType == "AsymmetricCipher") + TestAsymmetricCipher(v, totalTests); + else if (algType == "MessageDigest") + TestDigestOrMAC(v, true, totalTests); + else if (algType == "MAC") + TestDigestOrMAC(v, false, totalTests); + else if (algType == "KDF") + TestKeyDerivationFunction(v, totalTests); + else if (algType == "FileList") + TestDataFile(GetRequiredDatum(v, "Test"), g_nullNameValuePairs, totalTests, failedTests); + else + SignalUnknownAlgorithmError(algType); + } + catch (const TestFailure &) + { + failed = true; + std::cout << "\nTest FAILED.\n"; + } + catch (const Exception &e) + { + failed = true; + std::cout << "\nCryptoPP::Exception caught: " << e.what() << std::endl; + } + catch (const std::exception &e) + { + failed = true; + std::cout << "\nstd::exception caught: " << e.what() << std::endl; + } + + if (failed) + { + std::cout << "Skipping to next test." << std::endl; + failedTests++; + } + else + { + if (algType != "FileList") + { + unsigned int deltaTests = totalTests-currentTests; + if (deltaTests) + { + std::string progress(deltaTests, '.'); + std::cout << progress; + if (currentTests % 4 == 0) + std::cout << std::flush; + } + } + } + + // Most tests fully specify parameters, like key and iv. Each test gets + // its own unique value. Since each test gets a new value for each test + // case, latching a value in 'TestData v' does not matter. The old key + // or iv will get overwritten on the next test. + // + // If a per-test vector parameter was set for a test, like BlockPadding, + // BlockSize or Tweak, then it becomes latched in 'TestData v'. The old + // value is used in subsequent tests, and it could cause a self test + // failure in the next test. The behavior surfaced under Kalyna and + // Threefish. The Kalyna test vectors use NO_PADDING for all tests except + // one. Threefish occasionally uses a Tweak. + // + // Unlatch BlockPadding, BlockSize and Tweak now, after the test has been + // run. Also note we only unlatch from 'TestData v'. If overrideParameters + // are specified, the caller is responsible for managing the parameter. + v.erase("Tweak"); v.erase("InitialBlock"); + v.erase("BlockSize"); v.erase("BlockPaddingScheme"); + } + } +} + +ANONYMOUS_NAMESPACE_END + +bool RunTestDataFile(const char *filename, const NameValuePairs &overrideParameters, bool thorough) +{ + s_thorough = thorough; + unsigned int totalTests = 0, failedTests = 0; + TestDataFile((filename ? filename : ""), overrideParameters, totalTests, failedTests); + + std::cout << std::dec << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << "." << std::endl; + if (failedTests != 0) + std::cout << "SOME TESTS FAILED!\n"; + + CRYPTOPP_ASSERT(failedTests == 0); + return failedTests == 0; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/default.cpp b/external/ours/library/crypto/src/shared/original/default.cpp new file mode 100755 index 000000000..1723a0156 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/default.cpp @@ -0,0 +1,307 @@ +// default.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4127 4189) +#endif + +#include "cryptlib.h" +#include "filters.h" +#include "smartptr.h" +#include "default.h" +#include "queue.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +// The purpose of this function Mash() is to take an arbitrary length input +// string and *deterministicly* produce an arbitrary length output string such +// that (1) it looks random, (2) no information about the input is +// deducible from it, and (3) it contains as much entropy as it can hold, or +// the amount of entropy in the input string, whichever is smaller. + +template +static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations) +{ + if (BytePrecision(outLen) > 2) + throw InvalidArgument("Mash: output legnth too large"); + + size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)H::DIGESTSIZE); + byte b[2]; + SecByteBlock buf(bufSize); + SecByteBlock outBuf(bufSize); + H hash; + + unsigned int i; + for(i=0; i> 8); + b[1] = (byte) i; + hash.Update(b, 2); + hash.Update(in, inLen); + hash.Final(outBuf+i); + } + + while (iterations-- > 1) + { + memcpy(buf, outBuf, bufSize); + for (i=0; i> 8); + b[1] = (byte) i; + hash.Update(b, 2); + hash.Update(buf, bufSize); + hash.Final(outBuf+i); + } + } + + memcpy(out, outBuf, outLen); +} + +template +static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, unsigned int iterations, byte *key, byte *IV) +{ + // UBsan. User supplied params, may be NULL + SecByteBlock temp(passphraseLength+saltLength); + if (passphrase != NULLPTR) + memcpy(temp, passphrase, passphraseLength); + if (salt != NULLPTR) + memcpy(temp+passphraseLength, salt, saltLength); + + // OK. Derived params, cannot be NULL + SecByteBlock keyIV(EnumToInt(Info::KEYLENGTH)+EnumToInt(+Info::BLOCKSIZE)); + Mash(temp, passphraseLength + saltLength, keyIV, EnumToInt(Info::KEYLENGTH)+EnumToInt(+Info::BLOCKSIZE), iterations); + memcpy(key, keyIV, Info::KEYLENGTH); + memcpy(IV, keyIV+Info::KEYLENGTH, Info::BLOCKSIZE); +} + +// ******************************************************** + +template +DataEncryptor::DataEncryptor(const char *passphrase, BufferedTransformation *attachment) + : ProxyFilter(NULLPTR, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase)) +{ + CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= DIGESTSIZE); + CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE); +} + +template +DataEncryptor::DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) + : ProxyFilter(NULLPTR, 0, 0, attachment), m_passphrase(passphrase, passphraseLength) +{ + CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= (int)DIGESTSIZE); + CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE); +} + +template +void DataEncryptor::FirstPut(const byte *) +{ + SecByteBlock salt(DIGESTSIZE), keyCheck(DIGESTSIZE); + H hash; + + // use hash(passphrase | time | clock) as salt + hash.Update(m_passphrase, m_passphrase.size()); + time_t t=time(NULLPTR); + hash.Update((byte *)&t, sizeof(t)); + clock_t c=clock(); + hash.Update((byte *)&c, sizeof(c)); + hash.Final(salt); + + // use hash(passphrase | salt) as key check + hash.Update(m_passphrase, m_passphrase.size()); + hash.Update(salt, SALTLENGTH); + hash.Final(keyCheck); + + AttachedTransformation()->Put(salt, SALTLENGTH); + + // mash passphrase and salt together into key and IV + SecByteBlock key(KEYLENGTH); + SecByteBlock IV(BLOCKSIZE); + GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV); + + m_cipher.SetKeyWithIV(key, key.size(), IV); + SetFilter(new StreamTransformationFilter(m_cipher)); + + m_filter->Put(keyCheck, BLOCKSIZE); +} + +template +void DataEncryptor::LastPut(const byte *inString, size_t length) +{ + CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); + m_filter->MessageEnd(); +} + +// ******************************************************** + +template +DataDecryptor::DataDecryptor(const char *p, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULLPTR, EnumToInt(SALTLENGTH)+EnumToInt(BLOCKSIZE), 0, attachment) + , m_state(WAITING_FOR_KEYCHECK) + , m_passphrase((const byte *)p, strlen(p)) + , m_throwException(throwException) +{ + CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= (int)DIGESTSIZE); + CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE); +} + +template +DataDecryptor::DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULLPTR, EnumToInt(SALTLENGTH)+EnumToInt(BLOCKSIZE), 0, attachment) + , m_state(WAITING_FOR_KEYCHECK) + , m_passphrase(passphrase, passphraseLength) + , m_throwException(throwException) +{ + CRYPTOPP_COMPILE_ASSERT((int)SALTLENGTH <= (int)DIGESTSIZE); + CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE <= (int)DIGESTSIZE); +} + +template +void DataDecryptor::FirstPut(const byte *inString) +{ + CheckKey(inString, inString+SALTLENGTH); +} + +template +void DataDecryptor::LastPut(const byte *inString, size_t length) +{ + CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); + if (m_filter.get() == NULLPTR) + { + m_state = KEY_BAD; + if (m_throwException) + throw KeyBadErr(); + } + else + { + m_filter->MessageEnd(); + m_state = WAITING_FOR_KEYCHECK; + } +} + +template +void DataDecryptor::CheckKey(const byte *salt, const byte *keyCheck) +{ + SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DIGESTSIZE)); + + H hash; + hash.Update(m_passphrase, m_passphrase.size()); + hash.Update(salt, SALTLENGTH); + hash.Final(check); + + SecByteBlock key(KEYLENGTH); + SecByteBlock IV(BLOCKSIZE); + GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV); + + m_cipher.SetKeyWithIV(key, key.size(), IV); + member_ptr decryptor(new StreamTransformationFilter(m_cipher)); + + decryptor->Put(keyCheck, BLOCKSIZE); + decryptor->ForceNextPut(); + decryptor->Get(check+EnumToInt(BLOCKSIZE), BLOCKSIZE); + + SetFilter(decryptor.release()); + + if (!VerifyBufsEqual(check, check+EnumToInt(BLOCKSIZE), BLOCKSIZE)) + { + m_state = KEY_BAD; + if (m_throwException) + throw KeyBadErr(); + } + else + m_state = KEY_GOOD; +} + +// ******************************************************** + +template +static MAC* NewDataEncryptorMAC(const byte *passphrase, size_t passphraseLength) +{ + size_t macKeyLength = MAC::StaticGetValidKeyLength(16); + SecByteBlock macKey(macKeyLength); + // since the MAC is encrypted there is no reason to mash the passphrase for many iterations + Mash(passphrase, passphraseLength, macKey, macKeyLength, 1); + return new MAC(macKey, macKeyLength); +} + +template +DataEncryptorWithMAC::DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment) + : ProxyFilter(NULLPTR, 0, 0, attachment) + , m_mac(NewDataEncryptorMAC((const byte *)passphrase, strlen(passphrase))) +{ + SetFilter(new HashFilter(*m_mac, new DataEncryptor(passphrase), true)); +} + +template +DataEncryptorWithMAC::DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) + : ProxyFilter(NULLPTR, 0, 0, attachment) + , m_mac(NewDataEncryptorMAC(passphrase, passphraseLength)) +{ + SetFilter(new HashFilter(*m_mac, new DataEncryptor(passphrase, passphraseLength), true)); +} + +template +void DataEncryptorWithMAC::LastPut(const byte *inString, size_t length) +{ + CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); + m_filter->MessageEnd(); +} + +// ******************************************************** + +template +DataDecryptorWithMAC::DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULLPTR, 0, 0, attachment) + , m_mac(NewDataEncryptorMAC((const byte *)passphrase, strlen(passphrase))) + , m_throwException(throwException) +{ + SetFilter(new DataDecryptor(passphrase, m_hashVerifier=new HashVerificationFilter(*m_mac, NULLPTR, HashVerificationFilter::PUT_MESSAGE), throwException)); +} + +template +DataDecryptorWithMAC::DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULLPTR, 0, 0, attachment) + , m_mac(NewDataEncryptorMAC(passphrase, passphraseLength)) + , m_throwException(throwException) +{ + SetFilter(new DataDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerificationFilter(*m_mac, NULLPTR, HashVerificationFilter::PUT_MESSAGE), throwException)); +} + +template +typename DataDecryptor::State DataDecryptorWithMAC::CurrentState() const +{ + return static_cast *>(m_filter.get())->CurrentState(); +} + +template +bool DataDecryptorWithMAC::CheckLastMAC() const +{ + return m_hashVerifier->GetLastResult(); +} + +template +void DataDecryptorWithMAC::LastPut(const byte *inString, size_t length) +{ + CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); + m_filter->MessageEnd(); + if (m_throwException && !CheckLastMAC()) + throw MACBadErr(); +} + +template struct DataParametersInfo; +template struct DataParametersInfo; + +template class DataEncryptor; +template class DataDecryptor; +template class DataEncryptor; +template class DataDecryptor; +template class DataEncryptorWithMAC; +template class DataDecryptorWithMAC; +template class DataEncryptorWithMAC; +template class DataDecryptorWithMAC; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/default.h b/external/ours/library/crypto/src/shared/original/default.h new file mode 100755 index 000000000..7fe443f2a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/default.h @@ -0,0 +1,310 @@ +// default.h - originally written and placed in the public domain by Wei Dai + +/// \file default.h +/// \brief Classes for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC + +#ifndef CRYPTOPP_DEFAULT_H +#define CRYPTOPP_DEFAULT_H + +#include "sha.h" +#include "hmac.h" +#include "aes.h" +#include "des.h" +#include "modes.h" +#include "filters.h" +#include "smartptr.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Legacy block cipher for LegacyEncryptor, LegacyDecryptor, LegacyEncryptorWithMAC and LegacyDecryptorWithMAC +typedef DES_EDE2 LegacyBlockCipher; +/// \brief Legacy hash for use with LegacyEncryptorWithMAC and LegacyDecryptorWithMAC +typedef SHA1 LegacyHashModule; +/// \brief Legacy HMAC for use withLegacyEncryptorWithMAC and LegacyDecryptorWithMAC +typedef HMAC LegacyMAC; + +/// \brief Default block cipher for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC +typedef AES DefaultBlockCipher; +/// \brief Default hash for use with DefaultEncryptorWithMAC and DefaultDecryptorWithMAC +typedef SHA256 DefaultHashModule; +/// \brief Default HMAC for use withDefaultEncryptorWithMAC and DefaultDecryptorWithMAC +typedef HMAC DefaultMAC; + +/// \brief Exception thrown when LegacyDecryptorWithMAC or DefaultDecryptorWithMAC decryption error is encountered +class DataDecryptorErr : public Exception +{ +public: + DataDecryptorErr(const std::string &s) + : Exception(DATA_INTEGRITY_CHECK_FAILED, s) {} +}; + +/// \brief Exception thrown when a bad key is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC +class KeyBadErr : public DataDecryptorErr +{ + public: KeyBadErr() + : DataDecryptorErr("DataDecryptor: cannot decrypt message with this passphrase") {} +}; + +/// \brief Exception thrown when an incorrect MAC is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC +class MACBadErr : public DataDecryptorErr +{ + public: MACBadErr() + : DataDecryptorErr("DataDecryptorWithMAC: MAC check failed") {} +}; + +/// \brief Algorithm information for password-based encryptors and decryptors +template +struct DataParametersInfo +{ + CRYPTOPP_CONSTANT(BLOCKSIZE = BlockSize); + CRYPTOPP_CONSTANT(KEYLENGTH = KeyLength); + CRYPTOPP_CONSTANT(SALTLENGTH = SaltSize); + CRYPTOPP_CONSTANT(DIGESTSIZE = DigestSize); + CRYPTOPP_CONSTANT(ITERATIONS = Iterations); +}; + +typedef DataParametersInfo LegacyParametersInfo; +typedef DataParametersInfo DefaultParametersInfo; + +/// \brief Password-based Encryptor +/// \tparam BC BlockCipher based class used for encryption +/// \tparam H HashTransformation based class used for mashing +/// \tparam Info Constants used by the algorithms +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. +/// \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor +/// \since Crypto++ 2.0 +template +class DataEncryptor : public ProxyFilter, public Info +{ +public: + CRYPTOPP_CONSTANT(BLOCKSIZE = Info::BLOCKSIZE); + CRYPTOPP_CONSTANT(KEYLENGTH = Info::KEYLENGTH); + CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH); + CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS); + + /// \brief Construct a DataEncryptor + /// \param passphrase a C-String password + /// \param attachment a BufferedTransformation to attach to this object + DataEncryptor(const char *passphrase, BufferedTransformation *attachment = NULLPTR); + + /// \brief Construct a DataEncryptor + /// \param passphrase a byte string password + /// \param passphraseLength the length of the byte string password + /// \param attachment a BufferedTransformation to attach to this object + DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR); + +protected: + void FirstPut(const byte *); + void LastPut(const byte *inString, size_t length); + +private: + SecByteBlock m_passphrase; + typename CBC_Mode::Encryption m_cipher; +}; + +/// \brief Password-based Decryptor +/// \tparam BC BlockCipher based class used for encryption +/// \tparam H HashTransformation based class used for mashing +/// \tparam Info Constants used by the algorithms +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. +/// \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor +/// \since Crypto++ 2.0 +template +class DataDecryptor : public ProxyFilter, public Info +{ +public: + CRYPTOPP_CONSTANT(BLOCKSIZE = Info::BLOCKSIZE); + CRYPTOPP_CONSTANT(KEYLENGTH = Info::KEYLENGTH); + CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH); + CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS); + + /// \brief Constructs a DataDecryptor + /// \param passphrase a C-String password + /// \param attachment a BufferedTransformation to attach to this object + /// \param throwException a flag specifying whether an Exception should be thrown on error + DataDecryptor(const char *passphrase, BufferedTransformation *attachment = NULLPTR, bool throwException=true); + + /// \brief Constructs a DataDecryptor + /// \param passphrase a byte string password + /// \param passphraseLength the length of the byte string password + /// \param attachment a BufferedTransformation to attach to this object + /// \param throwException a flag specifying whether an Exception should be thrown on error + DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR, bool throwException=true); + + enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD}; + State CurrentState() const {return m_state;} + +protected: + void FirstPut(const byte *inString); + void LastPut(const byte *inString, size_t length); + + State m_state; + +private: + void CheckKey(const byte *salt, const byte *keyCheck); + + SecByteBlock m_passphrase; + typename CBC_Mode::Decryption m_cipher; + member_ptr m_decryptor; + bool m_throwException; + +}; + +/// \brief Password-based encryptor with MAC +/// \tparam BC BlockCipher based class used for encryption +/// \tparam H HashTransformation based class used for mashing +/// \tparam MAC HashTransformation based class used for authentication +/// \tparam Info Constants used by the algorithms +/// \details DataEncryptorWithMAC uses a non-standard mashup function called Mash() to derive key +/// bits from the password. +/// \details The purpose of the function Mash() is to take an arbitrary length input string and +/// *deterministically* produce an arbitrary length output string such that (1) it looks random, +/// (2) no information about the input is deducible from it, and (3) it contains as much entropy +/// as it can hold, or the amount of entropy in the input string, whichever is smaller. +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. +/// \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC +/// \since Crypto++ 2.0 +template +class DataEncryptorWithMAC : public ProxyFilter +{ +public: + CRYPTOPP_CONSTANT(BLOCKSIZE = Info::BLOCKSIZE); + CRYPTOPP_CONSTANT(KEYLENGTH = Info::KEYLENGTH); + CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH); + CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS); + + /// \brief Constructs a DataEncryptorWithMAC + /// \param passphrase a C-String password + /// \param attachment a BufferedTransformation to attach to this object + DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULLPTR); + + /// \brief Constructs a DataEncryptorWithMAC + /// \param passphrase a byte string password + /// \param passphraseLength the length of the byte string password + /// \param attachment a BufferedTransformation to attach to this object + DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR); + +protected: + void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);} + void LastPut(const byte *inString, size_t length); + +private: + member_ptr m_mac; + +}; + +/// \brief Password-based decryptor with MAC +/// \tparam BC BlockCipher based class used for encryption +/// \tparam H HashTransformation based class used for mashing +/// \tparam MAC HashTransformation based class used for authentication +/// \tparam Info Constants used by the algorithms +/// \details DataDecryptorWithMAC uses a non-standard mashup function called Mash() to derive key +/// bits from the password. +/// \details The purpose of the function Mash() is to take an arbitrary length input string and +/// *deterministically* produce an arbitrary length output string such that (1) it looks random, +/// (2) no information about the input is deducible from it, and (3) it contains as much entropy +/// as it can hold, or the amount of entropy in the input string, whichever is smaller. +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. +/// \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC +/// \since Crypto++ 2.0 +template +class DataDecryptorWithMAC : public ProxyFilter +{ +public: + CRYPTOPP_CONSTANT(BLOCKSIZE = Info::BLOCKSIZE); + CRYPTOPP_CONSTANT(KEYLENGTH = Info::KEYLENGTH); + CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH); + CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE); + CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS); + + /// \brief Constructs a DataDecryptor + /// \param passphrase a C-String password + /// \param attachment a BufferedTransformation to attach to this object + /// \param throwException a flag specifying whether an Exception should be thrown on error + DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULLPTR, bool throwException=true); + + /// \brief Constructs a DataDecryptor + /// \param passphrase a byte string password + /// \param passphraseLength the length of the byte string password + /// \param attachment a BufferedTransformation to attach to this object + /// \param throwException a flag specifying whether an Exception should be thrown on error + DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULLPTR, bool throwException=true); + + typename DataDecryptor::State CurrentState() const; + bool CheckLastMAC() const; + +protected: + void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);} + void LastPut(const byte *inString, size_t length); + +private: + member_ptr m_mac; + HashVerificationFilter *m_hashVerifier; + bool m_throwException; +}; + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Password-based encryptor (deprecated) +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct LegacyEncryptor : public DataEncryptor {}; +/// \brief Password-based decryptor (deprecated) +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct LegacyDecryptor : public DataDecryptor {}; +/// \brief Password-based encryptor +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct DefaultEncryptor : public DataEncryptor {}; +/// \brief Password-based decryptor +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct DefaultDecryptor : public DataDecryptor {}; +/// \brief Password-based encryptor with MAC (deprecated) +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct LegacyEncryptorWithMAC : public DataEncryptorWithMAC {}; +/// \brief Password-based decryptor with MAC (deprecated) +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct LegacyDecryptorWithMAC : public DataDecryptorWithMAC {}; +/// \brief Password-based encryptor with MAC +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct DefaultEncryptorWithMAC : public DataEncryptorWithMAC {}; +/// \brief Password-based decryptor with MAC +/// \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1. +/// Crypto++ 5.7 switched to AES and SHA256. The updated algorithms are available with the +/// Default* classes, and the old algorithms are available with the Legacy* classes. +struct DefaultDecryptorWithMAC : public DataDecryptorWithMAC {}; +#else +typedef DataEncryptor LegacyEncryptor; +typedef DataDecryptor LegacyDecryptor; + +typedef DataEncryptor DefaultEncryptor; +typedef DataDecryptor DefaultDecryptor; + +typedef DataEncryptorWithMAC LegacyEncryptorWithMAC; +typedef DataDecryptorWithMAC LegacyDecryptorWithMAC; + +typedef DataEncryptorWithMAC DefaultEncryptorWithMAC; +typedef DataDecryptorWithMAC DefaultDecryptorWithMAC; +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/des.cpp b/external/ours/library/crypto/src/shared/original/des.cpp new file mode 100755 index 000000000..2a130aa4a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/des.cpp @@ -0,0 +1,465 @@ +// des.cpp - modified by Wei Dai from Phil Karn's des.c +// The original code and all modifications are in the public domain. + +/* + * This is a major rewrite of my old public domain DES code written + * circa 1987, which in turn borrowed heavily from Jim Gillogly's 1977 + * public domain code. I pretty much kept my key scheduling code, but + * the actual encrypt/decrypt routines are taken from from Richard + * Outerbridge's DES code as printed in Schneier's "Applied Cryptography." + * + * This code is in the public domain. I would appreciate bug reports and + * enhancements. + * + * Phil Karn KA9Q, karn@unix.ka9q.ampr.org, August 1994. + */ + +#include "pch.h" +#include "misc.h" +#include "des.h" + +NAMESPACE_BEGIN(CryptoPP) + +typedef BlockGetAndPut Block; + +// Richard Outerbridge's initial permutation algorithm +/* +inline void IPERM(word32 &left, word32 &right) +{ + word32 work; + + work = ((left >> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + left ^= work << 4; + work = ((left >> 16) ^ right) & 0xffff; + right ^= work; + left ^= work << 16; + work = ((right >> 2) ^ left) & 0x33333333; + left ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ left) & 0xff00ff; + left ^= work; + right ^= (work << 8); + right = rotl(right, 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = rotl(left, 1); +} +inline void FPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotr(right, 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = rotr(left, 1); + work = ((left >> 8) ^ right) & 0xff00ff; + right ^= work; + left ^= work << 8; + work = ((left >> 2) ^ right) & 0x33333333; + right ^= work; + left ^= work << 2; + work = ((right >> 16) ^ left) & 0xffff; + left ^= work; + right ^= work << 16; + work = ((right >> 4) ^ left) & 0x0f0f0f0f; + left ^= work; + right ^= work << 4; +} +*/ + +// Wei Dai's modification to Richard Outerbridge's initial permutation +// algorithm, this one is faster if you have access to rotate instructions +// (like in MSVC) +static inline void IPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotlConstant<4>(right); + work = (left ^ right) & 0xf0f0f0f0; + left ^= work; + right = rotrConstant<20>(right^work); + work = (left ^ right) & 0xffff0000; + left ^= work; + right = rotrConstant<18>(right^work); + work = (left ^ right) & 0x33333333; + left ^= work; + right = rotrConstant<6>(right^work); + work = (left ^ right) & 0x00ff00ff; + left ^= work; + right = rotlConstant<9>(right^work); + work = (left ^ right) & 0xaaaaaaaa; + left = rotlConstant<1>(left^work); + right ^= work; +} + +static inline void FPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotrConstant<1>(right); + work = (left ^ right) & 0xaaaaaaaa; + right ^= work; + left = rotrConstant<9>(left^work); + work = (left ^ right) & 0x00ff00ff; + right ^= work; + left = rotlConstant<6>(left^work); + work = (left ^ right) & 0x33333333; + right ^= work; + left = rotlConstant<18>(left^work); + work = (left ^ right) & 0xffff0000; + right ^= work; + left = rotlConstant<20>(left^work); + work = (left ^ right) & 0xf0f0f0f0; + right ^= work; + left = rotrConstant<4>(left^work); +} + +void DES::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + RawSetKey(GetCipherDirection(), userKey); +} + +#ifndef CRYPTOPP_IMPORTS + +/* Tables defined in the Data Encryption Standard documents + * Three of these tables, the initial permutation, the final + * permutation and the expansion operator, are regular enough that + * for speed, we hard-code them. They're here for reference only. + * Also, the S and P boxes are used by a separate program, gensp.c, + * to build the combined SP box, Spbox[]. They're also here just + * for reference. + */ +#ifdef notdef +/* initial permutation IP */ +static byte ip[] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +/* final permutation IP^-1 */ +static byte fp[] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; +/* expansion operation matrix */ +static byte ei[] = { + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 +}; +/* The (in)famous S-boxes */ +static byte sbox[8][64] = { + /* S1 */ + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + + /* S2 */ + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + + /* S3 */ + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + + /* S4 */ + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + + /* S5 */ + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + + /* S6 */ + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + + /* S7 */ + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + + /* S8 */ + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 +}; + +/* 32-bit permutation function P used on the output of the S-boxes */ +namespace { + const byte p32i[] = { + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 + }; +} +#endif + +/* permuted choice table (key) */ +namespace { + const byte pc1[] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 + }; +} + +/* number left rotations of pc1 */ +namespace { + const byte totrot[] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 + }; +} + +/* permuted choice key (table) */ +namespace { + const byte pc2[] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 + }; +} + +/* End of DES-defined tables */ + +/* bit 0 is left-most in byte */ +namespace { + const int bytebit[] = { + 0200,0100,040,020,010,04,02,01 + }; +} + +/* Set key (initialize key schedule array) */ +void RawDES::RawSetKey(CipherDir dir, const byte *key) +{ +#if (_MSC_VER >= 1600) || (__cplusplus >= 201103L) +# define REGISTER /* Define to nothing for C++11 and above */ +#else +# define REGISTER register +#endif + + SecByteBlock buffer(56+56+8); + byte *const pc1m=buffer; /* place to modify pc1 into */ + byte *const pcr=pc1m+56; /* place to rotate pc1 into */ + byte *const ks=pcr+56; + REGISTER int i,j,l; + int m; + + for (j=0; j<56; j++) { /* convert pc1 to bits of key */ + l=pc1[j]-1; /* integer bit location */ + m = l & 07; /* find bit */ + pc1m[j]=(key[l>>3] & /* find which key byte l is in */ + bytebit[m]) /* and which bit of that byte */ + ? 1 : 0; /* and store 1-bit result */ + } + for (i=0; i<16; i++) { /* key chunk for each iteration */ + memset(ks,0,8); /* Clear key schedule */ + for (j=0; j<56; j++) /* rotate pc1 the right amount */ + pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28]; + /* rotate left and right halves independently */ + for (j=0; j<48; j++){ /* select bits individually */ + /* check bit that goes to ks[j] */ + if (pcr[pc2[j]-1]){ + /* mask it in if it's there */ + l= j % 6; + ks[j/6] |= bytebit[l] >> 2; + } + } + /* Now convert to odd/even interleaved form for use in F */ + k[2*i] = ((word32)ks[0] << 24) + | ((word32)ks[2] << 16) + | ((word32)ks[4] << 8) + | ((word32)ks[6]); + k[2*i+1] = ((word32)ks[1] << 24) + | ((word32)ks[3] << 16) + | ((word32)ks[5] << 8) + | ((word32)ks[7]); + } + + if (dir==DECRYPTION) // reverse key schedule order + for (i=0; i<16; i+=2) + { + std::swap(k[i], k[32-2-i]); + std::swap(k[i+1], k[32-1-i]); + } +} + +void RawDES::RawProcessBlock(word32 &l_, word32 &r_) const +{ + word32 l = l_, r = r_; + const word32 *kptr=k; + + for (unsigned i=0; i<8; i++) + { + word32 work = rotrConstant<4>(r) ^ kptr[4 * i + 0]; + l ^= Spbox[6][(work) & 0x3f] + ^ Spbox[4][(work >> 8) & 0x3f] + ^ Spbox[2][(work >> 16) & 0x3f] + ^ Spbox[0][(work >> 24) & 0x3f]; + work = r ^ kptr[4*i+1]; + l ^= Spbox[7][(work) & 0x3f] + ^ Spbox[5][(work >> 8) & 0x3f] + ^ Spbox[3][(work >> 16) & 0x3f] + ^ Spbox[1][(work >> 24) & 0x3f]; + + work = rotrConstant<4>(l) ^ kptr[4 * i + 2]; + r ^= Spbox[6][(work) & 0x3f] + ^ Spbox[4][(work >> 8) & 0x3f] + ^ Spbox[2][(work >> 16) & 0x3f] + ^ Spbox[0][(work >> 24) & 0x3f]; + work = l ^ kptr[4*i+3]; + r ^= Spbox[7][(work) & 0x3f] + ^ Spbox[5][(work >> 8) & 0x3f] + ^ Spbox[3][(work >> 16) & 0x3f] + ^ Spbox[1][(work >> 24) & 0x3f]; + } + + l_ = l; r_ = r; +} + +void DES_EDE2::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + m_des1.RawSetKey(GetCipherDirection(), userKey); + m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey+8); +} + +void DES_EDE2::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + m_des1.RawProcessBlock(l, r); + m_des2.RawProcessBlock(r, l); + m_des1.RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + +void DES_EDE3::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16)); + m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey + 8); + m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0)); +} + +void DES_EDE3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + m_des1.RawProcessBlock(l, r); + m_des2.RawProcessBlock(r, l); + m_des3.RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + +#endif // #ifndef CRYPTOPP_IMPORTS + +static inline bool CheckParity(byte b) +{ + unsigned int a = b ^ (b >> 4); + return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1; +} + +bool DES::CheckKeyParityBits(const byte *key) +{ + for (unsigned int i=0; i<8; i++) + if (!CheckParity(key[i])) + return false; + return true; +} + +void DES::CorrectKeyParityBits(byte *key) +{ + for (unsigned int i=0; i<8; i++) + if (!CheckParity(key[i])) + key[i] ^= 1; +} + +// Encrypt or decrypt a block of data in ECB mode +void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + +void DES_XEX3::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + if (!m_des.get()) + m_des.reset(new DES::Encryption); + + memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE); + m_des->RawSetKey(GetCipherDirection(), key + 8); + memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE); +} + +void DES_XEX3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE); + m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock); + xorbuf(outBlock, m_x3, BLOCKSIZE); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/des.h b/external/ours/library/crypto/src/shared/original/des.h new file mode 100755 index 000000000..ece7b378d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/des.h @@ -0,0 +1,163 @@ +// des.h - originally written and placed in the public domain by Wei Dai + +/// \file des.h +/// \brief Classes for DES, 2-key Triple-DES, 3-key Triple-DES and DESX + +#ifndef CRYPTOPP_DES_H +#define CRYPTOPP_DES_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief DES block cipher base class +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL RawDES +{ +public: + void RawSetKey(CipherDir direction, const byte *userKey); + void RawProcessBlock(word32 &l, word32 &r) const; + +protected: + static const word32 Spbox[8][64]; + + FixedSizeSecBlock k; +}; + +/// \brief DES block cipher information +/// \since Crypto++ 1.0 +struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8> +{ + // disable DES in DLL version by not exporting this function + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "DES";} +}; + +/// \brief DES block cipher +/// \details The DES implementation in Crypto++ ignores the parity bits +/// (the least significant bits of each byte) in the key. However you can use CheckKeyParityBits() +/// and CorrectKeyParityBits() to check or correct the parity bits if you wish. +/// \sa DES +/// \since Crypto++ 1.0 +class DES : public DES_Info, public BlockCipherDocumentation +{ + /// \brief DES block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl, public RawDES + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + /// check DES key parity bits + static bool CheckKeyParityBits(const byte *key); + /// correct DES key parity bits + static void CorrectKeyParityBits(byte *key); + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief 2-key TripleDES block cipher information +/// \since Crypto++ 1.0 +struct DES_EDE2_Info : public FixedBlockSize<8>, public FixedKeyLength<16> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE2";} +}; + +/// \brief 2-key TripleDES block cipher +/// \sa DES-EDE2 +/// \since Crypto++ 1.0 +class DES_EDE2 : public DES_EDE2_Info, public BlockCipherDocumentation +{ + /// \brief DES_EDE2 block cipher default operation + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + RawDES m_des1, m_des2; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief 3-key TripleDES block cipher information +/// \since Crypto++ 1.0 +struct DES_EDE3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE3";} +}; + +/// \brief 3-key TripleDES block cipher +/// \sa DES-EDE3 +/// \since Crypto++ 1.0 +class DES_EDE3 : public DES_EDE3_Info, public BlockCipherDocumentation +{ + /// \brief DES_EDE3 block cipher default operation + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + RawDES m_des1, m_des2, m_des3; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief DESX block cipher information +/// \since Crypto++ 3.2 +struct DES_XEX3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "DES-XEX3";} +}; + +/// \brief DESX block cipher +/// \sa DES-XEX3, AKA DESX +/// \since Crypto++ 3.2 +class DES_XEX3 : public DES_XEX3_Info, public BlockCipherDocumentation +{ + /// \brief DES_XEX3 block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + FixedSizeSecBlock m_x1, m_x3; + // VS2005 workaround: calling modules compiled with /clr gets unresolved external symbol DES::Base::ProcessAndXorBlock + // if we use DES::Encryption here directly without value_ptr. + value_ptr m_des; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef DES::Encryption DESEncryption; +typedef DES::Decryption DESDecryption; + +typedef DES_EDE2::Encryption DES_EDE2_Encryption; +typedef DES_EDE2::Decryption DES_EDE2_Decryption; + +typedef DES_EDE3::Encryption DES_EDE3_Encryption; +typedef DES_EDE3::Decryption DES_EDE3_Decryption; + +typedef DES_XEX3::Encryption DES_XEX3_Encryption; +typedef DES_XEX3::Decryption DES_XEX3_Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dessp.cpp b/external/ours/library/crypto/src/shared/original/dessp.cpp new file mode 100755 index 000000000..46ca7aaf7 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dessp.cpp @@ -0,0 +1,88 @@ +// This file is mostly generated by Phil Karn's gensp.c + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "des.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word32 RawDES::Spbox[8][64] = { +{ +0x01010400,0x00000000,0x00010000,0x01010404, 0x01010004,0x00010404,0x00000004,0x00010000, +0x00000400,0x01010400,0x01010404,0x00000400, 0x01000404,0x01010004,0x01000000,0x00000004, +0x00000404,0x01000400,0x01000400,0x00010400, 0x00010400,0x01010000,0x01010000,0x01000404, +0x00010004,0x01000004,0x01000004,0x00010004, 0x00000000,0x00000404,0x00010404,0x01000000, +0x00010000,0x01010404,0x00000004,0x01010000, 0x01010400,0x01000000,0x01000000,0x00000400, +0x01010004,0x00010000,0x00010400,0x01000004, 0x00000400,0x00000004,0x01000404,0x00010404, +0x01010404,0x00010004,0x01010000,0x01000404, 0x01000004,0x00000404,0x00010404,0x01010400, +0x00000404,0x01000400,0x01000400,0x00000000, 0x00010004,0x00010400,0x00000000,0x01010004}, +{ +0x80108020,0x80008000,0x00008000,0x00108020, 0x00100000,0x00000020,0x80100020,0x80008020, +0x80000020,0x80108020,0x80108000,0x80000000, 0x80008000,0x00100000,0x00000020,0x80100020, +0x00108000,0x00100020,0x80008020,0x00000000, 0x80000000,0x00008000,0x00108020,0x80100000, +0x00100020,0x80000020,0x00000000,0x00108000, 0x00008020,0x80108000,0x80100000,0x00008020, +0x00000000,0x00108020,0x80100020,0x00100000, 0x80008020,0x80100000,0x80108000,0x00008000, +0x80100000,0x80008000,0x00000020,0x80108020, 0x00108020,0x00000020,0x00008000,0x80000000, +0x00008020,0x80108000,0x00100000,0x80000020, 0x00100020,0x80008020,0x80000020,0x00100020, +0x00108000,0x00000000,0x80008000,0x00008020, 0x80000000,0x80100020,0x80108020,0x00108000}, +{ +0x00000208,0x08020200,0x00000000,0x08020008, 0x08000200,0x00000000,0x00020208,0x08000200, +0x00020008,0x08000008,0x08000008,0x00020000, 0x08020208,0x00020008,0x08020000,0x00000208, +0x08000000,0x00000008,0x08020200,0x00000200, 0x00020200,0x08020000,0x08020008,0x00020208, +0x08000208,0x00020200,0x00020000,0x08000208, 0x00000008,0x08020208,0x00000200,0x08000000, +0x08020200,0x08000000,0x00020008,0x00000208, 0x00020000,0x08020200,0x08000200,0x00000000, +0x00000200,0x00020008,0x08020208,0x08000200, 0x08000008,0x00000200,0x00000000,0x08020008, +0x08000208,0x00020000,0x08000000,0x08020208, 0x00000008,0x00020208,0x00020200,0x08000008, +0x08020000,0x08000208,0x00000208,0x08020000, 0x00020208,0x00000008,0x08020008,0x00020200}, +{ +0x00802001,0x00002081,0x00002081,0x00000080, 0x00802080,0x00800081,0x00800001,0x00002001, +0x00000000,0x00802000,0x00802000,0x00802081, 0x00000081,0x00000000,0x00800080,0x00800001, +0x00000001,0x00002000,0x00800000,0x00802001, 0x00000080,0x00800000,0x00002001,0x00002080, +0x00800081,0x00000001,0x00002080,0x00800080, 0x00002000,0x00802080,0x00802081,0x00000081, +0x00800080,0x00800001,0x00802000,0x00802081, 0x00000081,0x00000000,0x00000000,0x00802000, +0x00002080,0x00800080,0x00800081,0x00000001, 0x00802001,0x00002081,0x00002081,0x00000080, +0x00802081,0x00000081,0x00000001,0x00002000, 0x00800001,0x00002001,0x00802080,0x00800081, +0x00002001,0x00002080,0x00800000,0x00802001, 0x00000080,0x00800000,0x00002000,0x00802080}, +{ +0x00000100,0x02080100,0x02080000,0x42000100, 0x00080000,0x00000100,0x40000000,0x02080000, +0x40080100,0x00080000,0x02000100,0x40080100, 0x42000100,0x42080000,0x00080100,0x40000000, +0x02000000,0x40080000,0x40080000,0x00000000, 0x40000100,0x42080100,0x42080100,0x02000100, +0x42080000,0x40000100,0x00000000,0x42000000, 0x02080100,0x02000000,0x42000000,0x00080100, +0x00080000,0x42000100,0x00000100,0x02000000, 0x40000000,0x02080000,0x42000100,0x40080100, +0x02000100,0x40000000,0x42080000,0x02080100, 0x40080100,0x00000100,0x02000000,0x42080000, +0x42080100,0x00080100,0x42000000,0x42080100, 0x02080000,0x00000000,0x40080000,0x42000000, +0x00080100,0x02000100,0x40000100,0x00080000, 0x00000000,0x40080000,0x02080100,0x40000100}, +{ +0x20000010,0x20400000,0x00004000,0x20404010, 0x20400000,0x00000010,0x20404010,0x00400000, +0x20004000,0x00404010,0x00400000,0x20000010, 0x00400010,0x20004000,0x20000000,0x00004010, +0x00000000,0x00400010,0x20004010,0x00004000, 0x00404000,0x20004010,0x00000010,0x20400010, +0x20400010,0x00000000,0x00404010,0x20404000, 0x00004010,0x00404000,0x20404000,0x20000000, +0x20004000,0x00000010,0x20400010,0x00404000, 0x20404010,0x00400000,0x00004010,0x20000010, +0x00400000,0x20004000,0x20000000,0x00004010, 0x20000010,0x20404010,0x00404000,0x20400000, +0x00404010,0x20404000,0x00000000,0x20400010, 0x00000010,0x00004000,0x20400000,0x00404010, +0x00004000,0x00400010,0x20004010,0x00000000, 0x20404000,0x20000000,0x00400010,0x20004010}, +{ +0x00200000,0x04200002,0x04000802,0x00000000, 0x00000800,0x04000802,0x00200802,0x04200800, +0x04200802,0x00200000,0x00000000,0x04000002, 0x00000002,0x04000000,0x04200002,0x00000802, +0x04000800,0x00200802,0x00200002,0x04000800, 0x04000002,0x04200000,0x04200800,0x00200002, +0x04200000,0x00000800,0x00000802,0x04200802, 0x00200800,0x00000002,0x04000000,0x00200800, +0x04000000,0x00200800,0x00200000,0x04000802, 0x04000802,0x04200002,0x04200002,0x00000002, +0x00200002,0x04000000,0x04000800,0x00200000, 0x04200800,0x00000802,0x00200802,0x04200800, +0x00000802,0x04000002,0x04200802,0x04200000, 0x00200800,0x00000000,0x00000002,0x04200802, +0x00000000,0x00200802,0x04200000,0x00000800, 0x04000002,0x04000800,0x00000800,0x00200002}, +{ +0x10001040,0x00001000,0x00040000,0x10041040, 0x10000000,0x10001040,0x00000040,0x10000000, +0x00040040,0x10040000,0x10041040,0x00041000, 0x10041000,0x00041040,0x00001000,0x00000040, +0x10040000,0x10000040,0x10001000,0x00001040, 0x00041000,0x00040040,0x10040040,0x10041000, +0x00001040,0x00000000,0x00000000,0x10040040, 0x10000040,0x10001000,0x00041040,0x00040000, +0x00041040,0x00040000,0x10041000,0x00001000, 0x00000040,0x10040040,0x00001000,0x00041040, +0x10001000,0x00000040,0x10000040,0x10040000, 0x10040040,0x10000000,0x00040000,0x10001040, +0x00000000,0x10041040,0x00040040,0x10000040, 0x10040000,0x10001000,0x10001040,0x00000000, +0x10041040,0x00041000,0x00041000,0x00001040, 0x00001040,0x00040040,0x10000000,0x10041000} +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dh.cpp b/external/ours/library/crypto/src/shared/original/dh.cpp new file mode 100755 index 000000000..5a0e7d1d3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dh.cpp @@ -0,0 +1,21 @@ +// dh.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "dh.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void DH_TestInstantiations() +{ + DH dh1; + DH dh2(NullRNG(), 10); +} +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dh.h b/external/ours/library/crypto/src/shared/original/dh.h new file mode 100755 index 000000000..4f462e48c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dh.h @@ -0,0 +1,275 @@ +// dh.h - originally written and placed in the public domain by Wei Dai + +/// \file dh.h +/// \brief Classes for Diffie-Hellman key exchange + +#ifndef CRYPTOPP_DH_H +#define CRYPTOPP_DH_H + +#include "cryptlib.h" +#include "gfpcrypt.h" +#include "algebra.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Diffie-Hellman domain +/// \tparam GROUP_PARAMETERS group parameters +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \details A Diffie-Hellman domain is a set of parameters that must be shared +/// by two parties in a key agreement protocol, along with the algorithms +/// for generating key pairs and deriving agreed values. +/// \details For COFACTOR_OPTION, see CofactorMultiplicationOption. +/// \sa DL_SimpleKeyAgreementDomainBase +/// \since Crypto++ 1.0 +template +class DH_Domain : public DL_SimpleKeyAgreementDomainBase +{ + typedef DL_SimpleKeyAgreementDomainBase Base; + +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef DL_KeyAgreementAlgorithm_DH DH_Algorithm; + typedef DH_Domain Domain; + + virtual ~DH_Domain() {} + + /// \brief Construct a Diffie-Hellman domain + DH_Domain() {} + + /// \brief Construct a Diffie-Hellman domain + /// \param params group parameters and options + DH_Domain(const GroupParameters ¶ms) + : m_groupParameters(params) {} + + /// \brief Construct a Diffie-Hellman domain + /// \param bt BufferedTransformation with group parameters and options + DH_Domain(BufferedTransformation &bt) + {m_groupParameters.BERDecode(bt);} + + /// \brief Create a Diffie-Hellman domain + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 RandomNumberGenerator derived class + /// \param v2 second parameter + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + template + DH_Domain(RandomNumberGenerator &v1, const T2 &v2) + {m_groupParameters.Initialize(v1, v2);} + + /// \brief Create a Diffie-Hellman domain + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \param v1 RandomNumberGenerator derived class + /// \param v2 second parameter + /// \param v3 third parameter + /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. + template + DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3) + {m_groupParameters.Initialize(v1, v2, v3);} + + /// \brief Create a Diffie-Hellman domain + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \tparam T4 template parameter used as a constructor parameter + /// \param v1 RandomNumberGenerator derived class + /// \param v2 second parameter + /// \param v3 third parameter + /// \param v4 fourth parameter + /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. + template + DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + + /// \brief Construct a Diffie-Hellman domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + template + DH_Domain(const T1 &v1, const T2 &v2) + {m_groupParameters.Initialize(v1, v2);} + + /// \brief Construct a Diffie-Hellman domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. + template + DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3) + {m_groupParameters.Initialize(v1, v2, v3);} + + /// \brief Construct a Diffie-Hellman domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \tparam T4 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param v4 fourth parameter + /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. + template + DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a const reference + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a non-const reference + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + /// \brief Generate a public key from a private key in this domain + /// \param rng RandomNumberGenerator derived class + /// \param privateKey byte buffer with the previously generated private key + /// \param publicKey byte buffer for the generated public key in this domain + /// \details If using a FIPS 140-2 validated library on Windows, then this class will perform + /// a self test to ensure the key pair is pairwise consistent. Non-FIPS and non-Windows + /// builds of the library do not provide FIPS validated cryptography, so the code should be + /// removed by the optimizer. + /// \pre COUNTOF(publicKey) == PublicKeyLength() + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + Base::GeneratePublicKey(rng, privateKey, publicKey); + + if (FIPS_140_2_ComplianceEnabled()) + { + SecByteBlock privateKey2(this->PrivateKeyLength()); + this->GeneratePrivateKey(rng, privateKey2); + + SecByteBlock publicKey2(this->PublicKeyLength()); + Base::GeneratePublicKey(rng, privateKey2, publicKey2); + + SecByteBlock agreedValue(this->AgreedValueLength()), agreedValue2(this->AgreedValueLength()); + bool agreed1 = this->Agree(agreedValue, privateKey, publicKey2); + bool agreed2 = this->Agree(agreedValue2, privateKey2, publicKey); + + if (!agreed1 || !agreed2 || agreedValue != agreedValue2) + throw SelfTestFailure(this->AlgorithmName() + ": pairwise consistency test failed"); + } + } + + static std::string CRYPTOPP_API StaticAlgorithmName() + {return GroupParameters::StaticAlgorithmNamePrefix() + DH_Algorithm::StaticAlgorithmName();} + std::string AlgorithmName() const {return StaticAlgorithmName();} + +private: + const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const + {return Singleton().Ref();} + DL_GroupParameters & AccessAbstractGroupParameters() + {return m_groupParameters;} + + GroupParameters m_groupParameters; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DH_Domain; + +/// \brief Diffie-Hellman in GF(p) +/// \details DH() class is a typedef of DH_Domain(). The documentation that follows +/// does not exist. Rather the documentation was created in response to Issue +/// 328, Diffie-Hellman example code not compiling. +/// \details Generally speaking, a DH() object is ephemeral and is intended to execute one instance of the Diffie-Hellman protocol. The +/// private and public key parts are not intended to be set or persisted. Rather, a new set of domain parameters are generated each +/// time an object is created. +/// \details Once a DH() object is created, once can retrieve the ephemeral public key for the other party with code similar to the +/// following. +///
   AutoSeededRandomPool prng;
+///   Integer p, q, g;
+///   PrimeAndGenerator pg;
+///
+///   pg.Generate(1, prng, 512, 511);
+///   p = pg.Prime();
+///   q = pg.SubPrime();
+///   g = pg.Generator();
+///
+///   DH dh(p, q, g);
+///   SecByteBlock t1(dh.PrivateKeyLength()), t2(dh.PublicKeyLength());
+///   dh.GenerateKeyPair(prng, t1, t2);
+///   Integer k1(t1, t1.size()), k2(t2, t2.size());
+///
+///   cout << "Private key:\n";
+///   cout << hex << k1 << endl;
+///
+///   cout << "Public key:\n";
+///   cout << hex << k2 << endl;
+/// +/// \details Output of the program above will be similar to the following. +///
   $ ./cryptest.exe
+///   Private key:
+///   72b45a42371545e9d4880f48589aefh
+///   Public key:
+///   45fdb13f97b1840626f0250cec1dba4a23b894100b51fb5d2dd13693d789948f8bfc88f9200014b2
+///   ba8dd8a6debc471c69ef1e2326c61184a2eca88ec866346bh
+/// \sa Diffie-Hellman on the Crypto++ wiki and +/// Diffie-Hellman in GF(p) with key validation +/// \since Crypto++ 1.0 +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +struct DH : public DH_Domain +{ + typedef DH_Domain GroupParameters; + typedef GroupParameters::Element Element; + + virtual ~DH() {} + + /// \brief Create an uninitialized Diffie-Hellman object + DH() : DH_Domain() {} + + /// \brief Initialize a Diffie-Hellman object + /// \param bt BufferedTransformation with group parameters and options + DH(BufferedTransformation &bt) : DH_Domain(bt) {} + + /// \brief Initialize a Diffie-Hellman object + /// \param params group parameters and options + DH(const GroupParameters ¶ms) : DH_Domain(params) {} + + /// \brief Create a Diffie-Hellman object + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulus, in bits + /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it + /// takes a RandomNumberGenerator() as a parameter. + DH(RandomNumberGenerator &rng, unsigned int modulusBits) : DH_Domain(rng, modulusBits) {} + + /// \brief Initialize a Diffie-Hellman object + /// \param p the modulus + /// \param g the generator + DH(const Integer &p, const Integer &g) : DH_Domain(p, g) {} + + /// \brief Initialize a Diffie-Hellman object + /// \param p the modulus + /// \param q the subgroup order + /// \param g the generator + DH(const Integer &p, const Integer &q, const Integer &g) : DH_Domain(p, q, g) {} + + /// \brief Creates a Diffie-Hellman object + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulus, in bits + /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it + /// takes a RandomNumberGenerator() as a parameter. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {AccessGroupParameters().Initialize(rng, modulusBits);} + + /// \brief Initialize a Diffie-Hellman object + /// \param p the modulus + /// \param g the generator + void Initialize(const Integer &p, const Integer &g) + {AccessGroupParameters().Initialize(p, g);} + + /// \brief Initialize a Diffie-Hellman object + /// \param p the modulus + /// \param q the subgroup order + /// \param g the generator + void Initialize(const Integer &p, const Integer &q, const Integer &g) + {AccessGroupParameters().Initialize(p, q, g);} +}; +#else +// The real DH class is a typedef. +typedef DH_Domain DH; +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dh2.cpp b/external/ours/library/crypto/src/shared/original/dh2.cpp new file mode 100755 index 000000000..4c062d4e3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dh2.cpp @@ -0,0 +1,69 @@ +// dh2.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "cryptlib.h" +#include "misc.h" +#include "dh2.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +struct NullCryptoParameters : public CryptoParameters +{ + void AssignFrom(const NameValuePairs &source) { + CRYPTOPP_UNUSED(source); + } + bool Validate(RandomNumberGenerator &rng, unsigned int level) const { + CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level); + return false; + } + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { + CRYPTOPP_UNUSED(name); CRYPTOPP_UNUSED(valueType); CRYPTOPP_UNUSED(pValue); + return false; + } +}; + +struct NullSimpleKeyAgreementDomain : public TwoBases +{ + CryptoParameters & AccessCryptoParameters() { + return *this; + } + unsigned int AgreedValueLength() const { + return 1; + } + unsigned int PrivateKeyLength() const { + return 1; + } + unsigned int PublicKeyLength() const { + return 1; + } + void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const { + CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(privateKey); + } + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const { + CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(privateKey); CRYPTOPP_UNUSED(publicKey); + } + bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const { + CRYPTOPP_UNUSED(agreedValue); CRYPTOPP_UNUSED(privateKey); + CRYPTOPP_UNUSED(otherPublicKey); CRYPTOPP_UNUSED(validateOtherPublicKey); + return false; + } +}; + +void DH2_TestInstantiations() +{ + NullSimpleKeyAgreementDomain dom; + DH2 dh(dom); +} +#endif + +bool DH2::Agree(byte *agreedValue, + const byte *staticSecretKey, const byte *ephemeralSecretKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey) const +{ + return d1.Agree(agreedValue, staticSecretKey, staticOtherPublicKey, validateStaticOtherPublicKey) + && d2.Agree(agreedValue+d1.AgreedValueLength(), ephemeralSecretKey, ephemeralOtherPublicKey, true); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/dh2.h b/external/ours/library/crypto/src/shared/original/dh2.h new file mode 100755 index 000000000..b86161d79 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dh2.h @@ -0,0 +1,70 @@ +// dh2.h - originally written and placed in the public domain by Wei Dai + +/// \file dh2.h +/// \brief Classes for Unified Diffie-Hellman key exchange +/// \since Crypto++ 3.0 + +#ifndef CRYPTOPP_DH2_H +#define CRYPTOPP_DH2_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Unified Diffie-Hellman in GF(p) +/// \details A Diffie-Hellman domain is a set of parameters that must be shared +/// by two parties in a key agreement protocol, along with the algorithms +/// for generating key pairs and deriving agreed values. +/// \sa AuthenticatedKeyAgreementDomain, Unified Diffie-Hellman +/// \since Crypto++ 3.0 +class DH2 : public AuthenticatedKeyAgreementDomain +{ +public: + virtual ~DH2() {} + + /// \brief Construct a DH2 + DH2(SimpleKeyAgreementDomain &domain) + : d1(domain), d2(domain) {} + /// \brief Construct a DH2 + DH2(SimpleKeyAgreementDomain &staticDomain, SimpleKeyAgreementDomain &ephemeralDomain) + : d1(staticDomain), d2(ephemeralDomain) {} + + CryptoParameters & AccessCryptoParameters() {return d1.AccessCryptoParameters();} + + unsigned int AgreedValueLength() const + {return d1.AgreedValueLength() + d2.AgreedValueLength();} + + unsigned int StaticPrivateKeyLength() const + {return d1.PrivateKeyLength();} + unsigned int StaticPublicKeyLength() const + {return d1.PublicKeyLength();} + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + {d1.GeneratePrivateKey(rng, privateKey);} + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + {d1.GeneratePublicKey(rng, privateKey, publicKey);} + void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const + {d1.GenerateKeyPair(rng, privateKey, publicKey);} + + unsigned int EphemeralPrivateKeyLength() const + {return d2.PrivateKeyLength();} + unsigned int EphemeralPublicKeyLength() const + {return d2.PublicKeyLength();} + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + {d2.GeneratePrivateKey(rng, privateKey);} + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + {d2.GeneratePublicKey(rng, privateKey, publicKey);} + void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const + {d2.GenerateKeyPair(rng, privateKey, publicKey);} + + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const; + +protected: + SimpleKeyAgreementDomain &d1, &d2; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dll.cpp b/external/ours/library/crypto/src/shared/original/dll.cpp new file mode 100755 index 000000000..2115f9f58 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dll.cpp @@ -0,0 +1,169 @@ +// dll.cpp - originally written and placed in the public domain by Wei Dai + +#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#define CRYPTOPP_DEFAULT_NO_DLL + +#include "dll.h" +#include "config.h" +#include "iterhash.h" +#include "pkcspad.h" +#include "emsa2.h" + +#if defined(CRYPTOPP_MSC_VERSION) +// Cast from FARPROC to funcptr with args, http://stackoverflow.com/q/4192058/608639 +# pragma warning(disable: 4191) +#endif + +#if defined(CRYPTOPP_EXPORTS) && defined(CRYPTOPP_WIN32_AVAILABLE) +# include +#endif + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +// Guarding based on DLL due to Clang, http://github.com/weidai11/cryptopp/issues/300 +#ifdef CRYPTOPP_IS_DLL +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +// http://github.com/weidai11/cryptopp/issues/517. OIDs and encoded prefixes found at +// http://www.ietf.org/archive/id/draft-jivsov-openpgp-sha3-01.txt +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x08,0x05, 0x00,0x04,0x20}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x09,0x05, 0x00,0x04,0x30}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x0a,0x05, 0x00,0x04,0x40}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte EMSA2HashId::id = 0x33; +template<> const byte EMSA2HashId::id = 0x38; +template<> const byte EMSA2HashId::id = 0x34; +template<> const byte EMSA2HashId::id = 0x36; +template<> const byte EMSA2HashId::id = 0x35; + +#endif // CRYPTOPP_IS_DLL + +NAMESPACE_END + +#endif + +#ifdef CRYPTOPP_EXPORTS + +USING_NAMESPACE(CryptoPP) + +using std::set_new_handler; + +static PNew s_pNew = NULLPTR; +static PDelete s_pDelete = NULLPTR; + +static void * New (size_t size) +{ + void *p; + while ((p = malloc(size)) == NULLPTR) + CallNewHandler(); + + return p; +} + +static void SetNewAndDeleteFunctionPointers() +{ + void *p = NULLPTR; + HMODULE hModule = NULLPTR; + MEMORY_BASIC_INFORMATION mbi; + + while (true) + { + VirtualQuery(p, &mbi, sizeof(mbi)); + + if (p >= (char *)mbi.BaseAddress + mbi.RegionSize) + break; + + p = (char *)mbi.BaseAddress + mbi.RegionSize; + + if (!mbi.AllocationBase || mbi.AllocationBase == hModule) + continue; + + hModule = HMODULE(mbi.AllocationBase); + PGetNewAndDelete pGetNewAndDelete = (PGetNewAndDelete)GetProcAddress(hModule, "GetNewAndDeleteForCryptoPP"); + if (pGetNewAndDelete) + { + pGetNewAndDelete(s_pNew, s_pDelete); + return; + } + + PSetNewAndDelete pSetNewAndDelete = (PSetNewAndDelete)GetProcAddress(hModule, "SetNewAndDeleteFromCryptoPP"); + if (pSetNewAndDelete) + { + s_pNew = &New; + s_pDelete = &free; + pSetNewAndDelete(s_pNew, s_pDelete, &set_new_handler); + return; + } + } + + // try getting these directly using mangled names of new and delete operators + + hModule = GetModuleHandle("msvcrtd"); + if (!hModule) + hModule = GetModuleHandle("msvcrt"); + if (hModule) + { + // 32-bit versions + s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPAXI@Z"); + s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPAX@Z"); + if (s_pNew && s_pDelete) + return; + + // 64-bit versions + s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPEAX_K@Z"); + s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPEAX@Z"); + if (s_pNew && s_pDelete) + return; + } + + OutputDebugStringA("Crypto++ DLL was not able to obtain new and delete function pointers.\n"); + throw 0; +} + +// Cast from FARPROC to funcptr with args +#pragma warning(default: 4191) + +void * operator new (size_t size) +{ + if (!s_pNew) + SetNewAndDeleteFunctionPointers(); + + return s_pNew(size); +} + +void operator delete (void * p) +{ + s_pDelete(p); +} + +void * operator new [] (size_t size) +{ + return operator new (size); +} + +void operator delete [] (void * p) +{ + operator delete (p); +} + +#endif // CRYPTOPP_EXPORTS diff --git a/external/ours/library/crypto/src/shared/original/dll.h b/external/ours/library/crypto/src/shared/original/dll.h new file mode 100755 index 000000000..f923026cb --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dll.h @@ -0,0 +1,71 @@ +// dll.h - originally written and placed in the public domain by Wei Dai + +/// \file dll.h +/// \brief Functions and definitions required for building the FIPS-140 DLL on Windows + +#ifndef CRYPTOPP_DLL_H +#define CRYPTOPP_DLL_H + +#if !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_DEFAULT_NO_DLL) +#ifdef CRYPTOPP_CONFIG_H +#error To use the DLL version of Crypto++, this file must be included before any other Crypto++ header files. +#endif +#define CRYPTOPP_IMPORTS +#endif + +#include "aes.h" +#include "cbcmac.h" +#include "ccm.h" +#include "cmac.h" +#include "channels.h" +#include "des.h" +#include "dh.h" +#include "dsa.h" +#include "ec2n.h" +#include "eccrypto.h" +#include "ecp.h" +#include "files.h" +#include "fips140.h" +#include "gcm.h" +#include "hex.h" +#include "hmac.h" +#include "modes.h" +#include "mqueue.h" +#include "nbtheory.h" +#include "osrng.h" +#include "pkcspad.h" +#include "pssr.h" +#include "randpool.h" +#include "rsa.h" +#include "rw.h" +#include "sha.h" +#include "skipjack.h" + +#ifdef CRYPTOPP_IMPORTS + +#ifdef _DLL +// cause CRT DLL to be initialized before Crypto++ so that we can use malloc and free during DllMain() +#ifdef CRYPTOPP_DEBUG +# pragma comment(lib, "msvcrtd") +# pragma comment(lib, "cryptopp") +#else +# pragma comment(lib, "msvcrt") +# pragma comment(lib, "cryptopp") +#endif +#endif + +#endif // #ifdef CRYPTOPP_IMPORTS + +#include // for new_handler + +NAMESPACE_BEGIN(CryptoPP) + +typedef void * (CRYPTOPP_API * PNew)(size_t); +typedef void (CRYPTOPP_API * PDelete)(void *); +typedef void (CRYPTOPP_API * PGetNewAndDelete)(PNew &, PDelete &); +typedef std::new_handler (CRYPTOPP_API * PSetNewHandler)(std::new_handler); +typedef void (CRYPTOPP_API * PSetNewAndDelete)(PNew, PDelete, PSetNewHandler); + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dlltest.cpp b/external/ours/library/crypto/src/shared/original/dlltest.cpp new file mode 100755 index 000000000..addced553 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dlltest.cpp @@ -0,0 +1,212 @@ +#ifndef CRYPTOPP_DLL_ONLY +# define CRYPTOPP_DEFAULT_NO_DLL +#endif + +#include "dll.h" +#include "cryptlib.h" +#include "filters.h" +#include "pkcspad.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +USING_NAMESPACE(CryptoPP) + +void FIPS140_SampleApplication() +{ + if (!FIPS_140_2_ComplianceEnabled()) + { + std::cerr << "FIPS 140-2 compliance was turned off at compile time.\n"; + abort(); + } + + // check self test status + if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) + { + std::cerr << "Automatic power-up self test failed.\n"; + abort(); + } + std::cout << "0. Automatic power-up self test passed.\n"; + + // simulate a power-up self test error + SimulatePowerUpSelfTestFailure(); + try + { + // trying to use a crypto algorithm after power-up self test error will result in an exception + AES::Encryption aes; + + // should not be here + std::cerr << "Use of AES failed to cause an exception after power-up self test error.\n"; + abort(); + } + catch (SelfTestFailure &e) + { + std::cout << "1. Caught expected exception when simulating self test failure. Exception message follows: "; + std::cout << e.what() << std::endl; + } + + // clear the self test error state and redo power-up self test + DoDllPowerUpSelfTest(); + if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) + { + std::cerr << "Re-do power-up self test failed.\n"; + abort(); + } + std::cout << "2. Re-do power-up self test passed.\n"; + + // encrypt and decrypt + const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; + const byte plaintext[] = { // "Now is the time for all " without tailing 0 + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20}; + byte ciphertext[24]; + byte decrypted[24]; + + CFB_FIPS_Mode::Encryption encryption_DES_EDE3_CFB; + encryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); + encryption_DES_EDE3_CFB.ProcessString(ciphertext, plaintext, 24); + + CFB_FIPS_Mode::Decryption decryption_DES_EDE3_CFB; + decryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); + decryption_DES_EDE3_CFB.ProcessString(decrypted, ciphertext, 24); + + if (memcmp(plaintext, decrypted, 24) != 0) + { + std::cerr << "DES-EDE3-CFB Encryption/decryption failed.\n"; + abort(); + } + std::cout << "3. DES-EDE3-CFB Encryption/decryption succeeded.\n"; + + // hash + const byte message[] = {'a', 'b', 'c'}; + const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D}; + byte digest[20]; + + SHA1 sha; + sha.Update(message, 3); + sha.Final(digest); + + if (memcmp(digest, expectedDigest, 20) != 0) + { + std::cerr << "SHA-1 hash failed.\n"; + abort(); + } + std::cout << "4. SHA-1 hash succeeded.\n"; + + // create auto-seeded X9.17 RNG object, if available +#ifdef OS_RNG_AVAILABLE + AutoSeededX917RNG rng; +#else + // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs + RandomNumberGenerator &rng(NullRNG()); +#endif + + // generate DSA key + DSA::PrivateKey dsaPrivateKey; + dsaPrivateKey.GenerateRandomWithKeySize(rng, 1024); + DSA::PublicKey dsaPublicKey; + dsaPublicKey.AssignFrom(dsaPrivateKey); + if (!dsaPrivateKey.Validate(rng, 3) || !dsaPublicKey.Validate(rng, 3)) + { + std::cerr << "DSA key generation failed.\n"; + abort(); + } + std::cout << "5. DSA key generation succeeded.\n"; + + // encode DSA key + std::string encodedDsaPublicKey, encodedDsaPrivateKey; + dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref()); + dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref()); + + // decode DSA key + DSA::PrivateKey decodedDsaPrivateKey; + decodedDsaPrivateKey.BERDecode(StringStore(encodedDsaPrivateKey).Ref()); + DSA::PublicKey decodedDsaPublicKey; + decodedDsaPublicKey.BERDecode(StringStore(encodedDsaPublicKey).Ref()); + + if (!decodedDsaPrivateKey.Validate(rng, 3) || !decodedDsaPublicKey.Validate(rng, 3)) + { + std::cerr << "DSA key encode/decode failed.\n"; + abort(); + } + std::cout << "6. DSA key encode/decode succeeded.\n"; + + // sign and verify + byte signature[40]; + DSA::Signer signer(dsaPrivateKey); + CRYPTOPP_ASSERT(signer.SignatureLength() == 40); + signer.SignMessage(rng, message, 3, signature); + + DSA::Verifier verifier(dsaPublicKey); + if (!verifier.VerifyMessage(message, 3, signature, sizeof(signature))) + { + std::cerr << "DSA signature and verification failed.\n"; + abort(); + } + std::cout << "7. DSA signature and verification succeeded.\n"; + + + // try to verify an invalid signature + signature[0] ^= 1; + if (verifier.VerifyMessage(message, 3, signature, sizeof(signature))) + { + std::cerr << "DSA signature verification failed to detect bad signature.\n"; + abort(); + } + std::cout << "8. DSA signature verification successfully detected bad signature.\n"; + + // try to use an invalid key length + try + { + ECB_Mode::Encryption encryption_DES_EDE3_ECB; + encryption_DES_EDE3_ECB.SetKey(key, 5); + + // should not be here + std::cerr << "DES-EDE3 implementation did not detect use of invalid key length.\n"; + abort(); + } + catch (InvalidArgument &e) + { + std::cout << "9. Caught expected exception when using invalid key length. Exception message follows: "; + std::cout << e.what() << std::endl; + } + + std::cout << "\nFIPS 140-2 Sample Application completed normally.\n"; +} + +#ifdef CRYPTOPP_IMPORTS + +static PNew s_pNew = NULLPTR; +static PDelete s_pDelete = NULLPTR; + +extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler) +{ + (void)(pSetNewHandler); + s_pNew = pNew; + s_pDelete = pDelete; +} + +void * __cdecl operator new (size_t size) +{ + return s_pNew(size); +} + +void __cdecl operator delete (void * p) +{ + s_pDelete(p); +} + +#endif + +#ifdef CRYPTOPP_DLL_ONLY + +int __cdecl main() +{ + FIPS140_SampleApplication(); + return 0; +} + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dmac.h b/external/ours/library/crypto/src/shared/original/dmac.h new file mode 100755 index 000000000..9d911708c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dmac.h @@ -0,0 +1,114 @@ +// dmac.h - originally written and placed in the public domain by Wei Dai + +/// \file dmac.h +/// \brief Classes for DMAC message authentication code + +#ifndef CRYPTOPP_DMAC_H +#define CRYPTOPP_DMAC_H + +#include "cbcmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief DMAC message authentication code base class +/// \tparam T class derived from BlockCipherDocumentation +/// \since Crypto++ 3.1 +template +class CRYPTOPP_NO_VTABLE DMAC_Base : public SameKeyLengthAs, public MessageAuthenticationCode +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE); + static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";} + + virtual~DMAC_Base() {} + DMAC_Base() : m_subkeylength(0), m_counter(0) {} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + + std::string AlgorithmProvider() const; + +private: + byte *GenerateSubKeys(const byte *key, size_t keylength); + + size_t m_subkeylength; + SecByteBlock m_subkeys; + CBC_MAC m_mac1; + typename T::Encryption m_f2; + unsigned int m_counter; +}; + +template +std::string DMAC_Base::AlgorithmProvider() const +{ + return m_f2.AlgorithmProvider(); +} + +/// \brief DMAC message authentication code +/// \tparam T class derived from BlockCipherDocumentation +/// \sa CBC MAC for Real-Time Data Sources (08.15.1997) +/// by Erez Petrank and Charles Rackoff +/// \since Crypto++ 3.1 +template +class DMAC : public MessageAuthenticationCodeFinal > +{ +public: + /// \brief Construct a DMAC + DMAC() {} + + /// \brief Construct a DMAC + /// \param key a byte array used to key the cipher + /// \param length the size of the byte array, in bytes + DMAC(const byte *key, size_t length=DMAC_Base::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} +}; + +template +void DMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE); + m_subkeys.resize(2*UnsignedMin((unsigned int)T::BLOCKSIZE, m_subkeylength)); + m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params); + m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params); + m_counter = 0; + m_subkeys.resize(0); +} + +template +void DMAC_Base::Update(const byte *input, size_t length) +{ + m_mac1.Update(input, length); + m_counter = (unsigned int)((m_counter + length) % T::BLOCKSIZE); +} + +template +void DMAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + byte pad[T::BLOCKSIZE]; + byte padByte = byte(T::BLOCKSIZE-m_counter); + memset(pad, padByte, padByte); + m_mac1.Update(pad, padByte); + m_mac1.TruncatedFinal(mac, size); + m_f2.ProcessBlock(mac); + + m_counter = 0; // reset for next message +} + +template +byte *DMAC_Base::GenerateSubKeys(const byte *key, size_t keylength) +{ + typename T::Encryption cipher(key, keylength); + memset(m_subkeys, 0, m_subkeys.size()); + cipher.ProcessBlock(m_subkeys); + m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1; + cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2); + return m_subkeys; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/donna.h b/external/ours/library/crypto/src/shared/original/donna.h new file mode 100755 index 000000000..2f3365389 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna.h @@ -0,0 +1,178 @@ +// donna.h - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// https://github.com/floodyberry/curve25519-donna and +// https://github.com/floodyberry/ed25519-donna. + +// The curve25519 and ed25519 source files multiplex different repos and +// architectures using namespaces. The repos are Andrew Moon's +// curve25519-donna and ed25519-donna. The architectures are 32-bit, 64-bit +// and SSE. For example, 32-bit x25519 uses symbols from Donna::X25519 and +// Donna::Arch32. + +// If needed, see Moon's commit "Go back to ignoring 256th bit [sic]", +// https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658 + +/// \file donna.h +/// \details Functions for curve25519 and ed25519 operations +/// \details This header provides the entry points into Andrew Moon's +/// curve25519 and ed25519 curve functions. The Crypto++ classes x25519 +/// and ed25519 use the functions. The functions are in the Donna +/// namespace and are curve25519_mult(), ed25519_publickey(), +/// ed25519_sign() and ed25519_sign_open(). +/// \details At the moment the hash function for signing is fixed at +/// SHA512. + +#ifndef CRYPTOPP_DONNA_H +#define CRYPTOPP_DONNA_H + +#include "cryptlib.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) + +//***************************** curve25519 *****************************// + +/// \brief Generate a public key +/// \param publicKey byte array for the public key +/// \param secretKey byte array with the private key +/// \return 0 on success, non-0 otherwise +/// \details curve25519_mult() generates a public key from an existing +/// secret key. Internally curve25519_mult() performs a scalar +/// multiplication using the base point and writes the result to +/// pubkey. +int curve25519_mult(byte publicKey[32], const byte secretKey[32]); + +/// \brief Generate a shared key +/// \param sharedKey byte array for the shared secret +/// \param secretKey byte array with the private key +/// \param othersKey byte array with the peer's public key +/// \return 0 on success, non-0 otherwise +/// \details curve25519_mult() generates a shared key from an existing +/// secret key and the other party's public key. Internally +/// curve25519_mult() performs a scalar multiplication using the two keys +/// and writes the result to sharedKey. +int curve25519_mult(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]); + +//******************************* ed25519 *******************************// + +/// \brief Creates a public key from a secret key +/// \param publicKey byte array for the public key +/// \param secretKey byte array with the private key +/// \return 0 on success, non-0 otherwise +/// \details ed25519_publickey() generates a public key from a secret key. +/// Internally ed25519_publickey() performs a scalar multiplication +/// using the secret key and then writes the result to publicKey. +int ed25519_publickey(byte publicKey[32], const byte secretKey[32]); + +/// \brief Creates a signature on a message +/// \param message byte array with the message +/// \param messageLength size of the message, in bytes +/// \param publicKey byte array with the public key +/// \param secretKey byte array with the private key +/// \param signature byte array for the signature +/// \return 0 on success, non-0 otherwise +/// \details ed25519_sign() generates a signature on a message using +/// the public and private keys. The various buffers can be exact +/// sizes, and do not require extra space like when using the +/// NaCl library functions. +/// \details At the moment the hash function for signing is fixed at +/// SHA512. +int ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64]); + +/// \brief Creates a signature on a message +/// \param stream std::istream derived class +/// \param publicKey byte array with the public key +/// \param secretKey byte array with the private key +/// \param signature byte array for the signature +/// \return 0 on success, non-0 otherwise +/// \details ed25519_sign() generates a signature on a message using +/// the public and private keys. The various buffers can be exact +/// sizes, and do not require extra space like when using the +/// NaCl library functions. +/// \details This ed25519_sign() overload handles large streams. It +/// was added for signing and verifying files that are too large +/// for a memory allocation. +/// \details At the moment the hash function for signing is fixed at +/// SHA512. +int ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], byte signature[64]); + +/// \brief Verifies a signature on a message +/// \param message byte array with the message +/// \param messageLength size of the message, in bytes +/// \param publicKey byte array with the public key +/// \param signature byte array with the signature +/// \return 0 on success, non-0 otherwise +/// \details ed25519_sign_open() verifies a signature on a message using +/// the public key. The various buffers can be exact sizes, and do not +/// require extra space like when using the NaCl library functions. +/// \details At the moment the hash function for signing is fixed at +/// SHA512. +int +ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]); + +/// \brief Verifies a signature on a message +/// \param stream std::istream derived class +/// \param publicKey byte array with the public key +/// \param signature byte array with the signature +/// \return 0 on success, non-0 otherwise +/// \details ed25519_sign_open() verifies a signature on a message using +/// the public key. The various buffers can be exact sizes, and do not +/// require extra space like when using the NaCl library functions. +/// \details This ed25519_sign_open() overload handles large streams. It +/// was added for signing and verifying files that are too large +/// for a memory allocation. +/// \details At the moment the hash function for signing is fixed at +/// SHA512. +int +ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]); + +//****************************** Internal ******************************// + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + +// CRYPTOPP_WORD128_AVAILABLE mostly depends upon GCC support for +// __SIZEOF_INT128__. If __SIZEOF_INT128__ is not available then Moon +// provides routines for MSC and GCC. It should cover most platforms, +// but there are gaps like MS ARM64 and XLC. We tried to enable the +// 64-bit path for SunCC from 12.5 but we got the dreaded compile +// error "The operand ___LCM cannot be assigned to". + +#if defined(CRYPTOPP_WORD128_AVAILABLE) || \ + (defined(_MSC_VER) && defined(_M_X64)) +# define CRYPTOPP_CURVE25519_64BIT 1 +#else +# define CRYPTOPP_CURVE25519_32BIT 1 +#endif + +// Benchmarking on a modern 64-bit Core i5-6400 @2.7 GHz shows SSE2 on Linux +// is not profitable. Here are the numbers in milliseconds/operation: +// +// * Langley, C++, 0.050 +// * Moon, C++: 0.040 +// * Moon, SSE2: 0.061 +// * Moon, native: 0.045 +// +// However, a modern 64-bit Core i5-3200 @2.5 GHz shows SSE2 is profitable +// for MS compilers. Here are the numbers in milliseconds/operation: +// +// * x86, no SSE2, 0.294 +// * x86, SSE2, 0.097 +// * x64, no SSE2, 0.081 +// * x64, SSE2, 0.071 + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) && defined(_MSC_VER) +# define CRYPTOPP_CURVE25519_SSE2 1 +#endif + +#if (CRYPTOPP_CURVE25519_SSE2) + extern int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]); +#endif + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_DONNA_H diff --git a/external/ours/library/crypto/src/shared/original/donna_32.cpp b/external/ours/library/crypto/src/shared/original/donna_32.cpp new file mode 100755 index 000000000..51f0ae0ce --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna_32.cpp @@ -0,0 +1,2102 @@ +// donna_32.cpp - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// https://github.com/floodyberry/curve25519-donna and +// https://github.com/floodyberry/ed25519-donna. + +// The curve25519 and ed25519 source files multiplex different repos and +// architectures using namespaces. The repos are Andrew Moon's +// curve25519-donna and ed25519-donna. The architectures are 32-bit, 64-bit +// and SSE. For example, 32-bit x25519 uses symbols from Donna::X25519 and +// Donna::Arch32. + +// A fair amount of duplication happens below, but we could not directly +// use curve25519 for both x25519 and ed25519. A close examination reveals +// slight differences in the implementation. For example, look at the +// two curve25519_sub functions. + +// If needed, see Moon's commit "Go back to ignoring 256th bit [sic]", +// https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658 + +#include "pch.h" + +#include "config.h" +#include "donna.h" +#include "secblock.h" +#include "sha.h" +#include "misc.h" +#include "cpu.h" + +#include +#include + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4244) +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char DONNA32_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +// Can't use GetAlignmentOf() because of C++11 and constexpr +// Can use 'const unsigned int' because of MSVC 2013 +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +# define ALIGN_SPEC 16 +#else +# define ALIGN_SPEC 4 +#endif + +ANONYMOUS_NAMESPACE_END + +#if defined(CRYPTOPP_CURVE25519_32BIT) + +#include "donna_32.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::GetWord; +using CryptoPP::PutWord; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +inline word32 U8TO32_LE(const byte* p) +{ + return GetWord(false, LITTLE_ENDIAN_ORDER, p); +} + +inline void U32TO8_LE(byte* p, word32 w) +{ + PutWord(false, LITTLE_ENDIAN_ORDER, p, w); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(X25519) +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::sword32; +using CryptoPP::word64; +using CryptoPP::sword64; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; + +// Bring in all the symbols from the 32-bit header +using namespace CryptoPP::Donna::Arch32; + +/* out = in */ +inline void +curve25519_copy(bignum25519 out, const bignum25519 in) { + out[0] = in[0]; out[1] = in[1]; + out[2] = in[2]; out[3] = in[3]; + out[4] = in[4]; out[5] = in[5]; + out[6] = in[6]; out[7] = in[7]; + out[8] = in[8]; out[9] = in[9]; +} + +/* out = a + b */ +inline void +curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; out[9] = a[9] + b[9]; +} + +/* out = a - b */ +inline void +curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 c; + out[0] = 0x7ffffda + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = 0x3fffffe + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = 0x7fffffe + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = 0x3fffffe + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = 0x7fffffe + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = 0x3fffffe + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = 0x7fffffe + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = 0x3fffffe + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = 0x7fffffe + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = 0x3fffffe + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = in * scalar */ +inline void +curve25519_scalar_product(bignum25519 out, const bignum25519 in, const word32 scalar) { + word64 a; + word32 c; + a = mul32x32_64(in[0], scalar); out[0] = (word32)a & reduce_mask_26; c = (word32)(a >> 26); + a = mul32x32_64(in[1], scalar) + c; out[1] = (word32)a & reduce_mask_25; c = (word32)(a >> 25); + a = mul32x32_64(in[2], scalar) + c; out[2] = (word32)a & reduce_mask_26; c = (word32)(a >> 26); + a = mul32x32_64(in[3], scalar) + c; out[3] = (word32)a & reduce_mask_25; c = (word32)(a >> 25); + a = mul32x32_64(in[4], scalar) + c; out[4] = (word32)a & reduce_mask_26; c = (word32)(a >> 26); + a = mul32x32_64(in[5], scalar) + c; out[5] = (word32)a & reduce_mask_25; c = (word32)(a >> 25); + a = mul32x32_64(in[6], scalar) + c; out[6] = (word32)a & reduce_mask_26; c = (word32)(a >> 26); + a = mul32x32_64(in[7], scalar) + c; out[7] = (word32)a & reduce_mask_25; c = (word32)(a >> 25); + a = mul32x32_64(in[8], scalar) + c; out[8] = (word32)a & reduce_mask_26; c = (word32)(a >> 26); + a = mul32x32_64(in[9], scalar) + c; out[9] = (word32)a & reduce_mask_25; c = (word32)(a >> 25); + out[0] += c * 19; +} + +/* out = a * b */ +inline void +curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + word32 s0,s1,s2,s3,s4,s5,s6,s7,s8,s9; + word64 m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + word32 p; + + r0 = b[0]; r1 = b[1]; r2 = b[2]; r3 = b[3]; r4 = b[4]; + r5 = b[5]; r6 = b[6]; r7 = b[7]; r8 = b[8]; r9 = b[9]; + + s0 = a[0]; s1 = a[1]; s2 = a[2]; s3 = a[3]; s4 = a[4]; + s5 = a[5]; s6 = a[6]; s7 = a[7]; s8 = a[8]; s9 = a[9]; + + m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); + m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); + m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); + m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); + m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); + + r1 *= 2; r3 *= 2; r5 *= 2; r7 *= 2; + + m0 = mul32x32_64(r0, s0); + m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); + m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0); + m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); + m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0); + + r1 *= 19; r2 *= 19; + r3 = (r3 / 2) * 19; + r4 *= 19; + r5 = (r5 / 2) * 19; + r6 *= 19; + r7 = (r7 / 2) * 19; + r8 *= 19; r9 *= 19; + + m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); + m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); + m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); + m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); + + r3 *= 2; r5 *= 2; r7 *= 2; r9 *= 2; + + m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9)); + m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); + m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9)); + m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); + m8 += (mul32x32_64(r9, s9)); + + r0 = (word32)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (word32)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (word32)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (word32)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (word32)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (word32)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (word32)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (word32)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (word32)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (word32)m9 & reduce_mask_25; p = (word32)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (word32)m0 & reduce_mask_26; p = (word32)(m0 >> 26); + r1 += p; + + out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; + out[5] = r5; out[6] = r6; out[7] = r7; out[8] = r8; out[9] = r9; +} + +/* out = in * in */ +inline void +curve25519_square(bignum25519 out, const bignum25519 in) { + word32 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + word32 d6,d7,d8,d9; + word64 m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + word32 p; + + r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; + r5 = in[5]; r6 = in[6]; r7 = in[7]; r8 = in[8]; r9 = in[9]; + + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; d7 = r7 * 2 * 19; + d8 = r8 * 19; d9 = r9 * 2 * 19; + + m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); + m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); + m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); + m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); + m7 += (mul32x32_64(d9, r8 )); + m8 += (mul32x32_64(d9, r9 )); + + r0 = (word32)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (word32)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (word32)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (word32)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (word32)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (word32)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (word32)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (word32)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (word32)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (word32)m9 & reduce_mask_25; p = (word32)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (word32)m0 & reduce_mask_26; p = (word32)(m0 >> 26); + r1 += p; + + out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; + out[5] = r5; out[6] = r6; out[7] = r7; out[8] = r8; out[9] = r9; +} + +/* out = in^(2 * count) */ +void +curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { + word32 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + word32 d6,d7,d8,d9; + word64 m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + word32 p; + + r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; + r5 = in[5]; r6 = in[6]; r7 = in[7]; r8 = in[8]; r9 = in[9]; + + do { + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; d7 = r7 * 2 * 19; + d8 = r8 * 19; d9 = r9 * 2 * 19; + + m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); + m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); + m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); + m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); + m7 += (mul32x32_64(d9, r8 )); + m8 += (mul32x32_64(d9, r9 )); + + r0 = (word32)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (word32)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (word32)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (word32)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (word32)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (word32)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (word32)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (word32)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (word32)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (word32)m9 & reduce_mask_25; p = (word32)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (word32)m0 & reduce_mask_26; p = (word32)(m0 >> 26); + r1 += p; + } while (--count); + + out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; + out[5] = r5; out[6] = r6; out[7] = r7; out[8] = r8; out[9] = r9; +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +void +curve25519_expand(bignum25519 out, const byte in[32]) { + word32 x0,x1,x2,x3,x4,x5,x6,x7; + GetBlock block(in); + block(x0)(x1)(x2)(x3)(x4)(x5)(x6)(x7); + + out[0] = ( x0 ) & reduce_mask_26; + out[1] = ((((word64)x1 << 32) | x0) >> 26) & reduce_mask_25; + out[2] = ((((word64)x2 << 32) | x1) >> 19) & reduce_mask_26; + out[3] = ((((word64)x3 << 32) | x2) >> 13) & reduce_mask_25; + out[4] = (( x3) >> 6) & reduce_mask_26; + out[5] = ( x4 ) & reduce_mask_25; + out[6] = ((((word64)x5 << 32) | x4) >> 25) & reduce_mask_26; + out[7] = ((((word64)x6 << 32) | x5) >> 19) & reduce_mask_25; + out[8] = ((((word64)x7 << 32) | x6) >> 12) & reduce_mask_26; + out[9] = (( x7) >> 6) & reduce_mask_25; /* ignore the top bit */ +} + +/* Take a fully reduced polynomial form number and contract it into a little-endian, 32-byte array */ +void +curve25519_contract(byte out[32], const bignum25519 in) { + bignum25519 f; + curve25519_copy(f, in); + + #define carry_pass() \ + f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ + f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ + f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ + f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ + f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ + f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ + f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ + f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ + f[9] += f[8] >> 26; f[8] &= reduce_mask_26; + + #define carry_pass_full() \ + carry_pass() \ + f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; + + #define carry_pass_final() \ + carry_pass() \ + f[9] &= reduce_mask_25; + + carry_pass_full() + carry_pass_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + f[0] += 19; + carry_pass_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + f[0] += (1 << 26) - 19; + f[1] += (1 << 25) - 1; + f[2] += (1 << 26) - 1; + f[3] += (1 << 25) - 1; + f[4] += (1 << 26) - 1; + f[5] += (1 << 25) - 1; + f[6] += (1 << 26) - 1; + f[7] += (1 << 25) - 1; + f[8] += (1 << 26) - 1; + f[9] += (1 << 25) - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + carry_pass_final() + + #undef carry_pass + #undef carry_full + #undef carry_final + + f[1] <<= 2; + f[2] <<= 3; + f[3] <<= 5; + f[4] <<= 6; + f[6] <<= 1; + f[7] <<= 3; + f[8] <<= 4; + f[9] <<= 6; + + #define F(i, s) \ + out[s+0] |= (byte)( f[i] & 0xff); \ + out[s+1] = (byte)((f[i] >> 8) & 0xff); \ + out[s+2] = (byte)((f[i] >> 16) & 0xff); \ + out[s+3] = (byte)((f[i] >> 24) & 0xff); + + out[0] = out[16] = 0; + F(0,0); F(1,3); + F(2,6); F(3,9); + F(4,12); F(5,16); + F(6,19); F(7,22); + F(8,25); F(9,28); + #undef F +} + +inline void +curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word32 iswap) { + const word32 swap = (word32)(-(sword32)iswap); + word32 x0,x1,x2,x3,x4,x5,x6,x7,x8,x9; + + x0 = swap & (x[0] ^ qpx[0]); x[0] ^= x0; qpx[0] ^= x0; + x1 = swap & (x[1] ^ qpx[1]); x[1] ^= x1; qpx[1] ^= x1; + x2 = swap & (x[2] ^ qpx[2]); x[2] ^= x2; qpx[2] ^= x2; + x3 = swap & (x[3] ^ qpx[3]); x[3] ^= x3; qpx[3] ^= x3; + x4 = swap & (x[4] ^ qpx[4]); x[4] ^= x4; qpx[4] ^= x4; + x5 = swap & (x[5] ^ qpx[5]); x[5] ^= x5; qpx[5] ^= x5; + x6 = swap & (x[6] ^ qpx[6]); x[6] ^= x6; qpx[6] ^= x6; + x7 = swap & (x[7] ^ qpx[7]); x[7] ^= x7; qpx[7] ^= x7; + x8 = swap & (x[8] ^ qpx[8]); x[8] ^= x8; qpx[8] ^= x8; + x9 = swap & (x[9] ^ qpx[9]); x[9] ^= x9; qpx[9] ^= x9; +} + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void +curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + ALIGN(ALIGN_SPEC) bignum25519 t0,c; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void +curve25519_recip(bignum25519 out, const bignum25519 z) { + ALIGN(ALIGN_SPEC) bignum25519 a, t0, b; + + /* 2 */ curve25519_square(a, z); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square(t0, a); + /* 2^5 - 2^0 = 31 */ curve25519_mul(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul(out, b, a); +} + +ANONYMOUS_NAMESPACE_END +NAMESPACE_END // X25519 +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +//******************************* ed25519 *******************************// + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(Ed25519) +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::sword32; +using CryptoPP::word64; +using CryptoPP::sword64; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; + +using CryptoPP::SHA512; + +// Bring in all the symbols from the 32-bit header +using namespace CryptoPP::Donna::Arch32; + +/* out = in */ +inline void +curve25519_copy(bignum25519 out, const bignum25519 in) { + out[0] = in[0]; out[1] = in[1]; + out[2] = in[2]; out[3] = in[3]; + out[4] = in[4]; out[5] = in[5]; + out[6] = in[6]; out[7] = in[7]; + out[8] = in[8]; out[9] = in[9]; +} + +/* out = a + b */ +inline void +curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; out[9] = a[9] + b[9]; +} + +inline void +curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 c; + out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +inline void +curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 c; + out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = a - b */ +inline void +curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 c; + out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = twoP2468 + a[4] - b[4] + c; + out[5] = twoP13579 + a[5] - b[5] ; + out[6] = twoP2468 + a[6] - b[6] ; + out[7] = twoP13579 + a[7] - b[7] ; + out[8] = twoP2468 + a[8] - b[8] ; + out[9] = twoP13579 + a[9] - b[9] ; +} + +/* out = a - b, where a is the result of a basic op (add,sub) */ +inline void +curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 c; + out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +inline void +curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 c; + out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = -a */ +inline void +curve25519_neg(bignum25519 out, const bignum25519 a) { + word32 c; + out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = a * b */ +void +curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word32 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + word32 s0,s1,s2,s3,s4,s5,s6,s7,s8,s9; + word64 m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + word32 p; + + r0 = b[0]; r1 = b[1]; + r2 = b[2]; r3 = b[3]; + r4 = b[4]; r5 = b[5]; + r6 = b[6]; r7 = b[7]; + r8 = b[8]; r9 = b[9]; + + s0 = a[0]; s1 = a[1]; + s2 = a[2]; s3 = a[3]; + s4 = a[4]; s5 = a[5]; + s6 = a[6]; s7 = a[7]; + s8 = a[8]; s9 = a[9]; + + m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); + m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); + m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); + m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); + m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); + + r1 *= 2; r3 *= 2; + r5 *= 2; r7 *= 2; + + m0 = mul32x32_64(r0, s0); + m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); + m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0); + m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); + m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0); + + r1 *= 19; r2 *= 19; + r3 = (r3 / 2) * 19; + r4 *= 19; + r5 = (r5 / 2) * 19; + r6 *= 19; + r7 = (r7 / 2) * 19; + r8 *= 19; r9 *= 19; + + m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); + m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); + m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); + m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); + + r3 *= 2; r5 *= 2; + r7 *= 2; r9 *= 2; + + m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9)); + m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); + m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9)); + m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); + m8 += (mul32x32_64(r9, s9)); + + r0 = (word32)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (word32)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (word32)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (word32)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (word32)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (word32)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (word32)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (word32)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (word32)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (word32)m9 & reduce_mask_25; p = (word32)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (word32)m0 & reduce_mask_26; p = (word32)(m0 >> 26); + r1 += p; + + out[0] = r0; out[1] = r1; + out[2] = r2; out[3] = r3; + out[4] = r4; out[5] = r5; + out[6] = r6; out[7] = r7; + out[8] = r8; out[9] = r9; +} + +/* out = in*in */ +void +curve25519_square(bignum25519 out, const bignum25519 in) { + word32 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + word32 d6,d7,d8,d9; + word64 m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + word32 p; + + r0 = in[0]; r1 = in[1]; + r2 = in[2]; r3 = in[3]; + r4 = in[4]; r5 = in[5]; + r6 = in[6]; r7 = in[7]; + r8 = in[8]; r9 = in[9]; + + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; + d7 = r7 * 2 * 19; + d8 = r8 * 19; + d9 = r9 * 2 * 19; + + m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); + m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); + m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); + m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); + m7 += (mul32x32_64(d9, r8 )); + m8 += (mul32x32_64(d9, r9 )); + + r0 = (word32)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (word32)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (word32)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (word32)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (word32)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (word32)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (word32)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (word32)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (word32)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (word32)m9 & reduce_mask_25; p = (word32)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (word32)m0 & reduce_mask_26; p = (word32)(m0 >> 26); + r1 += p; + + out[0] = r0; out[1] = r1; + out[2] = r2; out[3] = r3; + out[4] = r4; out[5] = r5; + out[6] = r6; out[7] = r7; + out[8] = r8; out[9] = r9; +} + +/* out = in ^ (2 * count) */ +void +curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { + word32 r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + word32 d6,d7,d8,d9,p; + word64 m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + + r0 = in[0]; r1 = in[1]; + r2 = in[2]; r3 = in[3]; + r4 = in[4]; r5 = in[5]; + r6 = in[6]; r7 = in[7]; + r8 = in[8]; r9 = in[9]; + + do { + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; + d7 = r7 * 2 * 19; + d8 = r8 * 19; + d9 = r9 * 2 * 19; + + m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); + m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); + m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); + m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); + m7 += (mul32x32_64(d9, r8 )); + m8 += (mul32x32_64(d9, r9 )); + + r0 = (word32)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (word32)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (word32)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (word32)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (word32)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (word32)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (word32)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (word32)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (word32)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (word32)m9 & reduce_mask_25; p = (word32)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (word32)m0 & reduce_mask_26; p = (word32)(m0 >> 26); + r1 += p; + } while (--count); + + out[0] = r0; out[1] = r1; + out[2] = r2; out[3] = r3; + out[4] = r4; out[5] = r5; + out[6] = r6; out[7] = r7; + out[8] = r8; out[9] = r9; +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +void +curve25519_expand(bignum25519 out, const byte in[32]) { + word32 x0,x1,x2,x3,x4,x5,x6,x7; + GetBlock block(in); + block(x0)(x1)(x2)(x3)(x4)(x5)(x6)(x7); + + out[0] = ( x0 ) & 0x3ffffff; + out[1] = ((((word64)x1 << 32) | x0) >> 26) & 0x1ffffff; + out[2] = ((((word64)x2 << 32) | x1) >> 19) & 0x3ffffff; + out[3] = ((((word64)x3 << 32) | x2) >> 13) & 0x1ffffff; + out[4] = (( x3) >> 6) & 0x3ffffff; + out[5] = ( x4 ) & 0x1ffffff; + out[6] = ((((word64)x5 << 32) | x4) >> 25) & 0x3ffffff; + out[7] = ((((word64)x6 << 32) | x5) >> 19) & 0x1ffffff; + out[8] = ((((word64)x7 << 32) | x6) >> 12) & 0x3ffffff; + out[9] = (( x7) >> 6) & 0x1ffffff; +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +void +curve25519_contract(byte out[32], const bignum25519 in) { + bignum25519 f; + curve25519_copy(f, in); + + #define carry_pass() \ + f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ + f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ + f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ + f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ + f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ + f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ + f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ + f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ + f[9] += f[8] >> 26; f[8] &= reduce_mask_26; + + #define carry_pass_full() \ + carry_pass() \ + f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; + + #define carry_pass_final() \ + carry_pass() \ + f[9] &= reduce_mask_25; + + carry_pass_full() + carry_pass_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + f[0] += 19; + carry_pass_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + f[0] += (reduce_mask_26 + 1) - 19; + f[1] += (reduce_mask_25 + 1) - 1; + f[2] += (reduce_mask_26 + 1) - 1; + f[3] += (reduce_mask_25 + 1) - 1; + f[4] += (reduce_mask_26 + 1) - 1; + f[5] += (reduce_mask_25 + 1) - 1; + f[6] += (reduce_mask_26 + 1) - 1; + f[7] += (reduce_mask_25 + 1) - 1; + f[8] += (reduce_mask_26 + 1) - 1; + f[9] += (reduce_mask_25 + 1) - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + carry_pass_final() + + #undef carry_pass + #undef carry_full + #undef carry_final + + f[1] <<= 2; f[2] <<= 3; + f[3] <<= 5; f[4] <<= 6; + f[6] <<= 1; f[7] <<= 3; + f[8] <<= 4; f[9] <<= 6; + + #define F(i, s) \ + out[s+0] |= (byte)( f[i] & 0xff); \ + out[s+1] = (byte)((f[i] >> 8) & 0xff); \ + out[s+2] = (byte)((f[i] >> 16) & 0xff); \ + out[s+3] = (byte)((f[i] >> 24) & 0xff); + + out[0] = out[16] = 0; + F(0,0); F(1,3); + F(2,6); F(3,9); + F(4,12); F(5,16); + F(6,19); F(7,22); + F(8,25); F(9,28); + #undef F +} + +/* out = (flag) ? in : out */ +inline void +curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag) +{ + // TODO: enable this code path once we can test and benchmark it. + // It is about 48 insns shorter, it avoids punning which may be UB, + // and it is guaranteed constant time. +#if defined(__GNUC__) && defined(__i686__) && 0 + const word32 iter = 96/sizeof(word32); + word32* outl = reinterpret_cast(out); + const word32* inl = reinterpret_cast(in); + word32 idx=0, val; + + __asm__ __volatile__ ( + ".att_syntax ;\n" + "cmpl $0, %[flag] ;\n" // compare, set ZERO flag + "movl %[iter], %%ecx ;\n" // load iteration count + "1: ;\n" + " movl (%[idx],%[out]), %[val] ;\n" // val = out[idx] + " cmovnzl (%[idx],%[in]), %[val] ;\n" // copy in[idx] to val if NZ + " movl %[val], (%[idx],%[out]) ;\n" // out[idx] = val + " leal 4(%[idx]), %[idx] ;\n" // increment index + " loopnz 1b ;\n" // does not affect flags + : [out] "+S" (outl), [in] "+D" (inl), + [idx] "+b" (idx), [val] "=r" (val) + : [flag] "g" (flag), [iter] "I" (iter) + : "ecx", "memory", "cc" + ); +#else + const word32 nb = flag - 1, b = ~nb; + const word32 *inl = (const word32 *)in; + word32 *outl = (word32 *)out; + outl[0] = (outl[0] & nb) | (inl[0] & b); + outl[1] = (outl[1] & nb) | (inl[1] & b); + outl[2] = (outl[2] & nb) | (inl[2] & b); + outl[3] = (outl[3] & nb) | (inl[3] & b); + outl[4] = (outl[4] & nb) | (inl[4] & b); + outl[5] = (outl[5] & nb) | (inl[5] & b); + outl[6] = (outl[6] & nb) | (inl[6] & b); + outl[7] = (outl[7] & nb) | (inl[7] & b); + outl[8] = (outl[8] & nb) | (inl[8] & b); + outl[9] = (outl[9] & nb) | (inl[9] & b); + outl[10] = (outl[10] & nb) | (inl[10] & b); + outl[11] = (outl[11] & nb) | (inl[11] & b); + outl[12] = (outl[12] & nb) | (inl[12] & b); + outl[13] = (outl[13] & nb) | (inl[13] & b); + outl[14] = (outl[14] & nb) | (inl[14] & b); + outl[15] = (outl[15] & nb) | (inl[15] & b); + outl[16] = (outl[16] & nb) | (inl[16] & b); + outl[17] = (outl[17] & nb) | (inl[17] & b); + outl[18] = (outl[18] & nb) | (inl[18] & b); + outl[19] = (outl[19] & nb) | (inl[19] & b); + outl[20] = (outl[20] & nb) | (inl[20] & b); + outl[21] = (outl[21] & nb) | (inl[21] & b); + outl[22] = (outl[22] & nb) | (inl[22] & b); + outl[23] = (outl[23] & nb) | (inl[23] & b); +#endif +} + +/* if (iswap) swap(a, b) */ +inline void +curve25519_swap_conditional(bignum25519 a, bignum25519 b, word32 iswap) { + const word32 swap = (word32)(-(sword32)iswap); + word32 x0,x1,x2,x3,x4,x5,x6,x7,x8,x9; + + x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; + x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; + x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; + x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; + x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; + x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5; + x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6; + x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7; + x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8; + x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9; +} + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void +curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + ALIGN(ALIGN_SPEC) bignum25519 t0,c; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void +curve25519_recip(bignum25519 out, const bignum25519 z) { + ALIGN(ALIGN_SPEC) bignum25519 a,t0,b; + + /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square_times(t0, a, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul(out, b, a); +} + +/* + * z^((p-5)/8) = z^(2^252 - 3) + */ +void +curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { + ALIGN(ALIGN_SPEC) bignum25519 b,c,t0; + + /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ + /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ + /* 9 */ curve25519_mul(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul(c, b, c); /* c = 11 */ + /* 22 */ curve25519_square_times(t0, c, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); + /* 2^252 - 3 */ curve25519_mul(two252m3, b, z); +} + +inline void +ed25519_hash(byte *hash, const byte *in, size_t inlen) { + SHA512().CalculateDigest(hash, in, inlen); +} + +inline void +ed25519_extsk(hash_512bits extsk, const byte sk[32]) { + ed25519_hash(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; +} + +void +UpdateFromStream(HashTransformation& hash, std::istream& stream) +{ + SecByteBlock block(4096); + while (stream.read((char*)block.begin(), block.size())) + hash.Update(block, block.size()); + + std::streamsize rem = stream.gcount(); + if (rem) + hash.Update(block, (size_t)rem); + + block.SetMark(0); +} + +void +ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const byte *m, size_t mlen) { + SHA512 hash; + hash.Update(RS, 32); + hash.Update(pk, 32); + hash.Update(m, mlen); + hash.Final(hram); +} + +void +ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], std::istream& stream) { + SHA512 hash; + hash.Update(RS, 32); + hash.Update(pk, 32); + UpdateFromStream(hash, stream); + hash.Final(hram); +} + +inline bignum256modm_element_t +lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { + return (a - b) >> 31; +} + +/* see HAC, Alg. 14.42 Step 4 */ +void +reduce256_modm(bignum256modm r) { + bignum256modm t; + bignum256modm_element_t b = 0, pb, mask; + + /* t = r - m */ + pb = 0; + pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b; + pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b; + pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b; + pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b; + pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b; + pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b; + pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b; + pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b; + pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16)); + + /* keep r if r was smaller than m */ + mask = b - 1; + r[0] ^= mask & (r[0] ^ t[0]); + r[1] ^= mask & (r[1] ^ t[1]); + r[2] ^= mask & (r[2] ^ t[2]); + r[3] ^= mask & (r[3] ^ t[3]); + r[4] ^= mask & (r[4] ^ t[4]); + r[5] ^= mask & (r[5] ^ t[5]); + r[6] ^= mask & (r[6] ^ t[6]); + r[7] ^= mask & (r[7] ^ t[7]); + r[8] ^= mask & (r[8] ^ t[8]); +} + +/* Barrett reduction, see HAC, Alg. 14.42 */ +void +barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { + bignum256modm q3, r2; + word64 c; + bignum256modm_element_t f, b, pb; + + /* q1 = x >> 248 = 264 bits = 9 30 bit elements + q2 = mu * q1 + q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 + */ + c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]); + c >>= 30; + c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]); + f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]); + f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]); + f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]); + f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]); + f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]); + f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]); + f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]); + f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[8], q1[8]); + f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) + r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) + */ + c = mul32x32_64(modm_m[0], q3[0]); + r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]); + r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]); + r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]); + r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]); + r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]); + r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]); + r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]); + r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]); + r2[8] = (bignum256modm_element_t)(c & 0xffffff); + + /* r = r1 - r2 + if (r < 0) r += (1 << 264) */ + pb = 0; + pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b; + pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b; + pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b; + pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b; + pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b; + pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b; + pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b; + pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b; + pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24)); + + reduce256_modm(r); + reduce256_modm(r); +} + +/* addition modulo m */ +void +add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm_element_t c; + + c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30; + c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30; + c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30; + c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30; + c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30; + c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30; + c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30; + c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30; + c += x[8] + y[8]; r[8] = c; + + reduce256_modm(r); +} + +/* multiplication modulo m */ +void +mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm r1, q1; + word64 c; + bignum256modm_element_t f; + + c = mul32x32_64(x[0], y[0]); + f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]); + f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]); + f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]); + f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]); + f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]); + f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]); + f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]); + f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]); + f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]); + f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]); + f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]); + f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]); + f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]); + f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]); + f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]); + f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[8], y[8]); + f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff; + + barrett_reduce256_modm(r, q1, r1); +} + +void +expand256_modm(bignum256modm out, const byte *in, size_t len) { + byte work[64] = {0}; + bignum256modm_element_t x[16]; + bignum256modm q1; + + memcpy(work, in, len); + x[0] = U8TO32_LE(work + 0); + x[1] = U8TO32_LE(work + 4); + x[2] = U8TO32_LE(work + 8); + x[3] = U8TO32_LE(work + 12); + x[4] = U8TO32_LE(work + 16); + x[5] = U8TO32_LE(work + 20); + x[6] = U8TO32_LE(work + 24); + x[7] = U8TO32_LE(work + 28); + x[8] = U8TO32_LE(work + 32); + x[9] = U8TO32_LE(work + 36); + x[10] = U8TO32_LE(work + 40); + x[11] = U8TO32_LE(work + 44); + x[12] = U8TO32_LE(work + 48); + x[13] = U8TO32_LE(work + 52); + x[14] = U8TO32_LE(work + 56); + x[15] = U8TO32_LE(work + 60); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ + out[0] = ( x[0]) & 0x3fffffff; + out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; + out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; + out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; + out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; + out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; + out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; + out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; + out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff; + + /* 8*31 = 248 bits, no need to reduce */ + if (len < 32) + return; + + /* q1 = x >> 248 = 264 bits = 9 30 bit elements */ + q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff; + q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff; + q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff; + q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff; + q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff; + q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff; + q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff; + q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff; + q1[8] = ((x[15] >> 8) ); + + barrett_reduce256_modm(out, q1, out); +} + +void +expand_raw256_modm(bignum256modm out, const byte in[32]) { + bignum256modm_element_t x[8]; + + x[0] = U8TO32_LE(in + 0); + x[1] = U8TO32_LE(in + 4); + x[2] = U8TO32_LE(in + 8); + x[3] = U8TO32_LE(in + 12); + x[4] = U8TO32_LE(in + 16); + x[5] = U8TO32_LE(in + 20); + x[6] = U8TO32_LE(in + 24); + x[7] = U8TO32_LE(in + 28); + + out[0] = ( x[0]) & 0x3fffffff; + out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; + out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; + out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; + out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; + out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; + out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; + out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; + out[8] = ((x[ 7] >> 16) ) & 0x0000ffff; +} + +void +contract256_modm(byte out[32], const bignum256modm in) { + U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30)); + U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28)); + U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26)); + U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24)); + U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22)); + U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20)); + U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18)); + U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16)); +} + +void +contract256_window4_modm(signed char r[64], const bignum256modm in) { + char carry; + signed char *quads = r; + bignum256modm_element_t i, j, v; + + for (i = 0; i < 8; i += 2) { + v = in[i]; + for (j = 0; j < 7; j++) { + *quads++ = (v & 15); + v >>= 4; + } + v |= (in[i+1] << 2); + for (j = 0; j < 8; j++) { + *quads++ = (v & 15); + v >>= 4; + } + } + + v = in[8]; + *quads++ = (v & 15); v >>= 4; + *quads++ = (v & 15); v >>= 4; + *quads++ = (v & 15); v >>= 4; + *quads++ = (v & 15); v >>= 4; + + /* making it signed */ + carry = 0; + for(i = 0; i < 63; i++) { + r[i] += carry; + r[i+1] += (r[i] >> 4); + r[i] &= 15; + carry = (r[i] >> 3); + r[i] -= (carry << 4); + } + r[63] += carry; +} + +void +contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { + int i,j,k,b; + int m = (1 << (windowsize - 1)) - 1, soplen = 256; + signed char *bits = r; + bignum256modm_element_t v; + + /* first put the binary expansion into r */ + for (i = 0; i < 8; i++) { + v = s[i]; + for (j = 0; j < 30; j++, v >>= 1) + *bits++ = (v & 1); + } + v = s[8]; + for (j = 0; j < 16; j++, v >>= 1) + *bits++ = (v & 1); + + /* Making it sliding window */ + for (j = 0; j < soplen; j++) { + if (!r[j]) + continue; + + for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { + if ((r[j] + (r[j + b] << b)) <= m) { + r[j] += r[j + b] << b; + r[j + b] = 0; + } else if ((r[j] - (r[j + b] << b)) >= -m) { + r[j] -= r[j + b] << b; + for (k = j + b; k < soplen; k++) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else if (r[j + b]) { + break; + } + } + } +} + +inline void +ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); +} + +inline void +ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); + curve25519_mul(r->t, p->x, p->y); +} + +void +ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { + curve25519_sub(p->ysubx, r->y, r->x); + curve25519_add(p->xaddy, r->y, r->x); + curve25519_copy(p->z, r->z); + curve25519_mul(p->t2d, r->t, ge25519_ec2d); +} + +void +ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) { + bignum25519 a,b,c,d,t,u; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_sub(t, q->y, q->x); + curve25519_add(u, q->y, q->x); + curve25519_mul(a, a, t); + curve25519_mul(b, b, u); + curve25519_mul(c, p->t, q->t); + curve25519_mul(c, c, ge25519_ec2d); + curve25519_mul(d, p->z, q->z); + curve25519_add(d, d, d); + curve25519_sub(r->x, b, a); + curve25519_add(r->y, b, a); + curve25519_add_after_basic(r->z, d, c); + curve25519_sub_after_basic(r->t, d, c); +} + +void +ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { + bignum25519 a,b,c; + + curve25519_square(a, p->x); + curve25519_square(b, p->y); + curve25519_square(c, p->z); + curve25519_add_reduce(c, c, c); + curve25519_add(r->x, p->x, p->y); + curve25519_square(r->x, r->x); + curve25519_add(r->y, b, a); + curve25519_sub(r->z, b, a); + curve25519_sub_after_basic(r->x, r->x, r->y); + curve25519_sub_after_basic(r->t, c, r->z); +} + +void +ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, byte signbit) { + const bignum25519 *qb = (const bignum25519 *)q; + bignum25519 *rb = (bignum25519 *)r; + bignum25519 a,b,c; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ + curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_add_reduce(r->t, p->z, p->z); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ +} + +void +ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, byte signbit) { + const bignum25519 *qb = (const bignum25519 *)q; + bignum25519 *rb = (bignum25519 *)r; + bignum25519 a,b,c; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ + curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(r->t, p->z, q->z); + curve25519_add_reduce(r->t, r->t, r->t); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ +} + +void +ge25519_double_partial(ge25519 *r, const ge25519 *p) { + ge25519_p1p1 t; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_partial(r, &t); +} + +void +ge25519_double(ge25519 *r, const ge25519 *p) { + ge25519_p1p1 t; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_full(r, &t); +} + +void +ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) { + ge25519_p1p1 t; + ge25519_add_p1p1(&t, p, q); + ge25519_p1p1_to_full(r, &t); +} + +void +ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { + bignum25519 a,b,c,e,f,g,h; + + curve25519_sub(a, r->y, r->x); + curve25519_add(b, r->y, r->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(e, b, q->xaddy); + curve25519_add(h, e, a); + curve25519_sub(e, e, a); + curve25519_mul(c, r->t, q->t2d); + curve25519_add(f, r->z, r->z); + curve25519_add_after_basic(g, f, c); + curve25519_sub_after_basic(f, f, c); + curve25519_mul(r->x, e, f); + curve25519_mul(r->y, h, g); + curve25519_mul(r->z, g, f); + curve25519_mul(r->t, e, h); +} + +void +ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { + bignum25519 a,b,c,x,y,z,t; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(x, b, q->xaddy); + curve25519_add(y, x, a); + curve25519_sub(x, x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(t, p->z, q->z); + curve25519_add(t, t, t); + curve25519_add_after_basic(z, t, c); + curve25519_sub_after_basic(t, t, c); + curve25519_mul(r->xaddy, x, t); + curve25519_mul(r->ysubx, y, z); + curve25519_mul(r->z, z, t); + curve25519_mul(r->t2d, x, y); + curve25519_copy(y, r->ysubx); + curve25519_sub(r->ysubx, r->ysubx, r->xaddy); + curve25519_add(r->xaddy, r->xaddy, y); + curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); +} + +void +ge25519_pack(byte r[32], const ge25519 *p) { + bignum25519 tx, ty, zi; + byte parity[32]; + curve25519_recip(zi, p->z); + curve25519_mul(tx, p->x, zi); + curve25519_mul(ty, p->y, zi); + curve25519_contract(r, ty); + curve25519_contract(parity, tx); + r[31] ^= ((parity[0] & 1) << 7); +} + +int +ed25519_verify(const byte *x, const byte *y, size_t len) { + size_t differentbits = 0; + while (len--) + differentbits |= (*x++ ^ *y++); + return (int) (1 & ((differentbits - 1) >> 8)); +} + +int +ge25519_unpack_negative_vartime(ge25519 *r, const byte p[32]) { + const byte zero[32] = {0}; + const bignum25519 one = {1}; + byte parity = p[31] >> 7; + byte check[32]; + bignum25519 t, root, num, den, d3; + + curve25519_expand(r->y, p); + curve25519_copy(r->z, one); + curve25519_square(num, r->y); /* x = y^2 */ + curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ + curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ + curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ + + /* Computation of sqrt(num/den) */ + /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ + curve25519_square(t, den); + curve25519_mul(d3, t, den); + curve25519_square(r->x, d3); + curve25519_mul(r->x, r->x, den); + curve25519_mul(r->x, r->x, num); + curve25519_pow_two252m3(r->x, r->x); + + /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ + curve25519_mul(r->x, r->x, d3); + curve25519_mul(r->x, r->x, num); + + /* 3. Check if either of the roots works: */ + curve25519_square(t, r->x); + curve25519_mul(t, t, den); + curve25519_sub_reduce(root, t, num); + curve25519_contract(check, root); + if (!ed25519_verify(check, zero, 32)) { + curve25519_add_reduce(t, t, num); + curve25519_contract(check, t); + if (!ed25519_verify(check, zero, 32)) + return 0; + curve25519_mul(r->x, r->x, ge25519_sqrtneg1); + } + + curve25519_contract(check, r->x); + if ((check[0] & 1) == parity) { + curve25519_copy(t, r->x); + curve25519_neg(r->x, t); + } + curve25519_mul(r->t, r->x, r->y); + return 1; +} + +/* computes [s1]p1 + [s2]basepoint */ +void +ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { + signed char slide1[256], slide2[256]; + ge25519_pniels pre1[S1_TABLE_SIZE]; + ge25519 d1; + ge25519_p1p1 t; + sword32 i; + + contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); + contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); + + ge25519_double(&d1, p1); + ge25519_full_to_pniels(pre1, p1); + for (i = 0; i < S1_TABLE_SIZE - 1; i++) + ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]); + + /* set neutral */ + memset(r, 0, sizeof(ge25519)); + r->y[0] = 1; + r->z[0] = 1; + + i = 255; + while ((i >= 0) && !(slide1[i] | slide2[i])) + i--; + + for (; i >= 0; i--) { + ge25519_double_p1p1(&t, r); + + if (slide1[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (byte)slide1[i] >> 7); + } + + if (slide2[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (byte)slide2[i] >> 7); + } + + ge25519_p1p1_to_partial(r, &t); + } +} + +#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS) + +word32 +ge25519_windowb_equal(word32 b, word32 c) { + return ((b ^ c) - 1) >> 31; +} + +void +ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const byte table[256][96], word32 pos, signed char b) { + bignum25519 neg; + word32 sign = (word32)((byte)b >> 7); + word32 mask = ~(sign - 1); + word32 u = (b + mask) ^ mask; + word32 i; + + /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ + byte packed[96] = {0}; + packed[0] = 1; + packed[32] = 1; + + for (i = 0; i < 8; i++) + curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1)); + + /* expand in to t */ + curve25519_expand(t->ysubx, packed + 0); + curve25519_expand(t->xaddy, packed + 32); + curve25519_expand(t->t2d , packed + 64); + + /* adjust for sign */ + curve25519_swap_conditional(t->ysubx, t->xaddy, sign); + curve25519_neg(neg, t->t2d); + curve25519_swap_conditional(t->t2d, neg, sign); +} + +#endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */ + +/* computes [s]basepoint */ +void +ge25519_scalarmult_base_niels(ge25519 *r, const byte basepoint_table[256][96], const bignum256modm s) { + signed char b[64]; + word32 i; + ge25519_niels t; + + contract256_window4_modm(b, s); + + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); + curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); + curve25519_add_reduce(r->y, t.xaddy, t.ysubx); + memset(r->z, 0, sizeof(bignum25519)); + curve25519_copy(r->t, t.t2d); + r->z[0] = 2; + for (i = 3; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double(r, r); + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); + curve25519_mul(t.t2d, t.t2d, ge25519_ecd); + ge25519_nielsadd2(r, &t); + for(i = 2; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } +} + +ANONYMOUS_NAMESPACE_END +NAMESPACE_END // Ed25519 +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +//***************************** curve25519 *****************************// + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) + +int curve25519_mult_CXX(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]) +{ + using namespace CryptoPP::Donna::X25519; + + FixedSizeSecBlock e; + for (size_t i = 0; i < 32; ++i) + e[i] = secretKey[i]; + e[0] &= 0xf8; e[31] &= 0x7f; e[31] |= 0x40; + + bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx; + bignum25519 q, qx, qpqx, qqx, zzz, zmone; + size_t bit, lastbit; + + curve25519_expand(q, othersKey); + curve25519_copy(nqx, q); + + /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and + start pre-swapped on bit 254 */ + lastbit = 1; + + /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */ + for (int i = 253; i >= 2; i--) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_add(qpqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_mul(nqpqx, qpqx, nqz); + curve25519_mul(nqpqz, qx, nqpqz); + curve25519_add(qqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_square(nqpqz, nqpqz); + curve25519_square(nqpqx, qqx); + curve25519_mul(nqpqz, nqpqz, q); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + + bit = (e[i/8] >> (i & 7)) & 1; + curve25519_swap_conditional(nqx, nqpqx, (word32)(bit ^ lastbit)); + curve25519_swap_conditional(nqz, nqpqz, (word32)(bit ^ lastbit)); + lastbit = bit; + } + + /* the final 3 bits are always zero, so we only need to double */ + for (int i = 0; i < 3; i++) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + } + + curve25519_recip(zmone, nqz); + curve25519_mul(nqz, nqx, zmone); + curve25519_contract(sharedKey, nqz); + + return 0; +} + +int curve25519_mult(byte publicKey[32], const byte secretKey[32]) +{ + using namespace CryptoPP::Donna::X25519; + +#if (CRYPTOPP_CURVE25519_SSE2) + if (HasSSE2()) + return curve25519_mult_SSE2(publicKey, secretKey, basePoint); + else +#endif + + return curve25519_mult_CXX(publicKey, secretKey, basePoint); +} + +int curve25519_mult(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]) +{ +#if (CRYPTOPP_CURVE25519_SSE2) + if (HasSSE2()) + return curve25519_mult_SSE2(sharedKey, secretKey, othersKey); + else +#endif + + return curve25519_mult_CXX(sharedKey, secretKey, othersKey); +} + +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +//******************************* ed25519 *******************************// + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) + +int +ed25519_publickey_CXX(byte publicKey[32], const byte secretKey[32]) +{ + using namespace CryptoPP::Donna::Ed25519; + + bignum256modm a; + ALIGN(ALIGN_SPEC) ge25519 A; + hash_512bits extsk; + + /* A = aB */ + ed25519_extsk(extsk, secretKey); + expand256_modm(a, extsk, 32); + ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); + ge25519_pack(publicKey, &A); + + return 0; +} + +int +ed25519_publickey(byte publicKey[32], const byte secretKey[32]) +{ + return ed25519_publickey_CXX(publicKey, secretKey); +} + +int +ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byte RS[64]) +{ + using namespace CryptoPP::Donna::Ed25519; + + bignum256modm r, S, a; + ALIGN(ALIGN_SPEC) ge25519 R; + hash_512bits extsk, hashr, hram; + + // Unfortunately we need to read the stream twice. The fisrt time calculates + // 'r = H(aExt[32..64], m)'. The second time calculates 'S = H(R,A,m)'. There + // is a data dependency due to hashing 'RS' with 'R = [r]B' that does not + // allow us to read the stream once. + std::streampos where = stream.tellg(); + + ed25519_extsk(extsk, sk); + + /* r = H(aExt[32..64], m) */ + SHA512 hash; + hash.Update(extsk + 32, 32); + UpdateFromStream(hash, stream); + hash.Final(hashr); + expand256_modm(r, hashr, 64); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + ge25519_pack(RS, &R); + + // Reset stream for the second digest + stream.clear(); + stream.seekg(where); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, RS, pk, stream); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + mul256_modm(S, S, a); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(RS + 32, S); + + return 0; +} + +int +ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32], byte RS[64]) +{ + using namespace CryptoPP::Donna::Ed25519; + + bignum256modm r, S, a; + ALIGN(ALIGN_SPEC) ge25519 R; + hash_512bits extsk, hashr, hram; + + ed25519_extsk(extsk, sk); + + /* r = H(aExt[32..64], m) */ + SHA512 hash; + hash.Update(extsk + 32, 32); + hash.Update(m, mlen); + hash.Final(hashr); + expand256_modm(r, hashr, 64); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + ge25519_pack(RS, &R); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, RS, pk, m, mlen); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + mul256_modm(S, S, a); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(RS + 32, S); + + return 0; +} + +int +ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], + byte signature[64]) +{ + return ed25519_sign_CXX(stream, secretKey, publicKey, signature); +} + +int +ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], + const byte publicKey[32], byte signature[64]) +{ + return ed25519_sign_CXX(message, messageLength, secretKey, publicKey, signature); +} + +int +ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]) { + + using namespace CryptoPP::Donna::Ed25519; + + ALIGN(ALIGN_SPEC) ge25519 R, A; + hash_512bits hash; + bignum256modm hram, S; + byte checkR[32]; + + if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) + return -1; + + /* hram = H(R,A,m) */ + ed25519_hram(hash, RS, pk, stream); + expand256_modm(hram, hash, 64); + + /* S */ + expand256_modm(S, RS + 32, 32); + + /* SB - H(R,A,m)A */ + ge25519_double_scalarmult_vartime(&R, &A, hram, S); + ge25519_pack(checkR, &R); + + /* check that R = SB - H(R,A,m)A */ + return ed25519_verify(RS, checkR, 32) ? 0 : -1; +} + +int +ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte RS[64]) { + + using namespace CryptoPP::Donna::Ed25519; + + ALIGN(ALIGN_SPEC) ge25519 R, A; + hash_512bits hash; + bignum256modm hram, S; + byte checkR[32]; + + if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) + return -1; + + /* hram = H(R,A,m) */ + ed25519_hram(hash, RS, pk, m, mlen); + expand256_modm(hram, hash, 64); + + /* S */ + expand256_modm(S, RS + 32, 32); + + /* SB - H(R,A,m)A */ + ge25519_double_scalarmult_vartime(&R, &A, hram, S); + ge25519_pack(checkR, &R); + + /* check that R = SB - H(R,A,m)A */ + return ed25519_verify(RS, checkR, 32) ? 0 : -1; +} + +int +ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]) +{ + return ed25519_sign_open_CXX(message, messageLength, publicKey, signature); +} + +int +ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]) +{ + return ed25519_sign_open_CXX(stream, publicKey, signature); +} + +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_CURVE25519_32BIT diff --git a/external/ours/library/crypto/src/shared/original/donna_32.h b/external/ours/library/crypto/src/shared/original/donna_32.h new file mode 100755 index 000000000..dc9b91e5b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna_32.h @@ -0,0 +1,411 @@ +// donna_32.h - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// https://github.com/floodyberry/curve25519-donna and +// https://github.com/floodyberry/ed25519-donna. + +// This source file multiplexes two different repos using namespaces. This +// was a little easier from a project management standpoint. We only need +// two files per architecture at the expense of namespaces and bloat. + +#ifndef CRYPTOPP_DONNA_32_H +#define CRYPTOPP_DONNA_32_H +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + +#include "config.h" + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(Arch32) + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; + +// ******************** x25519 Agreement ************************* // + +#define ALIGN(n) CRYPTOPP_ALIGN_DATA(n) +#define mul32x32_64(a,b) (((word64)(a))*(b)) + +typedef word32 bignum25519[10]; + +const byte basePoint[32] = {9}; +const word32 reduce_mask_25 = (1 << 25) - 1; +const word32 reduce_mask_26 = (1 << 26) - 1; + +// ****************** ed25519 Signatures *********************** // + +typedef byte hash_512bits[64]; + +const int bignum256modm_bits_per_limb = 30; +const int bignum256modm_limb_size = 9; +typedef word32 bignum256modm_element_t; +typedef bignum256modm_element_t bignum256modm[9]; + +struct ge25519 { + bignum25519 x, y, z, t; +}; + +struct ge25519_p1p1 { + bignum25519 x, y, z, t; +}; + +struct ge25519_niels { + bignum25519 ysubx, xaddy, t2d; +}; + +struct ge25519_pniels { + bignum25519 ysubx, xaddy, z, t2d; +}; + +#define S1_SWINDOWSIZE 5 +#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2)) +#define S2_SWINDOWSIZE 7 +#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2)) + +// *************** ed25519-donna-32bit-tables.h *************** // + +ALIGN(16) const ge25519 ge25519_basepoint = { + {0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db}, + {0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999}, + {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}, + {0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c} +}; + +ALIGN(16) const bignum25519 ge25519_ecd = { + 0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3 +}; + +ALIGN(16) const bignum25519 ge25519_ec2d = { + 0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67 +}; + +ALIGN(16) const bignum25519 ge25519_sqrtneg1 = { + 0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92 +}; + +ALIGN(16) const ge25519_niels ge25519_niels_sliding_multiples[32] = { + {{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}}, + {{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}}, + {{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}}, + {{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}}, + {{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}}, + {{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}}, + {{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}}, + {{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}}, + {{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}}, + {{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}}, + {{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}}, + {{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}}, + {{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}}, + {{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}}, + {{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}}, + {{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}}, + {{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}}, + {{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}}, + {{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}}, + {{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}}, + {{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}}, + {{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}}, + {{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}}, + {{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}}, + {{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}}, + {{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}}, + {{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}}, + {{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}}, + {{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}}, + {{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}}, + {{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}}, + {{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}} +}; + +// *************** modm-donna-32bit.h *************** // + +const bignum256modm modm_m = { + 0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8, + 0x00000014, 0x00000000, 0x00000000, 0x00000000, + 0x00001000 +}; + +const bignum256modm modm_mu = { + 0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742, + 0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff, + 0x000fffff +}; + +/* multiples of p */ +const word32 twoP0 = 0x07ffffda; +const word32 twoP13579 = 0x03fffffe; +const word32 twoP2468 = 0x07fffffe; +const word32 fourP0 = 0x0fffffb4; +const word32 fourP13579 = 0x07fffffc; +const word32 fourP2468 = 0x0ffffffc; + +// *************** ed25519-donna-basepoint-table.h *************** // + +/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ +ALIGN(16) const byte ge25519_niels_base_multiples[256][96] = { + {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f}, + {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49}, + {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54}, + {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44}, + {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68}, + {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78}, + {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23}, + {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58}, + {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10}, + {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56}, + {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14}, + {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37}, + {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02}, + {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12}, + {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f}, + {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41}, + {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e}, + {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14}, + {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41}, + {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59}, + {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49}, + {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20}, + {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b}, + {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74}, + {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69}, + {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b}, + {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e}, + {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39}, + {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33}, + {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61}, + {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45}, + {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d}, + {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c}, + {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21}, + {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a}, + {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39}, + {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22}, + {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50}, + {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d}, + {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45}, + {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d}, + {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c}, + {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27}, + {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f}, + {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f}, + {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22}, + {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c}, + {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19}, + {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71}, + {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c}, + {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a}, + {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02}, + {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31}, + {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48}, + {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c}, + {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f}, + {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60}, + {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63}, + {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70}, + {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41}, + {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24}, + {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16}, + {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78}, + {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13}, + {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a}, + {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b}, + {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d}, + {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74}, + {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58}, + {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12}, + {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d}, + {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b}, + {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c}, + {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04}, + {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76}, + {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11}, + {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f}, + {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55}, + {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57}, + {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21}, + {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a}, + {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19}, + {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60}, + {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36}, + {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07}, + {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57}, + {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05}, + {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f}, + {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72}, + {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00}, + {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c}, + {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06}, + {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15}, + {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07}, + {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51}, + {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77}, + {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e}, + {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09}, + {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56}, + {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43}, + {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27}, + {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b}, + {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46}, + {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69}, + {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14}, + {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55}, + {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13}, + {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d}, + {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31}, + {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05}, + {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f}, + {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a}, + {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10}, + {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25}, + {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08}, + {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a}, + {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f}, + {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38}, + {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65}, + {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c}, + {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e}, + {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35}, + {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47}, + {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47}, + {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74}, + {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a}, + {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56}, + {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d}, + {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44}, + {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58}, + {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70}, + {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e}, + {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41}, + {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11}, + {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f}, + {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10}, + {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72}, + {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00}, + {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05}, + {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00}, + {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b}, + {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05}, + {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f}, + {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f}, + {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40}, + {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b}, + {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02}, + {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c}, + {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f}, + {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29}, + {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71}, + {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a}, + {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06}, + {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30}, + {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b}, + {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24}, + {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49}, + {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53}, + {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02}, + {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e}, + {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d}, + {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f}, + {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07}, + {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f}, + {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b}, + {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f}, + {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12}, + {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30}, + {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45}, + {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a}, + {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13}, + {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f}, + {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a}, + {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12}, + {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b}, + {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10}, + {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b}, + {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e}, + {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f}, + {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00}, + {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33}, + {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63}, + {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b}, + {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16}, + {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57}, + {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e}, + {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73}, + {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76}, + {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e}, + {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16}, + {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45}, + {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67}, + {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a}, + {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a}, + {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e}, + {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62}, + {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e}, + {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e}, + {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78}, + {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46}, + {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a}, + {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26}, + {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b}, + {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d}, + {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45}, + {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26}, + {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62}, + {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d}, + {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61}, + {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79}, + {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39}, + {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63}, + {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34}, + {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56}, + {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e}, + {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26}, + {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f}, + {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f}, + {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b}, + {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39}, + {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51}, + {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f}, + {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f}, + {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13}, + {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c}, + {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60}, + {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15}, + {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32}, + {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b}, + {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02}, + {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c}, + {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05}, + {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67}, + {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c}, + {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37}, + {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63}, + {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68}, + {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c}, + {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c}, + {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26}, + {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08}, + {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19}, + {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41}, + {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b}, + {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08}, + {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48}, + {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54}, + {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c}, + {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f}, + {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25}, + {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55}, + {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a}, + {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59}, + {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70}, + {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27}, + {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f} +}; + +NAMESPACE_END // Arch32 +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_DOXYGEN_PROCESSING +#endif // CRYPTOPP_DONNA_32_H diff --git a/external/ours/library/crypto/src/shared/original/donna_64.cpp b/external/ours/library/crypto/src/shared/original/donna_64.cpp new file mode 100755 index 000000000..ef07a5ab1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna_64.cpp @@ -0,0 +1,1815 @@ +// donna_64.cpp - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// https://github.com/floodyberry/curve25519-donna and +// https://github.com/floodyberry/ed25519-donna. + +// The curve25519 and ed25519 source files multiplex different repos and +// architectures using namespaces. The repos are Andrew Moon's +// curve25519-donna and ed25519-donna. The architectures are 32-bit, 64-bit +// and SSE. For example, 32-bit x25519 uses symbols from Donna::X25519 and +// Donna::Arch32. + +// A fair amount of duplication happens below, but we could not directly +// use curve25519 for both x25519 and ed25519. A close examination reveals +// slight differences in the implementation. For example, look at the +// two curve25519_sub functions. + +// If needed, see Moon's commit "Go back to ignoring 256th bit [sic]", +// https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658 + +#include "pch.h" + +#include "config.h" +#include "donna.h" +#include "secblock.h" +#include "sha.h" +#include "misc.h" +#include "cpu.h" + +#include +#include + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4244) +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char DONNA64_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +// Can't use GetAlignmentOf() because of C++11 and constexpr +// Can use 'const unsigned int' because of MSVC 2013 +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +# define ALIGN_SPEC 16 +#else +# define ALIGN_SPEC 8 +#endif + +ANONYMOUS_NAMESPACE_END + +#if defined(CRYPTOPP_CURVE25519_64BIT) + +#include "donna_64.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word64; +using CryptoPP::GetWord; +using CryptoPP::PutWord; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +inline word64 U8TO64_LE(const byte* p) +{ + return GetWord(false, LITTLE_ENDIAN_ORDER, p); +} + +inline void U64TO8_LE(byte* p, word64 w) +{ + PutWord(false, LITTLE_ENDIAN_ORDER, p, w); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(X25519) +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::sword32; +using CryptoPP::word64; +using CryptoPP::sword64; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; + +// Bring in all the symbols from the 64-bit header +using namespace CryptoPP::Donna::Arch64; + +/* out = in */ +inline void +curve25519_copy(bignum25519 out, const bignum25519 in) { + out[0] = in[0]; out[1] = in[1]; + out[2] = in[2]; out[3] = in[3]; + out[4] = in[4]; +} + +/* out = a + b */ +inline void +curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; +} + +/* out = a - b */ +inline void +curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + two54m152 - b[0]; + out[1] = a[1] + two54m8 - b[1]; + out[2] = a[2] + two54m8 - b[2]; + out[3] = a[3] + two54m8 - b[3]; + out[4] = a[4] + two54m8 - b[4]; +} + +/* out = (in * scalar) */ +inline void +curve25519_scalar_product(bignum25519 out, const bignum25519 in, const word64 scalar) { + word128 a; + word64 c; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + a = ((word128) in[0]) * scalar; out[0] = (word64)a & reduce_mask_51; c = (word64)(a >> 51); + a = ((word128) in[1]) * scalar + c; out[1] = (word64)a & reduce_mask_51; c = (word64)(a >> 51); + a = ((word128) in[2]) * scalar + c; out[2] = (word64)a & reduce_mask_51; c = (word64)(a >> 51); + a = ((word128) in[3]) * scalar + c; out[3] = (word64)a & reduce_mask_51; c = (word64)(a >> 51); + a = ((word128) in[4]) * scalar + c; out[4] = (word64)a & reduce_mask_51; c = (word64)(a >> 51); + out[0] += c * 19; +#else + mul64x64_128(a, in[0], scalar) out[0] = lo128(a) & reduce_mask_51; shr128(c, a, 51); + mul64x64_128(a, in[1], scalar) add128_64(a, c) out[1] = lo128(a) & reduce_mask_51; shr128(c, a, 51); + mul64x64_128(a, in[2], scalar) add128_64(a, c) out[2] = lo128(a) & reduce_mask_51; shr128(c, a, 51); + mul64x64_128(a, in[3], scalar) add128_64(a, c) out[3] = lo128(a) & reduce_mask_51; shr128(c, a, 51); + mul64x64_128(a, in[4], scalar) add128_64(a, c) out[4] = lo128(a) & reduce_mask_51; shr128(c, a, 51); + out[0] += c * 19; +#endif +} + +/* out = a * b */ +inline void +curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { +#if !defined(CRYPTOPP_WORD128_AVAILABLE) + word128 mul; +#endif + word128 t[5]; + word64 r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c; + + r0 = b[0]; r1 = b[1]; r2 = b[2]; r3 = b[3]; r4 = b[4]; + s0 = a[0]; s1 = a[1]; s2 = a[2]; s3 = a[3]; s4 = a[4]; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] = ((word128) r0) * s0; + t[1] = ((word128) r0) * s1 + ((word128) r1) * s0; + t[2] = ((word128) r0) * s2 + ((word128) r2) * s0 + ((word128) r1) * s1; + t[3] = ((word128) r0) * s3 + ((word128) r3) * s0 + ((word128) r1) * s2 + ((word128) r2) * s1; + t[4] = ((word128) r0) * s4 + ((word128) r4) * s0 + ((word128) r3) * s1 + ((word128) r1) * s3 + ((word128) r2) * s2; +#else + mul64x64_128(t[0], r0, s0) + mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul) + mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul) + mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul) + mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul) +#endif + + r1 *= 19; r2 *= 19; r3 *= 19; r4 *= 19; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] += ((word128) r4) * s1 + ((word128) r1) * s4 + ((word128) r2) * s3 + ((word128) r3) * s2; + t[1] += ((word128) r4) * s2 + ((word128) r2) * s4 + ((word128) r3) * s3; + t[2] += ((word128) r4) * s3 + ((word128) r3) * s4; + t[3] += ((word128) r4) * s4; +#else + mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul) + mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul) + mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul) + mul64x64_128(mul, r4, s4) add128(t[3], mul) +#endif + + r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); + add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); + add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); + add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); + add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); + r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; + r1 += c; + + out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; +} + +/* out = in^(2 * count) */ +inline void +curve25519_square_times(bignum25519 out, const bignum25519 in, word64 count) { +#if !defined(CRYPTOPP_WORD128_AVAILABLE) + word128 mul; +#endif + word128 t[5]; + word64 r0,r1,r2,r3,r4,c; + word64 d0,d1,d2,d4,d419; + + r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; + + do { + d0 = r0 * 2; d1 = r1 * 2; + d2 = r2 * 2 * 19; + d419 = r4 * 19; d4 = d419 * 2; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 )); + t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19)); + t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 )); + t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 )); + t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 )); +#else + mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul) + mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul) + mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul) + mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul) + mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul) +#endif + + r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); + add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); + add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); + add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); + add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); + r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; + r1 += c; + } while(--count); + + out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; +} + +inline void +curve25519_square(bignum25519 out, const bignum25519 in) { +#if !defined(CRYPTOPP_WORD128_AVAILABLE) + word128 mul; +#endif + word128 t[5]; + word64 r0,r1,r2,r3,r4,c; + word64 d0,d1,d2,d4,d419; + + r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; + + d0 = r0 * 2; d1 = r1 * 2; + d2 = r2 * 2 * 19; + d419 = r4 * 19; d4 = d419 * 2; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 )); + t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19)); + t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 )); + t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 )); + t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 )); +#else + mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul) + mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul) + mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul) + mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul) + mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul) +#endif + + r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); + add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); + add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); + add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); + add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); + r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; + r1 += c; + + out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +inline void +curve25519_expand(bignum25519 out, const byte *in) { + word64 x0,x1,x2,x3; + GetBlock block(in); + block(x0)(x1)(x2)(x3); + + out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13); + out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26); + out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39); + out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12); + out[4] = x3 & reduce_mask_51; /* ignore the top bit */ +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +inline void +curve25519_contract(byte *out, const bignum25519 input) { + word64 t[5]; + word64 f, i; + + t[0] = input[0]; + t[1] = input[1]; + t[2] = input[2]; + t[3] = input[3]; + t[4] = input[4]; + + #define curve25519_contract_carry() \ + t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \ + t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \ + t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \ + t[4] += t[3] >> 51; t[3] &= reduce_mask_51; + + #define curve25519_contract_carry_full() curve25519_contract_carry() \ + t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51; + + #define curve25519_contract_carry_final() curve25519_contract_carry() \ + t[4] &= reduce_mask_51; + + curve25519_contract_carry_full() + curve25519_contract_carry_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + t[0] += 19; + curve25519_contract_carry_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + t[0] += 0x8000000000000 - 19; + t[1] += 0x8000000000000 - 1; + t[2] += 0x8000000000000 - 1; + t[3] += 0x8000000000000 - 1; + t[4] += 0x8000000000000 - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + curve25519_contract_carry_final() + + #define write51full(n,shift) \ + f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \ + for (i = 0; i < 8; i++, f >>= 8) *out++ = (byte)f; + #define write51(n) write51full(n,13*n) + + write51(0) + write51(1) + write51(2) + write51(3) + + #undef curve25519_contract_carry + #undef curve25519_contract_carry_full + #undef curve25519_contract_carry_final + #undef write51full + #undef write51 +} + +/* + * Swap the contents of [qx] and [qpx] iff @swap is non-zero + */ +inline void +curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word64 iswap) { + const word64 swap = (word64)(-(sword64)iswap); + word64 x0,x1,x2,x3,x4; + + x0 = swap & (x[0] ^ qpx[0]); x[0] ^= x0; qpx[0] ^= x0; + x1 = swap & (x[1] ^ qpx[1]); x[1] ^= x1; qpx[1] ^= x1; + x2 = swap & (x[2] ^ qpx[2]); x[2] ^= x2; qpx[2] ^= x2; + x3 = swap & (x[3] ^ qpx[3]); x[3] ^= x3; qpx[3] ^= x3; + x4 = swap & (x[4] ^ qpx[4]); x[4] ^= x4; qpx[4] ^= x4; +} + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void +curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + ALIGN(ALIGN_SPEC) bignum25519 t0,c; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void +curve25519_recip(bignum25519 out, const bignum25519 z) { + ALIGN(ALIGN_SPEC) bignum25519 a, t0, b; + + /* 2 */ curve25519_square(a, z); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square(t0, a); + /* 2^5 - 2^0 = 31 */ curve25519_mul(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul(out, b, a); +} + +ANONYMOUS_NAMESPACE_END +NAMESPACE_END // X25519 +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +//******************************* ed25519 *******************************// + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(Ed25519) +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::sword32; +using CryptoPP::word64; +using CryptoPP::sword64; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; + +using CryptoPP::SHA512; + +// Bring in all the symbols from the 64-bit header +using namespace CryptoPP::Donna::Arch64; + +/* out = in */ +inline void +curve25519_copy(bignum25519 out, const bignum25519 in) { + out[0] = in[0]; out[1] = in[1]; + out[2] = in[2]; out[3] = in[3]; + out[4] = in[4]; +} + +/* out = a + b */ +inline void +curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; +} + +/* out = a + b, where a and/or b are the result of a basic op (add,sub) */ +inline void +curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; +} + +inline void +curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word64 c; + out[0] = a[0] + b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; + out[1] = a[1] + b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; + out[2] = a[2] + b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; + out[3] = a[3] + b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; + out[4] = a[4] + b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; + out[0] += c * 19; +} + +/* out = a - b */ +inline void +curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + twoP0 - b[0]; + out[1] = a[1] + twoP1234 - b[1]; + out[2] = a[2] + twoP1234 - b[2]; + out[3] = a[3] + twoP1234 - b[3]; + out[4] = a[4] + twoP1234 - b[4]; +} + +/* out = a - b, where a and/or b are the result of a basic op (add,sub) */ +inline void +curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + fourP0 - b[0]; + out[1] = a[1] + fourP1234 - b[1]; + out[2] = a[2] + fourP1234 - b[2]; + out[3] = a[3] + fourP1234 - b[3]; + out[4] = a[4] + fourP1234 - b[4]; +} + +inline void +curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + word64 c; + out[0] = a[0] + fourP0 - b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; + out[1] = a[1] + fourP1234 - b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; + out[2] = a[2] + fourP1234 - b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; + out[3] = a[3] + fourP1234 - b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; + out[4] = a[4] + fourP1234 - b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; + out[0] += c * 19; +} + +/* out = -a */ +inline void +curve25519_neg(bignum25519 out, const bignum25519 a) { + word64 c; + out[0] = twoP0 - a[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; + out[1] = twoP1234 - a[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; + out[2] = twoP1234 - a[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; + out[3] = twoP1234 - a[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; + out[4] = twoP1234 - a[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; + out[0] += c * 19; +} + +/* out = a * b */ +inline void +curve25519_mul(bignum25519 out, const bignum25519 in2, const bignum25519 in) { +#if !defined(CRYPTOPP_WORD128_AVAILABLE) + word128 mul; +#endif + word128 t[5]; + word64 r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c; + + r0 = in[0]; r1 = in[1]; + r2 = in[2]; r3 = in[3]; + r4 = in[4]; + + s0 = in2[0]; s1 = in2[1]; + s2 = in2[2]; s3 = in2[3]; + s4 = in2[4]; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] = ((word128) r0) * s0; + t[1] = ((word128) r0) * s1 + ((word128) r1) * s0; + t[2] = ((word128) r0) * s2 + ((word128) r2) * s0 + ((word128) r1) * s1; + t[3] = ((word128) r0) * s3 + ((word128) r3) * s0 + ((word128) r1) * s2 + ((word128) r2) * s1; + t[4] = ((word128) r0) * s4 + ((word128) r4) * s0 + ((word128) r3) * s1 + ((word128) r1) * s3 + ((word128) r2) * s2; +#else + mul64x64_128(t[0], r0, s0) + mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul) + mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul) + mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul) + mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul) +#endif + + r1 *= 19; r2 *= 19; + r3 *= 19; r4 *= 19; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] += ((word128) r4) * s1 + ((word128) r1) * s4 + ((word128) r2) * s3 + ((word128) r3) * s2; + t[1] += ((word128) r4) * s2 + ((word128) r2) * s4 + ((word128) r3) * s3; + t[2] += ((word128) r4) * s3 + ((word128) r3) * s4; + t[3] += ((word128) r4) * s4; +#else + mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul) + mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul) + mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul) + mul64x64_128(mul, r4, s4) add128(t[3], mul) +#endif + + r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); + add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); + add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); + add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); + add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); + r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; + r1 += c; + + out[0] = r0; out[1] = r1; + out[2] = r2; out[3] = r3; + out[4] = r4; +} + +void +curve25519_mul_noinline(bignum25519 out, const bignum25519 in2, const bignum25519 in) { + curve25519_mul(out, in2, in); +} + +/* out = in^(2 * count) */ +void +curve25519_square_times(bignum25519 out, const bignum25519 in, word64 count) { +#if !defined(CRYPTOPP_WORD128_AVAILABLE) + word128 mul; +#endif + word128 t[5]; + word64 r0,r1,r2,r3,r4,c; + word64 d0,d1,d2,d4,d419; + + r0 = in[0]; r1 = in[1]; + r2 = in[2]; r3 = in[3]; + r4 = in[4]; + + do { + d0 = r0 * 2; + d1 = r1 * 2; + d2 = r2 * 2 * 19; + d419 = r4 * 19; + d4 = d419 * 2; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 )); + t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19)); + t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 )); + t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 )); + t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 )); +#else + mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul) + mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul) + mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul) + mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul) + mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul) +#endif + + r0 = lo128(t[0]) & reduce_mask_51; + r1 = lo128(t[1]) & reduce_mask_51; shl128(c, t[0], 13); r1 += c; + r2 = lo128(t[2]) & reduce_mask_51; shl128(c, t[1], 13); r2 += c; + r3 = lo128(t[3]) & reduce_mask_51; shl128(c, t[2], 13); r3 += c; + r4 = lo128(t[4]) & reduce_mask_51; shl128(c, t[3], 13); r4 += c; + shl128(c, t[4], 13); r0 += c * 19; + c = r0 >> 51; r0 &= reduce_mask_51; + r1 += c ; c = r1 >> 51; r1 &= reduce_mask_51; + r2 += c ; c = r2 >> 51; r2 &= reduce_mask_51; + r3 += c ; c = r3 >> 51; r3 &= reduce_mask_51; + r4 += c ; c = r4 >> 51; r4 &= reduce_mask_51; + r0 += c * 19; + } while(--count); + + out[0] = r0; out[1] = r1; + out[2] = r2; out[3] = r3; + out[4] = r4; +} + +inline void +curve25519_square(bignum25519 out, const bignum25519 in) { +#if !defined(CRYPTOPP_WORD128_AVAILABLE) + word128 mul; +#endif + word128 t[5]; + word64 r0,r1,r2,r3,r4,c; + word64 d0,d1,d2,d4,d419; + + r0 = in[0]; r1 = in[1]; + r2 = in[2]; r3 = in[3]; + r4 = in[4]; + + d0 = r0 * 2; d1 = r1 * 2; + d2 = r2 * 2 * 19; + d419 = r4 * 19; + d4 = d419 * 2; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + t[0] = ((word128) r0) * r0 + ((word128) d4) * r1 + (((word128) d2) * (r3 )); + t[1] = ((word128) d0) * r1 + ((word128) d4) * r2 + (((word128) r3) * (r3 * 19)); + t[2] = ((word128) d0) * r2 + ((word128) r1) * r1 + (((word128) d4) * (r3 )); + t[3] = ((word128) d0) * r3 + ((word128) d1) * r2 + (((word128) r4) * (d419 )); + t[4] = ((word128) d0) * r4 + ((word128) d1) * r3 + (((word128) r2) * (r2 )); +#else + mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul) + mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul) + mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul) + mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul) + mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul) +#endif + + r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); + add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); + add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); + add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); + add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); + r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; + r1 += c; + + out[0] = r0; out[1] = r1; + out[2] = r2; out[3] = r3; + out[4] = r4; +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +inline void +curve25519_expand(bignum25519 out, const byte *in) { + word64 x0,x1,x2,x3; + GetBlock block(in); + block(x0)(x1)(x2)(x3); + + out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13); + out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26); + out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39); + out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12); + out[4] = x3 & reduce_mask_51; +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +inline void +curve25519_contract(byte *out, const bignum25519 input) { + word64 t[5]; + word64 f, i; + + t[0] = input[0]; + t[1] = input[1]; + t[2] = input[2]; + t[3] = input[3]; + t[4] = input[4]; + + #define curve25519_contract_carry() \ + t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \ + t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \ + t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \ + t[4] += t[3] >> 51; t[3] &= reduce_mask_51; + + #define curve25519_contract_carry_full() curve25519_contract_carry() \ + t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51; + + #define curve25519_contract_carry_final() curve25519_contract_carry() \ + t[4] &= reduce_mask_51; + + curve25519_contract_carry_full() + curve25519_contract_carry_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + t[0] += 19; + curve25519_contract_carry_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + t[0] += (reduce_mask_51 + 1) - 19; + t[1] += (reduce_mask_51 + 1) - 1; + t[2] += (reduce_mask_51 + 1) - 1; + t[3] += (reduce_mask_51 + 1) - 1; + t[4] += (reduce_mask_51 + 1) - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + curve25519_contract_carry_final() + + #define write51full(n,shift) \ + f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \ + for (i = 0; i < 8; i++, f >>= 8) *out++ = (byte)f; + #define write51(n) write51full(n,13*n) + write51(0) + write51(1) + write51(2) + write51(3) +} + +#if !defined(ED25519_GCC_64BIT_CHOOSE) + +/* out = (flag) ? in : out */ +inline void +curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag) +{ + // TODO: enable this code path once we can test and benchmark it. + // It is about 24 insns shorter, it avoids punning which may be UB, + // and it is guaranteed constant time. +#if defined(__GNUC__) && defined(__x86_64__) && 0 + const word32 iter = 96/sizeof(word64); + word64* outq = reinterpret_cast(out); + const word64* inq = reinterpret_cast(in); + word64 idx=0, val; + + __asm__ __volatile__ ( + ".att_syntax ;\n" + "cmpq $0, %[flag] ;\n" // compare, set ZERO flag + "movq %[iter], %%rcx ;\n" // load iteration count + "1: ;\n" + " movq (%[idx],%[out]), %[val] ;\n" // val = out[idx] + " cmovnzq (%[idx],%[in]), %[val] ;\n" // copy in[idx] to val if NZ + " movq %[val], (%[idx],%[out]) ;\n" // out[idx] = val + " leaq 8(%[idx]), %[idx] ;\n" // increment index + " loopnz 1b ;\n" // does not affect flags + : [out] "+S" (outq), [in] "+D" (inq), + [idx] "+b" (idx), [val] "=r" (val) + : [flag] "g" (flag), [iter] "I" (iter) + : "rcx", "memory", "cc" + ); +#else + const word64 nb = flag - 1, b = ~nb; + const word64 *inq = (const word64 *)(const void*)in; + word64 *outq = (word64 *)(void *)out; + outq[0] = (outq[0] & nb) | (inq[0] & b); + outq[1] = (outq[1] & nb) | (inq[1] & b); + outq[2] = (outq[2] & nb) | (inq[2] & b); + outq[3] = (outq[3] & nb) | (inq[3] & b); + outq[4] = (outq[4] & nb) | (inq[4] & b); + outq[5] = (outq[5] & nb) | (inq[5] & b); + outq[6] = (outq[6] & nb) | (inq[6] & b); + outq[7] = (outq[7] & nb) | (inq[7] & b); + outq[8] = (outq[8] & nb) | (inq[8] & b); + outq[9] = (outq[9] & nb) | (inq[9] & b); + outq[10] = (outq[10] & nb) | (inq[10] & b); + outq[11] = (outq[11] & nb) | (inq[11] & b); +#endif +} + +/* if (iswap) swap(a, b) */ +inline void +curve25519_swap_conditional(bignum25519 a, bignum25519 b, word64 iswap) { + const word64 swap = (word64)(-(sword64)iswap); + word64 x0,x1,x2,x3,x4; + + x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; + x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; + x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; + x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; + x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; +} + +#endif /* ED25519_GCC_64BIT_CHOOSE */ + +// ************************************************************************************ + +inline void +ed25519_hash(byte *hash, const byte *in, size_t inlen) { + SHA512().CalculateDigest(hash, in, inlen); +} + +inline void +ed25519_extsk(hash_512bits extsk, const byte sk[32]) { + ed25519_hash(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; +} + +void +UpdateFromStream(HashTransformation& hash, std::istream& stream) +{ + SecByteBlock block(4096); + while (stream.read((char*)block.begin(), block.size())) + hash.Update(block, block.size()); + + std::streamsize rem = stream.gcount(); + if (rem) + hash.Update(block, rem); + + block.SetMark(0); +} + +void +ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const byte *m, size_t mlen) { + SHA512 hash; + hash.Update(RS, 32); + hash.Update(pk, 32); + hash.Update(m, mlen); + hash.Final(hram); +} + +void +ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], std::istream& stream) { + SHA512 hash; + hash.Update(RS, 32); + hash.Update(pk, 32); + UpdateFromStream(hash, stream); + hash.Final(hram); +} + +bignum256modm_element_t +lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { + return (a - b) >> 63; +} + +void +reduce256_modm(bignum256modm r) { + bignum256modm t; + bignum256modm_element_t b = 0, pb, mask; + + /* t = r - m */ + pb = 0; + pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 56)); pb = b; + pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 56)); pb = b; + pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 56)); pb = b; + pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 56)); pb = b; + pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 32)); + + /* keep r if r was smaller than m */ + mask = b - 1; + + r[0] ^= mask & (r[0] ^ t[0]); + r[1] ^= mask & (r[1] ^ t[1]); + r[2] ^= mask & (r[2] ^ t[2]); + r[3] ^= mask & (r[3] ^ t[3]); + r[4] ^= mask & (r[4] ^ t[4]); +} + +void +barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { + bignum256modm q3, r2; + word128 c, mul; + bignum256modm_element_t f, b, pb; + + /* q1 = x >> 248 = 264 bits = 5 56 bit elements + q2 = mu * q1 + q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ + mul64x64_128(c, modm_mu[0], q1[3]) mul64x64_128(mul, modm_mu[3], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[2]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[1]) add128(c, mul) shr128(f, c, 56); + mul64x64_128(c, modm_mu[0], q1[4]) add128_64(c, f) mul64x64_128(mul, modm_mu[4], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[1]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[2]) add128(c, mul) + f = lo128(c); q3[0] = (f >> 40) & 0xffff; shr128(f, c, 56); + mul64x64_128(c, modm_mu[4], q1[1]) add128_64(c, f) mul64x64_128(mul, modm_mu[1], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[2]) add128(c, mul) + f = lo128(c); q3[0] |= (f << 16) & 0xffffffffffffff; q3[1] = (f >> 40) & 0xffff; shr128(f, c, 56); + mul64x64_128(c, modm_mu[4], q1[2]) add128_64(c, f) mul64x64_128(mul, modm_mu[2], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[3]) add128(c, mul) + f = lo128(c); q3[1] |= (f << 16) & 0xffffffffffffff; q3[2] = (f >> 40) & 0xffff; shr128(f, c, 56); + mul64x64_128(c, modm_mu[4], q1[3]) add128_64(c, f) mul64x64_128(mul, modm_mu[3], q1[4]) add128(c, mul) + f = lo128(c); q3[2] |= (f << 16) & 0xffffffffffffff; q3[3] = (f >> 40) & 0xffff; shr128(f, c, 56); + mul64x64_128(c, modm_mu[4], q1[4]) add128_64(c, f) + f = lo128(c); q3[3] |= (f << 16) & 0xffffffffffffff; q3[4] = (f >> 40) & 0xffff; shr128(f, c, 56); + q3[4] |= (f << 16); + + mul64x64_128(c, modm_m[0], q3[0]) + r2[0] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, modm_m[0], q3[1]) add128_64(c, f) mul64x64_128(mul, modm_m[1], q3[0]) add128(c, mul) + r2[1] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, modm_m[0], q3[2]) add128_64(c, f) mul64x64_128(mul, modm_m[2], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[1]) add128(c, mul) + r2[2] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, modm_m[0], q3[3]) add128_64(c, f) mul64x64_128(mul, modm_m[3], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[2]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[1]) add128(c, mul) + r2[3] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, modm_m[0], q3[4]) add128_64(c, f) mul64x64_128(mul, modm_m[4], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[3], q3[1]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[3]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[2]) add128(c, mul) + r2[4] = lo128(c) & 0x0000ffffffffff; + + pb = 0; + pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 56)); pb = b; + pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 56)); pb = b; + pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 56)); pb = b; + pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 56)); pb = b; + pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 40)); + + reduce256_modm(r); + reduce256_modm(r); +} + +void +add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm_element_t c; + + c = x[0] + y[0]; r[0] = c & 0xffffffffffffff; c >>= 56; + c += x[1] + y[1]; r[1] = c & 0xffffffffffffff; c >>= 56; + c += x[2] + y[2]; r[2] = c & 0xffffffffffffff; c >>= 56; + c += x[3] + y[3]; r[3] = c & 0xffffffffffffff; c >>= 56; + c += x[4] + y[4]; r[4] = c; + + reduce256_modm(r); +} + +void +mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm q1, r1; + word128 c, mul; + bignum256modm_element_t f; + + mul64x64_128(c, x[0], y[0]) + f = lo128(c); r1[0] = f & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, x[0], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[0]) add128(c, mul) + f = lo128(c); r1[1] = f & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, x[0], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[1]) add128(c, mul) + f = lo128(c); r1[2] = f & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, x[0], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[2]) add128(c, mul) mul64x64_128(mul, x[2], y[1]) add128(c, mul) + f = lo128(c); r1[3] = f & 0xffffffffffffff; shr128(f, c, 56); + mul64x64_128(c, x[0], y[4]) add128_64(c, f) mul64x64_128(mul, x[4], y[0]) add128(c, mul) mul64x64_128(mul, x[3], y[1]) add128(c, mul) mul64x64_128(mul, x[1], y[3]) add128(c, mul) mul64x64_128(mul, x[2], y[2]) add128(c, mul) + f = lo128(c); r1[4] = f & 0x0000ffffffffff; q1[0] = (f >> 24) & 0xffffffff; shr128(f, c, 56); + mul64x64_128(c, x[4], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[4]) add128(c, mul) mul64x64_128(mul, x[2], y[3]) add128(c, mul) mul64x64_128(mul, x[3], y[2]) add128(c, mul) + f = lo128(c); q1[0] |= (f << 32) & 0xffffffffffffff; q1[1] = (f >> 24) & 0xffffffff; shr128(f, c, 56); + mul64x64_128(c, x[4], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[4]) add128(c, mul) mul64x64_128(mul, x[3], y[3]) add128(c, mul) + f = lo128(c); q1[1] |= (f << 32) & 0xffffffffffffff; q1[2] = (f >> 24) & 0xffffffff; shr128(f, c, 56); + mul64x64_128(c, x[4], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[4]) add128(c, mul) + f = lo128(c); q1[2] |= (f << 32) & 0xffffffffffffff; q1[3] = (f >> 24) & 0xffffffff; shr128(f, c, 56); + mul64x64_128(c, x[4], y[4]) add128_64(c, f) + f = lo128(c); q1[3] |= (f << 32) & 0xffffffffffffff; q1[4] = (f >> 24) & 0xffffffff; shr128(f, c, 56); + q1[4] |= (f << 32); + + barrett_reduce256_modm(r, q1, r1); +} + +void +expand256_modm(bignum256modm out, const byte *in, size_t len) { + byte work[64] = {0}; + bignum256modm_element_t x[16]; + bignum256modm q1; + + memcpy(work, in, len); + x[0] = U8TO64_LE(work + 0); + x[1] = U8TO64_LE(work + 8); + x[2] = U8TO64_LE(work + 16); + x[3] = U8TO64_LE(work + 24); + x[4] = U8TO64_LE(work + 32); + x[5] = U8TO64_LE(work + 40); + x[6] = U8TO64_LE(work + 48); + x[7] = U8TO64_LE(work + 56); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ + out[0] = ( x[0]) & 0xffffffffffffff; + out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff; + out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff; + out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff; + out[4] = ((x[ 3] >> 32) | (x[ 4] << 32)) & 0x0000ffffffffff; + + /* under 252 bits, no need to reduce */ + if (len < 32) + return; + + /* q1 = x >> 248 = 264 bits */ + q1[0] = ((x[ 3] >> 56) | (x[ 4] << 8)) & 0xffffffffffffff; + q1[1] = ((x[ 4] >> 48) | (x[ 5] << 16)) & 0xffffffffffffff; + q1[2] = ((x[ 5] >> 40) | (x[ 6] << 24)) & 0xffffffffffffff; + q1[3] = ((x[ 6] >> 32) | (x[ 7] << 32)) & 0xffffffffffffff; + q1[4] = ((x[ 7] >> 24) ); + + barrett_reduce256_modm(out, q1, out); +} + +void +expand_raw256_modm(bignum256modm out, const byte in[32]) { + bignum256modm_element_t x[4]; + + x[0] = U8TO64_LE(in + 0); + x[1] = U8TO64_LE(in + 8); + x[2] = U8TO64_LE(in + 16); + x[3] = U8TO64_LE(in + 24); + + out[0] = ( x[0]) & 0xffffffffffffff; + out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff; + out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff; + out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff; + out[4] = ((x[ 3] >> 32) ) & 0x000000ffffffff; +} + +void +contract256_modm(byte out[32], const bignum256modm in) { + U64TO8_LE(out + 0, (in[0] ) | (in[1] << 56)); + U64TO8_LE(out + 8, (in[1] >> 8) | (in[2] << 48)); + U64TO8_LE(out + 16, (in[2] >> 16) | (in[3] << 40)); + U64TO8_LE(out + 24, (in[3] >> 24) | (in[4] << 32)); +} + +void +contract256_window4_modm(signed char r[64], const bignum256modm in) { + char carry; + signed char *quads = r; + bignum256modm_element_t i, j, v, m; + + for (i = 0; i < 5; i++) { + v = in[i]; + m = (i == 4) ? 8 : 14; + for (j = 0; j < m; j++) { + *quads++ = (v & 15); + v >>= 4; + } + } + + /* making it signed */ + carry = 0; + for(i = 0; i < 63; i++) { + r[i] += carry; + r[i+1] += (r[i] >> 4); + r[i] &= 15; + carry = (r[i] >> 3); + r[i] -= (carry << 4); + } + r[63] += carry; +} + +void +contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { + int i,j,k,b; + int m = (1 << (windowsize - 1)) - 1, soplen = 256; + signed char *bits = r; + bignum256modm_element_t v; + + /* first put the binary expansion into r */ + for (i = 0; i < 4; i++) { + v = s[i]; + for (j = 0; j < 56; j++, v >>= 1) + *bits++ = (v & 1); + } + v = s[4]; + for (j = 0; j < 32; j++, v >>= 1) + *bits++ = (v & 1); + + /* Making it sliding window */ + for (j = 0; j < soplen; j++) { + if (!r[j]) + continue; + + for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { + if ((r[j] + (r[j + b] << b)) <= m) { + r[j] += r[j + b] << b; + r[j + b] = 0; + } else if ((r[j] - (r[j + b] << b)) >= -m) { + r[j] -= r[j + b] << b; + for (k = j + b; k < soplen; k++) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else if (r[j + b]) { + break; + } + } + } +} + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void +curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + ALIGN(ALIGN_SPEC) bignum25519 t0,c; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void +curve25519_recip(bignum25519 out, const bignum25519 z) { + ALIGN(ALIGN_SPEC) bignum25519 a,t0,b; + + /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square_times(t0, a, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a); +} + +/* + * z^((p-5)/8) = z^(2^252 - 3) + */ +void +curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { + ALIGN(ALIGN_SPEC) bignum25519 b,c,t0; + + /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ + /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ + /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */ + /* 22 */ curve25519_square_times(t0, c, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); + /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z); +} + +inline void +ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); +} + +inline void +ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); + curve25519_mul(r->t, p->x, p->y); +} + +void +ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { + curve25519_sub(p->ysubx, r->y, r->x); + curve25519_add(p->xaddy, r->y, r->x); + curve25519_copy(p->z, r->z); + curve25519_mul(p->t2d, r->t, ge25519_ec2d); +} + +void +ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) { + bignum25519 a,b,c,d,t,u; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_sub(t, q->y, q->x); + curve25519_add(u, q->y, q->x); + curve25519_mul(a, a, t); + curve25519_mul(b, b, u); + curve25519_mul(c, p->t, q->t); + curve25519_mul(c, c, ge25519_ec2d); + curve25519_mul(d, p->z, q->z); + curve25519_add(d, d, d); + curve25519_sub(r->x, b, a); + curve25519_add(r->y, b, a); + curve25519_add_after_basic(r->z, d, c); + curve25519_sub_after_basic(r->t, d, c); +} + +void +ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { + bignum25519 a,b,c; + + curve25519_square(a, p->x); + curve25519_square(b, p->y); + curve25519_square(c, p->z); + curve25519_add_reduce(c, c, c); + curve25519_add(r->x, p->x, p->y); + curve25519_square(r->x, r->x); + curve25519_add(r->y, b, a); + curve25519_sub(r->z, b, a); + curve25519_sub_after_basic(r->x, r->x, r->y); + curve25519_sub_after_basic(r->t, c, r->z); +} + +void +ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, byte signbit) { + const bignum25519 *qb = (const bignum25519 *)q; + bignum25519 *rb = (bignum25519 *)r; + bignum25519 a,b,c; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ + curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_add_reduce(r->t, p->z, p->z); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ +} + +void +ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, byte signbit) { + const bignum25519 *qb = (const bignum25519 *)q; + bignum25519 *rb = (bignum25519 *)r; + bignum25519 a,b,c; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ + curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(r->t, p->z, q->z); + curve25519_add_reduce(r->t, r->t, r->t); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ +} + +void +ge25519_double_partial(ge25519 *r, const ge25519 *p) { + ge25519_p1p1 t; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_partial(r, &t); +} + +void +ge25519_double(ge25519 *r, const ge25519 *p) { + ge25519_p1p1 t; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_full(r, &t); +} + +void +ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) { + ge25519_p1p1 t; + ge25519_add_p1p1(&t, p, q); + ge25519_p1p1_to_full(r, &t); +} + +void +ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { + bignum25519 a,b,c,e,f,g,h; + + curve25519_sub(a, r->y, r->x); + curve25519_add(b, r->y, r->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(e, b, q->xaddy); + curve25519_add(h, e, a); + curve25519_sub(e, e, a); + curve25519_mul(c, r->t, q->t2d); + curve25519_add(f, r->z, r->z); + curve25519_add_after_basic(g, f, c); + curve25519_sub_after_basic(f, f, c); + curve25519_mul(r->x, e, f); + curve25519_mul(r->y, h, g); + curve25519_mul(r->z, g, f); + curve25519_mul(r->t, e, h); +} + +void +ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { + bignum25519 a,b,c,x,y,z,t; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(x, b, q->xaddy); + curve25519_add(y, x, a); + curve25519_sub(x, x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(t, p->z, q->z); + curve25519_add(t, t, t); + curve25519_add_after_basic(z, t, c); + curve25519_sub_after_basic(t, t, c); + curve25519_mul(r->xaddy, x, t); + curve25519_mul(r->ysubx, y, z); + curve25519_mul(r->z, z, t); + curve25519_mul(r->t2d, x, y); + curve25519_copy(y, r->ysubx); + curve25519_sub(r->ysubx, r->ysubx, r->xaddy); + curve25519_add(r->xaddy, r->xaddy, y); + curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); +} + +void +ge25519_pack(byte r[32], const ge25519 *p) { + bignum25519 tx, ty, zi; + byte parity[32]; + curve25519_recip(zi, p->z); + curve25519_mul(tx, p->x, zi); + curve25519_mul(ty, p->y, zi); + curve25519_contract(r, ty); + curve25519_contract(parity, tx); + r[31] ^= ((parity[0] & 1) << 7); +} + +int +ed25519_verify(const byte *x, const byte *y, size_t len) { + size_t differentbits = 0; + while (len--) + differentbits |= (*x++ ^ *y++); + return (int) (1 & ((differentbits - 1) >> 8)); +} + +int +ge25519_unpack_negative_vartime(ge25519 *r, const byte p[32]) { + const byte zero[32] = {0}; + const bignum25519 one = {1}; + byte parity = p[31] >> 7; + byte check[32]; + bignum25519 t, root, num, den, d3; + + curve25519_expand(r->y, p); + curve25519_copy(r->z, one); + curve25519_square(num, r->y); /* x = y^2 */ + curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ + curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ + curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ + + /* Computation of sqrt(num/den) */ + /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ + curve25519_square(t, den); + curve25519_mul(d3, t, den); + curve25519_square(r->x, d3); + curve25519_mul(r->x, r->x, den); + curve25519_mul(r->x, r->x, num); + curve25519_pow_two252m3(r->x, r->x); + + /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ + curve25519_mul(r->x, r->x, d3); + curve25519_mul(r->x, r->x, num); + + /* 3. Check if either of the roots works: */ + curve25519_square(t, r->x); + curve25519_mul(t, t, den); + curve25519_sub_reduce(root, t, num); + curve25519_contract(check, root); + if (!ed25519_verify(check, zero, 32)) { + curve25519_add_reduce(t, t, num); + curve25519_contract(check, t); + if (!ed25519_verify(check, zero, 32)) + return 0; + curve25519_mul(r->x, r->x, ge25519_sqrtneg1); + } + + curve25519_contract(check, r->x); + if ((check[0] & 1) == parity) { + curve25519_copy(t, r->x); + curve25519_neg(r->x, t); + } + curve25519_mul(r->t, r->x, r->y); + return 1; +} + +/* computes [s1]p1 + [s2]basepoint */ +void +ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { + signed char slide1[256], slide2[256]; + ge25519_pniels pre1[S1_TABLE_SIZE]; + ge25519 d1; + ge25519_p1p1 t; + sword32 i; + + contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); + contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); + + ge25519_double(&d1, p1); + ge25519_full_to_pniels(pre1, p1); + for (i = 0; i < S1_TABLE_SIZE - 1; i++) + ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]); + + /* set neutral */ + memset(r, 0, sizeof(ge25519)); + r->y[0] = 1; + r->z[0] = 1; + + i = 255; + while ((i >= 0) && !(slide1[i] | slide2[i])) + i--; + + for (; i >= 0; i--) { + ge25519_double_p1p1(&t, r); + + if (slide1[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (byte)slide1[i] >> 7); + } + + if (slide2[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (byte)slide2[i] >> 7); + } + + ge25519_p1p1_to_partial(r, &t); + } +} + +#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS) + +word32 +ge25519_windowb_equal(word32 b, word32 c) { + return ((b ^ c) - 1) >> 31; +} + +void +ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const byte table[256][96], word32 pos, signed char b) { + bignum25519 neg; + word32 sign = (word32)((byte)b >> 7); + word32 mask = ~(sign - 1); + word32 u = (b + mask) ^ mask; + word32 i; + + /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ + byte packed[96] = {0}; + packed[0] = 1; + packed[32] = 1; + + for (i = 0; i < 8; i++) + curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1)); + + /* expand in to t */ + curve25519_expand(t->ysubx, packed + 0); + curve25519_expand(t->xaddy, packed + 32); + curve25519_expand(t->t2d , packed + 64); + + /* adjust for sign */ + curve25519_swap_conditional(t->ysubx, t->xaddy, sign); + curve25519_neg(neg, t->t2d); + curve25519_swap_conditional(t->t2d, neg, sign); +} + +#endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */ + +/* computes [s]basepoint */ +void +ge25519_scalarmult_base_niels(ge25519 *r, const byte basepoint_table[256][96], const bignum256modm s) { + signed char b[64]; + word32 i; + ge25519_niels t; + + contract256_window4_modm(b, s); + + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); + curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); + curve25519_add_reduce(r->y, t.xaddy, t.ysubx); + memset(r->z, 0, sizeof(bignum25519)); + curve25519_copy(r->t, t.t2d); + r->z[0] = 2; + for (i = 3; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double(r, r); + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); + curve25519_mul(t.t2d, t.t2d, ge25519_ecd); + ge25519_nielsadd2(r, &t); + for(i = 2; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } +} + +ANONYMOUS_NAMESPACE_END +NAMESPACE_END // Ed25519 +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +//***************************** curve25519 *****************************// + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) + +int curve25519_mult_CXX(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]) +{ + using namespace CryptoPP::Donna::X25519; + + FixedSizeSecBlock e; + for (size_t i = 0;i < 32;++i) + e[i] = secretKey[i]; + e[0] &= 0xf8; e[31] &= 0x7f; e[31] |= 0x40; + + bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx; + bignum25519 q, qx, qpqx, qqx, zzz, zmone; + size_t bit, lastbit; + + curve25519_expand(q, othersKey); + curve25519_copy(nqx, q); + + /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and + start pre-swapped on bit 254 */ + lastbit = 1; + + /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */ + for (int i = 253; i >= 2; i--) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_add(qpqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_mul(nqpqx, qpqx, nqz); + curve25519_mul(nqpqz, qx, nqpqz); + curve25519_add(qqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_square(nqpqz, nqpqz); + curve25519_square(nqpqx, qqx); + curve25519_mul(nqpqz, nqpqz, q); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + + bit = (e[i/8] >> (i & 7)) & 1; + curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit); + curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit); + lastbit = bit; + } + + /* the final 3 bits are always zero, so we only need to double */ + for (int i = 0; i < 3; i++) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + } + + curve25519_recip(zmone, nqz); + curve25519_mul(nqz, nqx, zmone); + curve25519_contract(sharedKey, nqz); + + return 0; +} + +int curve25519_mult(byte publicKey[32], const byte secretKey[32]) +{ + using namespace CryptoPP::Donna::X25519; + +#if (CRYPTOPP_CURVE25519_SSE2) + if (HasSSE2()) + return curve25519_mult_SSE2(publicKey, secretKey, basePoint); + else +#endif + + return curve25519_mult_CXX(publicKey, secretKey, basePoint); +} + +int curve25519_mult(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]) +{ +#if (CRYPTOPP_CURVE25519_SSE2) + if (HasSSE2()) + return curve25519_mult_SSE2(sharedKey, secretKey, othersKey); + else +#endif + + return curve25519_mult_CXX(sharedKey, secretKey, othersKey); +} + +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +//******************************* ed25519 *******************************// + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) + +int +ed25519_publickey_CXX(byte publicKey[32], const byte secretKey[32]) +{ + using namespace CryptoPP::Donna::Ed25519; + + bignum256modm a; + ALIGN(ALIGN_SPEC) ge25519 A; + hash_512bits extsk; + + /* A = aB */ + ed25519_extsk(extsk, secretKey); + expand256_modm(a, extsk, 32); + ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); + ge25519_pack(publicKey, &A); + + return 0; +} + +int +ed25519_publickey(byte publicKey[32], const byte secretKey[32]) +{ + return ed25519_publickey_CXX(publicKey, secretKey); +} + +int +ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byte RS[64]) +{ + using namespace CryptoPP::Donna::Ed25519; + + bignum256modm r, S, a; + ALIGN(ALIGN_SPEC) ge25519 R; + hash_512bits extsk, hashr, hram; + + // Unfortunately we need to read the stream twice. The fisrt time calculates + // 'r = H(aExt[32..64], m)'. The second time calculates 'S = H(R,A,m)'. There + // is a data dependency due to hashing 'RS' with 'R = [r]B' that does not + // allow us to read the stream once. + std::streampos where = stream.tellg(); + + ed25519_extsk(extsk, sk); + + /* r = H(aExt[32..64], m) */ + SHA512 hash; + hash.Update(extsk + 32, 32); + UpdateFromStream(hash, stream); + hash.Final(hashr); + expand256_modm(r, hashr, 64); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + ge25519_pack(RS, &R); + + // Reset stream for the second digest + stream.clear(); + stream.seekg(where); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, RS, pk, stream); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + mul256_modm(S, S, a); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(RS + 32, S); + return 0; +} + +int +ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32], byte RS[64]) +{ + using namespace CryptoPP::Donna::Ed25519; + + bignum256modm r, S, a; + ALIGN(ALIGN_SPEC) ge25519 R; + hash_512bits extsk, hashr, hram; + + ed25519_extsk(extsk, sk); + + /* r = H(aExt[32..64], m) */ + SHA512 hash; + hash.Update(extsk + 32, 32); + hash.Update(m, mlen); + hash.Final(hashr); + expand256_modm(r, hashr, 64); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + ge25519_pack(RS, &R); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, RS, pk, m, mlen); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + mul256_modm(S, S, a); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(RS + 32, S); + return 0; +} + +int +ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], + byte signature[64]) +{ + return ed25519_sign_CXX(stream, secretKey, publicKey, signature); +} + +int +ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], + const byte publicKey[32], byte signature[64]) +{ + return ed25519_sign_CXX(message, messageLength, secretKey, publicKey, signature); +} + +int +ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte RS[64]) { + + using namespace CryptoPP::Donna::Ed25519; + + ALIGN(ALIGN_SPEC) ge25519 R, A; + hash_512bits hash; + bignum256modm hram, S; + byte checkR[32]; + + if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) + return -1; + + /* hram = H(R,A,m) */ + ed25519_hram(hash, RS, pk, m, mlen); + expand256_modm(hram, hash, 64); + + /* S */ + expand256_modm(S, RS + 32, 32); + + /* SB - H(R,A,m)A */ + ge25519_double_scalarmult_vartime(&R, &A, hram, S); + ge25519_pack(checkR, &R); + + /* check that R = SB - H(R,A,m)A */ + return ed25519_verify(RS, checkR, 32) ? 0 : -1; +} + +int +ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]) { + + using namespace CryptoPP::Donna::Ed25519; + + ALIGN(ALIGN_SPEC) ge25519 R, A; + hash_512bits hash; + bignum256modm hram, S; + byte checkR[32]; + + if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) + return -1; + + /* hram = H(R,A,m) */ + ed25519_hram(hash, RS, pk, stream); + expand256_modm(hram, hash, 64); + + /* S */ + expand256_modm(S, RS + 32, 32); + + /* SB - H(R,A,m)A */ + ge25519_double_scalarmult_vartime(&R, &A, hram, S); + ge25519_pack(checkR, &R); + + /* check that R = SB - H(R,A,m)A */ + return ed25519_verify(RS, checkR, 32) ? 0 : -1; +} + +int +ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]) +{ + return ed25519_sign_open_CXX(stream, publicKey, signature); +} + +int +ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]) +{ + return ed25519_sign_open_CXX(message, messageLength, publicKey, signature); +} + +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_CURVE25519_64BIT diff --git a/external/ours/library/crypto/src/shared/original/donna_64.h b/external/ours/library/crypto/src/shared/original/donna_64.h new file mode 100755 index 000000000..d98ad6400 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna_64.h @@ -0,0 +1,457 @@ +// donna_64.h - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// https://github.com/floodyberry/curve25519-donna and +// https://github.com/floodyberry/ed25519-donna. + +// This source file multiplexes two different repos using namespaces. This +// was a little easier from a project management standpoint. We only need +// two files per architecture at the expense of namespaces and bloat. + +#ifndef CRYPTOPP_DONNA_64_H +#define CRYPTOPP_DONNA_64_H +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + +#include "config.h" + +#if defined(_MSC_VER) +# include +# pragma intrinsic(_umul128) +# pragma intrinsic(__shiftright128) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(Arch64) + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; + +// ******************** x25519 Agreement ************************* // + +#define ALIGN(n) CRYPTOPP_ALIGN_DATA(n) +typedef word64 bignum25519[5]; + +const byte basePoint[32] = {9}; +const word64 reduce_mask_40 = ((word64)1 << 40) - 1; +const word64 reduce_mask_51 = ((word64)1 << 51) - 1; +const word64 reduce_mask_52 = ((word64)1 << 52) - 1; +const word64 reduce_mask_56 = ((word64)1 << 56) - 1; + +const word64 two54m152 = (((word64)1) << 54) - 152; +const word64 two54m8 = (((word64)1) << 54) - 8; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) +using CryptoPP::word128; +# define lo128(a) ((word64)a) +# define hi128(a) ((word64)(a >> 64)) +# define add128(a,b) a += b; +# define add128_64(a,b) a += (word64)b; +# define mul64x64_128(out,a,b) out = (word128)a * b; +# define shr128(out,in,shift) out = (word64)(in >> (shift)); +# define shl128(out,in,shift) out = (word64)((in << shift) >> 64); + +#elif defined(_MSC_VER) +struct word128 { word64 lo, hi; }; +# define mul64x64_128(out,a,b) out.lo = _umul128(a,b,&out.hi); +# define shr128_pair(out,hi,lo,shift) out = __shiftright128(lo, hi, shift); +# define shl128_pair(out,hi,lo,shift) out = __shiftleft128(lo, hi, shift); +# define shr128(out,in,shift) shr128_pair(out, in.hi, in.lo, shift) +# define shl128(out,in,shift) shl128_pair(out, in.hi, in.lo, shift) +# define add128(a,b) { word64 p = a.lo; a.lo += b.lo; a.hi += b.hi + (a.lo < p); } +# define add128_64(a,b) { word64 p = a.lo; a.lo += b; a.hi += (a.lo < p); } +# define lo128(a) (a.lo) +# define hi128(a) (a.hi) + +#elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) +struct word128 { word64 lo, hi; }; +# define mul64x64_128(out,a,b) __asm__ ("mulq %3" : "=a" (out.lo), "=d" (out.hi) : "a" (a), "rm" (b)); +# define shr128_pair(out,hi,lo,shift) __asm__ ("shrdq %2,%1,%0" : "+r" (lo) : "r" (hi), "J" (shift)); out = lo; +# define shl128_pair(out,hi,lo,shift) __asm__ ("shldq %2,%1,%0" : "+r" (hi) : "r" (lo), "J" (shift)); out = hi; +# define shr128(out,in,shift) shr128_pair(out,in.hi, in.lo, shift) +# define shl128(out,in,shift) shl128_pair(out,in.hi, in.lo, shift) +# define add128(a,b) __asm__ ("addq %4,%2; adcq %5,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b.lo), "rm" (b.hi) : "cc"); +# define add128_64(a,b) __asm__ ("addq %4,%2; adcq $0,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b) : "cc"); +# define lo128(a) (a.lo) +# define hi128(a) (a.hi) + +#else +// https://groups.google.com/forum/#!forum/cryptopp-users +# error "Unsupported platform" +#endif + +// ****************** ed25519 Signatures *********************** // + +typedef byte hash_512bits[64]; + +const int bignum256modm_bits_per_limb = 56; +const int bignum256modm_limb_size = 5; +typedef word64 bignum256modm_element_t; +typedef bignum256modm_element_t bignum256modm[5]; + +/* multiples of p */ +const word64 twoP0 = 0x0fffffffffffda; +const word64 twoP1234 = 0x0ffffffffffffe; +const word64 fourP0 = 0x1fffffffffffb4; +const word64 fourP1234 = 0x1ffffffffffffc; + +struct ge25519 { + bignum25519 x, y, z, t; +}; + +struct ge25519_p1p1 { + bignum25519 x, y, z, t; +}; + +struct ge25519_niels { + bignum25519 ysubx, xaddy, t2d; +}; + +struct ge25519_pniels { + bignum25519 ysubx, xaddy, z, t2d; +}; + +#define S1_SWINDOWSIZE 5 +#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2)) +#define S2_SWINDOWSIZE 7 +#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2)) + +// *************** ed25519-donna-64bit-tables.h *************** // + +const ge25519 ge25519_basepoint = { + {0x00062d608f25d51a,0x000412a4b4f6592a,0x00075b7171a4b31d,0x0001ff60527118fe,0x000216936d3cd6e5}, + {0x0006666666666658,0x0004cccccccccccc,0x0001999999999999,0x0003333333333333,0x0006666666666666}, + {0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000}, + {0x00068ab3a5b7dda3,0x00000eea2a5eadbb,0x0002af8df483c27e,0x000332b375274732,0x00067875f0fd78b7} +}; + +const bignum25519 ge25519_ecd = { + 0x00034dca135978a3,0x0001a8283b156ebd,0x0005e7a26001c029,0x000739c663a03cbb,0x00052036cee2b6ff +}; + +const bignum25519 ge25519_ec2d = { + 0x00069b9426b2f159,0x00035050762add7a,0x0003cf44c0038052,0x0006738cc7407977,0x0002406d9dc56dff +}; + +const bignum25519 ge25519_sqrtneg1 = { + 0x00061b274a0ea0b0,0x0000d5a5fc8f189d,0x0007ef5e9cbd0c60,0x00078595a6804c9e,0x0002b8324804fc1d +}; + +const ge25519_niels ge25519_niels_sliding_multiples[32] = { + {{0x00003905d740913e,0x0000ba2817d673a2,0x00023e2827f4e67c,0x000133d2e0c21a34,0x00044fd2f9298f81},{0x000493c6f58c3b85,0x0000df7181c325f7,0x0000f50b0b3e4cb7,0x0005329385a44c32,0x00007cf9d3a33d4b},{0x00011205877aaa68,0x000479955893d579,0x00050d66309b67a0,0x0002d42d0dbee5ee,0x0006f117b689f0c6}}, + {{0x00011fe8a4fcd265,0x0007bcb8374faacc,0x00052f5af4ef4d4f,0x0005314098f98d10,0x0002ab91587555bd},{0x0005b0a84cee9730,0x00061d10c97155e4,0x0004059cc8096a10,0x00047a608da8014f,0x0007a164e1b9a80f},{0x0006933f0dd0d889,0x00044386bb4c4295,0x0003cb6d3162508c,0x00026368b872a2c6,0x0005a2826af12b9b}}, + {{0x000182c3a447d6ba,0x00022964e536eff2,0x000192821f540053,0x0002f9f19e788e5c,0x000154a7e73eb1b5},{0x0002bc4408a5bb33,0x000078ebdda05442,0x0002ffb112354123,0x000375ee8df5862d,0x0002945ccf146e20},{0x0003dbf1812a8285,0x0000fa17ba3f9797,0x0006f69cb49c3820,0x00034d5a0db3858d,0x00043aabe696b3bb}}, + {{0x00072c9aaa3221b1,0x000267774474f74d,0x000064b0e9b28085,0x0003f04ef53b27c9,0x0001d6edd5d2e531},{0x00025cd0944ea3bf,0x00075673b81a4d63,0x000150b925d1c0d4,0x00013f38d9294114,0x000461bea69283c9},{0x00036dc801b8b3a2,0x0000e0a7d4935e30,0x0001deb7cecc0d7d,0x000053a94e20dd2c,0x0007a9fbb1c6a0f9}}, + {{0x0006217e039d8064,0x0006dea408337e6d,0x00057ac112628206,0x000647cb65e30473,0x00049c05a51fadc9},{0x0006678aa6a8632f,0x0005ea3788d8b365,0x00021bd6d6994279,0x0007ace75919e4e3,0x00034b9ed338add7},{0x0004e8bf9045af1b,0x000514e33a45e0d6,0x0007533c5b8bfe0f,0x000583557b7e14c9,0x00073c172021b008}}, + {{0x00075b0249864348,0x00052ee11070262b,0x000237ae54fb5acd,0x0003bfd1d03aaab5,0x00018ab598029d5c},{0x000700848a802ade,0x0001e04605c4e5f7,0x0005c0d01b9767fb,0x0007d7889f42388b,0x0004275aae2546d8},{0x00032cc5fd6089e9,0x000426505c949b05,0x00046a18880c7ad2,0x0004a4221888ccda,0x0003dc65522b53df}}, + {{0x0007013b327fbf93,0x0001336eeded6a0d,0x0002b565a2bbf3af,0x000253ce89591955,0x0000267882d17602},{0x0000c222a2007f6d,0x000356b79bdb77ee,0x00041ee81efe12ce,0x000120a9bd07097d,0x000234fd7eec346f},{0x0000a119732ea378,0x00063bf1ba8e2a6c,0x00069f94cc90df9a,0x000431d1779bfc48,0x000497ba6fdaa097}}, + {{0x0003cd86468ccf0b,0x00048553221ac081,0x0006c9464b4e0a6e,0x00075fba84180403,0x00043b5cd4218d05},{0x0006cc0313cfeaa0,0x0001a313848da499,0x0007cb534219230a,0x00039596dedefd60,0x00061e22917f12de},{0x0002762f9bd0b516,0x0001c6e7fbddcbb3,0x00075909c3ace2bd,0x00042101972d3ec9,0x000511d61210ae4d}}, + {{0x000386484420de87,0x0002d6b25db68102,0x000650b4962873c0,0x0004081cfd271394,0x00071a7fe6fe2482},{0x000676ef950e9d81,0x0001b81ae089f258,0x00063c4922951883,0x0002f1d54d9b3237,0x0006d325924ddb85},{0x000182b8a5c8c854,0x00073fcbe5406d8e,0x0005de3430cff451,0x000554b967ac8c41,0x0004746c4b6559ee}}, + {{0x000546c864741147,0x0003a1df99092690,0x0001ca8cc9f4d6bb,0x00036b7fc9cd3b03,0x000219663497db5e},{0x00077b3c6dc69a2b,0x0004edf13ec2fa6e,0x0004e85ad77beac8,0x0007dba2b28e7bda,0x0005c9a51de34fe9},{0x0000f1cf79f10e67,0x00043ccb0a2b7ea2,0x00005089dfff776a,0x0001dd84e1d38b88,0x0004804503c60822}}, + {{0x000021d23a36d175,0x0004fd3373c6476d,0x00020e291eeed02a,0x00062f2ecf2e7210,0x000771e098858de4},{0x00049ed02ca37fc7,0x000474c2b5957884,0x0005b8388e816683,0x0004b6c454b76be4,0x000553398a516506},{0x0002f5d278451edf,0x000730b133997342,0x0006965420eb6975,0x000308a3bfa516cf,0x0005a5ed1d68ff5a}}, + {{0x0005e0c558527359,0x0003395b73afd75c,0x000072afa4e4b970,0x00062214329e0f6d,0x000019b60135fefd},{0x0005122afe150e83,0x0004afc966bb0232,0x0001c478833c8268,0x00017839c3fc148f,0x00044acb897d8bf9},{0x000068145e134b83,0x0001e4860982c3cc,0x000068fb5f13d799,0x0007c9283744547e,0x000150c49fde6ad2}}, + {{0x0001863c9cdca868,0x0003770e295a1709,0x0000d85a3720fd13,0x0005e0ff1f71ab06,0x00078a6d7791e05f},{0x0003f29509471138,0x000729eeb4ca31cf,0x00069c22b575bfbc,0x0004910857bce212,0x0006b2b5a075bb99},{0x0007704b47a0b976,0x0002ae82e91aab17,0x00050bd6429806cd,0x00068055158fd8ea,0x000725c7ffc4ad55}}, + {{0x00002bf71cd098c0,0x00049dabcc6cd230,0x00040a6533f905b2,0x000573efac2eb8a4,0x0004cd54625f855f},{0x00026715d1cf99b2,0x0002205441a69c88,0x000448427dcd4b54,0x0001d191e88abdc5,0x000794cc9277cb1f},{0x0006c426c2ac5053,0x0005a65ece4b095e,0x0000c44086f26bb6,0x0007429568197885,0x0007008357b6fcc8}}, + {{0x00039fbb82584a34,0x00047a568f257a03,0x00014d88091ead91,0x0002145b18b1ce24,0x00013a92a3669d6d},{0x0000672738773f01,0x000752bf799f6171,0x0006b4a6dae33323,0x0007b54696ead1dc,0x00006ef7e9851ad0},{0x0003771cc0577de5,0x0003ca06bb8b9952,0x00000b81c5d50390,0x00043512340780ec,0x0003c296ddf8a2af}}, + {{0x00034d2ebb1f2541,0x0000e815b723ff9d,0x000286b416e25443,0x0000bdfe38d1bee8,0x0000a892c7007477},{0x000515f9d914a713,0x00073191ff2255d5,0x00054f5cc2a4bdef,0x0003dd57fc118bcf,0x0007a99d393490c7},{0x0002ed2436bda3e8,0x00002afd00f291ea,0x0000be7381dea321,0x0003e952d4b2b193,0x000286762d28302f}}, + {{0x00058e2bce2ef5bd,0x00068ce8f78c6f8a,0x0006ee26e39261b2,0x00033d0aa50bcf9d,0x0007686f2a3d6f17},{0x000036093ce35b25,0x0003b64d7552e9cf,0x00071ee0fe0b8460,0x00069d0660c969e5,0x00032f1da046a9d9},{0x000512a66d597c6a,0x0000609a70a57551,0x000026c08a3c464c,0x0004531fc8ee39e1,0x000561305f8a9ad2}}, + {{0x0002cc28e7b0c0d5,0x00077b60eb8a6ce4,0x0004042985c277a6,0x000636657b46d3eb,0x000030a1aef2c57c},{0x0004978dec92aed1,0x000069adae7ca201,0x00011ee923290f55,0x00069641898d916c,0x00000aaec53e35d4},{0x0001f773003ad2aa,0x000005642cc10f76,0x00003b48f82cfca6,0x0002403c10ee4329,0x00020be9c1c24065}}, + {{0x0000e44ae2025e60,0x0005f97b9727041c,0x0005683472c0ecec,0x000188882eb1ce7c,0x00069764c545067e},{0x000387d8249673a6,0x0005bea8dc927c2a,0x0005bd8ed5650ef0,0x0000ef0e3fcd40e1,0x000750ab3361f0ac},{0x00023283a2f81037,0x000477aff97e23d1,0x0000b8958dbcbb68,0x0000205b97e8add6,0x00054f96b3fb7075}}, + {{0x0005afc616b11ecd,0x00039f4aec8f22ef,0x0003b39e1625d92e,0x0005f85bd4508873,0x00078e6839fbe85d},{0x0005f20429669279,0x00008fafae4941f5,0x00015d83c4eb7688,0x0001cf379eca4146,0x0003d7fe9c52bb75},{0x00032df737b8856b,0x0000608342f14e06,0x0003967889d74175,0x0001211907fba550,0x00070f268f350088}}, + {{0x0004112070dcf355,0x0007dcff9c22e464,0x00054ada60e03325,0x00025cd98eef769a,0x000404e56c039b8c},{0x00064583b1805f47,0x00022c1baf832cd0,0x000132c01bd4d717,0x0004ecf4c3a75b8f,0x0007c0d345cfad88},{0x00071f4b8c78338a,0x00062cfc16bc2b23,0x00017cf51280d9aa,0x0003bbae5e20a95a,0x00020d754762aaec}}, + {{0x0004feb135b9f543,0x00063bd192ad93ae,0x00044e2ea612cdf7,0x000670f4991583ab,0x00038b8ada8790b4},{0x0007c36fc73bb758,0x0004a6c797734bd1,0x0000ef248ab3950e,0x00063154c9a53ec8,0x0002b8f1e46f3cee},{0x00004a9cdf51f95d,0x0005d963fbd596b8,0x00022d9b68ace54a,0x0004a98e8836c599,0x000049aeb32ceba1}}, + {{0x00067d3c63dcfe7e,0x000112f0adc81aee,0x00053df04c827165,0x0002fe5b33b430f0,0x00051c665e0c8d62},{0x00007d0b75fc7931,0x00016f4ce4ba754a,0x0005ace4c03fbe49,0x00027e0ec12a159c,0x000795ee17530f67},{0x00025b0a52ecbd81,0x0005dc0695fce4a9,0x0003b928c575047d,0x00023bf3512686e5,0x0006cd19bf49dc54}}, + {{0x0007619052179ca3,0x0000c16593f0afd0,0x000265c4795c7428,0x00031c40515d5442,0x0007520f3db40b2e},{0x0006612165afc386,0x0001171aa36203ff,0x0002642ea820a8aa,0x0001f3bb7b313f10,0x0005e01b3a7429e4},{0x00050be3d39357a1,0x0003ab33d294a7b6,0x0004c479ba59edb3,0x0004c30d184d326f,0x00071092c9ccef3c}}, + {{0x0000523f0364918c,0x000687f56d638a7b,0x00020796928ad013,0x0005d38405a54f33,0x0000ea15b03d0257},{0x0003d8ac74051dcf,0x00010ab6f543d0ad,0x0005d0f3ac0fda90,0x0005ef1d2573e5e4,0x0004173a5bb7137a},{0x00056e31f0f9218a,0x0005635f88e102f8,0x0002cbc5d969a5b8,0x000533fbc98b347a,0x0005fc565614a4e3}}, + {{0x0006570dc46d7ae5,0x00018a9f1b91e26d,0x000436b6183f42ab,0x000550acaa4f8198,0x00062711c414c454},{0x0002e1e67790988e,0x0001e38b9ae44912,0x000648fbb4075654,0x00028df1d840cd72,0x0003214c7409d466},{0x0001827406651770,0x0004d144f286c265,0x00017488f0ee9281,0x00019e6cdb5c760c,0x0005bea94073ecb8}}, + {{0x0005bf0912c89be4,0x00062fadcaf38c83,0x00025ec196b3ce2c,0x00077655ff4f017b,0x0003aacd5c148f61},{0x0000ce63f343d2f8,0x0001e0a87d1e368e,0x000045edbc019eea,0x0006979aed28d0d1,0x0004ad0785944f1b},{0x00063b34c3318301,0x0000e0e62d04d0b1,0x000676a233726701,0x00029e9a042d9769,0x0003aff0cb1d9028}}, + {{0x0005c7eb3a20405e,0x0005fdb5aad930f8,0x0004a757e63b8c47,0x00028e9492972456,0x000110e7e86f4cd2},{0x0006430bf4c53505,0x000264c3e4507244,0x00074c9f19a39270,0x00073f84f799bc47,0x0002ccf9f732bd99},{0x0000d89ed603f5e4,0x00051e1604018af8,0x0000b8eedc4a2218,0x00051ba98b9384d0,0x00005c557e0b9693}}, + {{0x0001ce311fc97e6f,0x0006023f3fb5db1f,0x0007b49775e8fc98,0x0003ad70adbf5045,0x0006e154c178fe98},{0x0006bbb089c20eb0,0x0006df41fb0b9eee,0x00051087ed87e16f,0x000102db5c9fa731,0x000289fef0841861},{0x00016336fed69abf,0x0004f066b929f9ec,0x0004e9ff9e6c5b93,0x00018c89bc4bb2ba,0x0006afbf642a95ca}}, + {{0x0000de0c62f5d2c1,0x00049601cf734fb5,0x0006b5c38263f0f6,0x0004623ef5b56d06,0x0000db4b851b9503},{0x00055070f913a8cc,0x000765619eac2bbc,0x0003ab5225f47459,0x00076ced14ab5b48,0x00012c093cedb801},{0x00047f9308b8190f,0x000414235c621f82,0x00031f5ff41a5a76,0x0006736773aab96d,0x00033aa8799c6635}}, + {{0x0007f51ebd085cf2,0x00012cfa67e3f5e1,0x0001800cf1e3d46a,0x00054337615ff0a8,0x000233c6f29e8e21},{0x0000f588fc156cb1,0x000363414da4f069,0x0007296ad9b68aea,0x0004d3711316ae43,0x000212cd0c1c8d58},{0x0004d5107f18c781,0x00064a4fd3a51a5e,0x0004f4cd0448bb37,0x000671d38543151e,0x0001db7778911914}}, + {{0x000352397c6bc26f,0x00018a7aa0227bbe,0x0005e68cc1ea5f8b,0x0006fe3e3a7a1d5f,0x00031ad97ad26e2a},{0x00014769dd701ab6,0x00028339f1b4b667,0x0004ab214b8ae37b,0x00025f0aefa0b0fe,0x0007ae2ca8a017d2},{0x000017ed0920b962,0x000187e33b53b6fd,0x00055829907a1463,0x000641f248e0a792,0x0001ed1fc53a6622}} +}; + +// ****************** modm-donna-64bit.h *********************** // + +const bignum256modm modm_m = { + 0x12631a5cf5d3ed, 0xf9dea2f79cd658, + 0x000000000014de, 0x00000000000000, + 0x00000010000000 +}; + +const bignum256modm modm_mu = { + 0x9ce5a30a2c131b, 0x215d086329a7ed, + 0xffffffffeb2106, 0xffffffffffffff, + 0x00000fffffffff +}; + +// *************** ed25519-donna-basepoint-table.h *************** // + +/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ +ALIGN(16) const byte ge25519_niels_base_multiples[256][96] = { + {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f}, + {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49}, + {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54}, + {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44}, + {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68}, + {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78}, + {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23}, + {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58}, + {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10}, + {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56}, + {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14}, + {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37}, + {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02}, + {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12}, + {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f}, + {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41}, + {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e}, + {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14}, + {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41}, + {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59}, + {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49}, + {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20}, + {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b}, + {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74}, + {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69}, + {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b}, + {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e}, + {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39}, + {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33}, + {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61}, + {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45}, + {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d}, + {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c}, + {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21}, + {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a}, + {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39}, + {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22}, + {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50}, + {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d}, + {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45}, + {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d}, + {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c}, + {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27}, + {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f}, + {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f}, + {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22}, + {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c}, + {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19}, + {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71}, + {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c}, + {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a}, + {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02}, + {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31}, + {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48}, + {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c}, + {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f}, + {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60}, + {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63}, + {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70}, + {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41}, + {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24}, + {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16}, + {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78}, + {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13}, + {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a}, + {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b}, + {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d}, + {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74}, + {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58}, + {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12}, + {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d}, + {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b}, + {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c}, + {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04}, + {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76}, + {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11}, + {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f}, + {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55}, + {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57}, + {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21}, + {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a}, + {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19}, + {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60}, + {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36}, + {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07}, + {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57}, + {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05}, + {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f}, + {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72}, + {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00}, + {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c}, + {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06}, + {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15}, + {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07}, + {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51}, + {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77}, + {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e}, + {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09}, + {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56}, + {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43}, + {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27}, + {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b}, + {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46}, + {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69}, + {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14}, + {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55}, + {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13}, + {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d}, + {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31}, + {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05}, + {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f}, + {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a}, + {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10}, + {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25}, + {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08}, + {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a}, + {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f}, + {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38}, + {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65}, + {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c}, + {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e}, + {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35}, + {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47}, + {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47}, + {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74}, + {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a}, + {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56}, + {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d}, + {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44}, + {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58}, + {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70}, + {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e}, + {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41}, + {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11}, + {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f}, + {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10}, + {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72}, + {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00}, + {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05}, + {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00}, + {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b}, + {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05}, + {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f}, + {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f}, + {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40}, + {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b}, + {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02}, + {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c}, + {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f}, + {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29}, + {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71}, + {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a}, + {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06}, + {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30}, + {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b}, + {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24}, + {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49}, + {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53}, + {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02}, + {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e}, + {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d}, + {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f}, + {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07}, + {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f}, + {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b}, + {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f}, + {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12}, + {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30}, + {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45}, + {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a}, + {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13}, + {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f}, + {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a}, + {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12}, + {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b}, + {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10}, + {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b}, + {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e}, + {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f}, + {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00}, + {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33}, + {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63}, + {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b}, + {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16}, + {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57}, + {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e}, + {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73}, + {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76}, + {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e}, + {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16}, + {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45}, + {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67}, + {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a}, + {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a}, + {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e}, + {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62}, + {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e}, + {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e}, + {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78}, + {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46}, + {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a}, + {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26}, + {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b}, + {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d}, + {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45}, + {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26}, + {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62}, + {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d}, + {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61}, + {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79}, + {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39}, + {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63}, + {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34}, + {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56}, + {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e}, + {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26}, + {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f}, + {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f}, + {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b}, + {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39}, + {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51}, + {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f}, + {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f}, + {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13}, + {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c}, + {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60}, + {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15}, + {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32}, + {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b}, + {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02}, + {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c}, + {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05}, + {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67}, + {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c}, + {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37}, + {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63}, + {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68}, + {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c}, + {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c}, + {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26}, + {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08}, + {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19}, + {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41}, + {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b}, + {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08}, + {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48}, + {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54}, + {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c}, + {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f}, + {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25}, + {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55}, + {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a}, + {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59}, + {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70}, + {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27}, + {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f} +}; + +NAMESPACE_END // Arch64 +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_DOXYGEN_PROCESSING +#endif // CRYPTOPP_DONNA_64_H diff --git a/external/ours/library/crypto/src/shared/original/donna_sse.cpp b/external/ours/library/crypto/src/shared/original/donna_sse.cpp new file mode 100755 index 000000000..2da9a6f73 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna_sse.cpp @@ -0,0 +1,1123 @@ +// donna_sse.cpp - written and placed in public domain by Jeffrey Walton +// This is a integration of Andrew Moon's public domain code. +// Also see https://github.com/floodyberry/curve25519-donna. + +// This is a integration of Andrew Moon's public domain code. The port was +// clean, but it has one potential problem. The original code is C and relies +// upon unions. Accessing the inactive union member is undefined behavior in +// C++. That means copying the array into packedelem8.u is OK; but then using +// packedelem8.v in a calcualtion is UB. Fortunately most (all?) compilers +// take pity on C++ developers and compile the code. We will have to keep an +// eye on things or rewrite significant portions of this code. + +// If needed, see Moon's commit "Go back to ignoring 256th bit [sic]", +// https://github.com/floodyberry/curve25519-donna/commit/57a683d18721a658 + +#include "pch.h" + +#include "config.h" +#include "donna.h" +#include "secblock.h" +#include "misc.h" + +// The data is aligned, but Clang issues warning based on type +// and not the actual alignment of the variable and data. +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wcast-align" +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4244) +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char DONNA_SSE_FNAME[] = __FILE__; + +#if (CRYPTOPP_CURVE25519_SSE2) + +#include "donna_sse.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::sword32; +using CryptoPP::word64; +using CryptoPP::sword64; +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; + +// Bring in all the symbols from the SSE header +using namespace CryptoPP::Donna::ArchSSE; + +/* Copy a bignum to another: out = in */ +inline void +curve25519_copy(bignum25519 out, const bignum25519 in) { + xmmi x0,x1,x2; + x0 = _mm_load_si128((xmmi*)in + 0); + x1 = _mm_load_si128((xmmi*)in + 1); + x2 = _mm_load_si128((xmmi*)in + 2); + _mm_store_si128((xmmi*)out + 0, x0); + _mm_store_si128((xmmi*)out + 1, x1); + _mm_store_si128((xmmi*)out + 2, x2); +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +inline void +curve25519_expand(bignum25519 out, const byte in[32]) { + word32 x0,x1,x2,x3,x4,x5,x6,x7; + + x0 = *(word32 *)(in + 0); + x1 = *(word32 *)(in + 4); + x2 = *(word32 *)(in + 8); + x3 = *(word32 *)(in + 12); + x4 = *(word32 *)(in + 16); + x5 = *(word32 *)(in + 20); + x6 = *(word32 *)(in + 24); + x7 = *(word32 *)(in + 28); + + out[0] = ( x0 ) & reduce_mask_26; + out[1] = ((((word64)x1 << 32) | x0) >> 26) & reduce_mask_25; + out[2] = ((((word64)x2 << 32) | x1) >> 19) & reduce_mask_26; + out[3] = ((((word64)x3 << 32) | x2) >> 13) & reduce_mask_25; + out[4] = (( x3) >> 6) & reduce_mask_26; + out[5] = ( x4 ) & reduce_mask_25; + out[6] = ((((word64)x5 << 32) | x4) >> 25) & reduce_mask_26; + out[7] = ((((word64)x6 << 32) | x5) >> 19) & reduce_mask_25; + out[8] = ((((word64)x7 << 32) | x6) >> 12) & reduce_mask_26; + out[9] = (( x7) >> 6) & reduce_mask_25; /* ignore the top bit */ + + out[10] = 0; + out[11] = 0; +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +inline void +curve25519_contract(byte out[32], const bignum25519 in) { + ALIGN(16) bignum25519 f; + + curve25519_copy(f, in); + + #define carry_pass() \ + f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ + f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ + f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ + f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ + f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ + f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ + f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ + f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ + f[9] += f[8] >> 26; f[8] &= reduce_mask_26; + + #define carry_pass_full() \ + carry_pass() \ + f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; + + #define carry_pass_final() \ + carry_pass() \ + f[9] &= reduce_mask_25; + + carry_pass_full() + carry_pass_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + f[0] += 19; + carry_pass_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + f[0] += (1 << 26) - 19; + f[1] += (1 << 25) - 1; + f[2] += (1 << 26) - 1; + f[3] += (1 << 25) - 1; + f[4] += (1 << 26) - 1; + f[5] += (1 << 25) - 1; + f[6] += (1 << 26) - 1; + f[7] += (1 << 25) - 1; + f[8] += (1 << 26) - 1; + f[9] += (1 << 25) - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + carry_pass_final() + + #undef carry_pass + #undef carry_full + #undef carry_final + + *(word32 *)(out + 0) = ((f[0] ) | (f[1] << 26)); + *(word32 *)(out + 4) = ((f[1] >> 6) | (f[2] << 19)); + *(word32 *)(out + 8) = ((f[2] >> 13) | (f[3] << 13)); + *(word32 *)(out + 12) = ((f[3] >> 19) | (f[4] << 6)); + *(word32 *)(out + 16) = ((f[5] ) | (f[6] << 25)); + *(word32 *)(out + 20) = ((f[6] >> 7) | (f[7] << 19)); + *(word32 *)(out + 24) = ((f[7] >> 13) | (f[8] << 12)); + *(word32 *)(out + 28) = ((f[8] >> 20) | (f[9] << 6)); +} + +/* + * Maybe swap the contents of two felem arrays (@a and @b), each 5 elements + * long. Perform the swap iff @swap is non-zero. + */ +inline void +curve25519_swap_conditional(bignum25519 a, bignum25519 b, word32 iswap) { + const word32 swap = (word32)(-(sword32)iswap); + xmmi a0,a1,a2,b0,b1,b2,x0,x1,x2; + xmmi mask = _mm_cvtsi32_si128(swap); + mask = _mm_shuffle_epi32(mask, 0); + a0 = _mm_load_si128((xmmi *)a + 0); + a1 = _mm_load_si128((xmmi *)a + 1); + a2 = _mm_load_si128((xmmi *)a + 2); + b0 = _mm_load_si128((xmmi *)b + 0); + b1 = _mm_load_si128((xmmi *)b + 1); + b2 = _mm_load_si128((xmmi *)b + 2); + b0 = _mm_xor_si128(a0, b0); + b1 = _mm_xor_si128(a1, b1); + b2 = _mm_xor_si128(a2, b2); + x0 = _mm_and_si128(b0, mask); + x1 = _mm_and_si128(b1, mask); + x2 = _mm_and_si128(b2, mask); + x0 = _mm_xor_si128(x0, a0); + x1 = _mm_xor_si128(x1, a1); + x2 = _mm_xor_si128(x2, a2); + a0 = _mm_xor_si128(x0, b0); + a1 = _mm_xor_si128(x1, b1); + a2 = _mm_xor_si128(x2, b2); + _mm_store_si128((xmmi *)a + 0, x0); + _mm_store_si128((xmmi *)a + 1, x1); + _mm_store_si128((xmmi *)a + 2, x2); + _mm_store_si128((xmmi *)b + 0, a0); + _mm_store_si128((xmmi *)b + 1, a1); + _mm_store_si128((xmmi *)b + 2, a2); +} + +/* interleave two bignums */ +inline void +curve25519_tangle32(packedelem32 *out, const bignum25519 x, const bignum25519 z) { + xmmi x0,x1,x2,z0,z1,z2; + + x0 = _mm_load_si128((xmmi *)(x + 0)); + x1 = _mm_load_si128((xmmi *)(x + 4)); + x2 = _mm_load_si128((xmmi *)(x + 8)); + z0 = _mm_load_si128((xmmi *)(z + 0)); + z1 = _mm_load_si128((xmmi *)(z + 4)); + z2 = _mm_load_si128((xmmi *)(z + 8)); + + out[0].v = _mm_unpacklo_epi32(x0, z0); + out[1].v = _mm_unpackhi_epi32(x0, z0); + out[2].v = _mm_unpacklo_epi32(x1, z1); + out[3].v = _mm_unpackhi_epi32(x1, z1); + out[4].v = _mm_unpacklo_epi32(x2, z2); +} + +/* split a packed bignum in to it's two parts */ +inline void +curve25519_untangle64(bignum25519 x, bignum25519 z, const packedelem64 *in) { + _mm_store_si128((xmmi *)(x + 0), _mm_unpacklo_epi64(_mm_unpacklo_epi32(in[0].v, in[1].v), _mm_unpacklo_epi32(in[2].v, in[3].v))); + _mm_store_si128((xmmi *)(x + 4), _mm_unpacklo_epi64(_mm_unpacklo_epi32(in[4].v, in[5].v), _mm_unpacklo_epi32(in[6].v, in[7].v))); + _mm_store_si128((xmmi *)(x + 8), _mm_unpacklo_epi32(in[8].v, in[9].v) ); + _mm_store_si128((xmmi *)(z + 0), _mm_unpacklo_epi64(_mm_unpackhi_epi32(in[0].v, in[1].v), _mm_unpackhi_epi32(in[2].v, in[3].v))); + _mm_store_si128((xmmi *)(z + 4), _mm_unpacklo_epi64(_mm_unpackhi_epi32(in[4].v, in[5].v), _mm_unpackhi_epi32(in[6].v, in[7].v))); + _mm_store_si128((xmmi *)(z + 8), _mm_unpackhi_epi32(in[8].v, in[9].v) ); +} + +/* add two packed bignums */ +inline void +curve25519_add_packed32(packedelem32 *out, const packedelem32 *r, const packedelem32 *s) { + out[0].v = _mm_add_epi32(r[0].v, s[0].v); + out[1].v = _mm_add_epi32(r[1].v, s[1].v); + out[2].v = _mm_add_epi32(r[2].v, s[2].v); + out[3].v = _mm_add_epi32(r[3].v, s[3].v); + out[4].v = _mm_add_epi32(r[4].v, s[4].v); +} + +/* subtract two packed bignums */ +inline void +curve25519_sub_packed32(packedelem32 *out, const packedelem32 *r, const packedelem32 *s) { + xmmi r0,r1,r2,r3,r4; + xmmi s0,s1,s2,s3; + xmmi c1,c2; + + r0 = _mm_add_epi32(r[0].v, packed32zeromodp0.v); + r1 = _mm_add_epi32(r[1].v, packed32zeromodp1.v); + r2 = _mm_add_epi32(r[2].v, packed32zeromodp1.v); + r3 = _mm_add_epi32(r[3].v, packed32zeromodp1.v); + r4 = _mm_add_epi32(r[4].v, packed32zeromodp1.v); + r0 = _mm_sub_epi32(r0, s[0].v); /* 00 11 */ + r1 = _mm_sub_epi32(r1, s[1].v); /* 22 33 */ + r2 = _mm_sub_epi32(r2, s[2].v); /* 44 55 */ + r3 = _mm_sub_epi32(r3, s[3].v); /* 66 77 */ + r4 = _mm_sub_epi32(r4, s[4].v); /* 88 99 */ + + s0 = _mm_unpacklo_epi64(r0, r2); /* 00 44 */ + s1 = _mm_unpackhi_epi64(r0, r2); /* 11 55 */ + s2 = _mm_unpacklo_epi64(r1, r3); /* 22 66 */ + s3 = _mm_unpackhi_epi64(r1, r3); /* 33 77 */ + + c1 = _mm_srli_epi32(s0, 26); c2 = _mm_srli_epi32(s2, 26); s0 = _mm_and_si128(s0, packedmask26262626.v); s2 = _mm_and_si128(s2, packedmask26262626.v); s1 = _mm_add_epi32(s1, c1); s3 = _mm_add_epi32(s3, c2); + c1 = _mm_srli_epi32(s1, 25); c2 = _mm_srli_epi32(s3, 25); s1 = _mm_and_si128(s1, packedmask25252525.v); s3 = _mm_and_si128(s3, packedmask25252525.v); s2 = _mm_add_epi32(s2, c1); r4 = _mm_add_epi32(r4, _mm_srli_si128(c2, 8)); s0 = _mm_add_epi32(s0, _mm_slli_si128(c2, 8)); + + out[0].v = _mm_unpacklo_epi64(s0, s1); /* 00 11 */ + out[1].v = _mm_unpacklo_epi64(s2, s3); /* 22 33 */ + out[2].v = _mm_unpackhi_epi64(s0, s1); /* 44 55 */ + out[3].v = _mm_unpackhi_epi64(s2, s3); /* 66 77 */ + out[4].v = r4; /* 88 99 */ +} + +/* multiply two packed bignums */ +inline void +curve25519_mul_packed64(packedelem64 *out, const packedelem64 *r, const packedelem64 *s) { + xmmi r1,r2,r3,r4,r5,r6,r7,r8,r9; + xmmi r1_2,r3_2,r5_2,r7_2,r9_2; + xmmi c1,c2; + + out[0].v = _mm_mul_epu32(r[0].v, s[0].v); + out[1].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[1].v), _mm_mul_epu32(r[1].v, s[0].v)); + r1_2 = _mm_slli_epi32(r[1].v, 1); + out[2].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r1_2 , s[1].v), _mm_mul_epu32(r[2].v, s[0].v))); + out[3].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[3].v), _mm_add_epi64(_mm_mul_epu32(r[1].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[1].v), _mm_mul_epu32(r[3].v, s[0].v)))); + r3_2 = _mm_slli_epi32(r[3].v, 1); + out[4].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[4].v), _mm_add_epi64(_mm_mul_epu32(r1_2 , s[3].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r3_2 , s[1].v), _mm_mul_epu32(r[4].v, s[0].v))))); + out[5].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[5].v), _mm_add_epi64(_mm_mul_epu32(r[1].v, s[4].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[3].v), _mm_add_epi64(_mm_mul_epu32(r[3].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r[4].v, s[1].v), _mm_mul_epu32(r[5].v, s[0].v)))))); + r5_2 = _mm_slli_epi32(r[5].v, 1); + out[6].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[6].v), _mm_add_epi64(_mm_mul_epu32(r1_2 , s[5].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[4].v), _mm_add_epi64(_mm_mul_epu32(r3_2 , s[3].v), _mm_add_epi64(_mm_mul_epu32(r[4].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r5_2 , s[1].v), _mm_mul_epu32(r[6].v, s[0].v))))))); + out[7].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[7].v), _mm_add_epi64(_mm_mul_epu32(r[1].v, s[6].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[5].v), _mm_add_epi64(_mm_mul_epu32(r[3].v, s[4].v), _mm_add_epi64(_mm_mul_epu32(r[4].v, s[3].v), _mm_add_epi64(_mm_mul_epu32(r[5].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r[6].v, s[1].v), _mm_mul_epu32(r[7].v , s[0].v)))))))); + r7_2 = _mm_slli_epi32(r[7].v, 1); + out[8].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[8].v), _mm_add_epi64(_mm_mul_epu32(r1_2 , s[7].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[6].v), _mm_add_epi64(_mm_mul_epu32(r3_2 , s[5].v), _mm_add_epi64(_mm_mul_epu32(r[4].v, s[4].v), _mm_add_epi64(_mm_mul_epu32(r5_2 , s[3].v), _mm_add_epi64(_mm_mul_epu32(r[6].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r7_2 , s[1].v), _mm_mul_epu32(r[8].v, s[0].v))))))))); + out[9].v = _mm_add_epi64(_mm_mul_epu32(r[0].v, s[9].v), _mm_add_epi64(_mm_mul_epu32(r[1].v, s[8].v), _mm_add_epi64(_mm_mul_epu32(r[2].v, s[7].v), _mm_add_epi64(_mm_mul_epu32(r[3].v, s[6].v), _mm_add_epi64(_mm_mul_epu32(r[4].v, s[5].v), _mm_add_epi64(_mm_mul_epu32(r[5].v, s[4].v), _mm_add_epi64(_mm_mul_epu32(r[6].v, s[3].v), _mm_add_epi64(_mm_mul_epu32(r[7].v, s[2].v), _mm_add_epi64(_mm_mul_epu32(r[8].v, s[1].v), _mm_mul_epu32(r[9].v, s[0].v)))))))))); + + r1 = _mm_mul_epu32(r[1].v, packednineteen.v); + r2 = _mm_mul_epu32(r[2].v, packednineteen.v); + r1_2 = _mm_slli_epi32(r1, 1); + r3 = _mm_mul_epu32(r[3].v, packednineteen.v); + r4 = _mm_mul_epu32(r[4].v, packednineteen.v); + r3_2 = _mm_slli_epi32(r3, 1); + r5 = _mm_mul_epu32(r[5].v, packednineteen.v); + r6 = _mm_mul_epu32(r[6].v, packednineteen.v); + r5_2 = _mm_slli_epi32(r5, 1); + r7 = _mm_mul_epu32(r[7].v, packednineteen.v); + r8 = _mm_mul_epu32(r[8].v, packednineteen.v); + r7_2 = _mm_slli_epi32(r7, 1); + r9 = _mm_mul_epu32(r[9].v, packednineteen.v); + r9_2 = _mm_slli_epi32(r9, 1); + + out[0].v = _mm_add_epi64(out[0].v, _mm_add_epi64(_mm_mul_epu32(r9_2, s[1].v), _mm_add_epi64(_mm_mul_epu32(r8, s[2].v), _mm_add_epi64(_mm_mul_epu32(r7_2, s[3].v), _mm_add_epi64(_mm_mul_epu32(r6, s[4].v), _mm_add_epi64(_mm_mul_epu32(r5_2, s[5].v), _mm_add_epi64(_mm_mul_epu32(r4, s[6].v), _mm_add_epi64(_mm_mul_epu32(r3_2, s[7].v), _mm_add_epi64(_mm_mul_epu32(r2, s[8].v), _mm_mul_epu32(r1_2, s[9].v)))))))))); + out[1].v = _mm_add_epi64(out[1].v, _mm_add_epi64(_mm_mul_epu32(r9 , s[2].v), _mm_add_epi64(_mm_mul_epu32(r8, s[3].v), _mm_add_epi64(_mm_mul_epu32(r7 , s[4].v), _mm_add_epi64(_mm_mul_epu32(r6, s[5].v), _mm_add_epi64(_mm_mul_epu32(r5 , s[6].v), _mm_add_epi64(_mm_mul_epu32(r4, s[7].v), _mm_add_epi64(_mm_mul_epu32(r3 , s[8].v), _mm_mul_epu32(r2, s[9].v))))))))); + out[2].v = _mm_add_epi64(out[2].v, _mm_add_epi64(_mm_mul_epu32(r9_2, s[3].v), _mm_add_epi64(_mm_mul_epu32(r8, s[4].v), _mm_add_epi64(_mm_mul_epu32(r7_2, s[5].v), _mm_add_epi64(_mm_mul_epu32(r6, s[6].v), _mm_add_epi64(_mm_mul_epu32(r5_2, s[7].v), _mm_add_epi64(_mm_mul_epu32(r4, s[8].v), _mm_mul_epu32(r3_2, s[9].v)))))))); + out[3].v = _mm_add_epi64(out[3].v, _mm_add_epi64(_mm_mul_epu32(r9 , s[4].v), _mm_add_epi64(_mm_mul_epu32(r8, s[5].v), _mm_add_epi64(_mm_mul_epu32(r7 , s[6].v), _mm_add_epi64(_mm_mul_epu32(r6, s[7].v), _mm_add_epi64(_mm_mul_epu32(r5 , s[8].v), _mm_mul_epu32(r4, s[9].v))))))); + out[4].v = _mm_add_epi64(out[4].v, _mm_add_epi64(_mm_mul_epu32(r9_2, s[5].v), _mm_add_epi64(_mm_mul_epu32(r8, s[6].v), _mm_add_epi64(_mm_mul_epu32(r7_2, s[7].v), _mm_add_epi64(_mm_mul_epu32(r6, s[8].v), _mm_mul_epu32(r5_2, s[9].v)))))); + out[5].v = _mm_add_epi64(out[5].v, _mm_add_epi64(_mm_mul_epu32(r9 , s[6].v), _mm_add_epi64(_mm_mul_epu32(r8, s[7].v), _mm_add_epi64(_mm_mul_epu32(r7 , s[8].v), _mm_mul_epu32(r6, s[9].v))))); + out[6].v = _mm_add_epi64(out[6].v, _mm_add_epi64(_mm_mul_epu32(r9_2, s[7].v), _mm_add_epi64(_mm_mul_epu32(r8, s[8].v), _mm_mul_epu32(r7_2, s[9].v)))); + out[7].v = _mm_add_epi64(out[7].v, _mm_add_epi64(_mm_mul_epu32(r9 , s[8].v), _mm_mul_epu32(r8, s[9].v))); + out[8].v = _mm_add_epi64(out[8].v, _mm_mul_epu32(r9_2, s[9].v)); + + c1 = _mm_srli_epi64(out[0].v, 26); c2 = _mm_srli_epi64(out[4].v, 26); out[0].v = _mm_and_si128(out[0].v, packedmask26.v); out[4].v = _mm_and_si128(out[4].v, packedmask26.v); out[1].v = _mm_add_epi64(out[1].v, c1); out[5].v = _mm_add_epi64(out[5].v, c2); + c1 = _mm_srli_epi64(out[1].v, 25); c2 = _mm_srli_epi64(out[5].v, 25); out[1].v = _mm_and_si128(out[1].v, packedmask25.v); out[5].v = _mm_and_si128(out[5].v, packedmask25.v); out[2].v = _mm_add_epi64(out[2].v, c1); out[6].v = _mm_add_epi64(out[6].v, c2); + c1 = _mm_srli_epi64(out[2].v, 26); c2 = _mm_srli_epi64(out[6].v, 26); out[2].v = _mm_and_si128(out[2].v, packedmask26.v); out[6].v = _mm_and_si128(out[6].v, packedmask26.v); out[3].v = _mm_add_epi64(out[3].v, c1); out[7].v = _mm_add_epi64(out[7].v, c2); + c1 = _mm_srli_epi64(out[3].v, 25); c2 = _mm_srli_epi64(out[7].v, 25); out[3].v = _mm_and_si128(out[3].v, packedmask25.v); out[7].v = _mm_and_si128(out[7].v, packedmask25.v); out[4].v = _mm_add_epi64(out[4].v, c1); out[8].v = _mm_add_epi64(out[8].v, c2); + c2 = _mm_srli_epi64(out[8].v, 26); out[8].v = _mm_and_si128(out[8].v, packedmask26.v); out[9].v = _mm_add_epi64(out[9].v, c2); + c2 = _mm_srli_epi64(out[9].v, 25); out[9].v = _mm_and_si128(out[9].v, packedmask25.v); out[0].v = _mm_add_epi64(out[0].v, _mm_mul_epu32(c2, packednineteen.v)); + c1 = _mm_srli_epi64(out[0].v, 26); c2 = _mm_srli_epi64(out[4].v, 26); out[0].v = _mm_and_si128(out[0].v, packedmask26.v); out[4].v = _mm_and_si128(out[4].v, packedmask26.v); out[1].v = _mm_add_epi64(out[1].v, c1); out[5].v = _mm_add_epi64(out[5].v, c2); +} + +/* multiply a bignum */ +void +curve25519_mul(bignum25519 out, const bignum25519 r, const bignum25519 s) { + xmmi m01,m23,m45,m67,m89; + xmmi m0123,m4567; + xmmi s0123,s4567; + xmmi s01,s23,s45,s67,s89; + xmmi s12,s34,s56,s78,s9; + xmmi r0,r2,r4,r6,r8; + xmmi r1,r3,r5,r7,r9; + xmmi r119,r219,r319,r419,r519,r619,r719,r819,r919; + xmmi c1,c2,c3; + + s0123 = _mm_load_si128((xmmi*)s + 0); + s01 = _mm_shuffle_epi32(s0123,_MM_SHUFFLE(3,1,2,0)); + s12 = _mm_shuffle_epi32(s0123, _MM_SHUFFLE(2,2,1,1)); + s23 = _mm_shuffle_epi32(s0123,_MM_SHUFFLE(3,3,2,2)); + s4567 = _mm_load_si128((xmmi*)s + 1); + s34 = _mm_unpacklo_epi64(_mm_srli_si128(s0123,12),s4567); + s45 = _mm_shuffle_epi32(s4567,_MM_SHUFFLE(3,1,2,0)); + s56 = _mm_shuffle_epi32(s4567, _MM_SHUFFLE(2,2,1,1)); + s67 = _mm_shuffle_epi32(s4567,_MM_SHUFFLE(3,3,2,2)); + s89 = _mm_load_si128((xmmi*)s + 2); + s78 = _mm_unpacklo_epi64(_mm_srli_si128(s4567,12),s89); + s89 = _mm_shuffle_epi32(s89,_MM_SHUFFLE(3,1,2,0)); + s9 = _mm_shuffle_epi32(s89, _MM_SHUFFLE(3,3,2,2)); + + r0 = _mm_load_si128((xmmi*)r + 0); + r1 = _mm_shuffle_epi32(r0, _MM_SHUFFLE(1,1,1,1)); + r1 = _mm_add_epi64(r1, _mm_and_si128(r1, sse2_top64bitmask.v)); + r2 = _mm_shuffle_epi32(r0, _MM_SHUFFLE(2,2,2,2)); + r3 = _mm_shuffle_epi32(r0, _MM_SHUFFLE(3,3,3,3)); + r3 = _mm_add_epi64(r3, _mm_and_si128(r3, sse2_top64bitmask.v)); + r0 = _mm_shuffle_epi32(r0, _MM_SHUFFLE(0,0,0,0)); + r4 = _mm_load_si128((xmmi*)r + 1); + r5 = _mm_shuffle_epi32(r4, _MM_SHUFFLE(1,1,1,1)); + r5 = _mm_add_epi64(r5, _mm_and_si128(r5, sse2_top64bitmask.v)); + r6 = _mm_shuffle_epi32(r4, _MM_SHUFFLE(2,2,2,2)); + r7 = _mm_shuffle_epi32(r4, _MM_SHUFFLE(3,3,3,3)); + r7 = _mm_add_epi64(r7, _mm_and_si128(r7, sse2_top64bitmask.v)); + r4 = _mm_shuffle_epi32(r4, _MM_SHUFFLE(0,0,0,0)); + r8 = _mm_load_si128((xmmi*)r + 2); + r9 = _mm_shuffle_epi32(r8, _MM_SHUFFLE(3,1,3,1)); + r9 = _mm_add_epi64(r9, _mm_and_si128(r9, sse2_top64bitmask.v)); + r8 = _mm_shuffle_epi32(r8, _MM_SHUFFLE(3,0,3,0)); + + m01 = _mm_mul_epu32(r1,s01); + m23 = _mm_mul_epu32(r1,s23); + m45 = _mm_mul_epu32(r1,s45); + m67 = _mm_mul_epu32(r1,s67); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r3,s01)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r3,s23)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r3,s45)); + m89 = _mm_mul_epu32(r1,s89); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r5,s01)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r5,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r3,s67)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r7,s01)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r5,s45)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r7,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r9,s01)); + + /* shift up */ + m89 = _mm_unpackhi_epi64(m67,_mm_slli_si128(m89,8)); + m67 = _mm_unpackhi_epi64(m45,_mm_slli_si128(m67,8)); + m45 = _mm_unpackhi_epi64(m23,_mm_slli_si128(m45,8)); + m23 = _mm_unpackhi_epi64(m01,_mm_slli_si128(m23,8)); + m01 = _mm_unpackhi_epi64(_mm_setzero_si128(),_mm_slli_si128(m01,8)); + + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r0,s01)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r0,s23)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r0,s45)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r0,s67)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r2,s01)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r2,s23)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r4,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r0,s89)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r4,s01)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r2,s45)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r2,s67)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r6,s01)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r4,s45)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r6,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r8,s01)); + + r219 = _mm_mul_epu32(r2, packednineteen.v); + r419 = _mm_mul_epu32(r4, packednineteen.v); + r619 = _mm_mul_epu32(r6, packednineteen.v); + r819 = _mm_mul_epu32(r8, packednineteen.v); + r119 = _mm_shuffle_epi32(r1,_MM_SHUFFLE(0,0,2,2)); r119 = _mm_mul_epu32(r119, packednineteen.v); + r319 = _mm_shuffle_epi32(r3,_MM_SHUFFLE(0,0,2,2)); r319 = _mm_mul_epu32(r319, packednineteen.v); + r519 = _mm_shuffle_epi32(r5,_MM_SHUFFLE(0,0,2,2)); r519 = _mm_mul_epu32(r519, packednineteen.v); + r719 = _mm_shuffle_epi32(r7,_MM_SHUFFLE(0,0,2,2)); r719 = _mm_mul_epu32(r719, packednineteen.v); + r919 = _mm_shuffle_epi32(r9,_MM_SHUFFLE(0,0,2,2)); r919 = _mm_mul_epu32(r919, packednineteen.v); + + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r919,s12)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r919,s34)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r919,s56)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r919,s78)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r719,s34)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r719,s56)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r719,s78)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r719,s9)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r519,s56)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r519,s78)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r519,s9)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r819,s89)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r319,s78)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r319,s9)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r619,s89)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r919,s9)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r819,s23)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r819,s45)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r819,s67)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r619,s45)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r619,s67)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r419,s67)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r419,s89)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r219,s89)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r119,s9)); + + r0 = _mm_unpacklo_epi64(m01, m45); + r1 = _mm_unpackhi_epi64(m01, m45); + r2 = _mm_unpacklo_epi64(m23, m67); + r3 = _mm_unpackhi_epi64(m23, m67); + r4 = _mm_unpacklo_epi64(m89, m89); + r5 = _mm_unpackhi_epi64(m89, m89); + + c1 = _mm_srli_epi64(r0, 26); c2 = _mm_srli_epi64(r2, 26); r0 = _mm_and_si128(r0, packedmask26.v); r2 = _mm_and_si128(r2, packedmask26.v); r1 = _mm_add_epi64(r1, c1); r3 = _mm_add_epi64(r3, c2); + c1 = _mm_srli_epi64(r1, 25); c2 = _mm_srli_epi64(r3, 25); r1 = _mm_and_si128(r1, packedmask25.v); r3 = _mm_and_si128(r3, packedmask25.v); r2 = _mm_add_epi64(r2, c1); r4 = _mm_add_epi64(r4, c2); c3 = _mm_slli_si128(c2, 8); + c1 = _mm_srli_epi64(r4, 26); r4 = _mm_and_si128(r4, packedmask26.v); r5 = _mm_add_epi64(r5, c1); + c1 = _mm_srli_epi64(r5, 25); r5 = _mm_and_si128(r5, packedmask25.v); r0 = _mm_add_epi64(r0, _mm_unpackhi_epi64(_mm_mul_epu32(c1, packednineteen.v), c3)); + c1 = _mm_srli_epi64(r0, 26); c2 = _mm_srli_epi64(r2, 26); r0 = _mm_and_si128(r0, packedmask26.v); r2 = _mm_and_si128(r2, packedmask26.v); r1 = _mm_add_epi64(r1, c1); r3 = _mm_add_epi64(r3, c2); + + m0123 = _mm_unpacklo_epi32(r0, r1); + m4567 = _mm_unpackhi_epi32(r0, r1); + m0123 = _mm_unpacklo_epi64(m0123, _mm_unpacklo_epi32(r2, r3)); + m4567 = _mm_unpacklo_epi64(m4567, _mm_unpackhi_epi32(r2, r3)); + m89 = _mm_unpackhi_epi32(r4, r5); + + _mm_store_si128((xmmi*)out + 0, m0123); + _mm_store_si128((xmmi*)out + 1, m4567); + _mm_store_si128((xmmi*)out + 2, m89); +} + +typedef struct bignum25519mulprecomp_t { + xmmi r0,r2,r4,r6,r8; + xmmi r1,r3,r5,r7,r9; + xmmi r119,r219,r319,r419,r519,r619,r719,r819,r919; +} bignum25519mulprecomp; + +/* precompute a constant to multiply by */ +inline void +curve25519_mul_precompute(bignum25519mulprecomp *pre, const bignum25519 r) { + pre->r0 = _mm_load_si128((xmmi*)r + 0); + pre->r1 = _mm_shuffle_epi32(pre->r0, _MM_SHUFFLE(1,1,1,1)); + pre->r1 = _mm_add_epi64(pre->r1, _mm_and_si128(pre->r1, sse2_top64bitmask.v)); + pre->r2 = _mm_shuffle_epi32(pre->r0, _MM_SHUFFLE(2,2,2,2)); + pre->r3 = _mm_shuffle_epi32(pre->r0, _MM_SHUFFLE(3,3,3,3)); + pre->r3 = _mm_add_epi64(pre->r3, _mm_and_si128(pre->r3, sse2_top64bitmask.v)); + pre->r0 = _mm_shuffle_epi32(pre->r0, _MM_SHUFFLE(0,0,0,0)); + pre->r4 = _mm_load_si128((xmmi*)r + 1); + pre->r5 = _mm_shuffle_epi32(pre->r4, _MM_SHUFFLE(1,1,1,1)); + pre->r5 = _mm_add_epi64(pre->r5, _mm_and_si128(pre->r5, sse2_top64bitmask.v)); + pre->r6 = _mm_shuffle_epi32(pre->r4, _MM_SHUFFLE(2,2,2,2)); + pre->r7 = _mm_shuffle_epi32(pre->r4, _MM_SHUFFLE(3,3,3,3)); + pre->r7 = _mm_add_epi64(pre->r7, _mm_and_si128(pre->r7, sse2_top64bitmask.v)); + pre->r4 = _mm_shuffle_epi32(pre->r4, _MM_SHUFFLE(0,0,0,0)); + pre->r8 = _mm_load_si128((xmmi*)r + 2); + pre->r9 = _mm_shuffle_epi32(pre->r8, _MM_SHUFFLE(3,1,3,1)); + pre->r9 = _mm_add_epi64(pre->r9, _mm_and_si128(pre->r9, sse2_top64bitmask.v)); + pre->r8 = _mm_shuffle_epi32(pre->r8, _MM_SHUFFLE(3,0,3,0)); + + pre->r219 = _mm_mul_epu32(pre->r2, packednineteen.v); + pre->r419 = _mm_mul_epu32(pre->r4, packednineteen.v); + pre->r619 = _mm_mul_epu32(pre->r6, packednineteen.v); + pre->r819 = _mm_mul_epu32(pre->r8, packednineteen.v); + pre->r119 = _mm_shuffle_epi32(pre->r1,_MM_SHUFFLE(0,0,2,2)); pre->r119 = _mm_mul_epu32(pre->r119, packednineteen.v); + pre->r319 = _mm_shuffle_epi32(pre->r3,_MM_SHUFFLE(0,0,2,2)); pre->r319 = _mm_mul_epu32(pre->r319, packednineteen.v); + pre->r519 = _mm_shuffle_epi32(pre->r5,_MM_SHUFFLE(0,0,2,2)); pre->r519 = _mm_mul_epu32(pre->r519, packednineteen.v); + pre->r719 = _mm_shuffle_epi32(pre->r7,_MM_SHUFFLE(0,0,2,2)); pre->r719 = _mm_mul_epu32(pre->r719, packednineteen.v); + pre->r919 = _mm_shuffle_epi32(pre->r9,_MM_SHUFFLE(0,0,2,2)); pre->r919 = _mm_mul_epu32(pre->r919, packednineteen.v); +} + + +/* multiply a bignum by a pre-computed constant */ +inline void +curve25519_mul_precomputed(bignum25519 out, const bignum25519 s, const bignum25519mulprecomp *r) { + xmmi m01,m23,m45,m67,m89; + xmmi m0123,m4567; + xmmi s0123,s4567; + xmmi s01,s23,s45,s67,s89; + xmmi s12,s34,s56,s78,s9; + xmmi r0,r1,r2,r3,r4,r5; + xmmi c1,c2,c3; + + s0123 = _mm_load_si128((xmmi*)s + 0); + s01 = _mm_shuffle_epi32(s0123,_MM_SHUFFLE(3,1,2,0)); + s12 = _mm_shuffle_epi32(s0123, _MM_SHUFFLE(2,2,1,1)); + s23 = _mm_shuffle_epi32(s0123,_MM_SHUFFLE(3,3,2,2)); + s4567 = _mm_load_si128((xmmi*)s + 1); + s34 = _mm_unpacklo_epi64(_mm_srli_si128(s0123,12),s4567); + s45 = _mm_shuffle_epi32(s4567,_MM_SHUFFLE(3,1,2,0)); + s56 = _mm_shuffle_epi32(s4567, _MM_SHUFFLE(2,2,1,1)); + s67 = _mm_shuffle_epi32(s4567,_MM_SHUFFLE(3,3,2,2)); + s89 = _mm_load_si128((xmmi*)s + 2); + s78 = _mm_unpacklo_epi64(_mm_srli_si128(s4567,12),s89); + s89 = _mm_shuffle_epi32(s89,_MM_SHUFFLE(3,1,2,0)); + s9 = _mm_shuffle_epi32(s89, _MM_SHUFFLE(3,3,2,2)); + + m01 = _mm_mul_epu32(r->r1,s01); + m23 = _mm_mul_epu32(r->r1,s23); + m45 = _mm_mul_epu32(r->r1,s45); + m67 = _mm_mul_epu32(r->r1,s67); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r3,s01)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r3,s23)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r3,s45)); + m89 = _mm_mul_epu32(r->r1,s89); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r5,s01)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r5,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r3,s67)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r7,s01)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r5,s45)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r7,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r9,s01)); + + /* shift up */ + m89 = _mm_unpackhi_epi64(m67,_mm_slli_si128(m89,8)); + m67 = _mm_unpackhi_epi64(m45,_mm_slli_si128(m67,8)); + m45 = _mm_unpackhi_epi64(m23,_mm_slli_si128(m45,8)); + m23 = _mm_unpackhi_epi64(m01,_mm_slli_si128(m23,8)); + m01 = _mm_unpackhi_epi64(_mm_setzero_si128(),_mm_slli_si128(m01,8)); + + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r0,s01)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r0,s23)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r0,s45)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r0,s67)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r2,s01)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r2,s23)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r4,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r0,s89)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r4,s01)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r2,s45)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r2,s67)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r6,s01)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r4,s45)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r6,s23)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r8,s01)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r919,s12)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r919,s34)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r919,s56)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r919,s78)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r719,s34)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r719,s56)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r719,s78)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r719,s9)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r519,s56)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r519,s78)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r519,s9)); + m67 = _mm_add_epi64(m67,_mm_mul_epu32(r->r819,s89)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r319,s78)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r319,s9)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r619,s89)); + m89 = _mm_add_epi64(m89,_mm_mul_epu32(r->r919,s9)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r819,s23)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r819,s45)); + m45 = _mm_add_epi64(m45,_mm_mul_epu32(r->r819,s67)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r619,s45)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r619,s67)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r419,s67)); + m23 = _mm_add_epi64(m23,_mm_mul_epu32(r->r419,s89)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r219,s89)); + m01 = _mm_add_epi64(m01,_mm_mul_epu32(r->r119,s9)); + + r0 = _mm_unpacklo_epi64(m01, m45); + r1 = _mm_unpackhi_epi64(m01, m45); + r2 = _mm_unpacklo_epi64(m23, m67); + r3 = _mm_unpackhi_epi64(m23, m67); + r4 = _mm_unpacklo_epi64(m89, m89); + r5 = _mm_unpackhi_epi64(m89, m89); + + c1 = _mm_srli_epi64(r0, 26); c2 = _mm_srli_epi64(r2, 26); r0 = _mm_and_si128(r0, packedmask26.v); r2 = _mm_and_si128(r2, packedmask26.v); r1 = _mm_add_epi64(r1, c1); r3 = _mm_add_epi64(r3, c2); + c1 = _mm_srli_epi64(r1, 25); c2 = _mm_srli_epi64(r3, 25); r1 = _mm_and_si128(r1, packedmask25.v); r3 = _mm_and_si128(r3, packedmask25.v); r2 = _mm_add_epi64(r2, c1); r4 = _mm_add_epi64(r4, c2); c3 = _mm_slli_si128(c2, 8); + c1 = _mm_srli_epi64(r4, 26); r4 = _mm_and_si128(r4, packedmask26.v); r5 = _mm_add_epi64(r5, c1); + c1 = _mm_srli_epi64(r5, 25); r5 = _mm_and_si128(r5, packedmask25.v); r0 = _mm_add_epi64(r0, _mm_unpackhi_epi64(_mm_mul_epu32(c1, packednineteen.v), c3)); + c1 = _mm_srli_epi64(r0, 26); c2 = _mm_srli_epi64(r2, 26); r0 = _mm_and_si128(r0, packedmask26.v); r2 = _mm_and_si128(r2, packedmask26.v); r1 = _mm_add_epi64(r1, c1); r3 = _mm_add_epi64(r3, c2); + + m0123 = _mm_unpacklo_epi32(r0, r1); + m4567 = _mm_unpackhi_epi32(r0, r1); + m0123 = _mm_unpacklo_epi64(m0123, _mm_unpacklo_epi32(r2, r3)); + m4567 = _mm_unpacklo_epi64(m4567, _mm_unpackhi_epi32(r2, r3)); + m89 = _mm_unpackhi_epi32(r4, r5); + + _mm_store_si128((xmmi*)out + 0, m0123); + _mm_store_si128((xmmi*)out + 1, m4567); + _mm_store_si128((xmmi*)out + 2, m89); +} + +/* square a bignum 'count' times */ +#define curve25519_square(r,x) curve25519_square_times(r,x,1) + +void +curve25519_square_times(bignum25519 r, const bignum25519 in, int count) { + xmmi m01,m23,m45,m67,m89; + xmmi r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + xmmi r0a,r1a,r2a,r3a,r7a,r9a; + xmmi r0123,r4567; + xmmi r01,r23,r45,r67,r6x,r89,r8x; + xmmi r12,r34,r56,r78,r9x; + xmmi r5619; + xmmi c1,c2,c3; + + r0123 = _mm_load_si128((xmmi*)in + 0); + r01 = _mm_shuffle_epi32(r0123,_MM_SHUFFLE(3,1,2,0)); + r23 = _mm_shuffle_epi32(r0123,_MM_SHUFFLE(3,3,2,2)); + r4567 = _mm_load_si128((xmmi*)in + 1); + r45 = _mm_shuffle_epi32(r4567,_MM_SHUFFLE(3,1,2,0)); + r67 = _mm_shuffle_epi32(r4567,_MM_SHUFFLE(3,3,2,2)); + r89 = _mm_load_si128((xmmi*)in + 2); + r89 = _mm_shuffle_epi32(r89,_MM_SHUFFLE(3,1,2,0)); + + do { + r12 = _mm_unpackhi_epi64(r01, _mm_slli_si128(r23, 8)); + r0 = _mm_shuffle_epi32(r01, _MM_SHUFFLE(0,0,0,0)); + r0 = _mm_add_epi64(r0, _mm_and_si128(r0, sse2_top64bitmask.v)); + r0a = _mm_shuffle_epi32(r0,_MM_SHUFFLE(3,2,1,2)); + r1 = _mm_shuffle_epi32(r01, _MM_SHUFFLE(2,2,2,2)); + r2 = _mm_shuffle_epi32(r23, _MM_SHUFFLE(0,0,0,0)); + r2 = _mm_add_epi64(r2, _mm_and_si128(r2, sse2_top64bitmask.v)); + r2a = _mm_shuffle_epi32(r2,_MM_SHUFFLE(3,2,1,2)); + r3 = _mm_shuffle_epi32(r23, _MM_SHUFFLE(2,2,2,2)); + r34 = _mm_unpackhi_epi64(r23, _mm_slli_si128(r45, 8)); + r4 = _mm_shuffle_epi32(r45, _MM_SHUFFLE(0,0,0,0)); + r4 = _mm_add_epi64(r4, _mm_and_si128(r4, sse2_top64bitmask.v)); + r56 = _mm_unpackhi_epi64(r45, _mm_slli_si128(r67, 8)); + r5619 = _mm_mul_epu32(r56, packednineteen.v); + r5 = _mm_shuffle_epi32(r5619, _MM_SHUFFLE(1,1,1,0)); + r6 = _mm_shuffle_epi32(r5619, _MM_SHUFFLE(3,2,3,2)); + r78 = _mm_unpackhi_epi64(r67, _mm_slli_si128(r89, 8)); + r6x = _mm_unpacklo_epi64(r67, _mm_setzero_si128()); + r7 = _mm_shuffle_epi32(r67, _MM_SHUFFLE(2,2,2,2)); + r7 = _mm_mul_epu32(r7, packed3819.v); + r7a = _mm_shuffle_epi32(r7, _MM_SHUFFLE(3,3,3,2)); + r8x = _mm_unpacklo_epi64(r89, _mm_setzero_si128()); + r8 = _mm_shuffle_epi32(r89, _MM_SHUFFLE(0,0,0,0)); + r8 = _mm_mul_epu32(r8, packednineteen.v); + r9 = _mm_shuffle_epi32(r89, _MM_SHUFFLE(2,2,2,2)); + r9x = _mm_slli_epi32(_mm_shuffle_epi32(r89, _MM_SHUFFLE(3,3,3,2)), 1); + r9 = _mm_mul_epu32(r9, packed3819.v); + r9a = _mm_shuffle_epi32(r9, _MM_SHUFFLE(2,2,2,2)); + + m01 = _mm_mul_epu32(r01, r0); + m23 = _mm_mul_epu32(r23, r0a); + m45 = _mm_mul_epu32(r45, r0a); + m45 = _mm_add_epi64(m45, _mm_mul_epu32(r23, r2)); + r23 = _mm_slli_epi32(r23, 1); + m67 = _mm_mul_epu32(r67, r0a); + m67 = _mm_add_epi64(m67, _mm_mul_epu32(r45, r2a)); + m89 = _mm_mul_epu32(r89, r0a); + m89 = _mm_add_epi64(m89, _mm_mul_epu32(r67, r2a)); + r67 = _mm_slli_epi32(r67, 1); + m89 = _mm_add_epi64(m89, _mm_mul_epu32(r45, r4)); + r45 = _mm_slli_epi32(r45, 1); + + r1 = _mm_slli_epi32(r1, 1); + r3 = _mm_slli_epi32(r3, 1); + r1a = _mm_add_epi64(r1, _mm_and_si128(r1, sse2_bot64bitmask.v)); + r3a = _mm_add_epi64(r3, _mm_and_si128(r3, sse2_bot64bitmask.v)); + + m23 = _mm_add_epi64(m23, _mm_mul_epu32(r12, r1)); + m45 = _mm_add_epi64(m45, _mm_mul_epu32(r34, r1a)); + m67 = _mm_add_epi64(m67, _mm_mul_epu32(r56, r1a)); + m67 = _mm_add_epi64(m67, _mm_mul_epu32(r34, r3)); + r34 = _mm_slli_epi32(r34, 1); + m89 = _mm_add_epi64(m89, _mm_mul_epu32(r78, r1a)); + r78 = _mm_slli_epi32(r78, 1); + m89 = _mm_add_epi64(m89, _mm_mul_epu32(r56, r3a)); + r56 = _mm_slli_epi32(r56, 1); + + m01 = _mm_add_epi64(m01, _mm_mul_epu32(_mm_slli_epi32(r12, 1), r9)); + m01 = _mm_add_epi64(m01, _mm_mul_epu32(r34, r7)); + m23 = _mm_add_epi64(m23, _mm_mul_epu32(r34, r9)); + m01 = _mm_add_epi64(m01, _mm_mul_epu32(r56, r5)); + m23 = _mm_add_epi64(m23, _mm_mul_epu32(r56, r7)); + m45 = _mm_add_epi64(m45, _mm_mul_epu32(r56, r9)); + m01 = _mm_add_epi64(m01, _mm_mul_epu32(r23, r8)); + m01 = _mm_add_epi64(m01, _mm_mul_epu32(r45, r6)); + m23 = _mm_add_epi64(m23, _mm_mul_epu32(r45, r8)); + m23 = _mm_add_epi64(m23, _mm_mul_epu32(r6x, r6)); + m45 = _mm_add_epi64(m45, _mm_mul_epu32(r78, r7a)); + m67 = _mm_add_epi64(m67, _mm_mul_epu32(r78, r9)); + m45 = _mm_add_epi64(m45, _mm_mul_epu32(r67, r8)); + m67 = _mm_add_epi64(m67, _mm_mul_epu32(r8x, r8)); + m89 = _mm_add_epi64(m89, _mm_mul_epu32(r9x, r9a)); + + r0 = _mm_unpacklo_epi64(m01, m45); + r1 = _mm_unpackhi_epi64(m01, m45); + r2 = _mm_unpacklo_epi64(m23, m67); + r3 = _mm_unpackhi_epi64(m23, m67); + r4 = _mm_unpacklo_epi64(m89, m89); + r5 = _mm_unpackhi_epi64(m89, m89); + + c1 = _mm_srli_epi64(r0, 26); c2 = _mm_srli_epi64(r2, 26); r0 = _mm_and_si128(r0, packedmask26.v); r2 = _mm_and_si128(r2, packedmask26.v); r1 = _mm_add_epi64(r1, c1); r3 = _mm_add_epi64(r3, c2); + c1 = _mm_srli_epi64(r1, 25); c2 = _mm_srli_epi64(r3, 25); r1 = _mm_and_si128(r1, packedmask25.v); r3 = _mm_and_si128(r3, packedmask25.v); r2 = _mm_add_epi64(r2, c1); r4 = _mm_add_epi64(r4, c2); c3 = _mm_slli_si128(c2, 8); + c1 = _mm_srli_epi64(r4, 26); r4 = _mm_and_si128(r4, packedmask26.v); r5 = _mm_add_epi64(r5, c1); + c1 = _mm_srli_epi64(r5, 25); r5 = _mm_and_si128(r5, packedmask25.v); r0 = _mm_add_epi64(r0, _mm_unpackhi_epi64(_mm_mul_epu32(c1, packednineteen.v), c3)); + c1 = _mm_srli_epi64(r0, 26); c2 = _mm_srli_epi64(r2, 26); r0 = _mm_and_si128(r0, packedmask26.v); r2 = _mm_and_si128(r2, packedmask26.v); r1 = _mm_add_epi64(r1, c1); r3 = _mm_add_epi64(r3, c2); + + r01 = _mm_unpacklo_epi64(r0, r1); + r45 = _mm_unpackhi_epi64(r0, r1); + r23 = _mm_unpacklo_epi64(r2, r3); + r67 = _mm_unpackhi_epi64(r2, r3); + r89 = _mm_unpackhi_epi64(r4, r5); + } while (--count); + + r0123 = _mm_shuffle_epi32(r23, _MM_SHUFFLE(2,0,3,3)); + r4567 = _mm_shuffle_epi32(r67, _MM_SHUFFLE(2,0,3,3)); + r0123 = _mm_or_si128(r0123, _mm_shuffle_epi32(r01, _MM_SHUFFLE(3,3,2,0))); + r4567 = _mm_or_si128(r4567, _mm_shuffle_epi32(r45, _MM_SHUFFLE(3,3,2,0))); + r89 = _mm_shuffle_epi32(r89, _MM_SHUFFLE(3,3,2,0)); + + _mm_store_si128((xmmi*)r + 0, r0123); + _mm_store_si128((xmmi*)r + 1, r4567); + _mm_store_si128((xmmi*)r + 2, r89); +} + +/* square two packed bignums */ +inline void +curve25519_square_packed64(packedelem64 *out, const packedelem64 *r) { + xmmi r0,r1,r2,r3; + xmmi r1_2,r3_2,r4_2,r5_2,r6_2,r7_2; + xmmi d5,d6,d7,d8,d9; + xmmi c1,c2; + + r0 = r[0].v; + r1 = r[1].v; + r2 = r[2].v; + r3 = r[3].v; + + out[0].v = _mm_mul_epu32(r0, r0); + r0 = _mm_slli_epi32(r0, 1); + out[1].v = _mm_mul_epu32(r0, r1); + r1_2 = _mm_slli_epi32(r1, 1); + out[2].v = _mm_add_epi64(_mm_mul_epu32(r0, r2 ), _mm_mul_epu32(r1, r1_2)); + r1 = r1_2; + out[3].v = _mm_add_epi64(_mm_mul_epu32(r0, r3 ), _mm_mul_epu32(r1, r2 )); + r3_2 = _mm_slli_epi32(r3, 1); + out[4].v = _mm_add_epi64(_mm_mul_epu32(r0, r[4].v), _mm_add_epi64(_mm_mul_epu32(r1, r3_2 ), _mm_mul_epu32(r2, r2))); + r2 = _mm_slli_epi32(r2, 1); + out[5].v = _mm_add_epi64(_mm_mul_epu32(r0, r[5].v), _mm_add_epi64(_mm_mul_epu32(r1, r[4].v), _mm_mul_epu32(r2, r3))); + r5_2 = _mm_slli_epi32(r[5].v, 1); + out[6].v = _mm_add_epi64(_mm_mul_epu32(r0, r[6].v), _mm_add_epi64(_mm_mul_epu32(r1, r5_2 ), _mm_add_epi64(_mm_mul_epu32(r2, r[4].v), _mm_mul_epu32(r3, r3_2 )))); + r3 = r3_2; + out[7].v = _mm_add_epi64(_mm_mul_epu32(r0, r[7].v), _mm_add_epi64(_mm_mul_epu32(r1, r[6].v), _mm_add_epi64(_mm_mul_epu32(r2, r[5].v), _mm_mul_epu32(r3, r[4].v)))); + r7_2 = _mm_slli_epi32(r[7].v, 1); + out[8].v = _mm_add_epi64(_mm_mul_epu32(r0, r[8].v), _mm_add_epi64(_mm_mul_epu32(r1, r7_2 ), _mm_add_epi64(_mm_mul_epu32(r2, r[6].v), _mm_add_epi64(_mm_mul_epu32(r3, r5_2 ), _mm_mul_epu32(r[4].v, r[4].v))))); + out[9].v = _mm_add_epi64(_mm_mul_epu32(r0, r[9].v), _mm_add_epi64(_mm_mul_epu32(r1, r[8].v), _mm_add_epi64(_mm_mul_epu32(r2, r[7].v), _mm_add_epi64(_mm_mul_epu32(r3, r[6].v), _mm_mul_epu32(r[4].v, r5_2 ))))); + + d5 = _mm_mul_epu32(r[5].v, packedthirtyeight.v); + d6 = _mm_mul_epu32(r[6].v, packednineteen.v); + d7 = _mm_mul_epu32(r[7].v, packedthirtyeight.v); + d8 = _mm_mul_epu32(r[8].v, packednineteen.v); + d9 = _mm_mul_epu32(r[9].v, packedthirtyeight.v); + + r4_2 = _mm_slli_epi32(r[4].v, 1); + r6_2 = _mm_slli_epi32(r[6].v, 1); + out[0].v = _mm_add_epi64(out[0].v, _mm_add_epi64(_mm_mul_epu32(d9, r1 ), _mm_add_epi64(_mm_mul_epu32(d8, r2 ), _mm_add_epi64(_mm_mul_epu32(d7, r3 ), _mm_add_epi64(_mm_mul_epu32(d6, r4_2), _mm_mul_epu32(d5, r[5].v)))))); + out[1].v = _mm_add_epi64(out[1].v, _mm_add_epi64(_mm_mul_epu32(d9, _mm_srli_epi32(r2, 1)), _mm_add_epi64(_mm_mul_epu32(d8, r3 ), _mm_add_epi64(_mm_mul_epu32(d7, r[4].v), _mm_mul_epu32(d6, r5_2 ))))); + out[2].v = _mm_add_epi64(out[2].v, _mm_add_epi64(_mm_mul_epu32(d9, r3 ), _mm_add_epi64(_mm_mul_epu32(d8, r4_2), _mm_add_epi64(_mm_mul_epu32(d7, r5_2 ), _mm_mul_epu32(d6, r[6].v))))); + out[3].v = _mm_add_epi64(out[3].v, _mm_add_epi64(_mm_mul_epu32(d9, r[4].v ), _mm_add_epi64(_mm_mul_epu32(d8, r5_2), _mm_mul_epu32(d7, r[6].v)))); + out[4].v = _mm_add_epi64(out[4].v, _mm_add_epi64(_mm_mul_epu32(d9, r5_2 ), _mm_add_epi64(_mm_mul_epu32(d8, r6_2), _mm_mul_epu32(d7, r[7].v)))); + out[5].v = _mm_add_epi64(out[5].v, _mm_add_epi64(_mm_mul_epu32(d9, r[6].v ), _mm_mul_epu32(d8, r7_2 ))); + out[6].v = _mm_add_epi64(out[6].v, _mm_add_epi64(_mm_mul_epu32(d9, r7_2 ), _mm_mul_epu32(d8, r[8].v))); + out[7].v = _mm_add_epi64(out[7].v, _mm_mul_epu32(d9, r[8].v)); + out[8].v = _mm_add_epi64(out[8].v, _mm_mul_epu32(d9, r[9].v)); + + c1 = _mm_srli_epi64(out[0].v, 26); c2 = _mm_srli_epi64(out[4].v, 26); out[0].v = _mm_and_si128(out[0].v, packedmask26.v); out[4].v = _mm_and_si128(out[4].v, packedmask26.v); out[1].v = _mm_add_epi64(out[1].v, c1); out[5].v = _mm_add_epi64(out[5].v, c2); + c1 = _mm_srli_epi64(out[1].v, 25); c2 = _mm_srli_epi64(out[5].v, 25); out[1].v = _mm_and_si128(out[1].v, packedmask25.v); out[5].v = _mm_and_si128(out[5].v, packedmask25.v); out[2].v = _mm_add_epi64(out[2].v, c1); out[6].v = _mm_add_epi64(out[6].v, c2); + c1 = _mm_srli_epi64(out[2].v, 26); c2 = _mm_srli_epi64(out[6].v, 26); out[2].v = _mm_and_si128(out[2].v, packedmask26.v); out[6].v = _mm_and_si128(out[6].v, packedmask26.v); out[3].v = _mm_add_epi64(out[3].v, c1); out[7].v = _mm_add_epi64(out[7].v, c2); + c1 = _mm_srli_epi64(out[3].v, 25); c2 = _mm_srli_epi64(out[7].v, 25); out[3].v = _mm_and_si128(out[3].v, packedmask25.v); out[7].v = _mm_and_si128(out[7].v, packedmask25.v); out[4].v = _mm_add_epi64(out[4].v, c1); out[8].v = _mm_add_epi64(out[8].v, c2); + c2 = _mm_srli_epi64(out[8].v, 26); out[8].v = _mm_and_si128(out[8].v, packedmask26.v); out[9].v = _mm_add_epi64(out[9].v, c2); + c2 = _mm_srli_epi64(out[9].v, 25); out[9].v = _mm_and_si128(out[9].v, packedmask25.v); out[0].v = _mm_add_epi64(out[0].v, _mm_mul_epu32(c2, packednineteen.v)); + c1 = _mm_srli_epi64(out[0].v, 26); c2 = _mm_srli_epi64(out[4].v, 26); out[0].v = _mm_and_si128(out[0].v, packedmask26.v); out[4].v = _mm_and_si128(out[4].v, packedmask26.v); out[1].v = _mm_add_epi64(out[1].v, c1); out[5].v = _mm_add_epi64(out[5].v, c2); +} + +/* make [nqx+nqz,nqpqx+nqpqz], [nqpqx-nqpqz,nqx-nqz] from [nqx+nqz,nqpqx+nqpqz], [nqx-nqz,nqpqx-nqpqz] */ +inline void +curve25519_make_nqpq(packedelem64 *primex, packedelem64 *primez, const packedelem32 *pqx, const packedelem32 *pqz) { + primex[0].v = _mm_shuffle_epi32(pqx[0].v, _MM_SHUFFLE(1,1,0,0)); + primex[1].v = _mm_shuffle_epi32(pqx[0].v, _MM_SHUFFLE(3,3,2,2)); + primex[2].v = _mm_shuffle_epi32(pqx[1].v, _MM_SHUFFLE(1,1,0,0)); + primex[3].v = _mm_shuffle_epi32(pqx[1].v, _MM_SHUFFLE(3,3,2,2)); + primex[4].v = _mm_shuffle_epi32(pqx[2].v, _MM_SHUFFLE(1,1,0,0)); + primex[5].v = _mm_shuffle_epi32(pqx[2].v, _MM_SHUFFLE(3,3,2,2)); + primex[6].v = _mm_shuffle_epi32(pqx[3].v, _MM_SHUFFLE(1,1,0,0)); + primex[7].v = _mm_shuffle_epi32(pqx[3].v, _MM_SHUFFLE(3,3,2,2)); + primex[8].v = _mm_shuffle_epi32(pqx[4].v, _MM_SHUFFLE(1,1,0,0)); + primex[9].v = _mm_shuffle_epi32(pqx[4].v, _MM_SHUFFLE(3,3,2,2)); + primez[0].v = _mm_shuffle_epi32(pqz[0].v, _MM_SHUFFLE(0,0,1,1)); + primez[1].v = _mm_shuffle_epi32(pqz[0].v, _MM_SHUFFLE(2,2,3,3)); + primez[2].v = _mm_shuffle_epi32(pqz[1].v, _MM_SHUFFLE(0,0,1,1)); + primez[3].v = _mm_shuffle_epi32(pqz[1].v, _MM_SHUFFLE(2,2,3,3)); + primez[4].v = _mm_shuffle_epi32(pqz[2].v, _MM_SHUFFLE(0,0,1,1)); + primez[5].v = _mm_shuffle_epi32(pqz[2].v, _MM_SHUFFLE(2,2,3,3)); + primez[6].v = _mm_shuffle_epi32(pqz[3].v, _MM_SHUFFLE(0,0,1,1)); + primez[7].v = _mm_shuffle_epi32(pqz[3].v, _MM_SHUFFLE(2,2,3,3)); + primez[8].v = _mm_shuffle_epi32(pqz[4].v, _MM_SHUFFLE(0,0,1,1)); + primez[9].v = _mm_shuffle_epi32(pqz[4].v, _MM_SHUFFLE(2,2,3,3)); +} + +/* make [nqx+nqz,nqx-nqz] from [nqx+nqz,nqpqx+nqpqz], [nqx-nqz,nqpqx-nqpqz] */ +inline void +curve25519_make_nq(packedelem64 *nq, const packedelem32 *pqx, const packedelem32 *pqz) { + nq[0].v = _mm_unpacklo_epi64(pqx[0].v, pqz[0].v); + nq[1].v = _mm_unpackhi_epi64(pqx[0].v, pqz[0].v); + nq[2].v = _mm_unpacklo_epi64(pqx[1].v, pqz[1].v); + nq[3].v = _mm_unpackhi_epi64(pqx[1].v, pqz[1].v); + nq[4].v = _mm_unpacklo_epi64(pqx[2].v, pqz[2].v); + nq[5].v = _mm_unpackhi_epi64(pqx[2].v, pqz[2].v); + nq[6].v = _mm_unpacklo_epi64(pqx[3].v, pqz[3].v); + nq[7].v = _mm_unpackhi_epi64(pqx[3].v, pqz[3].v); + nq[8].v = _mm_unpacklo_epi64(pqx[4].v, pqz[4].v); + nq[9].v = _mm_unpackhi_epi64(pqx[4].v, pqz[4].v); +} + +/* compute [nqx+nqz,nqx-nqz] from nqx, nqz */ +inline void +curve25519_compute_nq(packedelem64 *nq, const bignum25519 nqx, const bignum25519 nqz) { + xmmi x0,x1,x2; + xmmi z0,z1,z2; + xmmi a0,a1,a2; + xmmi s0,s1,s2; + xmmi r0,r1; + xmmi c1,c2; + x0 = _mm_load_si128((xmmi*)nqx + 0); + x1 = _mm_load_si128((xmmi*)nqx + 1); + x2 = _mm_load_si128((xmmi*)nqx + 2); + z0 = _mm_load_si128((xmmi*)nqz + 0); + z1 = _mm_load_si128((xmmi*)nqz + 1); + z2 = _mm_load_si128((xmmi*)nqz + 2); + a0 = _mm_add_epi32(x0, z0); + a1 = _mm_add_epi32(x1, z1); + a2 = _mm_add_epi32(x2, z2); + s0 = _mm_add_epi32(x0, packed2p0.v); + s1 = _mm_add_epi32(x1, packed2p1.v); + s2 = _mm_add_epi32(x2, packed2p2.v); + s0 = _mm_sub_epi32(s0, z0); + s1 = _mm_sub_epi32(s1, z1); + s2 = _mm_sub_epi32(s2, z2); + r0 = _mm_and_si128(_mm_shuffle_epi32(s0, _MM_SHUFFLE(2,2,0,0)), sse2_bot32bitmask.v); + r1 = _mm_and_si128(_mm_shuffle_epi32(s0, _MM_SHUFFLE(3,3,1,1)), sse2_bot32bitmask.v); + c1 = _mm_srli_epi32(r0, 26); + c2 = _mm_srli_epi32(r1, 25); + r0 = _mm_and_si128(r0, packedmask26.v); + r1 = _mm_and_si128(r1, packedmask25.v); + r0 = _mm_add_epi32(r0, _mm_slli_si128(c2, 8)); + r1 = _mm_add_epi32(r1, c1); + s0 = _mm_unpacklo_epi64(_mm_unpacklo_epi32(r0, r1), _mm_unpackhi_epi32(r0, r1)); + s1 = _mm_add_epi32(s1, _mm_srli_si128(c2, 8)); + nq[0].v = _mm_unpacklo_epi64(a0, s0); + nq[2].v = _mm_unpackhi_epi64(a0, s0); + nq[4].v = _mm_unpacklo_epi64(a1, s1); + nq[6].v = _mm_unpackhi_epi64(a1, s1); + nq[8].v = _mm_unpacklo_epi64(a2, s2); + nq[1].v = _mm_shuffle_epi32(nq[0].v, _MM_SHUFFLE(3,3,1,1)); + nq[3].v = _mm_shuffle_epi32(nq[2].v, _MM_SHUFFLE(3,3,1,1)); + nq[5].v = _mm_shuffle_epi32(nq[4].v, _MM_SHUFFLE(3,3,1,1)); + nq[7].v = _mm_shuffle_epi32(nq[6].v, _MM_SHUFFLE(3,3,1,1)); + nq[9].v = _mm_shuffle_epi32(nq[8].v, _MM_SHUFFLE(3,3,1,1)); +} + + +/* compute [x+z,x-z] from [x,z] */ +inline void +curve25519_addsub_packed64(packedelem64 *r) { + packed32bignum25519 x,z,add,sub; + + x[0].v = _mm_unpacklo_epi64(r[0].v, r[1].v); + z[0].v = _mm_unpackhi_epi64(r[0].v, r[1].v); + x[1].v = _mm_unpacklo_epi64(r[2].v, r[3].v); + z[1].v = _mm_unpackhi_epi64(r[2].v, r[3].v); + x[2].v = _mm_unpacklo_epi64(r[4].v, r[5].v); + z[2].v = _mm_unpackhi_epi64(r[4].v, r[5].v); + x[3].v = _mm_unpacklo_epi64(r[6].v, r[7].v); + z[3].v = _mm_unpackhi_epi64(r[6].v, r[7].v); + x[4].v = _mm_unpacklo_epi64(r[8].v, r[9].v); + z[4].v = _mm_unpackhi_epi64(r[8].v, r[9].v); + + curve25519_add_packed32(add, x, z); + curve25519_sub_packed32(sub, x, z); + + r[0].v = _mm_unpacklo_epi64(add[0].v, sub[0].v); + r[1].v = _mm_unpackhi_epi64(add[0].v, sub[0].v); + r[2].v = _mm_unpacklo_epi64(add[1].v, sub[1].v); + r[3].v = _mm_unpackhi_epi64(add[1].v, sub[1].v); + r[4].v = _mm_unpacklo_epi64(add[2].v, sub[2].v); + r[5].v = _mm_unpackhi_epi64(add[2].v, sub[2].v); + r[6].v = _mm_unpacklo_epi64(add[3].v, sub[3].v); + r[7].v = _mm_unpackhi_epi64(add[3].v, sub[3].v); + r[8].v = _mm_unpacklo_epi64(add[4].v, sub[4].v); + r[9].v = _mm_unpackhi_epi64(add[4].v, sub[4].v); +} + +/* compute [x,z] * [121666,121665] */ +inline void +curve25519_121665_packed64(packedelem64 *out, const packedelem64 *in) { + xmmi c1,c2; + + out[0].v = _mm_mul_epu32(in[0].v, packed121666121665.v); + out[1].v = _mm_mul_epu32(in[1].v, packed121666121665.v); + out[2].v = _mm_mul_epu32(in[2].v, packed121666121665.v); + out[3].v = _mm_mul_epu32(in[3].v, packed121666121665.v); + out[4].v = _mm_mul_epu32(in[4].v, packed121666121665.v); + out[5].v = _mm_mul_epu32(in[5].v, packed121666121665.v); + out[6].v = _mm_mul_epu32(in[6].v, packed121666121665.v); + out[7].v = _mm_mul_epu32(in[7].v, packed121666121665.v); + out[8].v = _mm_mul_epu32(in[8].v, packed121666121665.v); + out[9].v = _mm_mul_epu32(in[9].v, packed121666121665.v); + + c1 = _mm_srli_epi64(out[0].v, 26); c2 = _mm_srli_epi64(out[4].v, 26); out[0].v = _mm_and_si128(out[0].v, packedmask26.v); out[4].v = _mm_and_si128(out[4].v, packedmask26.v); out[1].v = _mm_add_epi64(out[1].v, c1); out[5].v = _mm_add_epi64(out[5].v, c2); + c1 = _mm_srli_epi64(out[1].v, 25); c2 = _mm_srli_epi64(out[5].v, 25); out[1].v = _mm_and_si128(out[1].v, packedmask25.v); out[5].v = _mm_and_si128(out[5].v, packedmask25.v); out[2].v = _mm_add_epi64(out[2].v, c1); out[6].v = _mm_add_epi64(out[6].v, c2); + c1 = _mm_srli_epi64(out[2].v, 26); c2 = _mm_srli_epi64(out[6].v, 26); out[2].v = _mm_and_si128(out[2].v, packedmask26.v); out[6].v = _mm_and_si128(out[6].v, packedmask26.v); out[3].v = _mm_add_epi64(out[3].v, c1); out[7].v = _mm_add_epi64(out[7].v, c2); + c1 = _mm_srli_epi64(out[3].v, 25); c2 = _mm_srli_epi64(out[7].v, 25); out[3].v = _mm_and_si128(out[3].v, packedmask25.v); out[7].v = _mm_and_si128(out[7].v, packedmask25.v); out[4].v = _mm_add_epi64(out[4].v, c1); out[8].v = _mm_add_epi64(out[8].v, c2); + c2 = _mm_srli_epi64(out[8].v, 26); out[8].v = _mm_and_si128(out[8].v, packedmask26.v); out[9].v = _mm_add_epi64(out[9].v, c2); + c2 = _mm_srli_epi64(out[9].v, 25); out[9].v = _mm_and_si128(out[9].v, packedmask25.v); out[0].v = _mm_add_epi64(out[0].v, _mm_mul_epu32(c2, packednineteen.v)); + c1 = _mm_srli_epi64(out[0].v, 26); c2 = _mm_srli_epi64(out[4].v, 26); out[0].v = _mm_and_si128(out[0].v, packedmask26.v); out[4].v = _mm_and_si128(out[4].v, packedmask26.v); out[1].v = _mm_add_epi64(out[1].v, c1); out[5].v = _mm_add_epi64(out[5].v, c2); +} + +/* compute [sq.x,sqscalar.x-sqscalar.z] * [sq.z,sq.x-sq.z] */ +inline void +curve25519_final_nq(packedelem64 *nq, const packedelem64 *sq, const packedelem64 *sq121665) { + packed32bignum25519 x, z, sub; + packed64bignum25519 t, nqa, nqb; + + x[0].v = _mm_or_si128(_mm_unpacklo_epi64(sq[0].v, sq[1].v), _mm_slli_si128(_mm_unpacklo_epi64(sq121665[0].v, sq121665[1].v), 4)); + z[0].v = _mm_or_si128(_mm_unpackhi_epi64(sq[0].v, sq[1].v), _mm_slli_si128(_mm_unpackhi_epi64(sq121665[0].v, sq121665[1].v), 4)); + x[1].v = _mm_or_si128(_mm_unpacklo_epi64(sq[2].v, sq[3].v), _mm_slli_si128(_mm_unpacklo_epi64(sq121665[2].v, sq121665[3].v), 4)); + z[1].v = _mm_or_si128(_mm_unpackhi_epi64(sq[2].v, sq[3].v), _mm_slli_si128(_mm_unpackhi_epi64(sq121665[2].v, sq121665[3].v), 4)); + x[2].v = _mm_or_si128(_mm_unpacklo_epi64(sq[4].v, sq[5].v), _mm_slli_si128(_mm_unpacklo_epi64(sq121665[4].v, sq121665[5].v), 4)); + z[2].v = _mm_or_si128(_mm_unpackhi_epi64(sq[4].v, sq[5].v), _mm_slli_si128(_mm_unpackhi_epi64(sq121665[4].v, sq121665[5].v), 4)); + x[3].v = _mm_or_si128(_mm_unpacklo_epi64(sq[6].v, sq[7].v), _mm_slli_si128(_mm_unpacklo_epi64(sq121665[6].v, sq121665[7].v), 4)); + z[3].v = _mm_or_si128(_mm_unpackhi_epi64(sq[6].v, sq[7].v), _mm_slli_si128(_mm_unpackhi_epi64(sq121665[6].v, sq121665[7].v), 4)); + x[4].v = _mm_or_si128(_mm_unpacklo_epi64(sq[8].v, sq[9].v), _mm_slli_si128(_mm_unpacklo_epi64(sq121665[8].v, sq121665[9].v), 4)); + z[4].v = _mm_or_si128(_mm_unpackhi_epi64(sq[8].v, sq[9].v), _mm_slli_si128(_mm_unpackhi_epi64(sq121665[8].v, sq121665[9].v), 4)); + + curve25519_sub_packed32(sub, x, z); + + t[0].v = _mm_shuffle_epi32(sub[0].v, _MM_SHUFFLE(1,1,0,0)); + t[1].v = _mm_shuffle_epi32(sub[0].v, _MM_SHUFFLE(3,3,2,2)); + t[2].v = _mm_shuffle_epi32(sub[1].v, _MM_SHUFFLE(1,1,0,0)); + t[3].v = _mm_shuffle_epi32(sub[1].v, _MM_SHUFFLE(3,3,2,2)); + t[4].v = _mm_shuffle_epi32(sub[2].v, _MM_SHUFFLE(1,1,0,0)); + t[5].v = _mm_shuffle_epi32(sub[2].v, _MM_SHUFFLE(3,3,2,2)); + t[6].v = _mm_shuffle_epi32(sub[3].v, _MM_SHUFFLE(1,1,0,0)); + t[7].v = _mm_shuffle_epi32(sub[3].v, _MM_SHUFFLE(3,3,2,2)); + t[8].v = _mm_shuffle_epi32(sub[4].v, _MM_SHUFFLE(1,1,0,0)); + t[9].v = _mm_shuffle_epi32(sub[4].v, _MM_SHUFFLE(3,3,2,2)); + + nqa[0].v = _mm_unpacklo_epi64(sq[0].v, t[0].v); + nqb[0].v = _mm_unpackhi_epi64(sq[0].v, t[0].v); + nqa[1].v = _mm_unpacklo_epi64(sq[1].v, t[1].v); + nqb[1].v = _mm_unpackhi_epi64(sq[1].v, t[1].v); + nqa[2].v = _mm_unpacklo_epi64(sq[2].v, t[2].v); + nqb[2].v = _mm_unpackhi_epi64(sq[2].v, t[2].v); + nqa[3].v = _mm_unpacklo_epi64(sq[3].v, t[3].v); + nqb[3].v = _mm_unpackhi_epi64(sq[3].v, t[3].v); + nqa[4].v = _mm_unpacklo_epi64(sq[4].v, t[4].v); + nqb[4].v = _mm_unpackhi_epi64(sq[4].v, t[4].v); + nqa[5].v = _mm_unpacklo_epi64(sq[5].v, t[5].v); + nqb[5].v = _mm_unpackhi_epi64(sq[5].v, t[5].v); + nqa[6].v = _mm_unpacklo_epi64(sq[6].v, t[6].v); + nqb[6].v = _mm_unpackhi_epi64(sq[6].v, t[6].v); + nqa[7].v = _mm_unpacklo_epi64(sq[7].v, t[7].v); + nqb[7].v = _mm_unpackhi_epi64(sq[7].v, t[7].v); + nqa[8].v = _mm_unpacklo_epi64(sq[8].v, t[8].v); + nqb[8].v = _mm_unpackhi_epi64(sq[8].v, t[8].v); + nqa[9].v = _mm_unpacklo_epi64(sq[9].v, t[9].v); + nqb[9].v = _mm_unpackhi_epi64(sq[9].v, t[9].v); + + curve25519_mul_packed64(nq, nqa, nqb); +} + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void +curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + ALIGN(16) bignum25519 t0,c; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void +curve25519_recip(bignum25519 out, const bignum25519 z) { + ALIGN(16) bignum25519 a, t0, b; + + /* 2 */ curve25519_square(a, z); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square(t0, a); + /* 2^5 - 2^0 = 31 */ curve25519_mul(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul(out, b, a); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) + +int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]) +{ + FixedSizeSecBlock e; + for (size_t i = 0;i < 32;++i) + e[i] = secretKey[i]; + e[0] &= 0xf8; e[31] &= 0x7f; e[31] |= 0x40; + + ALIGN(16) bignum25519 nqx = {1}, nqpqz = {1}, nqz = {0}, nqpqx, zmone; + packed32bignum25519 qx, qz, pqz, pqx; + packed64bignum25519 nq, sq, sqscalar, prime, primex, primez, nqpq; + bignum25519mulprecomp preq; + size_t bit=0; + + curve25519_expand(nqpqx, othersKey); + curve25519_mul_precompute(&preq, nqpqx); + + /* do bits 254..3 */ + for (size_t i = 254, lastbit=0; i >= 3; i--) { + bit = (e[i/8] >> (i & 7)) & 1; + curve25519_swap_conditional(nqx, nqpqx, (word32)(bit ^ lastbit)); + curve25519_swap_conditional(nqz, nqpqz, (word32)(bit ^ lastbit)); + lastbit = bit; + + curve25519_tangle32(qx, nqx, nqpqx); /* qx = [nqx,nqpqx] */ + curve25519_tangle32(qz, nqz, nqpqz); /* qz = [nqz,nqpqz] */ + + curve25519_add_packed32(pqx, qx, qz); /* pqx = [nqx+nqz,nqpqx+nqpqz] */ + curve25519_sub_packed32(pqz, qx, qz); /* pqz = [nqx-nqz,nqpqx-nqpqz] */ + + curve25519_make_nqpq(primex, primez, pqx, pqz); /* primex = [nqx+nqz,nqpqx+nqpqz], primez = [nqpqx-nqpqz,nqx-nqz] */ + curve25519_mul_packed64(prime, primex, primez); /* prime = [nqx+nqz,nqpqx+nqpqz] * [nqpqx-nqpqz,nqx-nqz] */ + curve25519_addsub_packed64(prime); /* prime = [prime.x+prime.z,prime.x-prime.z] */ + curve25519_square_packed64(nqpq, prime); /* nqpq = prime^2 */ + curve25519_untangle64(nqpqx, nqpqz, nqpq); + curve25519_mul_precomputed(nqpqz, nqpqz, &preq); /* nqpqz = nqpqz * q */ + + /* (((sq.x-sq.z)*121665)+sq.x) * (sq.x-sq.z) is equivalent to (sq.x*121666-sq.z*121665) * (sq.x-sq.z) */ + curve25519_make_nq(nq, pqx, pqz); /* nq = [nqx+nqz,nqx-nqz] */ + curve25519_square_packed64(sq, nq); /* sq = nq^2 */ + curve25519_121665_packed64(sqscalar, sq); /* sqscalar = sq * [121666,121665] */ + curve25519_final_nq(nq, sq, sqscalar); /* nq = [sq.x,sqscalar.x-sqscalar.z] * [sq.z,sq.x-sq.z] */ + curve25519_untangle64(nqx, nqz, nq); + }; + + /* it's possible to get rid of this swap with the swap in the above loop + at the bottom instead of the top, but compilers seem to optimize better this way */ + curve25519_swap_conditional(nqx, nqpqx, (word32)bit); + curve25519_swap_conditional(nqz, nqpqz, (word32)bit); + + /* do bits 2..0 */ + for (size_t i = 0; i < 3; i++) { + curve25519_compute_nq(nq, nqx, nqz); + curve25519_square_packed64(sq, nq); /* sq = nq^2 */ + curve25519_121665_packed64(sqscalar, sq); /* sqscalar = sq * [121666,121665] */ + curve25519_final_nq(nq, sq, sqscalar); /* nq = [sq.x,sqscalar.x-sqscalar.z] * [sq.z,sq.x-sq.z] */ + curve25519_untangle64(nqx, nqz, nq); + } + + curve25519_recip(zmone, nqz); + curve25519_mul(nqz, nqx, zmone); + curve25519_contract(sharedKey, nqz); + + return 0; +} + +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_CURVE25519_SSE2 diff --git a/external/ours/library/crypto/src/shared/original/donna_sse.h b/external/ours/library/crypto/src/shared/original/donna_sse.h new file mode 100755 index 000000000..298a91417 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/donna_sse.h @@ -0,0 +1,86 @@ +// donna_sse.h - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// https://github.com/floodyberry/curve25519-donna and +// https://github.com/floodyberry/ed25519-donna. + +// This source file multiplexes two different repos using namespaces. This +// was a little easier from a project management standpoint. We only need +// two files per architecture at the expense of namespaces and bloat. + +#ifndef CRYPTOPP_DONNA_SSE_H +#define CRYPTOPP_DONNA_SSE_H +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + +#include "config.h" +#include + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Donna) +NAMESPACE_BEGIN(ArchSSE) + +using CryptoPP::byte; +using CryptoPP::word32; + +typedef __m128i xmmi; +#define ALIGN(n) CRYPTOPP_ALIGN_DATA(n) + +typedef union packedelem8_t { + byte u[16]; + xmmi v; +} packedelem8; + +typedef union packedelem32_t { + word32 u[4]; + xmmi v; +} packedelem32; + +typedef union packedelem64_t { + word64 u[2]; + xmmi v; +} packedelem64; + +/* 10 elements + an extra 2 to fit in 3 xmm registers */ +typedef word32 bignum25519[12]; +typedef packedelem32 packed32bignum25519[5]; +typedef packedelem64 packed64bignum25519[10]; + +const word32 reduce_mask_26 = (1 << 26) - 1; +const word32 reduce_mask_25 = (1 << 25) - 1; + +const packedelem32 sse2_bot32bitmask = {{0xffffffff, 0x00000000, 0xffffffff, 0x00000000}}; +const packedelem32 sse2_top32bitmask = {{0x00000000, 0xffffffff, 0x00000000, 0xffffffff}}; +const packedelem32 sse2_top64bitmask = {{0x00000000, 0x00000000, 0xffffffff, 0xffffffff}}; +const packedelem32 sse2_bot64bitmask = {{0xffffffff, 0xffffffff, 0x00000000, 0x00000000}}; + +/* reduction masks */ +const packedelem64 packedmask26 = {{0x03ffffff, 0x03ffffff}}; +const packedelem64 packedmask25 = {{0x01ffffff, 0x01ffffff}}; +const packedelem32 packedmask2625 = {{0x3ffffff,0,0x1ffffff,0}}; +const packedelem32 packedmask26262626 = {{0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff}}; +const packedelem32 packedmask25252525 = {{0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff}}; + +/* multipliers */ +const packedelem64 packednineteen = {{19, 19}}; +const packedelem64 packednineteenone = {{19, 1}}; +const packedelem64 packedthirtyeight = {{38, 38}}; +const packedelem64 packed3819 = {{19*2,19}}; +const packedelem64 packed9638 = {{19*4,19*2}}; + +/* 121666,121665 */ +const packedelem64 packed121666121665 = {{121666, 121665}}; + +/* 2*(2^255 - 19) = 0 mod p */ +const packedelem32 packed2p0 = {{0x7ffffda,0x3fffffe,0x7fffffe,0x3fffffe}}; +const packedelem32 packed2p1 = {{0x7fffffe,0x3fffffe,0x7fffffe,0x3fffffe}}; +const packedelem32 packed2p2 = {{0x7fffffe,0x3fffffe,0x0000000,0x0000000}}; + +const packedelem32 packed32zeromodp0 = {{0x7ffffda,0x7ffffda,0x3fffffe,0x3fffffe}}; +const packedelem32 packed32zeromodp1 = {{0x7fffffe,0x7fffffe,0x3fffffe,0x3fffffe}}; + +NAMESPACE_END // ArchSSE +NAMESPACE_END // Donna +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_DOXYGEN_PROCESSING +#endif // CRYPTOPP_DONNA_SSE_H diff --git a/external/ours/library/crypto/src/shared/original/drbg.h b/external/ours/library/crypto/src/shared/original/drbg.h new file mode 100755 index 000000000..b56256def --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/drbg.h @@ -0,0 +1,718 @@ +// drbg.h - written and placed in public domain by Jeffrey Walton. + +/// \file drbg.h +/// \brief Classes for NIST DRBGs from SP 800-90A +/// \sa Recommendation +/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015) +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_NIST_DRBG_H +#define CRYPTOPP_NIST_DRBG_H + +#include "cryptlib.h" +#include "secblock.h" +#include "hmac.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Interface for NIST DRBGs from SP 800-90A +/// \details NIST_DRBG is the base class interface for NIST DRBGs from SP 800-90A Rev 1 (June 2015) +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa Recommendation +/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015) +/// \since Crypto++ 6.0 +class NIST_DRBG : public RandomNumberGenerator +{ +public: + /// \brief Exception thrown when a NIST DRBG encounters an error + class Err : public Exception + { + public: + explicit Err(const std::string &c, const std::string &m) + : Exception(OTHER_ERROR, c + ": " + m) {} + }; + +public: + virtual ~NIST_DRBG() {} + + /// \brief Determines if a generator can accept additional entropy + /// \return true + /// \details All NIST_DRBG return true + virtual bool CanIncorporateEntropy() const {return true;} + + /// \brief Update RNG state with additional unpredictable values + /// \param input the entropy to add to the generator + /// \param length the size of the input buffer + /// \throw NIST_DRBG::Err if the generator is reseeded with insufficient entropy + /// \details NIST instantiation and reseed requirements demand the generator is constructed + /// with at least MINIMUM_ENTROPY entropy. The byte array for input must + /// meet NIST SP 800-90B or + /// SP 800-90C requirements. + virtual void IncorporateEntropy(const byte *input, size_t length)=0; + + /// \brief Update RNG state with additional unpredictable values + /// \param entropy the entropy to add to the generator + /// \param entropyLength the size of the input buffer + /// \param additional additional input to add to the generator + /// \param additionaLength the size of the additional input buffer + /// \throw NIST_DRBG::Err if the generator is reseeded with insufficient entropy + /// \details IncorporateEntropy() is an overload provided to match NIST requirements. NIST + /// instantiation and reseed requirements demand the generator is constructed with at least + /// MINIMUM_ENTROPY entropy. The byte array for entropy must meet + /// NIST SP 800-90B or + ///! SP 800-90C requirements. + virtual void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0; + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + /// \throw NIST_DRBG::Err if a reseed is required + /// \throw NIST_DRBG::Err if the size exceeds MAXIMUM_BYTES_PER_REQUEST + virtual void GenerateBlock(byte *output, size_t size)=0; + + /// \brief Generate random array of bytes + /// \param additional additional input to add to the generator + /// \param additionaLength the size of the additional input buffer + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + /// \throw NIST_DRBG::Err if a reseed is required + /// \throw NIST_DRBG::Err if the size exceeds MAXIMUM_BYTES_PER_REQUEST + /// \details GenerateBlock() is an overload provided to match NIST requirements. The byte + /// array for additional input is optional. If present the additional randomness + /// is mixed before generating the output bytes. + virtual void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)=0; + + /// \brief Provides the security strength + /// \return The security strength of the generator, in bytes + /// \details The equivalent class constant is SECURITY_STRENGTH + virtual unsigned int SecurityStrength() const=0; + + /// \brief Provides the seed length + /// \return The seed size of the generator, in bytes + /// \details The equivalent class constant is SEED_LENGTH. The size is + /// used to maintain internal state of V and C. + virtual unsigned int SeedLength() const=0; + + /// \brief Provides the minimum entropy size + /// \return The minimum entropy size required by the generator, in bytes + /// \details The equivalent class constant is MINIMUM_ENTROPY. All NIST DRBGs must + /// be instaniated with at least MINIMUM_ENTROPY bytes of entropy. The bytes must + /// meet NIST SP 800-90B or + /// SP 800-90C requirements. + virtual unsigned int MinEntropyLength() const=0; + + /// \brief Provides the maximum entropy size + /// \return The maximum entropy size that can be consumed by the generator, in bytes + /// \details The equivalent class constant is MAXIMUM_ENTROPY. The bytes must + /// meet NIST SP 800-90B or + /// SP 800-90C requirements. MAXIMUM_ENTROPY has been reduced from + /// 235 to INT_MAX to fit the underlying C++ datatype. + virtual unsigned int MaxEntropyLength() const=0; + + /// \brief Provides the minimum nonce size + /// \return The minimum nonce size recommended for the generator, in bytes + /// \details The equivalent class constant is MINIMUM_NONCE. If a nonce is not + /// required then MINIMUM_NONCE is 0. Hash_DRBG does not require a + /// nonce, while HMAC_DRBG and CTR_DRBG require a nonce. + virtual unsigned int MinNonceLength() const=0; + + /// \brief Provides the maximum nonce size + /// \return The maximum nonce that can be consumed by the generator, in bytes + /// \details The equivalent class constant is MAXIMUM_NONCE. MAXIMUM_NONCE + /// has been reduced from 235 to INT_MAX to fit the underlying C++ datatype. + /// If a nonce is not required then MINIMUM_NONCE is 0. Hash_DRBG does not + /// require a nonce, while HMAC_DRBG and CTR_DRBG require a nonce. + virtual unsigned int MaxNonceLength() const=0; + + /// \brief Provides the maximum size of a request to GenerateBlock + /// \return The maximum size of a request to GenerateBlock(), in bytes + /// \details The equivalent class constant is MAXIMUM_BYTES_PER_REQUEST + virtual unsigned int MaxBytesPerRequest() const=0; + + /// \brief Provides the maximum number of requests before a reseed + /// \return The maximum number of requests before a reseed, in bytes + /// \details The equivalent class constant is MAXIMUM_REQUESTS_BEFORE_RESEED. + /// MAXIMUM_REQUESTS_BEFORE_RESEED has been reduced from 248 to INT_MAX + /// to fit the underlying C++ datatype. + virtual unsigned int MaxRequestBeforeReseed() const=0; + +protected: + virtual void DRBG_Instantiate(const byte* entropy, size_t entropyLength, + const byte* nonce, size_t nonceLength, const byte* personalization, size_t personalizationLength)=0; + + virtual void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0; +}; + +// ************************************************************* + +/// \tparam HASH NIST approved hash derived from HashTransformation +/// \tparam STRENGTH security strength, in bytes +/// \tparam SEEDLENGTH seed length, in bytes +/// \brief Hash_DRBG from SP 800-90A Rev 1 (June 2015) +/// \details The NIST Hash DRBG is instantiated with a number of parameters. Two of the parameters, +/// Security Strength and Seed Length, depend on the hash and are specified as template parameters. +/// The remaining parameters are included in the class. The parameters and their values are listed +/// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38). +/// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto +/// 248 requests before a reseed. However, Hash_DRBG limits it to INT_MAX due +/// to the limited data range of an int. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa Recommendation +/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015) +/// \since Crypto++ 6.0 +template +class Hash_DRBG : public NIST_DRBG, public NotCopyable +{ +public: + CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH); + CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH); + CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH); + CRYPTOPP_CONSTANT(MINIMUM_NONCE=0); + CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0); + CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0); + CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536); + CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX); + + static std::string StaticAlgorithmName() { return std::string("Hash_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); } + + /// \brief Construct a Hash DRBG + /// \param entropy the entropy to instantiate the generator + /// \param entropyLength the size of the entropy buffer + /// \param nonce additional input to instantiate the generator + /// \param nonceLength the size of the nonce buffer + /// \param personalization additional input to instantiate the generator + /// \param personalizationLength the size of the personalization buffer + /// \throw NIST_DRBG::Err if the generator is instantiated with insufficient entropy + /// \details All NIST DRBGs must be instaniated with at least MINIMUM_ENTROPY bytes of entropy. + /// The byte array for entropy must meet NIST + /// SP 800-90B or SP 800-90C requirements. + /// \details The nonce and personalization are optional byte arrays. If nonce is supplied, + /// then it should be at least MINIMUM_NONCE bytes of entropy. + /// \details An example of instantiating a SHA256 generator is shown below. + /// The example provides more entropy than required for SHA256. The NonblockingRng meets the + /// requirements of NIST SP 800-90B or SP 800-90C. + /// RDRAND() and RDSEED() generators would work as well. + ///
+    ///   SecByteBlock entropy(48), result(128);
+    ///   NonblockingRng prng;
+    ///   RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
+    ///
+    ///   Hash_DRBG drbg(entropy, 32, entropy+32, 16);
+    ///   drbg.GenerateBlock(result, result.size());
+    /// 
+ Hash_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR, + size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0) + : NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH), m_reseed(0) + { + if (m_c.data()) // GCC analyzer warning + std::memset(m_c.data(), 0x00, m_c.size()); + if (m_v.data()) // GCC analyzer warning + std::memset(m_v.data(), 0x00, m_v.size()); + + if (entropy != NULLPTR && entropyLength != 0) + DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength); + } + + unsigned int SecurityStrength() const {return SECURITY_STRENGTH;} + unsigned int SeedLength() const {return SEED_LENGTH;} + unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;} + unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;} + unsigned int MinNonceLength() const {return MINIMUM_NONCE;} + unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;} + unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;} + unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;} + + void IncorporateEntropy(const byte *input, size_t length) + {return DRBG_Reseed(input, length, NULLPTR, 0);} + + void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength) + {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);} + + void GenerateBlock(byte *output, size_t size) + {return Hash_Generate(NULLPTR, 0, output, size);} + + void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size) + {return Hash_Generate(additional, additionaLength, output, size);} + + std::string AlgorithmProvider() const + {/*Hack*/HASH hash; return hash.AlgorithmProvider();} + +protected: + // 10.1.1.2 Instantiation of Hash_DRBG (p.39) + void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength, + const byte* personalization, size_t personalizationLength); + + // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40) + void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength); + + // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41) + void Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size); + + // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49) + void Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, + const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen); + +private: + HASH m_hash; + SecByteBlock m_c, m_v, m_temp; + word64 m_reseed; +}; + +// typedef Hash_DRBG Hash_SHA1_DRBG; +// typedef Hash_DRBG Hash_SHA256_DRBG; +// typedef Hash_DRBG Hash_SHA384_DRBG; +// typedef Hash_DRBG Hash_SHA512_DRBG; + +// ************************************************************* + +/// \tparam HASH NIST approved hash derived from HashTransformation +/// \tparam STRENGTH security strength, in bytes +/// \tparam SEEDLENGTH seed length, in bytes +/// \brief HMAC_DRBG from SP 800-90A Rev 1 (June 2015) +/// \details The NIST HMAC DRBG is instantiated with a number of parameters. Two of the parameters, +/// Security Strength and Seed Length, depend on the hash and are specified as template parameters. +/// The remaining parameters are included in the class. The parameters and their values are listed +/// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38). +/// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto 248 requests +/// before a reseed. However, HMAC_DRBG limits it to INT_MAX due to the limited data range of an int. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa Recommendation +/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015) +/// \since Crypto++ 6.0 +template +class HMAC_DRBG : public NIST_DRBG, public NotCopyable +{ +public: + CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH); + CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH); + CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH); + CRYPTOPP_CONSTANT(MINIMUM_NONCE=0); + CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0); + CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0); + CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX); + CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536); + CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX); + + static std::string StaticAlgorithmName() { return std::string("HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); } + + /// \brief Construct a HMAC DRBG + /// \param entropy the entropy to instantiate the generator + /// \param entropyLength the size of the entropy buffer + /// \param nonce additional input to instantiate the generator + /// \param nonceLength the size of the nonce buffer + /// \param personalization additional input to instantiate the generator + /// \param personalizationLength the size of the personalization buffer + /// \throw NIST_DRBG::Err if the generator is instantiated with insufficient entropy + /// \details All NIST DRBGs must be instaniated with at least MINIMUM_ENTROPY bytes of entropy. + /// The byte array for entropy must meet NIST + /// SP 800-90B or SP 800-90C requirements. + /// \details The nonce and personalization are optional byte arrays. If nonce is supplied, + /// then it should be at least MINIMUM_NONCE bytes of entropy. + /// \details An example of instantiating a SHA256 generator is shown below. + /// The example provides more entropy than required for SHA256. The NonblockingRng meets the + /// requirements of NIST SP 800-90B or SP 800-90C. + /// RDRAND() and RDSEED() generators would work as well. + ///
+    ///   SecByteBlock entropy(48), result(128);
+    ///   NonblockingRng prng;
+    ///   RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
+    ///
+    ///   HMAC_DRBG drbg(entropy, 32, entropy+32, 16);
+    ///   drbg.GenerateBlock(result, result.size());
+    /// 
+ HMAC_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR, + size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0) + : NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0) + { + if (m_k.data()) // GCC analyzer warning + std::memset(m_k, 0x00, m_k.size()); + if (m_v.data()) // GCC analyzer warning + std::memset(m_v, 0x00, m_v.size()); + + if (entropy != NULLPTR && entropyLength != 0) + DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength); + } + + unsigned int SecurityStrength() const {return SECURITY_STRENGTH;} + unsigned int SeedLength() const {return SEED_LENGTH;} + unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;} + unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;} + unsigned int MinNonceLength() const {return MINIMUM_NONCE;} + unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;} + unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;} + unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;} + + void IncorporateEntropy(const byte *input, size_t length) + {return DRBG_Reseed(input, length, NULLPTR, 0);} + + void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength) + {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);} + + void GenerateBlock(byte *output, size_t size) + {return HMAC_Generate(NULLPTR, 0, output, size);} + + void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size) + {return HMAC_Generate(additional, additionaLength, output, size);} + + std::string AlgorithmProvider() const + {/*Hack*/HASH hash; return hash.AlgorithmProvider();} + +protected: + // 10.1.2.3 Instantiation of HMAC_DRBG (p.45) + void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength, + const byte* personalization, size_t personalizationLength); + + // 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46) + void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength); + + // 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46) + void HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size); + + // 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44) + void HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3); + +private: + HMAC m_hmac; + SecByteBlock m_k, m_v; + word64 m_reseed; +}; + +// typedef HMAC_DRBG HMAC_SHA1_DRBG; +// typedef HMAC_DRBG HMAC_SHA256_DRBG; +// typedef HMAC_DRBG HMAC_SHA384_DRBG; +// typedef HMAC_DRBG HMAC_SHA512_DRBG; + +// ************************************************************* + +// 10.1.1.2 Instantiation of Hash_DRBG (p.39) +template +void Hash_DRBG::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength, + const byte* personalization, size_t personalizationLength) +{ + // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security + // strength of the instantiation. Additional entropy may be provided in the nonce or the optional + // personalization string during instantiation, or in the additional input during reseeding and generation, + // but this is not required and does not increase the "official" security strength of the DRBG + // instantiation that is recorded in the internal state. + CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY); + if (entropyLength < MINIMUM_ENTROPY) + throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during instantiate"); + + // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce, + // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds. + CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY); + CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE); + CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION); + + const byte zero = 0; + SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH); + Hash_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULLPTR, 0, t1, t1.size()); + Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size()); + + m_v.swap(t1); m_c.swap(t2); + m_reseed = 1; +} + +// 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40) +template +void Hash_DRBG::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength) +{ + // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security + // strength of the instantiation. Additional entropy may be provided in the nonce or the optional + // personalization string during instantiation, or in the additional input during reseeding and generation, + // but this is not required and does not increase the "official" security strength of the DRBG + // instantiation that is recorded in the internal state.. + CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY); + if (entropyLength < MINIMUM_ENTROPY) + throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during reseed"); + + // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce, + // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds. + CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY); + CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL); + + const byte zero = 0, one = 1; + SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH); + Hash_Update(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size()); + Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size()); + + m_v.swap(t1); m_c.swap(t2); + m_reseed = 1; +} + +// 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41) +template +void Hash_DRBG::Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size) +{ + // Step 1 + if (static_cast(m_reseed) >= static_cast(MaxRequestBeforeReseed())) + throw NIST_DRBG::Err("Hash_DRBG", "Reseed required"); + + if (size > MaxBytesPerRequest()) + throw NIST_DRBG::Err("Hash_DRBG", "Request size exceeds limit"); + + // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce, + // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds. + CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL); + + // Step 2 + if (additional && additionaLength) + { + const byte two = 2; + m_temp.New(HASH::DIGESTSIZE); + + m_hash.Update(&two, 1); + m_hash.Update(m_v, m_v.size()); + m_hash.Update(additional, additionaLength); + m_hash.Final(m_temp); + + CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE); + int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1; + while (j>=0) + { + carry = m_v[i] + m_temp[j] + carry; + m_v[i] = static_cast(carry); + i--; j--; carry >>= 8; + } + while (i>=0) + { + carry = m_v[i] + carry; + m_v[i] = static_cast(carry); + i--; carry >>= 8; + } + } + + // Step 3 + { + m_temp.Assign(m_v); + while (size) + { + m_hash.Update(m_temp, m_temp.size()); + size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE); + m_hash.TruncatedFinal(output, count); + + IncrementCounterByOne(m_temp, static_cast(m_temp.size())); + size -= count; output += count; + } + } + + // Steps 4-7 + { + const byte three = 3; + m_temp.New(HASH::DIGESTSIZE); + + m_hash.Update(&three, 1); + m_hash.Update(m_v, m_v.size()); + m_hash.Final(m_temp); + + CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE); + CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed)); + int carry=0, k=sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1; + + while (k>=0) + { + carry = m_v[i] + m_c[i] + m_temp[j] + GetByte(BIG_ENDIAN_ORDER, m_reseed, k) + carry; + m_v[i] = static_cast(carry); + i--; j--; k--; carry >>= 8; + } + + while (j>=0) + { + carry = m_v[i] + m_c[i] + m_temp[j] + carry; + m_v[i] = static_cast(carry); + i--; j--; carry >>= 8; + } + + while (i>=0) + { + carry = m_v[i] + m_c[i] + carry; + m_v[i] = static_cast(carry); + i--; carry >>= 8; + } + } + + m_reseed++; +} + +// 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49) +template +void Hash_DRBG::Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, + const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen) +{ + byte counter = 1; + word32 bits = ConditionalByteReverse(BIG_ENDIAN_ORDER, static_cast(outlen*8)); + + while (outlen) + { + m_hash.Update(&counter, 1); + m_hash.Update(reinterpret_cast(&bits), 4); + + if (input1 && inlen1) + m_hash.Update(input1, inlen1); + if (input2 && inlen2) + m_hash.Update(input2, inlen2); + if (input3 && inlen3) + m_hash.Update(input3, inlen3); + if (input4 && inlen4) + m_hash.Update(input4, inlen4); + + size_t count = STDMIN(outlen, (size_t)HASH::DIGESTSIZE); + m_hash.TruncatedFinal(output, count); + + output += count; outlen -= count; + counter++; + } +} + +// ************************************************************* + +// 10.1.2.3 Instantiation of HMAC_DRBG (p.45) +template +void HMAC_DRBG::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength, + const byte* personalization, size_t personalizationLength) +{ + // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security + // strength of the instantiation. Additional entropy may be provided in the nonce or the optional + // personalization string during instantiation, or in the additional input during reseeding and generation, + // but this is not required and does not increase the "official" security strength of the DRBG + // instantiation that is recorded in the internal state. + CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY); + if (entropyLength < MINIMUM_ENTROPY) + throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during instantiate"); + + // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce, + // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds. + CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY); + CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE); + CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION); + + std::fill(m_k.begin(), m_k.begin()+m_k.size(), byte(0)); + std::fill(m_v.begin(), m_v.begin()+m_v.size(), byte(1)); + + HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength); + m_reseed = 1; +} + +// 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46) +template +void HMAC_DRBG::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength) +{ + // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security + // strength of the instantiation. Additional entropy may be provided in the nonce or the optional + // personalization string during instantiation, or in the additional input during reseeding and generation, + // but this is not required and does not increase the "official" security strength of the DRBG + // instantiation that is recorded in the internal state.. + CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY); + if (entropyLength < MINIMUM_ENTROPY) + throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during reseed"); + + // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce, + // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds. + CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY); + CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL); + + HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0); + m_reseed = 1; +} + +// 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46) +template +void HMAC_DRBG::HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size) +{ + // Step 1 + if (static_cast(m_reseed) >= static_cast(MaxRequestBeforeReseed())) + throw NIST_DRBG::Err("HMAC_DRBG", "Reseed required"); + + if (size > MaxBytesPerRequest()) + throw NIST_DRBG::Err("HMAC_DRBG", "Request size exceeds limit"); + + // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce, + // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds. + CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL); + + // Step 2 + if (additional && additionaLength) + HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0); + + // Step 3 + m_hmac.SetKey(m_k, m_k.size()); + + while (size) + { + m_hmac.Update(m_v, m_v.size()); + m_hmac.TruncatedFinal(m_v, m_v.size()); + + size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE); + memcpy(output, m_v, count); + size -= count; output += count; + } + + HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0); + m_reseed++; +} + +// 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44) +template +void HMAC_DRBG::HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3) +{ + const byte zero = 0, one = 1; + + // Step 1 + m_hmac.SetKey(m_k, m_k.size()); + m_hmac.Update(m_v, m_v.size()); + m_hmac.Update(&zero, 1); + + if (input1 && inlen1) + m_hmac.Update(input1, inlen1); + if (input2 && inlen2) + m_hmac.Update(input2, inlen2); + if (input3 && inlen3) + m_hmac.Update(input3, inlen3); + + m_hmac.TruncatedFinal(m_k, m_k.size()); + + // Step 2 + m_hmac.SetKey(m_k, m_k.size()); + m_hmac.Update(m_v, m_v.size()); + + m_hmac.TruncatedFinal(m_v, m_v.size()); + + // Step 3 + if ((inlen1 | inlen2 | inlen3) == 0) + return; + + // Step 4 + m_hmac.SetKey(m_k, m_k.size()); + m_hmac.Update(m_v, m_v.size()); + m_hmac.Update(&one, 1); + + if (input1 && inlen1) + m_hmac.Update(input1, inlen1); + if (input2 && inlen2) + m_hmac.Update(input2, inlen2); + if (input3 && inlen3) + m_hmac.Update(input3, inlen3); + + m_hmac.TruncatedFinal(m_k, m_k.size()); + + // Step 5 + m_hmac.SetKey(m_k, m_k.size()); + m_hmac.Update(m_v, m_v.size()); + + m_hmac.TruncatedFinal(m_v, m_v.size()); +} + +NAMESPACE_END + +#endif // CRYPTOPP_NIST_DRBG_H diff --git a/external/ours/library/crypto/src/shared/original/dsa.cpp b/external/ours/library/crypto/src/shared/original/dsa.cpp new file mode 100755 index 000000000..6bc187a91 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dsa.cpp @@ -0,0 +1,66 @@ +// dsa.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "dsa.h" +#include "asn.h" +#include "integer.h" +#include "filters.h" +#include "nbtheory.h" + +NAMESPACE_BEGIN(CryptoPP) + +size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat) +{ + Integer r, s; + StringStore store(signature, signatureLen); + ArraySink sink(buffer, bufferSize); + + switch (fromFormat) + { + case DSA_P1363: + r.Decode(store, signatureLen/2); + s.Decode(store, signatureLen/2); + break; + case DSA_DER: + { + BERSequenceDecoder seq(store); + r.BERDecode(seq); + s.BERDecode(seq); + seq.MessageEnd(); + break; + } + case DSA_OPENPGP: + r.OpenPGPDecode(store); + s.OpenPGPDecode(store); + break; + } + + switch (toFormat) + { + case DSA_P1363: + r.Encode(sink, bufferSize/2); + s.Encode(sink, bufferSize/2); + break; + case DSA_DER: + { + DERSequenceEncoder seq(sink); + r.DEREncode(seq); + s.DEREncode(seq); + seq.MessageEnd(); + break; + } + case DSA_OPENPGP: + r.OpenPGPEncode(sink); + s.OpenPGPEncode(sink); + break; + } + + return (size_t)sink.TotalPutLength(); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/dsa.h b/external/ours/library/crypto/src/shared/original/dsa.h new file mode 100755 index 000000000..01e5fecdf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/dsa.h @@ -0,0 +1,53 @@ +// dsa.h - originally written and placed in the public domain by Wei Dai + +/// \file dsa.h +/// \brief Classes for the DSA signature algorithm + +#ifndef CRYPTOPP_DSA_H +#define CRYPTOPP_DSA_H + +#include "cryptlib.h" +#include "gfpcrypt.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief DSA Signature Format +/// \details The DSA signature format used by Crypto++ is as defined by IEEE P1363. +/// OpenSSL, Java and .Net use the DER format, and OpenPGP uses the OpenPGP format. +/// \sa DSAConvertSignatureFormat +/// on the Crypto++ wiki. +/// \since Crypto++ 1.0 +enum DSASignatureFormat { + /// \brief Crypto++ native signature encoding format + DSA_P1363, + /// \brief signature encoding format used by OpenSSL, Java and .Net + DSA_DER, + /// \brief OpenPGP signature encoding format + DSA_OPENPGP +}; + +/// \brief Converts between signature encoding formats +/// \param buffer byte buffer for the converted signature encoding +/// \param bufferSize the length of the converted signature encoding buffer +/// \param toFormat the source signature format +/// \param signature byte buffer for the existing signature encoding +/// \param signatureLen the length of the existing signature encoding buffer +/// \param fromFormat the source signature format +/// \return the number of bytes written during encoding +/// \details This function converts between these formats, and returns length +/// of signature in the target format. If toFormat == DSA_P1363, then +/// bufferSize must equal publicKey.SignatureLength() or +/// verifier.SignatureLength(). +/// \details If the destination buffer is too small then the output of the +/// encoded r and s will be truncated. Be sure to provide +/// an adequately sized buffer and check the return value for the number of +/// bytes written. +/// \sa DSAConvertSignatureFormat +/// on the Crypto++ wiki. +/// \since Crypto++ 1.0 +size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, + const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat); + +NAMESPACE_END + +#endif // CRYPTOPP_DSA_H diff --git a/external/ours/library/crypto/src/shared/original/eax.cpp b/external/ours/library/crypto/src/shared/original/eax.cpp new file mode 100755 index 000000000..90b9d90b8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/eax.cpp @@ -0,0 +1,59 @@ +// eax.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "eax.h" + +NAMESPACE_BEGIN(CryptoPP) + +void EAX_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) +{ + AccessMAC().SetKey(userKey, keylength, params); + m_buffer.New(2*AccessMAC().TagSize()); +} + +void EAX_Base::Resync(const byte *iv, size_t len) +{ + MessageAuthenticationCode &mac = AccessMAC(); + unsigned int blockSize = mac.TagSize(); + + memset(m_buffer, 0, blockSize); + mac.Update(m_buffer, blockSize); + mac.CalculateDigest(m_buffer+blockSize, iv, len); + + m_buffer[blockSize-1] = 1; + mac.Update(m_buffer, blockSize); + + m_ctr.SetCipherWithIV(AccessMAC().AccessCipher(), m_buffer+blockSize, blockSize); +} + +size_t EAX_Base::AuthenticateBlocks(const byte *data, size_t len) +{ + AccessMAC().Update(data, len); + return 0; +} + +void EAX_Base::AuthenticateLastHeaderBlock() +{ + CRYPTOPP_ASSERT(m_bufferedDataLength == 0); + MessageAuthenticationCode &mac = AccessMAC(); + const unsigned int blockSize = mac.TagSize(); + + mac.Final(m_buffer); + xorbuf(m_buffer+blockSize, m_buffer, blockSize); + + memset(m_buffer, 0, blockSize); + m_buffer[blockSize-1] = 2; + mac.Update(m_buffer, blockSize); +} + +void EAX_Base::AuthenticateLastFooterBlock(byte *tag, size_t macSize) +{ + CRYPTOPP_ASSERT(m_bufferedDataLength == 0); + MessageAuthenticationCode &mac = AccessMAC(); + unsigned int blockSize = mac.TagSize(); + + mac.TruncatedFinal(m_buffer, macSize); + xorbuf(tag, m_buffer, m_buffer+blockSize, macSize); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/eax.h b/external/ours/library/crypto/src/shared/original/eax.h new file mode 100755 index 000000000..9d4edfaae --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/eax.h @@ -0,0 +1,112 @@ +// eax.h - originally written and placed in the public domain by Wei Dai + +/// \file eax.h +/// \brief EAX block cipher mode of operation + +#ifndef CRYPTOPP_EAX_H +#define CRYPTOPP_EAX_H + +#include "authenc.h" +#include "modes.h" +#include "cmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief EAX block cipher base implementation +/// \details Base implementation of the AuthenticatedSymmetricCipher interface +/// \since Crypto++ 5.6.0 +class CRYPTOPP_NO_VTABLE EAX_Base : public AuthenticatedSymmetricCipherBase +{ +public: + // AuthenticatedSymmetricCipher + std::string AlgorithmName() const + {return GetMAC().GetCipher().AlgorithmName() + std::string("/EAX");} + std::string AlgorithmProvider() const + {return GetMAC().GetCipher().AlgorithmProvider();} + size_t MinKeyLength() const + {return GetMAC().MinKeyLength();} + size_t MaxKeyLength() const + {return GetMAC().MaxKeyLength();} + size_t DefaultKeyLength() const + {return GetMAC().DefaultKeyLength();} + size_t GetValidKeyLength(size_t n) const + {return GetMAC().GetValidKeyLength(n);} + bool IsValidKeyLength(size_t n) const + {return GetMAC().IsValidKeyLength(n);} + unsigned int OptimalDataAlignment() const + {return GetMAC().OptimalDataAlignment();} + IV_Requirement IVRequirement() const + {return UNIQUE_IV;} + unsigned int IVSize() const + {return GetMAC().TagSize();} + unsigned int MinIVLength() const + {return 0;} + unsigned int MaxIVLength() const + {return UINT_MAX;} + unsigned int DigestSize() const + {return GetMAC().TagSize();} + lword MaxHeaderLength() const + {return LWORD_MAX;} + lword MaxMessageLength() const + {return LWORD_MAX;} + +protected: + // AuthenticatedSymmetricCipherBase + bool AuthenticationIsOnPlaintext() const + {return false;} + unsigned int AuthenticationBlockSize() const + {return 1;} + void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); + void Resync(const byte *iv, size_t len); + size_t AuthenticateBlocks(const byte *data, size_t len); + void AuthenticateLastHeaderBlock(); + void AuthenticateLastFooterBlock(byte *mac, size_t macSize); + SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} + const CMAC_Base & GetMAC() const {return const_cast(this)->AccessMAC();} + virtual CMAC_Base & AccessMAC() =0; + + CTR_Mode_ExternalCipher::Encryption m_ctr; +}; + +/// \brief EAX block cipher final implementation +/// \tparam T_BlockCipher block cipher +/// \tparam T_IsEncryption direction in which to operate the cipher +/// \since Crypto++ 5.6.0 +template +class EAX_Final : public EAX_Base +{ +public: + static std::string StaticAlgorithmName() + {return T_BlockCipher::StaticAlgorithmName() + std::string("/EAX");} + std::string AlgorithmProvider() const + {return m_cmac.AlgorithmProvider();} + bool IsForwardTransformation() const + {return T_IsEncryption;} + +private: + CMAC_Base & AccessMAC() {return m_cmac;} + CMAC m_cmac; +}; + +#ifdef EAX // EAX is defined to 11 on GCC 3.4.3, OpenSolaris 8.11 +#undef EAX +#endif + +/// \brief EAX block cipher mode of operation +/// \tparam T_BlockCipher block cipher +/// \details \p EAX provides the \p Encryption and \p Decryption typedef. See EAX_Base +/// and EAX_Final for the AuthenticatedSymmetricCipher implementation. +/// \sa EAX Mode and +/// Modes of Operation +/// on the Crypto++ wiki. +/// \since Crypto++ 5.6.0 +template +struct EAX : public AuthenticatedSymmetricCipherDocumentation +{ + typedef EAX_Final Encryption; + typedef EAX_Final Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ec2n.cpp b/external/ours/library/crypto/src/shared/original/ec2n.cpp new file mode 100755 index 000000000..87aed8532 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ec2n.cpp @@ -0,0 +1,320 @@ +// ec2n.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "ec2n.h" +#include "asn.h" +#include "integer.h" +#include "filters.h" +#include "algebra.cpp" +#include "eprecomp.cpp" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::EC2N; + +#if defined(HAVE_GCC_INIT_PRIORITY) + #define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51))) + const EC2N::Point g_identity INIT_ATTRIBUTE = EC2N::Point(); +#elif defined(HAVE_MSC_INIT_PRIORITY) + #pragma warning(disable: 4075) + #pragma init_seg(".CRT$XCU") + const EC2N::Point g_identity; + #pragma warning(default: 4075) +#elif defined(HAVE_XLC_INIT_PRIORITY) + #pragma priority(290) + const EC2N::Point g_identity; +#endif + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +EC2N::EC2N(BufferedTransformation &bt) + : m_field(BERDecodeGF2NP(bt)) +{ + BERSequenceDecoder seq(bt); + m_field->BERDecodeElement(seq, m_a); + m_field->BERDecodeElement(seq, m_b); + // skip optional seed + if (!seq.EndReached()) + { + SecByteBlock seed; + unsigned int unused; + BERDecodeBitString(seq, seed, unused); + } + seq.MessageEnd(); +} + +void EC2N::DEREncode(BufferedTransformation &bt) const +{ + m_field->DEREncode(bt); + DERSequenceEncoder seq(bt); + m_field->DEREncodeElement(seq, m_a); + m_field->DEREncodeElement(seq, m_b); + seq.MessageEnd(); +} + +bool EC2N::DecodePoint(EC2N::Point &P, const byte *encodedPoint, size_t encodedPointLen) const +{ + StringStore store(encodedPoint, encodedPointLen); + return DecodePoint(P, store, encodedPointLen); +} + +bool EC2N::DecodePoint(EC2N::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const +{ + byte type; + if (encodedPointLen < 1 || !bt.Get(type)) + return false; + + switch (type) + { + case 0: + P.identity = true; + return true; + case 2: + case 3: + { + if (encodedPointLen != EncodedPointSize(true)) + return false; + + P.identity = false; + P.x.Decode(bt, m_field->MaxElementByteLength()); + + if (P.x.IsZero()) + { + P.y = m_field->SquareRoot(m_b); + return true; + } + + FieldElement z = m_field->Square(P.x); + CRYPTOPP_ASSERT(P.x == m_field->SquareRoot(z)); + P.y = m_field->Divide(m_field->Add(m_field->Multiply(z, m_field->Add(P.x, m_a)), m_b), z); + CRYPTOPP_ASSERT(P.x == m_field->Subtract(m_field->Divide(m_field->Subtract(m_field->Multiply(P.y, z), m_b), z), m_a)); + z = m_field->SolveQuadraticEquation(P.y); + CRYPTOPP_ASSERT(m_field->Add(m_field->Square(z), z) == P.y); + z.SetCoefficient(0, type & 1); + + P.y = m_field->Multiply(z, P.x); + return true; + } + case 4: + { + if (encodedPointLen != EncodedPointSize(false)) + return false; + + unsigned int len = m_field->MaxElementByteLength(); + P.identity = false; + P.x.Decode(bt, len); + P.y.Decode(bt, len); + return true; + } + default: + return false; + } +} + +void EC2N::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + if (P.identity) + NullStore().TransferTo(bt, EncodedPointSize(compressed)); + else if (compressed) + { + bt.Put((byte)(2U + (!P.x ? 0U : m_field->Divide(P.y, P.x).GetBit(0)))); + P.x.Encode(bt, m_field->MaxElementByteLength()); + } + else + { + unsigned int len = m_field->MaxElementByteLength(); + bt.Put(4); // uncompressed + P.x.Encode(bt, len); + P.y.Encode(bt, len); + } +} + +void EC2N::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const +{ + ArraySink sink(encodedPoint, EncodedPointSize(compressed)); + EncodePoint(sink, P, compressed); + CRYPTOPP_ASSERT(sink.TotalPutLength() == EncodedPointSize(compressed)); +} + +EC2N::Point EC2N::BERDecodePoint(BufferedTransformation &bt) const +{ + SecByteBlock str; + BERDecodeOctetString(bt, str); + Point P; + if (!DecodePoint(P, str, str.size())) + BERDecodeError(); + return P; +} + +void EC2N::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + SecByteBlock str(EncodedPointSize(compressed)); + EncodePoint(str, P, compressed); + DEREncodeOctetString(bt, str); +} + +bool EC2N::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng); + bool pass = !!m_b; + pass = pass && m_a.CoefficientCount() <= m_field->MaxElementBitLength(); + pass = pass && m_b.CoefficientCount() <= m_field->MaxElementBitLength(); + + if (level >= 1) + pass = pass && m_field->GetModulus().IsIrreducible(); + + return pass; +} + +bool EC2N::VerifyPoint(const Point &P) const +{ + const FieldElement &x = P.x, &y = P.y; + return P.identity || + (x.CoefficientCount() <= m_field->MaxElementBitLength() + && y.CoefficientCount() <= m_field->MaxElementBitLength() + && !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field->GetModulus())); +} + +bool EC2N::Equal(const Point &P, const Point &Q) const +{ + if (P.identity && Q.identity) + return true; + + if (P.identity && !Q.identity) + return false; + + if (!P.identity && Q.identity) + return false; + + return (m_field->Equal(P.x,Q.x) && m_field->Equal(P.y,Q.y)); +} + +const EC2N::Point& EC2N::Identity() const +{ +#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) + return g_identity; +#elif defined(CRYPTOPP_CXX11_STATIC_INIT) + static const EC2N::Point g_identity; + return g_identity; +#else + return Singleton().Ref(); +#endif +} + +const EC2N::Point& EC2N::Inverse(const Point &P) const +{ + if (P.identity) + return P; + else + { + m_R.identity = false; + m_R.y = m_field->Add(P.x, P.y); + m_R.x = P.x; + return m_R; + } +} + +const EC2N::Point& EC2N::Add(const Point &P, const Point &Q) const +{ + if (P.identity) return Q; + if (Q.identity) return P; + if (Equal(P, Q)) return Double(P); + if (m_field->Equal(P.x, Q.x) && m_field->Equal(P.y, m_field->Add(Q.x, Q.y))) return Identity(); + + FieldElement t = m_field->Add(P.y, Q.y); + t = m_field->Divide(t, m_field->Add(P.x, Q.x)); + FieldElement x = m_field->Square(t); + m_field->Accumulate(x, t); + m_field->Accumulate(x, Q.x); + m_field->Accumulate(x, m_a); + m_R.y = m_field->Add(P.y, m_field->Multiply(t, x)); + m_field->Accumulate(x, P.x); + m_field->Accumulate(m_R.y, x); + + m_R.x.swap(x); + m_R.identity = false; + return m_R; +} + +const EC2N::Point& EC2N::Double(const Point &P) const +{ + if (P.identity) return P; + if (!m_field->IsUnit(P.x)) return Identity(); + + FieldElement t = m_field->Divide(P.y, P.x); + m_field->Accumulate(t, P.x); + m_R.y = m_field->Square(P.x); + m_R.x = m_field->Square(t); + m_field->Accumulate(m_R.x, t); + m_field->Accumulate(m_R.x, m_a); + m_field->Accumulate(m_R.y, m_field->Multiply(t, m_R.x)); + m_field->Accumulate(m_R.y, m_R.x); + + m_R.identity = false; + return m_R; +} + +// ******************************************************** + +#if 0 +EcPrecomputation& EcPrecomputation::operator=(const EcPrecomputation &rhs) +{ + m_ec = rhs.m_ec; + m_ep = rhs.m_ep; + m_ep.m_group = m_ec.get(); + return *this; +} + +void EcPrecomputation::SetCurveAndBase(const EC2N &ec, const EC2N::Point &base) +{ + m_ec.reset(new EC2N(ec)); + m_ep.SetGroupAndBase(*m_ec, base); +} + +void EcPrecomputation::Precompute(unsigned int maxExpBits, unsigned int storage) +{ + m_ep.Precompute(maxExpBits, storage); +} + +void EcPrecomputation::Load(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); + m_ep.m_exponentBase.BERDecode(seq); + m_ep.m_windowSize = m_ep.m_exponentBase.BitCount() - 1; + m_ep.m_bases.clear(); + while (!seq.EndReached()) + m_ep.m_bases.push_back(m_ec->BERDecodePoint(seq)); + seq.MessageEnd(); +} + +void EcPrecomputation::Save(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + DEREncodeUnsigned(seq, 1); // version + m_ep.m_exponentBase.DEREncode(seq); + for (unsigned i=0; iDEREncodePoint(seq, m_ep.m_bases[i]); + seq.MessageEnd(); +} + +EC2N::Point EcPrecomputation::Exponentiate(const Integer &exponent) const +{ + return m_ep.Exponentiate(exponent); +} + +EC2N::Point EcPrecomputation::CascadeExponentiate(const Integer &exponent, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const +{ + return m_ep.CascadeExponentiate(exponent, static_cast &>(pc2).m_ep, exponent2); +} +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ec2n.h b/external/ours/library/crypto/src/shared/original/ec2n.h new file mode 100755 index 000000000..1da178423 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ec2n.h @@ -0,0 +1,136 @@ +// ec2n.h - originally written and placed in the public domain by Wei Dai + +/// \file ec2n.h +/// \brief Classes for Elliptic Curves over binary fields + +#ifndef CRYPTOPP_EC2N_H +#define CRYPTOPP_EC2N_H + +#include "cryptlib.h" +#include "gf2n.h" +#include "integer.h" +#include "algebra.h" +#include "ecpoint.h" +#include "eprecomp.h" +#include "smartptr.h" +#include "pubkey.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Elliptic Curve over GF(2^n) +class CRYPTOPP_DLL EC2N : public AbstractGroup, public EncodedPoint +{ +public: + typedef GF2NP Field; + typedef Field::Element FieldElement; + typedef EC2NPoint Point; + + virtual ~EC2N() {} + + /// \brief Construct an EC2N + EC2N() {} + + /// \brief Construct an EC2N + /// \param field Field, GF2NP derived class + /// \param a Field::Element + /// \param b Field::Element + EC2N(const Field &field, const Field::Element &a, const Field::Element &b) + : m_field(field), m_a(a), m_b(b) {} + + /// \brief Construct an EC2N from BER encoded parameters + /// \param bt BufferedTransformation derived object + /// \details This constructor will decode and extract the fields fieldID and curve of the sequence ECParameters + EC2N(BufferedTransformation &bt); + + /// \brief Encode the fields fieldID and curve of the sequence ECParameters + /// \param bt BufferedTransformation derived object + void DEREncode(BufferedTransformation &bt) const; + + bool Equal(const Point &P, const Point &Q) const; + const Point& Identity() const; + const Point& Inverse(const Point &P) const; + bool InversionIsFast() const {return true;} + const Point& Add(const Point &P, const Point &Q) const; + const Point& Double(const Point &P) const; + + Point Multiply(const Integer &k, const Point &P) const + {return ScalarMultiply(P, k);} + Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const + {return CascadeScalarMultiply(P, k1, Q, k2);} + + bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const; + bool VerifyPoint(const Point &P) const; + + unsigned int EncodedPointSize(bool compressed = false) const + {return 1 + (compressed?1:2)*m_field->MaxElementByteLength();} + // returns false if point is compressed and not valid (doesn't check if uncompressed) + bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const; + bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const; + void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const; + void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Point BERDecodePoint(BufferedTransformation &bt) const; + void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Integer FieldSize() const {return Integer::Power2(m_field->MaxElementBitLength());} + const Field & GetField() const {return *m_field;} + const FieldElement & GetA() const {return m_a;} + const FieldElement & GetB() const {return m_b;} + + bool operator==(const EC2N &rhs) const + {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;} + +private: + clonable_ptr m_field; + FieldElement m_a, m_b; + mutable Point m_R; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation; + +/// \brief Elliptic Curve precomputation +/// \tparam EC elliptic curve field +template class EcPrecomputation; + +/// \brief EC2N precomputation specialization +/// \details Implementation of DL_GroupPrecomputation +/// \sa DL_GroupPrecomputation +template<> class EcPrecomputation : public DL_GroupPrecomputation +{ +public: + typedef EC2N EllipticCurve; + + virtual ~EcPrecomputation() {} + + // DL_GroupPrecomputation + const AbstractGroup & GetGroup() const {return m_ec;} + Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec.BERDecodePoint(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec.DEREncodePoint(bt, v, false);} + + /// \brief Set the elliptic curve + /// \param ec ECP derived class + /// \details SetCurve() is not inherited + void SetCurve(const EC2N &ec) {m_ec = ec;} + + /// \brief Get the elliptic curve + /// \return EC2N curve + /// \details GetCurve() is not inherited + const EC2N & GetCurve() const {return m_ec;} + +private: + EC2N m_ec; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/eccrypto.cpp b/external/ours/library/crypto/src/shared/original/eccrypto.cpp new file mode 100755 index 000000000..9a0914c03 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/eccrypto.cpp @@ -0,0 +1,840 @@ +// eccrypto.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4127 4189 4505) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#ifndef CRYPTOPP_IMPORTS + +#include "eccrypto.h" +#include "integer.h" +#include "nbtheory.h" +#include "filters.h" +#include "argnames.h" +#include "smartptr.h" +#include "oids.h" +#include "asn.h" +#include "hex.h" +#include "ec2n.h" +#include "misc.h" + +#include +#include + +// Squash MS LNK4221 and libtool warnings +#ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +extern const char ECCRYPTO_FNAME[] = __FILE__; +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if 0 +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +static void ECDSA_TestInstantiations() +{ + ECDSA::Signer t1; + ECDSA::Verifier t2(t1); + ECNR::Signer t3; + ECNR::Verifier t4(t3); + ECIES::Encryptor t5; + ECIES::Decryptor t6; + ECDH::Domain t7; + ECMQV::Domain t8; +} +#endif +#endif + +ANONYMOUS_NAMESPACE_BEGIN +inline Integer ConvertToInteger(const PolynomialMod2 &x) +{ + unsigned int l = x.ByteCount(); + SecByteBlock temp(l); + x.Encode(temp, l); + return Integer(temp, l); +} + +inline Integer ConvertToInteger(const Integer &x) +{ + return x; +} + +inline bool CheckMOVCondition(const Integer &q, const Integer &r) +{ + // see "Updated standards for validating elliptic curves", http://eprint.iacr.org/2007/343 + Integer t = 1; + unsigned int n = q.IsEven() ? 1 : q.BitCount(), m = r.BitCount(); + + for (unsigned int i=n; DiscreteLogWorkFactor(i) struct EcRecommendedParameters; + +template<> struct EcRecommendedParameters +{ + EcRecommendedParameters(const OID &oid, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h) + : oid(oid), a(a), b(b), g(g), n(n), h(h), t0(0), t1(0), t2(t2), t3(t3), t4(t4) {} + EcRecommendedParameters(const OID &oid, unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h) + : oid(oid), a(a), b(b), g(g), n(n), h(h), t0(t0), t1(t1), t2(t2), t3(t3), t4(t4) {} + EC2N *NewEC() const + { + StringSource ssA(a, true, new HexDecoder); + StringSource ssB(b, true, new HexDecoder); + if (t0 == 0) + { + if (t2 == 233 && t3 == 74 && t4 == 0) + return new EC2N(GF2NT233(233, 74, 0), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + else + return new EC2N(GF2NT(t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + } + else + return new EC2N(GF2NPP(t0, t1, t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + }; + + OID oid; + const char *a, *b, *g, *n; + unsigned int h, t0, t1, t2, t3, t4; +}; + +template<> struct EcRecommendedParameters +{ + EcRecommendedParameters(const OID &oid, const char *p, const char *a, const char *b, const char *g, const char *n, unsigned int h) + : oid(oid), p(p), a(a), b(b), g(g), n(n), h(h) {} + ECP *NewEC() const + { + StringSource ssP(p, true, new HexDecoder); + StringSource ssA(a, true, new HexDecoder); + StringSource ssB(b, true, new HexDecoder); + return new ECP(Integer(ssP, (size_t)ssP.MaxRetrievable()), ECP::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), ECP::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + }; + + OID oid; + const char *p, *a, *b, *g, *n; + unsigned int h; +}; + +struct OIDLessThan +{ + template + inline bool operator()(const EcRecommendedParameters& a, const OID& b) {return a.oid < b;} + template + inline bool operator()(const OID& a, const EcRecommendedParameters& b) {return a < b.oid;} + template + inline bool operator()(const EcRecommendedParameters& a, const EcRecommendedParameters& b) {return a.oid < b.oid;} +}; + +static void GetRecommendedParameters(const EcRecommendedParameters *&begin, const EcRecommendedParameters *&end) +{ + // this array must be sorted by OID + static const EcRecommendedParameters rec[] = { + EcRecommendedParameters(ASN1::sect163k1(), + 163, 7, 6, 3, 0, + "000000000000000000000000000000000000000001", + "000000000000000000000000000000000000000001", + "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9", + "04000000000000000000020108A2E0CC0D99F8A5EF", + 2), + EcRecommendedParameters(ASN1::sect163r1(), + 163, 7, 6, 3, 0, + "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", + "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", + "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883", + "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", + 2), + EcRecommendedParameters(ASN1::sect239k1(), + 239, 158, 0, + "000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000001", + "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", + "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", + 4), + EcRecommendedParameters(ASN1::sect113r1(), + 113, 9, 0, + "003088250CA6E7C7FE649CE85820F7", + "00E8BEE4D3E2260744188BE0E9C723", + "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886", + "0100000000000000D9CCEC8A39E56F", + 2), + EcRecommendedParameters(ASN1::sect113r2(), + 113, 9, 0, + "00689918DBEC7E5A0DD6DFC0AA55C7", + "0095E9A9EC9B297BD4BF36E059184F", + "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D", + "010000000000000108789B2496AF93", + 2), + EcRecommendedParameters(ASN1::sect163r2(), + 163, 7, 6, 3, 0, + "000000000000000000000000000000000000000001", + "020A601907B8C953CA1481EB10512F78744A3205FD", + "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", + "040000000000000000000292FE77E70C12A4234C33", + 2), + EcRecommendedParameters(ASN1::sect283k1(), + 283, 12, 7, 5, 0, + "000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000001", + "040503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC245849283601CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", + 4), + EcRecommendedParameters(ASN1::sect283r1(), + 283, 12, 7, 5, 0, + "000000000000000000000000000000000000000000000000000000000000000000000001", + "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", + "0405F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B1205303676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", + "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", + 2), + EcRecommendedParameters(ASN1::sect131r1(), + 131, 8, 3, 2, 0, + "07A11B09A76B562144418FF3FF8C2570B8", + "0217C05610884B63B9C6C7291678F9D341", + "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150", + "0400000000000000023123953A9464B54D", + 2), + EcRecommendedParameters(ASN1::sect131r2(), + 131, 8, 3, 2, 0, + "03E5A88919D7CAFCBF415F07C2176573B2", + "04B8266A46C55657AC734CE38F018F2192", + "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F", + "0400000000000000016954A233049BA98F", + 2), + EcRecommendedParameters(ASN1::sect193r1(), + 193, 15, 0, + "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", + "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", + "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", + "01000000000000000000000000C7F34A778F443ACC920EBA49", + 2), + EcRecommendedParameters(ASN1::sect193r2(), + 193, 15, 0, + "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", + "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", + "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", + "010000000000000000000000015AAB561B005413CCD4EE99D5", + 2), + EcRecommendedParameters(ASN1::sect233k1(), + 233, 74, 0, + "000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000001", + "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", + "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", + 4), + EcRecommendedParameters(ASN1::sect233r1(), + 233, 74, 0, + "000000000000000000000000000000000000000000000000000000000001", + "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", + "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", + "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", + 2), + EcRecommendedParameters(ASN1::sect409k1(), + 409, 87, 0, + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "040060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE902374601E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", + 4), + EcRecommendedParameters(ASN1::sect409r1(), + 409, 87, 0, + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", + "04015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A70061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", + "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", + 2), + EcRecommendedParameters(ASN1::sect571k1(), + 571, 10, 5, 2, 0, + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "04026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C89720349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", + "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", + 4), + EcRecommendedParameters(ASN1::sect571r1(), + 571, 10, 5, 2, 0, + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", + "040303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", + "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", + 2), + }; + begin = rec; + end = rec + sizeof(rec)/sizeof(rec[0]); +} + +// See https://www.cryptopp.com/wiki/SM2 for details on sm2p256v1 and sm2encrypt_recommendedParameters +static void GetRecommendedParameters(const EcRecommendedParameters *&begin, const EcRecommendedParameters *&end) +{ + // this array must be sorted by OID + static const EcRecommendedParameters rec[] = { + EcRecommendedParameters(ASN1::sm2p256v1(), + "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF", + "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC", + "28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93", + "04" "32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7" + "BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0", + "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123", + 1), + EcRecommendedParameters(ASN1::sm2encrypt_recommendedParameters(), + "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF", + "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC", + "28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93", + "04" "32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7" + "BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0", + "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123", + 1), + EcRecommendedParameters(ASN1::secp192r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + 1), + EcRecommendedParameters(ASN1::secp256r1(), + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + 1), + EcRecommendedParameters(ASN1::brainpoolP160r1(), + "E95E4A5F737059DC60DFC7AD95B3D8139515620F", + "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", + "1E589A8595423412134FAA2DBDEC95C8D8675E58", + "04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321", + "E95E4A5F737059DC60DF5991D45029409E60FC09", + 1), + EcRecommendedParameters(ASN1::brainpoolP192r1(), + "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", + "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", + "04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", + "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + 1), + EcRecommendedParameters(ASN1::brainpoolP224r1(), + "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", + "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", + "040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + 1), + EcRecommendedParameters(ASN1::brainpoolP256r1(), + "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + "048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + 1), + EcRecommendedParameters(ASN1::brainpoolP320r1(), + "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", + "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", + "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", + "0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", + "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", + 1), + EcRecommendedParameters(ASN1::brainpoolP384r1(), + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + "041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + 1), + EcRecommendedParameters(ASN1::brainpoolP512r1(), + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + "0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + 1), + EcRecommendedParameters(ASN1::secp112r1(), + "DB7C2ABF62E35E668076BEAD208B", + "DB7C2ABF62E35E668076BEAD2088", + "659EF8BA043916EEDE8911702B22", + "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500", + "DB7C2ABF62E35E7628DFAC6561C5", + 1), + EcRecommendedParameters(ASN1::secp112r2(), + "DB7C2ABF62E35E668076BEAD208B", + "6127C24C05F38A0AAAF65C0EF02C", + "51DEF1815DB5ED74FCC34C85D709", + "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97", + "36DF0AAFD8B8D7597CA10520D04B", + 4), + EcRecommendedParameters(ASN1::secp160r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32", + "0100000000000000000001F4C8F927AED3CA752257", + 1), + EcRecommendedParameters(ASN1::secp160k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000007", + "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE", + "0100000000000000000001B8FA16DFAB9ACA16B6B3", + 1), + EcRecommendedParameters(ASN1::secp256k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000007", + "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + 1), + EcRecommendedParameters(ASN1::secp128r1(), + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", + "E87579C11079F43DD824993C2CEE5ED3", + "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83", + "FFFFFFFE0000000075A30D1B9038A115", + 1), + EcRecommendedParameters(ASN1::secp128r2(), + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + "D6031998D1B3BBFEBF59CC9BBFF9AEE1", + "5EEEFCA380D02919DC2C6558BB6D8A5D", + "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44", + "3FFFFFFF7FFFFFFFBE0024720613B5A3", + 4), + EcRecommendedParameters(ASN1::secp160r2(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", + "B4E134D3FB59EB8BAB57274904664D5AF50388BA", + "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", + "0100000000000000000000351EE786A818F3A1A16B", + 1), + EcRecommendedParameters(ASN1::secp192k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000003", + "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", + "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", + 1), + EcRecommendedParameters(ASN1::secp224k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", + "00000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000005", + "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", + "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", + 1), + EcRecommendedParameters(ASN1::secp224r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + 1), + EcRecommendedParameters(ASN1::secp384r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + "04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + 1), + EcRecommendedParameters(ASN1::secp521r1(), + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + 1), + }; + begin = rec; + end = rec + sizeof(rec)/sizeof(rec[0]); +} + +template OID DL_GroupParameters_EC::GetNextRecommendedParametersOID(const OID &oid) +{ + const EcRecommendedParameters *begin, *end; + GetRecommendedParameters(begin, end); + const EcRecommendedParameters *it = std::upper_bound(begin, end, oid, OIDLessThan()); + return (it == end ? OID() : it->oid); +} + +template void DL_GroupParameters_EC::Initialize(const OID &oid) +{ + const EcRecommendedParameters *begin, *end; + GetRecommendedParameters(begin, end); + const EcRecommendedParameters *it = std::lower_bound(begin, end, oid, OIDLessThan()); + if (it == end || it->oid != oid) + throw UnknownOID(); + + const EcRecommendedParameters ¶m = *it; + m_oid = oid; + member_ptr ec(param.NewEC()); + this->m_groupPrecomputation.SetCurve(*ec); + + StringSource ssG(param.g, true, new HexDecoder); + Element G; + bool result = GetCurve().DecodePoint(G, ssG, (size_t)ssG.MaxRetrievable()); + this->SetSubgroupGenerator(G); + + // TODO: this fails in practice. Should it throw? + CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result); + + StringSource ssN(param.n, true, new HexDecoder); + m_n.Decode(ssN, (size_t)ssN.MaxRetrievable()); + m_k = param.h; +} + +template +bool DL_GroupParameters_EC::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (strcmp(name, Name::GroupOID()) == 0) + { + if (m_oid.Empty()) + return false; + + this->ThrowIfTypeMismatch(name, typeid(OID), valueType); + *reinterpret_cast(pValue) = m_oid; + return true; + } + else + return GetValueHelper >(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Curve); +} + +template +void DL_GroupParameters_EC::AssignFrom(const NameValuePairs &source) +{ + OID oid; + if (source.GetValue(Name::GroupOID(), oid)) + Initialize(oid); + else + { + EllipticCurve ec; + Point G; + Integer n; + + source.GetRequiredParameter("DL_GroupParameters_EC", Name::Curve(), ec); + source.GetRequiredParameter("DL_GroupParameters_EC", Name::SubgroupGenerator(), G); + source.GetRequiredParameter("DL_GroupParameters_EC", Name::SubgroupOrder(), n); + Integer k = source.GetValueWithDefault(Name::Cofactor(), Integer::Zero()); + + Initialize(ec, G, n, k); + } +} + +template +void DL_GroupParameters_EC::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + try + { + CRYPTOPP_UNUSED(rng); + AssignFrom(alg); + } + catch (InvalidArgument &) + { + throw NotImplemented("DL_GroupParameters_EC: curve generation is not implemented yet"); + } +} + +template +void DL_GroupParameters_EC::BERDecode(BufferedTransformation &bt) +{ + byte b; + if (!bt.Peek(b)) + BERDecodeError(); + if (b == OBJECT_IDENTIFIER) + Initialize(OID(bt)); + else + { + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); // check version + EllipticCurve ec(seq); + Point G = ec.BERDecodePoint(seq); + Integer n(seq); + Integer k; + bool cofactorPresent = !seq.EndReached(); + if (cofactorPresent) + k.BERDecode(seq); + else + k = Integer::Zero(); + seq.MessageEnd(); + + Initialize(ec, G, n, k); + } +} + +template +void DL_GroupParameters_EC::DEREncode(BufferedTransformation &bt) const +{ + if (m_encodeAsOID && !m_oid.Empty()) + m_oid.DEREncode(bt); + else + { + DERSequenceEncoder seq(bt); + DEREncodeUnsigned(seq, 1); // version + GetCurve().DEREncode(seq); + GetCurve().DEREncodePoint(seq, this->GetSubgroupGenerator(), m_compress); + m_n.DEREncode(seq); + if (m_k.NotZero()) + m_k.DEREncode(seq); + seq.MessageEnd(); + } +} + +template +Integer DL_GroupParameters_EC::GetCofactor() const +{ + if (!m_k) + { + Integer q = GetCurve().FieldSize(); + Integer qSqrt = q.SquareRoot(); + m_k = (q+2*qSqrt+1)/m_n; + } + + return m_k; +} + +template +Integer DL_GroupParameters_EC::ConvertElementToInteger(const Element &element) const +{ + return ConvertToInteger(element.x); +} + +template +bool DL_GroupParameters_EC::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = GetCurve().ValidateParameters(rng, level); + CRYPTOPP_ASSERT(pass); + + Integer q = GetCurve().FieldSize(); + pass = pass && m_n!=q; + CRYPTOPP_ASSERT(pass); + + if (level >= 2) + { + Integer qSqrt = q.SquareRoot(); + pass = pass && m_n>4*qSqrt; + CRYPTOPP_ASSERT(pass); + pass = pass && VerifyPrime(rng, m_n, level-2); + CRYPTOPP_ASSERT(pass); + pass = pass && (m_k.IsZero() || m_k == (q+2*qSqrt+1)/m_n); + CRYPTOPP_ASSERT(pass); + pass = pass && CheckMOVCondition(q, m_n); + CRYPTOPP_ASSERT(pass); + } + + return pass; +} + +template +bool DL_GroupParameters_EC::ValidateElement(unsigned int level, const Element &g, const DL_FixedBasePrecomputation *gpc) const +{ + bool pass = !IsIdentity(g); + CRYPTOPP_ASSERT(pass); + pass = pass && GetCurve().VerifyPoint(g); + CRYPTOPP_ASSERT(pass); + + if (level >= 1) + { + if (gpc) + { + pass = pass && gpc->Exponentiate(this->GetGroupPrecomputation(), Integer::One()) == g; + CRYPTOPP_ASSERT(pass); + } + } + if (level >= 2 && pass) + { + const Integer &q = GetSubgroupOrder(); + Element gq = gpc ? gpc->Exponentiate(this->GetGroupPrecomputation(), q) : this->ExponentiateElement(g, q); + pass = pass && IsIdentity(gq); + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +template +void DL_GroupParameters_EC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const +{ + GetCurve().SimultaneousMultiply(results, base, exponents, exponentsCount); +} + +template +typename DL_GroupParameters_EC::Element DL_GroupParameters_EC::MultiplyElements(const Element &a, const Element &b) const +{ + return GetCurve().Add(a, b); +} + +template +typename DL_GroupParameters_EC::Element DL_GroupParameters_EC::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const +{ + return GetCurve().CascadeMultiply(exponent1, element1, exponent2, element2); +} + +template +OID DL_GroupParameters_EC::GetAlgorithmID() const +{ + return ASN1::id_ecPublicKey(); +} + +std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC::Element& obj) +{ + std::ostringstream oss; + oss << "(" << std::hex << obj.x << ", " << std::hex << obj.y << ")"; + return os << oss.str(); +} + +// ****************************************************************** + +template +void DL_PublicKey_EC::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) +{ + CRYPTOPP_UNUSED(parametersPresent); + + typename EC::Point P; + if (!this->GetGroupParameters().GetCurve().DecodePoint(P, bt, size)) + BERDecodeError(); + this->SetPublicElement(P); +} + +template +void DL_PublicKey_EC::DEREncodePublicKey(BufferedTransformation &bt) const +{ + this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression()); +} + +// ****************************************************************** + +template +void DL_PrivateKey_EC::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) +{ + CRYPTOPP_UNUSED(size); + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); // check version + + BERGeneralDecoder dec(seq, OCTET_STRING); + if (!dec.IsDefiniteLength()) + BERDecodeError(); + Integer x; + x.Decode(dec, (size_t)dec.RemainingLength()); + dec.MessageEnd(); + if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) + BERDecodeError(); + if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) + { + BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0); + this->AccessGroupParameters().BERDecode(parameters); + parameters.MessageEnd(); + } + if (!seq.EndReached()) + { + // skip over the public element + SecByteBlock subjectPublicKey; + unsigned int unusedBits; + BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + BERDecodeBitString(publicKey, subjectPublicKey, unusedBits); + publicKey.MessageEnd(); + Element Q; + if (!(unusedBits == 0 && this->GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size()))) + BERDecodeError(); + } + seq.MessageEnd(); + + this->SetPrivateExponent(x); +} + +template +void DL_PrivateKey_EC::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + DEREncodeUnsigned(privateKey, 1); // version + // SEC 1 ver 1.0 says privateKey (m_d) has the same length as order of the curve + // this will be changed to order of base point in a future version + this->GetPrivateExponent().DEREncodeAsOctetString(privateKey, this->GetGroupParameters().GetSubgroupOrder().ByteCount()); + privateKey.MessageEnd(); +} + +// ****************************************************************** + +template +void DL_PublicKey_ECGDSA::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) +{ + CRYPTOPP_UNUSED(parametersPresent); + + typename EC::Point P; + if (!this->GetGroupParameters().GetCurve().DecodePoint(P, bt, size)) + BERDecodeError(); + this->SetPublicElement(P); +} + +template +void DL_PublicKey_ECGDSA::DEREncodePublicKey(BufferedTransformation &bt) const +{ + this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression()); +} + +// ****************************************************************** + +template +void DL_PrivateKey_ECGDSA::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) +{ + CRYPTOPP_UNUSED(size); + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); // check version + + BERGeneralDecoder dec(seq, OCTET_STRING); + if (!dec.IsDefiniteLength()) + BERDecodeError(); + Integer x; + x.Decode(dec, (size_t)dec.RemainingLength()); + dec.MessageEnd(); + if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) + BERDecodeError(); + if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) + { + BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0); + this->AccessGroupParameters().BERDecode(parameters); + parameters.MessageEnd(); + } + if (!seq.EndReached()) + { + // skip over the public element + SecByteBlock subjectPublicKey; + unsigned int unusedBits; + BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + BERDecodeBitString(publicKey, subjectPublicKey, unusedBits); + publicKey.MessageEnd(); + Element Q; + if (!(unusedBits == 0 && this->GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size()))) + BERDecodeError(); + } + seq.MessageEnd(); + + this->SetPrivateExponent(x); +} + +template +void DL_PrivateKey_ECGDSA::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + DEREncodeUnsigned(privateKey, 1); // version + // SEC 1 ver 1.0 says privateKey (m_d) has the same length as order of the curve + // this will be changed to order of base point in a future version + this->GetPrivateExponent().DEREncodeAsOctetString(privateKey, this->GetGroupParameters().GetSubgroupOrder().ByteCount()); + privateKey.MessageEnd(); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/eccrypto.h b/external/ours/library/crypto/src/shared/original/eccrypto.h new file mode 100755 index 000000000..870628684 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/eccrypto.h @@ -0,0 +1,686 @@ +// eccrypto.h - originally written and placed in the public domain by Wei Dai +// deterministic signatures added by by Douglas Roark + +/// \file eccrypto.h +/// \brief Classes and functions for Elliptic Curves over prime and binary fields + +#ifndef CRYPTOPP_ECCRYPTO_H +#define CRYPTOPP_ECCRYPTO_H + +#include "config.h" +#include "cryptlib.h" +#include "pubkey.h" +#include "integer.h" +#include "asn.h" +#include "hmac.h" +#include "sha.h" +#include "gfpcrypt.h" +#include "dh.h" +#include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" +#include "ecp.h" +#include "ec2n.h" + +#include + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Elliptic Curve Parameters +/// \tparam EC elliptic curve field +/// \details This class corresponds to the ASN.1 sequence of the same name +/// in ANSI X9.62 and SEC 1. EC is currently defined for ECP and EC2N. +template +class DL_GroupParameters_EC : public DL_GroupParametersImpl > +{ + typedef DL_GroupParameters_EC ThisClass; + +public: + typedef EC EllipticCurve; + typedef typename EllipticCurve::Point Point; + typedef Point Element; + typedef IncompatibleCofactorMultiplication DefaultCofactorOption; + + virtual ~DL_GroupParameters_EC() {} + + /// \brief Construct an EC GroupParameters + DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(true) {} + + /// \brief Construct an EC GroupParameters + /// \param oid the OID of a curve + DL_GroupParameters_EC(const OID &oid) + : m_compress(false), m_encodeAsOID(true) {Initialize(oid);} + + /// \brief Construct an EC GroupParameters + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \param k the cofactor + DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) + : m_compress(false), m_encodeAsOID(true) {Initialize(ec, G, n, k);} + + /// \brief Construct an EC GroupParameters + /// \param bt BufferedTransformation with group parameters + DL_GroupParameters_EC(BufferedTransformation &bt) + : m_compress(false), m_encodeAsOID(true) {BERDecode(bt);} + + /// \brief Initialize an EC GroupParameters using {EC,G,n,k} + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \param k the cofactor + /// \details This Initialize() function overload initializes group parameters from existing parameters. + void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) + { + this->m_groupPrecomputation.SetCurve(ec); + this->SetSubgroupGenerator(G); + m_n = n; + m_k = k; + } + + /// \brief Initialize a DL_GroupParameters_EC {EC,G,n,k} + /// \param oid the OID of a curve + /// \details This Initialize() function overload initializes group parameters from existing parameters. + void Initialize(const OID &oid); + + // NameValuePairs + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // GeneratibleCryptoMaterial interface + /// this implementation doesn't actually generate a curve, it just initializes the parameters with existing values + /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + // DL_GroupParameters + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} + const Integer & GetSubgroupOrder() const {return m_n;} + Integer GetCofactor() const; + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation *precomp) const; + bool FastSubgroupCheckAvailable() const {return false;} + void EncodeElement(bool reversible, const Element &element, byte *encoded) const + { + if (reversible) + GetCurve().EncodePoint(encoded, element, m_compress); + else + element.x.Encode(encoded, GetEncodedElementSize(false)); + } + virtual unsigned int GetEncodedElementSize(bool reversible) const + { + if (reversible) + return GetCurve().EncodedPointSize(m_compress); + else + return GetCurve().GetField().MaxElementByteLength(); + } + Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const + { + Point result; + if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true))) + throw DL_BadElement(); + if (checkForGroupMembership && !ValidateElement(1, result, NULLPTR)) + throw DL_BadElement(); + return result; + } + Integer ConvertElementToInteger(const Element &element) const; + Integer GetMaxExponent() const {return GetSubgroupOrder()-1;} + bool IsIdentity(const Element &element) const {return element.identity;} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";} + + // ASN1Key + OID GetAlgorithmID() const; + + // used by MQV + Element MultiplyElements(const Element &a, const Element &b) const; + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; + + // non-inherited + + // enumerate OIDs for recommended parameters, use OID() to get first one + static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid); + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + void SetPointCompression(bool compress) {m_compress = compress;} + bool GetPointCompression() const {return m_compress;} + + void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;} + bool GetEncodeAsOID() const {return m_encodeAsOID;} + + const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();} + + bool operator==(const ThisClass &rhs) const + {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);} + +protected: + unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();} + unsigned int ExponentLength() const {return m_n.ByteCount();} + + OID m_oid; // set if parameters loaded from a recommended curve + Integer m_n; // order of base point + mutable Integer m_k; // cofactor + mutable bool m_compress, m_encodeAsOID; // presentation details +}; + +inline std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC::Element& obj); + +/// \brief Elliptic Curve Discrete Log (DL) public key +/// \tparam EC elliptic curve field +template +class DL_PublicKey_EC : public DL_PublicKeyImpl > +{ +public: + typedef typename EC::Point Element; + + virtual ~DL_PublicKey_EC() {} + + /// \brief Initialize an EC Public Key using {GP,Q} + /// \param params group parameters + /// \param Q the public point + /// \details This Initialize() function overload initializes a public key from existing parameters. + void Initialize(const DL_GroupParameters_EC ¶ms, const Element &Q) + {this->AccessGroupParameters() = params; this->SetPublicElement(Q);} + + /// \brief Initialize an EC Public Key using {EC,G,n,Q} + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \param Q the public point + /// \details This Initialize() function overload initializes a public key from existing parameters. + void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q) + {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);} + + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; +}; + +/// \brief Elliptic Curve Discrete Log (DL) private key +/// \tparam EC elliptic curve field +template +class DL_PrivateKey_EC : public DL_PrivateKeyImpl > +{ +public: + typedef typename EC::Point Element; + + virtual ~DL_PrivateKey_EC(); + + /// \brief Initialize an EC Private Key using {GP,x} + /// \param params group parameters + /// \param x the private exponent + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const DL_GroupParameters_EC ¶ms, const Integer &x) + {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);} + + /// \brief Initialize an EC Private Key using {EC,G,n,x} + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \param x the private exponent + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x) + {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);} + + /// \brief Create an EC private key + /// \param rng a RandomNumberGenerator derived class + /// \param params the EC group parameters + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC ¶ms) + {this->GenerateRandom(rng, params);} + + /// \brief Create an EC private key + /// \param rng a RandomNumberGenerator derived class + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n) + {this->GenerateRandom(rng, DL_GroupParameters_EC(ec, G, n));} + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; +}; + +// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499 +template +DL_PrivateKey_EC::~DL_PrivateKey_EC() {} + +/// \brief Elliptic Curve Diffie-Hellman +/// \tparam EC elliptic curve field +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \sa CofactorMultiplicationOption, Elliptic Curve Diffie-Hellman, AKA ECDH +/// \since Crypto++ 3.0 +template ::DefaultCofactorOption> +struct ECDH +{ + typedef DH_Domain, COFACTOR_OPTION> Domain; +}; + +/// \brief Elliptic Curve Menezes-Qu-Vanstone +/// \tparam EC elliptic curve field +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \sa CofactorMultiplicationOption, Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV +template ::DefaultCofactorOption> +struct ECMQV +{ + typedef MQV_Domain, COFACTOR_OPTION> Domain; +}; + +/// \brief Hashed Elliptic Curve Menezes-Qu-Vanstone +/// \tparam EC elliptic curve field +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \details This implementation follows Hugo Krawczyk's HMQV: A High-Performance +/// Secure Diffie-Hellman Protocol. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. +/// \sa CofactorMultiplicationOption +template ::DefaultCofactorOption, class HASH = SHA256> +struct ECHMQV +{ + typedef HMQV_Domain, COFACTOR_OPTION, HASH> Domain; +}; + +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain ECHMQV160; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain ECHMQV256; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECHMQV384; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECHMQV512; + +/// \brief Fully Hashed Elliptic Curve Menezes-Qu-Vanstone +/// \tparam EC elliptic curve field +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's +/// A Secure and Efficient Authenticated Diffie-Hellman Protocol. +/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +/// \sa CofactorMultiplicationOption +template ::DefaultCofactorOption, class HASH = SHA256> +struct ECFHMQV +{ + typedef FHMQV_Domain, COFACTOR_OPTION, HASH> Domain; +}; + +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain ECFHMQV160; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain ECFHMQV256; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECFHMQV384; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECFHMQV512; + +/// \brief Elliptic Curve Discrete Log (DL) keys +/// \tparam EC elliptic curve field +template +struct DL_Keys_EC +{ + typedef DL_PublicKey_EC PublicKey; + typedef DL_PrivateKey_EC PrivateKey; +}; + +// Forward declaration; documented below +template +struct ECDSA; + +/// \brief Elliptic Curve DSA keys +/// \tparam EC elliptic curve field +/// \since Crypto++ 3.2 +template +struct DL_Keys_ECDSA +{ + typedef DL_PublicKey_EC PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA > PrivateKey; +}; + +/// \brief Elliptic Curve DSA (ECDSA) signature algorithm +/// \tparam EC elliptic curve field +/// \since Crypto++ 3.2 +template +class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} +}; + +/// \brief Elliptic Curve DSA (ECDSA) signature algorithm based on RFC 6979 +/// \tparam EC elliptic curve field +/// \sa RFC 6979, Deterministic Usage of the +/// Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) +/// \since Crypto++ 6.0 +template +class DL_Algorithm_ECDSA_RFC6979 : public DL_Algorithm_DSA_RFC6979 +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECDSA-RFC6979";} +}; + +/// \brief Elliptic Curve NR (ECNR) signature algorithm +/// \tparam EC elliptic curve field +template +class DL_Algorithm_ECNR : public DL_Algorithm_NR +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} +}; + +/// \brief Elliptic Curve DSA (ECDSA) signature scheme +/// \tparam EC elliptic curve field +/// \tparam H HashTransformation derived class +/// \sa ECDSA +/// \since Crypto++ 3.2 +template +struct ECDSA : public DL_SS, DL_Algorithm_ECDSA, DL_SignatureMessageEncodingMethod_DSA, H> +{ +}; + +/// \brief Elliptic Curve DSA (ECDSA) deterministic signature scheme +/// \tparam EC elliptic curve field +/// \tparam H HashTransformation derived class +/// \sa Deterministic Usage of the +/// Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) +/// \since Crypto++ 6.0 +template +struct ECDSA_RFC6979 : public DL_SS< + DL_Keys_ECDSA, + DL_Algorithm_ECDSA_RFC6979, + DL_SignatureMessageEncodingMethod_DSA, + H, + ECDSA_RFC6979 > +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("ECDSA-RFC6979/") + H::StaticAlgorithmName();} +}; + +/// \brief Elliptic Curve NR (ECNR) signature scheme +/// \tparam EC elliptic curve field +/// \tparam H HashTransformation derived class +template +struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMessageEncodingMethod_NR, H> +{ +}; + +// ****************************************** + +template +class DL_PublicKey_ECGDSA; +template +class DL_PrivateKey_ECGDSA; + +/// \brief Elliptic Curve German DSA key for ISO/IEC 15946 +/// \tparam EC elliptic curve field +/// \sa ECGDSA +/// \since Crypto++ 6.0 +template +class DL_PrivateKey_ECGDSA : public DL_PrivateKeyImpl > +{ +public: + typedef typename EC::Point Element; + + virtual ~DL_PrivateKey_ECGDSA() {} + + /// \brief Initialize an EC Private Key using {GP,x} + /// \param params group parameters + /// \param x the private exponent + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const DL_GroupParameters_EC ¶ms, const Integer &x) + { + this->AccessGroupParameters() = params; + this->SetPrivateExponent(x); + CRYPTOPP_ASSERT(x>=1 && x<=params.GetSubgroupOrder()-1); + } + + /// \brief Initialize an EC Private Key using {EC,G,n,x} + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \param x the private exponent + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x) + { + this->AccessGroupParameters().Initialize(ec, G, n); + this->SetPrivateExponent(x); + CRYPTOPP_ASSERT(x>=1 && x<=this->AccessGroupParameters().GetSubgroupOrder()-1); + } + + /// \brief Create an EC private key + /// \param rng a RandomNumberGenerator derived class + /// \param params the EC group parameters + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC ¶ms) + {this->GenerateRandom(rng, params);} + + /// \brief Create an EC private key + /// \param rng a RandomNumberGenerator derived class + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n) + {this->GenerateRandom(rng, DL_GroupParameters_EC(ec, G, n));} + + virtual void MakePublicKey(DL_PublicKey_ECGDSA &pub) const + { + const DL_GroupParameters& params = this->GetAbstractGroupParameters(); + pub.AccessAbstractGroupParameters().AssignFrom(params); + const Integer &xInv = this->GetPrivateExponent().InverseMod(params.GetSubgroupOrder()); + pub.SetPublicElement(params.ExponentiateBase(xInv)); + CRYPTOPP_ASSERT(xInv.NotZero()); + } + + virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper, + DL_PrivateKey_ECGDSA >(this, name, valueType, pValue).Assignable(); + } + + virtual void AssignFrom(const NameValuePairs &source) + { + AssignFromHelper, + DL_PrivateKey_ECGDSA >(this, source); + } + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; +}; + +/// \brief Elliptic Curve German DSA key for ISO/IEC 15946 +/// \tparam EC elliptic curve field +/// \sa ECGDSA +/// \since Crypto++ 6.0 +template +class DL_PublicKey_ECGDSA : public DL_PublicKeyImpl > +{ + typedef DL_PublicKey_ECGDSA ThisClass; + +public: + typedef typename EC::Point Element; + + virtual ~DL_PublicKey_ECGDSA() {} + + /// \brief Initialize an EC Public Key using {GP,Q} + /// \param params group parameters + /// \param Q the public point + /// \details This Initialize() function overload initializes a public key from existing parameters. + void Initialize(const DL_GroupParameters_EC ¶ms, const Element &Q) + {this->AccessGroupParameters() = params; this->SetPublicElement(Q);} + + /// \brief Initialize an EC Public Key using {EC,G,n,Q} + /// \param ec the elliptic curve + /// \param G the base point + /// \param n the order of the base point + /// \param Q the public point + /// \details This Initialize() function overload initializes a public key from existing parameters. + void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q) + {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);} + + virtual void AssignFrom(const NameValuePairs &source) + { + DL_PrivateKey_ECGDSA *pPrivateKey = NULLPTR; + if (source.GetThisPointer(pPrivateKey)) + pPrivateKey->MakePublicKey(*this); + else + { + this->AccessAbstractGroupParameters().AssignFrom(source); + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement); + } + } + + // DL_PublicKey + virtual void SetPublicElement(const Element &y) + {this->AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);} + + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; +}; + +/// \brief Elliptic Curve German DSA keys for ISO/IEC 15946 +/// \tparam EC elliptic curve field +/// \sa ECGDSA +/// \since Crypto++ 6.0 +template +struct DL_Keys_ECGDSA +{ + typedef DL_PublicKey_ECGDSA PublicKey; + typedef DL_PrivateKey_ECGDSA PrivateKey; +}; + +/// \brief Elliptic Curve German DSA signature algorithm +/// \tparam EC elliptic curve field +/// \sa ECGDSA +/// \since Crypto++ 6.0 +template +class DL_Algorithm_ECGDSA : public DL_Algorithm_GDSA_ISO15946 +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECGDSA";} +}; + +/// \brief Elliptic Curve German Digital Signature Algorithm signature scheme +/// \tparam EC elliptic curve field +/// \tparam H HashTransformation derived class +/// \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf The Digital Signature Scheme +/// ECGDSA (October 24, 2006) +/// \since Crypto++ 6.0 +template +struct ECGDSA : public DL_SS< + DL_Keys_ECGDSA, + DL_Algorithm_ECGDSA, + DL_SignatureMessageEncodingMethod_DSA, + H> +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("ECGDSA-ISO15946/") + H::StaticAlgorithmName();} +}; + +// ****************************************** + +/// \brief Elliptic Curve Integrated Encryption Scheme +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \tparam HASH HashTransformation derived class used for key drivation and MAC computation +/// \tparam DHAES_MODE flag indicating if the MAC includes additional context parameters such as u·V, v·U and label +/// \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits +/// \details ECIES is an Elliptic Curve based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation +/// Method (KEM) with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is +/// IND-CCA2, which is a strong notion of security. +/// You should prefer an Integrated Encryption Scheme over homegrown schemes. +/// \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the ECIES_P1363. +/// If you desire an Integrated Encryption Scheme compatibile with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES +/// template class with NoCofactorMultiplication, DHAES_MODE=true and LABEL_OCTETS=false. +/// \details The default template parameters ensure compatibility with Bouncy Castle 1.54 and Botan 1.11. The combination of +/// IncompatibleCofactorMultiplication and DHAES_MODE=true is recommended for best efficiency and security. +/// SHA1 is used for compatibility reasons, but it can be changed if desired. +/// \sa DLIES, ECIES_P1363, Elliptic Curve Integrated Encryption Scheme (ECIES), +/// Martínez, Encinas, and Ávila's A Survey of the Elliptic +/// Curve Integrated Encryption Schemes +/// \since Crypto++ 4.0, Crypto++ 5.7 for Bouncy Castle and Botan compatibility +template +struct ECIES + : public DL_ES< + DL_Keys_EC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, + ECIES > +{ + // TODO: fix this after name is standardized + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} +}; + +/// \brief Elliptic Curve Integrated Encryption Scheme for P1363 +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \tparam HASH HashTransformation derived class used for key drivation and MAC computation +/// \details ECIES_P1363 is an Elliptic Curve based Integrated Encryption Scheme (IES) for P1363. The scheme combines a Key Encapsulation +/// Method (KEM) with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is +/// IND-CCA2, which is a strong notion of security. +/// You should prefer an Integrated Encryption Scheme over homegrown schemes. +/// \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom +/// SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used the early draft in its Integrated Ecryption +/// Schemes with NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +/// \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the ECIES_P1363. +/// If you desire an Integrated Encryption Scheme compatibile with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES +/// template class with NoCofactorMultiplication, DHAES_MODE=true and LABEL_OCTETS=false. +/// \details The default template parameters ensure compatibility with P1363. The combination of +/// IncompatibleCofactorMultiplication and DHAES_MODE=true is recommended for best efficiency and security. +/// SHA1 is used for compatibility reasons, but it can be changed if desired. +/// \sa DLIES, ECIES, Elliptic Curve Integrated Encryption Scheme (ECIES), +/// Martínez, Encinas, and Ávila's A Survey of the Elliptic +/// Curve Integrated Encryption Schemes +/// \since Crypto++ 4.0 +template +struct ECIES_P1363 + : public DL_ES< + DL_Keys_EC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, false, true>, + ECIES > +{ + // TODO: fix this after name is standardized + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES-P1363";} +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "eccrypto.cpp" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_ECGDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_ECGDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_ECGDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_ECGDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA >; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ecp.cpp b/external/ours/library/crypto/src/shared/original/ecp.cpp new file mode 100755 index 000000000..643ba70a0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ecp.cpp @@ -0,0 +1,506 @@ +// ecp.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "ecp.h" +#include "asn.h" +#include "integer.h" +#include "nbtheory.h" +#include "modarith.h" +#include "filters.h" +#include "algebra.cpp" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::ECP; +using CryptoPP::Integer; +using CryptoPP::ModularArithmetic; + +#if defined(HAVE_GCC_INIT_PRIORITY) + #define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50))) + const ECP::Point g_identity INIT_ATTRIBUTE = ECP::Point(); +#elif defined(HAVE_MSC_INIT_PRIORITY) + #pragma warning(disable: 4075) + #pragma init_seg(".CRT$XCU") + const ECP::Point g_identity; + #pragma warning(default: 4075) +#elif defined(HAVE_XLC_INIT_PRIORITY) + #pragma priority(290) + const ECP::Point g_identity; +#endif + +inline ECP::Point ToMontgomery(const ModularArithmetic &mr, const ECP::Point &P) +{ + return P.identity ? P : ECP::Point(mr.ConvertIn(P.x), mr.ConvertIn(P.y)); +} + +inline ECP::Point FromMontgomery(const ModularArithmetic &mr, const ECP::Point &P) +{ + return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y)); +} + +inline Integer IdentityToInteger(bool val) +{ + return val ? Integer::One() : Integer::Zero(); +} + +struct ProjectivePoint +{ + ProjectivePoint() {} + ProjectivePoint(const Integer &x, const Integer &y, const Integer &z) + : x(x), y(y), z(z) {} + + Integer x, y, z; +}; + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +ECP::ECP(const ECP &ecp, bool convertToMontgomeryRepresentation) +{ + if (convertToMontgomeryRepresentation && !ecp.GetField().IsMontgomeryRepresentation()) + { + m_fieldPtr.reset(new MontgomeryRepresentation(ecp.GetField().GetModulus())); + m_a = GetField().ConvertIn(ecp.m_a); + m_b = GetField().ConvertIn(ecp.m_b); + } + else + operator=(ecp); +} + +ECP::ECP(BufferedTransformation &bt) + : m_fieldPtr(new Field(bt)) +{ + BERSequenceDecoder seq(bt); + GetField().BERDecodeElement(seq, m_a); + GetField().BERDecodeElement(seq, m_b); + // skip optional seed + if (!seq.EndReached()) + { + SecByteBlock seed; + unsigned int unused; + BERDecodeBitString(seq, seed, unused); + } + seq.MessageEnd(); +} + +void ECP::DEREncode(BufferedTransformation &bt) const +{ + GetField().DEREncode(bt); + DERSequenceEncoder seq(bt); + GetField().DEREncodeElement(seq, m_a); + GetField().DEREncodeElement(seq, m_b); + seq.MessageEnd(); +} + +bool ECP::DecodePoint(ECP::Point &P, const byte *encodedPoint, size_t encodedPointLen) const +{ + StringStore store(encodedPoint, encodedPointLen); + return DecodePoint(P, store, encodedPointLen); +} + +bool ECP::DecodePoint(ECP::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const +{ + byte type; + if (encodedPointLen < 1 || !bt.Get(type)) + return false; + + switch (type) + { + case 0: + P.identity = true; + return true; + case 2: + case 3: + { + if (encodedPointLen != EncodedPointSize(true)) + return false; + + Integer p = FieldSize(); + + P.identity = false; + P.x.Decode(bt, GetField().MaxElementByteLength()); + P.y = ((P.x*P.x+m_a)*P.x+m_b) % p; + + if (Jacobi(P.y, p) !=1) + return false; + + P.y = ModularSquareRoot(P.y, p); + + if ((type & 1) != P.y.GetBit(0)) + P.y = p-P.y; + + return true; + } + case 4: + { + if (encodedPointLen != EncodedPointSize(false)) + return false; + + unsigned int len = GetField().MaxElementByteLength(); + P.identity = false; + P.x.Decode(bt, len); + P.y.Decode(bt, len); + return true; + } + default: + return false; + } +} + +void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + if (P.identity) + NullStore().TransferTo(bt, EncodedPointSize(compressed)); + else if (compressed) + { + bt.Put((byte)(2U + P.y.GetBit(0))); + P.x.Encode(bt, GetField().MaxElementByteLength()); + } + else + { + unsigned int len = GetField().MaxElementByteLength(); + bt.Put(4U); // uncompressed + P.x.Encode(bt, len); + P.y.Encode(bt, len); + } +} + +void ECP::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const +{ + ArraySink sink(encodedPoint, EncodedPointSize(compressed)); + EncodePoint(sink, P, compressed); + CRYPTOPP_ASSERT(sink.TotalPutLength() == EncodedPointSize(compressed)); +} + +ECP::Point ECP::BERDecodePoint(BufferedTransformation &bt) const +{ + SecByteBlock str; + BERDecodeOctetString(bt, str); + Point P; + if (!DecodePoint(P, str, str.size())) + BERDecodeError(); + return P; +} + +void ECP::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + SecByteBlock str(EncodedPointSize(compressed)); + EncodePoint(str, P, compressed); + DEREncodeOctetString(bt, str); +} + +bool ECP::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const +{ + Integer p = FieldSize(); + + bool pass = p.IsOdd(); + pass = pass && !m_a.IsNegative() && m_a

= 1) + pass = pass && ((4*m_a*m_a*m_a+27*m_b*m_b)%p).IsPositive(); + + if (level >= 2) + pass = pass && VerifyPrime(rng, p); + + return pass; +} + +bool ECP::VerifyPoint(const Point &P) const +{ + const FieldElement &x = P.x, &y = P.y; + Integer p = FieldSize(); + return P.identity || + (!x.IsNegative() && x

().Ref(); +#endif +} + +const ECP::Point& ECP::Inverse(const Point &P) const +{ + if (P.identity) + return P; + else + { + m_R.identity = false; + m_R.x = P.x; + m_R.y = GetField().Inverse(P.y); + return m_R; + } +} + +const ECP::Point& ECP::Add(const Point &P, const Point &Q) const +{ + if (P.identity) return Q; + if (Q.identity) return P; + if (GetField().Equal(P.x, Q.x)) + return GetField().Equal(P.y, Q.y) ? Double(P) : Identity(); + + FieldElement t = GetField().Subtract(Q.y, P.y); + t = GetField().Divide(t, GetField().Subtract(Q.x, P.x)); + FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), Q.x); + m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); + + m_R.x.swap(x); + m_R.identity = false; + return m_R; +} + +const ECP::Point& ECP::Double(const Point &P) const +{ + if (P.identity || P.y==GetField().Identity()) return Identity(); + + FieldElement t = GetField().Square(P.x); + t = GetField().Add(GetField().Add(GetField().Double(t), t), m_a); + t = GetField().Divide(t, GetField().Double(P.y)); + FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), P.x); + m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); + + m_R.x.swap(x); + m_R.identity = false; + return m_R; +} + +template void ParallelInvert(const AbstractRing &ring, Iterator begin, Iterator end) +{ + size_t n = end-begin; + if (n == 1) + *begin = ring.MultiplicativeInverse(*begin); + else if (n > 1) + { + std::vector vec((n+1)/2); + unsigned int i; + Iterator it; + + for (i=0, it=begin; i::iterator it) : it(it) {} + Integer& operator*() {return it->z;} + int operator-(ZIterator it2) {return int(it-it2.it);} + ZIterator operator+(int i) {return ZIterator(it+i);} + ZIterator& operator+=(int i) {it+=i; return *this;} + std::vector::iterator it; +}; + +ECP::Point ECP::ScalarMultiply(const Point &P, const Integer &k) const +{ + Element result; + if (k.BitCount() <= 5) + AbstractGroup::SimultaneousMultiply(&result, P, &k, 1); + else + ECP::SimultaneousMultiply(&result, P, &k, 1); + return result; +} + +void ECP::SimultaneousMultiply(ECP::Point *results, const ECP::Point &P, const Integer *expBegin, unsigned int expCount) const +{ + if (!GetField().IsMontgomeryRepresentation()) + { + ECP ecpmr(*this, true); + const ModularArithmetic &mr = ecpmr.GetField(); + ecpmr.SimultaneousMultiply(results, ToMontgomery(mr, P), expBegin, expCount); + for (unsigned int i=0; i bases; + std::vector exponents; + exponents.reserve(expCount); + std::vector > baseIndices(expCount); + std::vector > negateBase(expCount); + std::vector > exponentWindows(expCount); + unsigned int i; + + for (i=0; iNotNegative()); + exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 5)); + exponents[i].FindNextWindow(); + } + + unsigned int expBitPosition = 0; + bool notDone = true; + + while (notDone) + { + notDone = false; + bool baseAdded = false; + for (i=0; i > finalCascade; + for (i=0; i::CascadeScalarMultiply(P, k1, Q, k2); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ecp.h b/external/ours/library/crypto/src/shared/original/ecp.h new file mode 100755 index 000000000..1dc02ab05 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ecp.h @@ -0,0 +1,167 @@ +// ecp.h - originally written and placed in the public domain by Wei Dai + +/// \file ecp.h +/// \brief Classes for Elliptic Curves over prime fields + +#ifndef CRYPTOPP_ECP_H +#define CRYPTOPP_ECP_H + +#include "cryptlib.h" +#include "integer.h" +#include "algebra.h" +#include "modarith.h" +#include "ecpoint.h" +#include "eprecomp.h" +#include "smartptr.h" +#include "pubkey.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Elliptic Curve over GF(p), where p is prime +class CRYPTOPP_DLL ECP : public AbstractGroup, public EncodedPoint +{ +public: + typedef ModularArithmetic Field; + typedef Integer FieldElement; + typedef ECPPoint Point; + + virtual ~ECP() {} + + /// \brief Construct an ECP + ECP() {} + + /// \brief Construct an ECP + /// \param ecp the other ECP object + /// \param convertToMontgomeryRepresentation flag indicating if the curve + /// should be converted to a MontgomeryRepresentation. + /// \details Prior to Crypto++ 8.3 the default value for + /// convertToMontgomeryRepresentation was false. it was changed due to + /// two audit tools finding, "Signature-compatible with a copy constructor". + /// \sa ModularArithmetic, MontgomeryRepresentation + ECP(const ECP &ecp, bool convertToMontgomeryRepresentation); + + /// \brief Construct an ECP + /// \param modulus the prime modulus + /// \param a Field::Element + /// \param b Field::Element + ECP(const Integer &modulus, const FieldElement &a, const FieldElement &b) + : m_fieldPtr(new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {} + + /// \brief Construct an ECP from BER encoded parameters + /// \param bt BufferedTransformation derived object + /// \details This constructor will decode and extract the fields + /// fieldID and curve of the sequence ECParameters + ECP(BufferedTransformation &bt); + + /// \brief DER Encode + /// \param bt BufferedTransformation derived object + /// \details DEREncode encode the fields fieldID and curve of the sequence + /// ECParameters + void DEREncode(BufferedTransformation &bt) const; + + /// \brief Compare two points + /// \param P the first point + /// \param Q the second point + /// \return true if equal, false otherwise + bool Equal(const Point &P, const Point &Q) const; + + const Point& Identity() const; + const Point& Inverse(const Point &P) const; + bool InversionIsFast() const {return true;} + const Point& Add(const Point &P, const Point &Q) const; + const Point& Double(const Point &P) const; + Point ScalarMultiply(const Point &P, const Integer &k) const; + Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const; + void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const; + + Point Multiply(const Integer &k, const Point &P) const + {return ScalarMultiply(P, k);} + Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const + {return CascadeScalarMultiply(P, k1, Q, k2);} + + bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const; + bool VerifyPoint(const Point &P) const; + + unsigned int EncodedPointSize(bool compressed = false) const + {return 1 + (compressed?1:2)*GetField().MaxElementByteLength();} + // returns false if point is compressed and not valid (doesn't check if uncompressed) + bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const; + bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const; + void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const; + void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Point BERDecodePoint(BufferedTransformation &bt) const; + void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Integer FieldSize() const {return GetField().GetModulus();} + const Field & GetField() const {return *m_fieldPtr;} + const FieldElement & GetA() const {return m_a;} + const FieldElement & GetB() const {return m_b;} + + bool operator==(const ECP &rhs) const + {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;} + +private: + clonable_ptr m_fieldPtr; + FieldElement m_a, m_b; + mutable Point m_R; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation; + +/// \brief Elliptic Curve precomputation +/// \tparam EC elliptic curve field +template class EcPrecomputation; + +/// \brief ECP precomputation specialization +/// \details Implementation of DL_GroupPrecomputation with input and output +/// conversions for Montgomery modular multiplication. +/// \sa DL_GroupPrecomputation, ModularArithmetic, MontgomeryRepresentation +template<> class EcPrecomputation : public DL_GroupPrecomputation +{ +public: + typedef ECP EllipticCurve; + + virtual ~EcPrecomputation() {} + + // DL_GroupPrecomputation + bool NeedConversions() const {return true;} + Element ConvertIn(const Element &P) const + {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));}; + Element ConvertOut(const Element &P) const + {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));} + const AbstractGroup & GetGroup() const {return *m_ec;} + Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec->BERDecodePoint(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec->DEREncodePoint(bt, v, false);} + + /// \brief Set the elliptic curve + /// \param ec ECP derived class + /// \details SetCurve() is not inherited + void SetCurve(const ECP &ec) + { + m_ec.reset(new ECP(ec, true)); + m_ecOriginal = ec; + } + + /// \brief Get the elliptic curve + /// \return ECP curve + /// \details GetCurve() is not inherited + const ECP & GetCurve() const {return *m_ecOriginal;} + +private: + value_ptr m_ec, m_ecOriginal; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ecpoint.h b/external/ours/library/crypto/src/shared/original/ecpoint.h new file mode 100755 index 000000000..1fe3820fb --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ecpoint.h @@ -0,0 +1,146 @@ +// ecpoint.h - written and placed in the public domain by Jeffrey Walton +// Data structures moved from ecp.h and ec2n.h. Added EncodedPoint interface + +/// \file ecpoint.h +/// \brief Classes for Elliptic Curve points +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_ECPOINT_H +#define CRYPTOPP_ECPOINT_H + +#include "cryptlib.h" +#include "integer.h" +#include "algebra.h" +#include "gf2n.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Elliptical Curve Point over GF(p), where p is prime +/// \since Crypto++ 2.0 +struct CRYPTOPP_DLL ECPPoint +{ + virtual ~ECPPoint() {} + + /// \brief Construct an ECPPoint + /// \details identity is set to true + ECPPoint() : identity(true) {} + + /// \brief Construct an ECPPoint from coordinates + /// \details identity is set to false + ECPPoint(const Integer &x, const Integer &y) + : x(x), y(y), identity(false) {} + + /// \brief Tests points for equality + /// \param t the other point + /// \return true if the points are equal, false otherwise + bool operator==(const ECPPoint &t) const + {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);} + + /// \brief Tests points for ordering + /// \param t the other point + /// \return true if this point is less than other, false otherwise + bool operator< (const ECPPoint &t) const + {return identity ? !t.identity : (!t.identity && (x; + +/// \brief Elliptical Curve Point over GF(2^n) +/// \since Crypto++ 2.0 +struct CRYPTOPP_DLL EC2NPoint +{ + virtual ~EC2NPoint() {} + + /// \brief Construct an EC2NPoint + /// \details identity is set to true + EC2NPoint() : identity(true) {} + + /// \brief Construct an EC2NPoint from coordinates + /// \details identity is set to false + EC2NPoint(const PolynomialMod2 &x, const PolynomialMod2 &y) + : x(x), y(y), identity(false) {} + + /// \brief Tests points for equality + /// \param t the other point + /// \return true if the points are equal, false otherwise + bool operator==(const EC2NPoint &t) const + {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);} + + /// \brief Tests points for ordering + /// \param t the other point + /// \return true if this point is less than other, false otherwise + bool operator< (const EC2NPoint &t) const + {return identity ? !t.identity : (!t.identity && (x; + +/// \brief Abstract class for encoding and decoding ellicptic curve points +/// \tparam Point ellicptic curve point +/// \details EncodedPoint is an interface for encoding and decoding elliptic curve points. +/// The template parameter Point should be a class like ECP or EC2N. +/// \since Crypto++ 6.0 +template +class EncodedPoint +{ +public: + virtual ~EncodedPoint() {} + + /// \brief Decodes an elliptic curve point + /// \param P point which is decoded + /// \param bt source BufferedTransformation + /// \param len number of bytes to read from the BufferedTransformation + /// \return true if a point was decoded, false otherwise + virtual bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const =0; + + /// \brief Decodes an elliptic curve point + /// \param P point which is decoded + /// \param encodedPoint byte array with the encoded point + /// \param len the size of the array + /// \return true if a point was decoded, false otherwise + virtual bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const =0; + + /// \brief Verifies points on elliptic curve + /// \param P point to verify + /// \return true if the point is valid, false otherwise + virtual bool VerifyPoint(const Point &P) const =0; + + /// \brief Determines encoded point size + /// \param compressed flag indicating if the point is compressed + /// \return the minimum number of bytes required to encode the point + virtual unsigned int EncodedPointSize(bool compressed = false) const =0; + + /// \brief Encodes an elliptic curve point + /// \param P point which is decoded + /// \param encodedPoint byte array for the encoded point + /// \param compressed flag indicating if the point is compressed + /// \details encodedPoint must be at least EncodedPointSize() in length + virtual void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const =0; + + /// \brief Encodes an elliptic curve point + /// \param bt target BufferedTransformation + /// \param P point which is encoded + /// \param compressed flag indicating if the point is compressed + virtual void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const =0; + + /// \brief BER Decodes an elliptic curve point + /// \param bt source BufferedTransformation + /// \return the decoded elliptic curve point + virtual Point BERDecodePoint(BufferedTransformation &bt) const =0; + + /// \brief DER Encodes an elliptic curve point + /// \param bt target BufferedTransformation + /// \param P point which is encoded + /// \param compressed flag indicating if the point is compressed + virtual void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const =0; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_ECPOINT_H diff --git a/external/ours/library/crypto/src/shared/original/elgamal.cpp b/external/ours/library/crypto/src/shared/original/elgamal.cpp new file mode 100755 index 000000000..9871c538d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/elgamal.cpp @@ -0,0 +1,22 @@ +// elgamal.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "elgamal.h" +#include "asn.h" +#include "nbtheory.h" + +// Squash MS LNK4221 and libtool warnings +extern const char ELGAMAL_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void ElGamal_TestInstantiations() +{ + ElGamalEncryptor test1(1, 1, 1); + ElGamalDecryptor test2(NullRNG(), 123); + ElGamalEncryptor test3(test2); +} +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/elgamal.h b/external/ours/library/crypto/src/shared/original/elgamal.h new file mode 100755 index 000000000..c4e1732d8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/elgamal.h @@ -0,0 +1,308 @@ +// elgamal.h - originally written and placed in the public domain by Wei Dai + +/// \file elgamal.h +/// \brief Classes and functions for ElGamal key agreement and encryption schemes + +#ifndef CRYPTOPP_ELGAMAL_H +#define CRYPTOPP_ELGAMAL_H + +#include "cryptlib.h" +#include "modexppc.h" +#include "integer.h" +#include "gfpcrypt.h" +#include "pubkey.h" +#include "misc.h" +#include "oids.h" +#include "dsa.h" +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief ElGamal key agreement and encryption schemes base class +/// \since Crypto++ 1.0 +class CRYPTOPP_NO_VTABLE ElGamalBase : + public DL_KeyAgreementAlgorithm_DH, + public DL_KeyDerivationAlgorithm, + public DL_SymmetricEncryptionAlgorithm +{ +public: + virtual ~ElGamalBase() {} + + void Derive(const DL_GroupParameters &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const + { + CRYPTOPP_UNUSED(groupParams); CRYPTOPP_UNUSED(ephemeralPublicKey); + CRYPTOPP_UNUSED(derivationParams); + agreedElement.Encode(derivedKey, derivedLength); + } + + size_t GetSymmetricKeyLength(size_t plainTextLength) const + { + CRYPTOPP_UNUSED(plainTextLength); + return GetGroupParameters().GetModulus().ByteCount(); + } + + size_t GetSymmetricCiphertextLength(size_t plainTextLength) const + { + unsigned int len = GetGroupParameters().GetModulus().ByteCount(); + if (plainTextLength <= GetMaxSymmetricPlaintextLength(len)) + return len; + else + return 0; + } + + size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const + { + unsigned int len = GetGroupParameters().GetModulus().ByteCount(); + CRYPTOPP_ASSERT(len >= 3); + + if (cipherTextLength == len) + return STDMIN(255U, len-3); + else + return 0; + } + + void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs ¶meters) const + { + CRYPTOPP_UNUSED(parameters); + const Integer &p = GetGroupParameters().GetModulus(); + unsigned int modulusLen = p.ByteCount(); + + SecByteBlock block(modulusLen-1); + rng.GenerateBlock(block, modulusLen-2-plainTextLength); + memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength); + block[modulusLen-2] = (byte)plainTextLength; + + a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen); + } + + DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs ¶meters) const + { + CRYPTOPP_UNUSED(parameters); + const Integer &p = GetGroupParameters().GetModulus(); + unsigned int modulusLen = p.ByteCount(); + + if (cipherTextLength != modulusLen) + return DecodingResult(); + + Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p); + + m.Encode(plainText, 1); + unsigned int plainTextLength = plainText[0]; + if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen)) + return DecodingResult(); + m >>= 8; + m.Encode(plainText, plainTextLength); + return DecodingResult(plainTextLength); + } + + virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0; +}; + +/// \brief ElGamal key agreement and encryption schemes default implementation +/// \tparam BASE Base class implementation +/// \tparam SCHEME_OPTIONS Scheme options +/// \tparam KEY ElGamal key classes +/// \since Crypto++ 1.0 +template +class ElGamalObjectImpl : + public DL_ObjectImplBase, + public ElGamalBase +{ +public: + virtual ~ElGamalObjectImpl() {} + + size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());} + size_t FixedCiphertextLength() const {return this->CiphertextLength(0);} + + const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();} + + DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const + {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);} + +protected: + const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const {return *this;} + const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const {return *this;} + const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;} +}; + +/// \brief ElGamal Public Key adapter +/// \tparam BASE PublicKey derived class +/// \details DL_PublicKey_ElGamal provides an override for GetAlgorithmID() +/// to utilize 1.3.14.7.2.1.1. Prior to DL_PublicKey_ElGamal, the ElGamal +/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP(). +/// If you need to Load an ElGamal key with the wrong OID then +/// see ElGamal on +/// the Crypto++ wiki. +/// \sa Issue 876, +/// Issue 567 +/// \since Crypto++ 8.3 +template +struct DL_PublicKey_ElGamal : public BASE +{ + virtual ~DL_PublicKey_ElGamal() {} + + /// \brief Retrieves the OID of the algorithm + /// \return OID of the algorithm + /// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID() + /// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal + /// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP(). + /// If you need to Load an ElGamal key with the wrong OID then + /// see ElGamal on + /// the Crypto++ wiki. + /// \sa Issue 876, + /// Issue 567 + virtual OID GetAlgorithmID() const { + return ASN1::elGamal(); + } +}; + +/// \brief ElGamal Private Key adapter +/// \tparam BASE PrivateKey derived class +/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID() +/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal +/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP(). +/// If you need to Load an ElGamal key with the wrong OID then +/// see ElGamal on +/// the Crypto++ wiki. +/// \sa Issue 876, +/// Issue 567 +/// \since Crypto++ 8.3 +template +struct DL_PrivateKey_ElGamal : public BASE +{ + virtual ~DL_PrivateKey_ElGamal() {} + + /// \brief Retrieves the OID of the algorithm + /// \return OID of the algorithm + /// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID() + /// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal + /// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP(). + /// If you need to Load an ElGamal key with the wrong OID then + /// see ElGamal on + /// the Crypto++ wiki. + /// \sa Issue 876, + /// Issue 567 + virtual OID GetAlgorithmID() const { + return ASN1::elGamal(); + } + + /// \brief Check the key for errors + /// \param rng RandomNumberGenerator for objects which use randomized testing + /// \param level level of thoroughness + /// \return true if the tests succeed, false otherwise + /// \details There are four levels of thoroughness: + ///

    + ///
  • 0 - using this object won't cause a crash or exception + ///
  • 1 - this object will probably function, and encrypt, sign, other + /// operations correctly + ///
  • 2 - ensure this object will function correctly, and perform + /// reasonable security checks + ///
  • 3 - perform reasonable security checks, and do checks that may + /// take a long time + ///
+ /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can + /// be used for level 0. Level 1 may not check for weak keys and such. + /// Levels 2 and 3 are recommended. + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + // Validate() formerly used DL_PrivateKey_GFP implementation through + // inheritance. However, it would reject keys from other libraries + // like BouncyCastle. The failure was x < q. According to ElGamal's + // paper and the HAC, the private key is selected in over [1,p-1], + // Later Tsiounis and Yung showed the lower limit as [1,q-1] in + // "On the Security of EIGamal Based Encryption". As such, Crypto++ + // will generate a key in the range [1,q-1], but accept a key + // in [1,p-1]. Thanks to JPM for finding the reference. Also see + // https://github.com/weidai11/cryptopp/commit/a5a684d92986. + + CRYPTOPP_ASSERT(this->GetAbstractGroupParameters().Validate(rng, level)); + bool pass = this->GetAbstractGroupParameters().Validate(rng, level); + + const Integer &p = this->GetGroupParameters().GetModulus(); + const Integer &q = this->GetAbstractGroupParameters().GetSubgroupOrder(); + const Integer &x = this->GetPrivateExponent(); + + // Changed to x < p-1 based on ElGamal's paper and the HAC. + CRYPTOPP_ASSERT(x.IsPositive()); + CRYPTOPP_ASSERT(x < p-1); + pass = pass && x.IsPositive() && x < p-1; + + if (level >= 1) + { + // Minimum security level due to Tsiounis and Yung. + CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One()); + pass = pass && Integer::Gcd(x, q) == Integer::One(); + } + return pass; + } +}; + +/// \brief ElGamal key agreement and encryption schemes keys +/// \details ElGamalKeys provide the algorithm implementation ElGamal key +/// agreement and encryption schemes. +/// \details The ElGamalKeys class used DL_PrivateKey_GFP_OldFormat +/// and DL_PublicKey_GFP_OldFormat for the PrivateKey and +/// PublicKey from about Crypto++ 1.0 through Crypto++ 5.6.5. At +/// Crypto++ 6.0 the serialization format was cutover to standard PKCS8 and +/// X509 encodings. +/// \details The ElGamalKeys class [mistakenly] used the OID for DSA from +/// about Crypto++ 1.0 through Crypto++ 8.2. At Crypto++ 8.3 the OID was +/// fixed and now uses ElGamal encryption, which is 1.3.14.7.2.1.1. +/// If you need to Load an ElGamal key with the wrong OID then +/// see ElGamal on +/// the Crypto++ wiki. +/// \details At Crypto++ 8.6 ElGamalKeys were changed to use DL_CryptoKeys_ElGamal +/// due to Issue 1069 and CVE-2021-40530. DL_CryptoKeys_ElGamal group parameters +/// use the subgroup order, and not an estimated work factor. +/// \sa Issue 876, +/// Issue 567, +/// Issue 1059 +/// \since Crypto++ 1.0 +struct ElGamalKeys +{ + /// \brief Implements DL_GroupParameters interface + typedef DL_CryptoKeys_ElGamal::GroupParameters GroupParameters; + /// \brief Implements DL_PrivateKey interface + typedef DL_PrivateKey_ElGamal PrivateKey; + /// \brief Implements DL_PublicKey interface + typedef DL_PublicKey_ElGamal PublicKey; +}; + +/// \brief ElGamal encryption scheme with non-standard padding +/// \details ElGamal provide the algorithm implementation ElGamal key +/// agreement and encryption schemes. +/// \details The ElGamal class [mistakenly] used the OID for DSA from about +/// Crypto++ 1.0 through Crypto++ 8.2. At Crypto++ 8.3 the OID was fixed +/// and now uses ElGamal encryption, which is 1.3.14.7.2.1.1. +/// If you need to Load an ElGamal key with the wrong OID then +/// see ElGamal on +/// the Crypto++ wiki. +/// \sa Issue 876, +/// Issue 567 +/// \since Crypto++ 1.0 +struct ElGamal +{ + typedef DL_CryptoSchemeOptions SchemeOptions; + typedef SchemeOptions::PrivateKey PrivateKey; + typedef SchemeOptions::PublicKey PublicKey; + + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";} + + /// \brief Implements DL_GroupParameters interface + typedef SchemeOptions::GroupParameters GroupParameters; + /// \brief Implements PK_Encryptor interface + typedef PK_FinalTemplate, SchemeOptions, SchemeOptions::PublicKey> > Encryptor; + /// \brief Implements PK_Encryptor interface + typedef PK_FinalTemplate, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor; +}; + +typedef ElGamal::Encryptor ElGamalEncryptor; +typedef ElGamal::Decryptor ElGamalDecryptor; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/emsa2.cpp b/external/ours/library/crypto/src/shared/original/emsa2.cpp new file mode 100755 index 000000000..dd5173dde --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/emsa2.cpp @@ -0,0 +1,44 @@ +// emsa2.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "emsa2.h" + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +// Inclusion based on DLL due to Clang, http://github.com/weidai11/cryptopp/issues/300 +#ifndef CRYPTOPP_IS_DLL +template<> const byte EMSA2HashId::id = 0x33; +template<> const byte EMSA2HashId::id = 0x38; +template<> const byte EMSA2HashId::id = 0x34; +template<> const byte EMSA2HashId::id = 0x36; +template<> const byte EMSA2HashId::id = 0x35; +#endif + +void EMSA2Pad::ComputeMessageRepresentative(RandomNumberGenerator& /*rng*/, + const byte* recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength), CRYPTOPP_UNUSED(representativeBitLength); + CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + if (representativeBitLength % 8 != 7) + throw PK_SignatureScheme::InvalidKeyLength("EMSA2: EMSA2 requires a key length that is a multiple of 8"); + + size_t digestSize = hash.DigestSize(); + size_t representativeByteLength = BitsToBytes(representativeBitLength); + + representative[0] = messageEmpty ? 0x4b : 0x6b; + memset(representative+1, 0xbb, representativeByteLength-digestSize-4); // pad with 0xbb + byte *afterP2 = representative+representativeByteLength-digestSize-3; + afterP2[0] = 0xba; + hash.Final(afterP2+1); + representative[representativeByteLength-2] = *hashIdentifier.first; + representative[representativeByteLength-1] = 0xcc; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/emsa2.h b/external/ours/library/crypto/src/shared/original/emsa2.h new file mode 100755 index 000000000..0db5ea341 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/emsa2.h @@ -0,0 +1,101 @@ +// emsa2.h - originally written and placed in the public domain by Wei Dai + +/// \file emsa2.h +/// \brief Classes and functions for various padding schemes used in public key algorithms + +#ifndef CRYPTOPP_EMSA2_H +#define CRYPTOPP_EMSA2_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "hashfwd.h" +#include "misc.h" + +#ifdef CRYPTOPP_IS_DLL +# include "sha.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief EMSA2 hash identifier +/// \tparam H HashTransformation derived class +/// \since Crypto++ 5.0 +template class EMSA2HashId +{ +public: + static const byte id; +}; + +/// \brief EMSA2 padding method +/// \tparam BASE Message encoding method +/// \since Crypto++ 5.0 +template +class EMSA2HashIdLookup : public BASE +{ +public: + struct HashIdentifierLookup + { + template struct HashIdentifierLookup2 + { + static HashIdentifier Lookup() + { + return HashIdentifier(&EMSA2HashId::id, 1); + } + }; + }; +}; + +// EMSA2HashId can be instantiated with the following classes. +// SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD128, RIPEMD160, Whirlpool + +#ifdef CRYPTOPP_IS_DLL +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +#endif + +// https://github.com/weidai11/cryptopp/issues/300 and +// https://github.com/weidai11/cryptopp/issues/533 +#if defined(__clang__) +template<> const byte EMSA2HashId::id; +template<> const byte EMSA2HashId::id; +template<> const byte EMSA2HashId::id; +template<> const byte EMSA2HashId::id; +template<> const byte EMSA2HashId::id; +#endif + +/// \brief EMSA2 padding method +/// \since Crypto++ 5.0 +class CRYPTOPP_DLL EMSA2Pad : public EMSA2HashIdLookup +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "EMSA2";} + + size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const + {CRYPTOPP_UNUSED(hashIdentifierLength); return 8*digestLength + 31;} + + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +// EMSA2, for use with RWSS and RSA_ISO +// Only the following hash functions are supported by this signature standard: +// \dontinclude emsa2.h +// \skip EMSA2HashId can be instantiated +// \until end of list + +/// \brief EMSA2/P1363 padding method +/// \details Use with RWSS and RSA_ISO +/// \since Crypto++ 5.0 +struct P1363_EMSA2 : public SignatureStandard +{ + typedef EMSA2Pad SignatureMessageEncodingMethod; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/eprecomp.cpp b/external/ours/library/crypto/src/shared/original/eprecomp.cpp new file mode 100755 index 000000000..751030893 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/eprecomp.cpp @@ -0,0 +1,114 @@ +// eprecomp.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "eprecomp.h" +#include "integer.h" +#include "algebra.h" +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +template void DL_FixedBasePrecomputationImpl::SetBase(const DL_GroupPrecomputation &group, const Element &i_base) +{ + m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base; + + if (m_bases.empty() || !(m_base == m_bases[0])) + { + m_bases.resize(1); + m_bases[0] = m_base; + } + + if (group.NeedConversions()) + m_base = i_base; +} + +template void DL_FixedBasePrecomputationImpl::Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) +{ + CRYPTOPP_ASSERT(m_bases.size() > 0); + CRYPTOPP_ASSERT(storage <= maxExpBits); + + if (storage > 1) + { + m_windowSize = (maxExpBits+storage-1)/storage; + m_exponentBase = Integer::Power2(m_windowSize); + } + + m_bases.resize(storage); + for (unsigned i=1; i void DL_FixedBasePrecomputationImpl::Load(const DL_GroupPrecomputation &group, BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); + m_exponentBase.BERDecode(seq); + m_windowSize = m_exponentBase.BitCount() - 1; + m_bases.clear(); + while (!seq.EndReached()) + m_bases.push_back(group.BERDecodeElement(seq)); + if (!m_bases.empty() && group.NeedConversions()) + m_base = group.ConvertOut(m_bases[0]); + seq.MessageEnd(); +} + +template void DL_FixedBasePrecomputationImpl::Save(const DL_GroupPrecomputation &group, BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + DEREncodeUnsigned(seq, 1); // version + m_exponentBase.DEREncode(seq); + for (unsigned i=0; i void DL_FixedBasePrecomputationImpl::PrepareCascade(const DL_GroupPrecomputation &i_group, std::vector > &eb, const Integer &exponent) const +{ + const AbstractGroup &group = i_group.GetGroup(); + + Integer r, q, e = exponent; + bool fastNegate = group.InversionIsFast() && m_windowSize > 1; + unsigned int i; + + for (i=0; i+1(group.Inverse(m_bases[i]), m_exponentBase - r)); + } + else + eb.push_back(BaseAndExponent(m_bases[i], r)); + } + eb.push_back(BaseAndExponent(m_bases[i], e)); +} + +template T DL_FixedBasePrecomputationImpl::Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const +{ + std::vector > eb; // array of segments of the exponent and precalculated bases + eb.reserve(m_bases.size()); + PrepareCascade(group, eb, exponent); + return group.ConvertOut(GeneralCascadeMultiplication(group.GetGroup(), eb.begin(), eb.end())); +} + +template T + DL_FixedBasePrecomputationImpl::CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, + const DL_FixedBasePrecomputation &i_pc2, const Integer &exponent2) const +{ + std::vector > eb; // array of segments of the exponent and precalculated bases + const DL_FixedBasePrecomputationImpl &pc2 = static_cast &>(i_pc2); + eb.reserve(m_bases.size() + pc2.m_bases.size()); + PrepareCascade(group, eb, exponent); + pc2.PrepareCascade(group, eb, exponent2); + return group.ConvertOut(GeneralCascadeMultiplication(group.GetGroup(), eb.begin(), eb.end())); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/eprecomp.h b/external/ours/library/crypto/src/shared/original/eprecomp.h new file mode 100755 index 000000000..737a15694 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/eprecomp.h @@ -0,0 +1,162 @@ +// eprecomp.h - originally written and placed in the public domain by Wei Dai + +/// \file eprecomp.h +/// \brief Classes for precomputation in a group + +#ifndef CRYPTOPP_EPRECOMP_H +#define CRYPTOPP_EPRECOMP_H + +#include "cryptlib.h" +#include "integer.h" +#include "algebra.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief DL_GroupPrecomputation interface +/// \tparam T Field element +template +class DL_GroupPrecomputation +{ +public: + typedef T Element; + + virtual ~DL_GroupPrecomputation() {} + + /// \brief Determines if elements needs conversion + /// \return true if the element needs conversion, false otherwise + /// \details NeedConversions determines if an element must convert between representations. + virtual bool NeedConversions() const {return false;} + + /// \brief Converts an element between representations + /// \param v element to convert + /// \return an element converted to an alternate representation for internal use + /// \details ConvertIn is used when an element must convert between representations. + virtual Element ConvertIn(const Element &v) const {return v;} + + /// \brief Converts an element between representations + /// \param v element to convert + /// \return an element converted from an alternate representation + virtual Element ConvertOut(const Element &v) const {return v;} + + /// \brief Retrieves AbstractGroup interface + /// \return GetGroup() returns the AbstractGroup interface + virtual const AbstractGroup & GetGroup() const =0; + + /// \brief Decodes element in DER format + /// \param bt BufferedTransformation object + /// \return element in the group + virtual Element BERDecodeElement(BufferedTransformation &bt) const =0; + + /// \brief Encodes element in DER format + /// \param bt BufferedTransformation object + /// \param P Element to encode + virtual void DEREncodeElement(BufferedTransformation &bt, const Element &P) const =0; +}; + +/// \brief DL_FixedBasePrecomputation interface +/// \tparam T Field element +template +class DL_FixedBasePrecomputation +{ +public: + typedef T Element; + + virtual ~DL_FixedBasePrecomputation() {} + + /// \brief Determines whether this object is initialized + /// \return true if this object is initialized, false otherwise + virtual bool IsInitialized() const =0; + + /// \brief Set the base element + /// \param group the group + /// \param base element in the group + virtual void SetBase(const DL_GroupPrecomputation &group, const Element &base) =0; + + /// \brief Get the base element + /// \param group the group + /// \return base element in the group + virtual const Element & GetBase(const DL_GroupPrecomputation &group) const =0; + + /// \brief Perform precomputation + /// \param group the group + /// \param maxExpBits used to calculate the exponent base + /// \param storage the suggested number of objects for the precompute table + /// \details The exact semantics of Precompute() varies, but it typically means calculate + /// a table of n objects that can be used later to speed up computation. + /// \details If a derived class does not override Precompute(), then the base class throws + /// NotImplemented. + /// \sa SupportsPrecomputation(), LoadPrecomputation(), SavePrecomputation() + virtual void Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) =0; + + /// \brief Retrieve previously saved precomputation + /// \param group the group + /// \param storedPrecomputation BufferedTransformation with the saved precomputation + /// \throw NotImplemented + /// \sa SupportsPrecomputation(), Precompute() + virtual void Load(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) =0; + + /// \brief Save precomputation for later use + /// \param group the group + /// \param storedPrecomputation BufferedTransformation to write the precomputation + /// \throw NotImplemented + /// \sa SupportsPrecomputation(), Precompute() + virtual void Save(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) const =0; + + /// \brief Exponentiates an element + /// \param group the group + /// \param exponent the exponent + /// \return the result of the exponentiation + virtual Element Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const =0; + + /// \brief Exponentiates an element + /// \param pc1 the first the group precomputation + /// \param exponent1 the first exponent + /// \param pc2 the second the group precomputation + /// \param exponent2 the first exponent2 + /// \return the public element raised to the exponent + /// \details CascadeExponentiateBaseAndPublicElement raises the public element to + /// the base element and precomputation. + virtual Element CascadeExponentiate(const DL_GroupPrecomputation &pc1, const Integer &exponent1, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const =0; +}; + +/// \brief DL_FixedBasePrecomputation adapter class +/// \tparam T Field element +template +class DL_FixedBasePrecomputationImpl : public DL_FixedBasePrecomputation +{ +public: + typedef T Element; + + virtual ~DL_FixedBasePrecomputationImpl() {} + + DL_FixedBasePrecomputationImpl() : m_windowSize(0) {} + + // DL_FixedBasePrecomputation + bool IsInitialized() const + {return !m_bases.empty();} + void SetBase(const DL_GroupPrecomputation &group, const Element &base); + const Element & GetBase(const DL_GroupPrecomputation &group) const + {return group.NeedConversions() ? m_base : m_bases[0];} + void Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage); + void Load(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation); + void Save(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) const; + Element Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const; + Element CascadeExponentiate(const DL_GroupPrecomputation &pc1, const Integer &exponent1, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const; + +private: + void PrepareCascade(const DL_GroupPrecomputation &group, std::vector > &eb, const Integer &exponent) const; + + Element m_base; + unsigned int m_windowSize; + Integer m_exponentBase; // what base to represent the exponent in + std::vector m_bases; // precalculated bases +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "eprecomp.cpp" +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/esign.cpp b/external/ours/library/crypto/src/shared/original/esign.cpp new file mode 100755 index 000000000..7c69a6841 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/esign.cpp @@ -0,0 +1,233 @@ +// esign.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +// TODO: fix the C4589 warnings +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4589) +#endif + +#include "esign.h" +#include "modarith.h" +#include "integer.h" +#include "nbtheory.h" +#include "algparam.h" +#include "sha.h" +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void ESIGN_TestInstantiations() +{ + ESIGN::Verifier x1(1, 1); + ESIGN::Signer x2(NullRNG(), 1); + ESIGN::Verifier x3(x2); + ESIGN::Verifier x4(x2.GetKey()); + ESIGN::Verifier x5(x3); + ESIGN::Signer x6 = x2; + + x6 = x2; + x3 = ESIGN::Verifier(x2); + x4 = x2.GetKey(); +} +#endif + +void ESIGNFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_e.BERDecode(seq); + seq.MessageEnd(); +} + +void ESIGNFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_e.DEREncode(seq); + seq.MessageEnd(); +} + +Integer ESIGNFunction::ApplyFunction(const Integer &x) const +{ + DoQuickSanityCheck(); + return STDMIN(a_exp_b_mod_c(x, m_e, m_n) >> (2*GetK()+2), MaxImage()); +} + +bool ESIGNFunction::Validate(RandomNumberGenerator& rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(level); + bool pass = true; + pass = pass && m_n > Integer::One() && m_n.IsOdd(); + CRYPTOPP_ASSERT(pass); + pass = pass && m_e >= 8 && m_e < m_n; + CRYPTOPP_ASSERT(pass); + return pass; +} + +bool ESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) + ; +} + +void ESIGNFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) + ; +} + +// ***************************************************************************** + +void InvertibleESIGNFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶m) +{ + int modulusSize = 1023*2; + param.GetIntValue("ModulusSize", modulusSize) || param.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 24) + throw InvalidArgument("InvertibleESIGNFunction: specified modulus size is too small"); + + if (modulusSize % 3 != 0) + throw InvalidArgument("InvertibleESIGNFunction: modulus size must be divisible by 3"); + + m_e = param.GetValueWithDefault("PublicExponent", Integer(32)); + + if (m_e < 8) + throw InvalidArgument("InvertibleESIGNFunction: public exponents less than 8 may not be secure"); + + // VC70 workaround: putting these after primeParam causes overlapped stack allocation + ConstByteArrayParameter seedParam; + SecByteBlock seed; + + const Integer minP = Integer(204) << (modulusSize/3-8); + const Integer maxP = Integer::Power2(modulusSize/3)-1; + AlgorithmParameters primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME); + + if (param.GetValue("Seed", seedParam)) + { + seed.resize(seedParam.size() + 4); + memcpy(seed + 4, seedParam.begin(), seedParam.size()); + + PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0); + m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed)))); + PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)1); + m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed)))); + } + else + { + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + } + + m_n = m_p * m_p * m_q; + + CRYPTOPP_ASSERT(m_n.BitCount() == (unsigned int)modulusSize); +} + +void InvertibleESIGNFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder privateKey(bt); + m_n.BERDecode(privateKey); + m_e.BERDecode(privateKey); + m_p.BERDecode(privateKey); + m_q.BERDecode(privateKey); + privateKey.MessageEnd(); +} + +void InvertibleESIGNFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + m_n.DEREncode(privateKey); + m_e.DEREncode(privateKey); + m_p.DEREncode(privateKey); + m_q.DEREncode(privateKey); + privateKey.MessageEnd(); +} + +Integer InvertibleESIGNFunction::CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + DoQuickSanityCheck(); + + Integer pq = m_p * m_q; + Integer p2 = m_p * m_p; + Integer r, z, re, a, w0, w1; + + do + { + r.Randomize(rng, Integer::Zero(), pq); + z = x << (2*GetK()+2); + re = a_exp_b_mod_c(r, m_e, m_n); + a = (z - re) % m_n; + Integer::Divide(w1, w0, a, pq); + if (w1.NotZero()) + { + ++w0; + w1 = pq - w1; + } + } + while ((w1 >> (2*GetK()+1)).IsPositive()); + + ModularArithmetic modp(m_p); + Integer t = modp.Divide(w0 * r % m_p, m_e * re % m_p); + Integer s = r + t*pq; + CRYPTOPP_ASSERT(s < m_n); +#if 0 + using namespace std; + cout << "f = " << x << endl; + cout << "r = " << r << endl; + cout << "z = " << z << endl; + cout << "a = " << a << endl; + cout << "w0 = " << w0 << endl; + cout << "w1 = " << w1 << endl; + cout << "t = " << t << endl; + cout << "s = " << s << endl; +#endif + return s; +} + +bool InvertibleESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = ESIGNFunction::Validate(rng, level); + CRYPTOPP_ASSERT(pass); + pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_p.BitCount() == m_q.BitCount(); + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && m_p * m_p * m_q == m_n; + CRYPTOPP_ASSERT(pass); + } + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool InvertibleESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + ; +} + +void InvertibleESIGNFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + ; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/esign.h b/external/ours/library/crypto/src/shared/original/esign.h new file mode 100755 index 000000000..274c18106 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/esign.h @@ -0,0 +1,169 @@ +// esign.h - originally written and placed in the public domain by Wei Dai + +/// \file esign.h +/// \brief Classes providing ESIGN signature schemes as defined in IEEE P1363a +/// \since Crypto++ 5.0 + +#ifndef CRYPTOPP_ESIGN_H +#define CRYPTOPP_ESIGN_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "integer.h" +#include "asn.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief ESIGN trapdoor function using the public key +/// \since Crypto++ 5.0 +class ESIGNFunction : public TrapdoorFunction, public ASN1CryptoMaterial +{ + typedef ESIGNFunction ThisClass; + +public: + + /// \brief Initialize a ESIGN public key with {n,e} + /// \param n the modulus + /// \param e the public exponent + void Initialize(const Integer &n, const Integer &e) + {m_n = n; m_e = e;} + + // PublicKey + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // TrapdoorFunction + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return Integer::Power2(GetK());} + + // non-derived + const Integer & GetModulus() const {return m_n;} + const Integer & GetPublicExponent() const {return m_e;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetPublicExponent(const Integer &e) {m_e = e;} + +protected: + // Covertiy finding on overflow. The library allows small values for research purposes. + unsigned int GetK() const {return SaturatingSubtract(m_n.BitCount()/3, 1U);} + + Integer m_n, m_e; +}; + +/// \brief ESIGN trapdoor function using the private key +/// \since Crypto++ 5.0 +class InvertibleESIGNFunction : public ESIGNFunction, public RandomizedTrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleESIGNFunction ThisClass; + +public: + + /// \brief Initialize a ESIGN private key with {n,e,p,q} + /// \param n modulus + /// \param e public exponent + /// \param p first prime factor + /// \param q second prime factor + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q) + {m_n = n; m_e = e; m_p = p; m_q = q;} + + /// \brief Create a ESIGN private key + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulud, in bits + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {GenerateRandomWithKeySize(rng, modulusBits);} + + // Squash Visual Studio C4250 warning + void Save(BufferedTransformation &bt) const + {BEREncode(bt);} + + // Squash Visual Studio C4250 warning + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const; + + // GeneratibleCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + +protected: + Integer m_p, m_q; +}; + +/// \brief EMSA5 padding method +/// \tparam T Mask Generation Function +/// \since Crypto++ 5.0 +template +class EMSA5Pad : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "EMSA5";} + + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const + { + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength); + CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier); + SecByteBlock digest(hash.DigestSize()); + hash.Final(digest); + size_t representativeByteLength = BitsToBytes(representativeBitLength); + T mgf; + mgf.GenerateAndMask(hash, representative, representativeByteLength, digest, digest.size(), false); + if (representativeBitLength % 8 != 0) + representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); + } +}; + +/// \brief EMSA5 padding method, for use with ESIGN +/// \since Crypto++ 5.0 +struct P1363_EMSA5 : public SignatureStandard +{ + typedef EMSA5Pad SignatureMessageEncodingMethod; +}; + +/// \brief ESIGN keys +/// \since Crypto++ 5.0 +struct ESIGN_Keys +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ESIGN";} + typedef ESIGNFunction PublicKey; + typedef InvertibleESIGNFunction PrivateKey; +}; + +/// \brief ESIGN signature scheme, IEEE P1363a +/// \tparam H HashTransformation derived class +/// \tparam STANDARD Signature encoding method +/// \since Crypto++ 5.0 +template +struct ESIGN : public TF_SS +{ +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/factory.h b/external/ours/library/crypto/src/shared/original/factory.h new file mode 100755 index 000000000..d3d36e3c3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/factory.h @@ -0,0 +1,179 @@ +// factory.h - originally written and placed in the public domain by Wei Dai + +/// \file factory.h +/// \brief Classes and functions for registering and locating library objects + +#ifndef CRYPTOPP_OBJFACT_H +#define CRYPTOPP_OBJFACT_H + +#include "cryptlib.h" +#include "misc.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Object factory interface for registering objects +/// \tparam AbstractClass Base class interface of the object +template +class ObjectFactory +{ +public: + virtual ~ObjectFactory () {} + virtual AbstractClass * CreateObject() const =0; +}; + +/// \brief Object factory for registering objects +/// \tparam AbstractClass Base class interface of the object +/// \tparam ConcreteClass Class object +template +class DefaultObjectFactory : public ObjectFactory +{ +public: + AbstractClass * CreateObject() const + { + return new ConcreteClass; + } +}; + +/// \brief Object factory registry +/// \tparam AbstractClass Base class interface of the object +/// \tparam instance unique identifier +template +class ObjectFactoryRegistry +{ +public: + class FactoryNotFound : public Exception + { + public: + FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {} + }; + + ~ObjectFactoryRegistry() + { + for (typename Map::iterator i = m_map.begin(); i != m_map.end(); ++i) + { + delete (ObjectFactory *)i->second; + i->second = NULLPTR; + } + } + + void RegisterFactory(const std::string &name, ObjectFactory *factory) + { + m_map[name] = factory; + } + + const ObjectFactory * GetFactory(const char *name) const + { + typename Map::const_iterator i = m_map.find(name); + return i == m_map.end() ? NULLPTR : (ObjectFactory *)i->second; + } + + AbstractClass *CreateObject(const char *name) const + { + const ObjectFactory *factory = GetFactory(name); + if (!factory) + throw FactoryNotFound(name); + return factory->CreateObject(); + } + + // Return a vector containing the factory names. This is easier than returning an iterator. + // from Andrew Pitonyak + std::vector GetFactoryNames() const + { + std::vector names; + typename Map::const_iterator iter; + for (iter = m_map.begin(); iter != m_map.end(); ++iter) + names.push_back(iter->first); + return names; + } + + CRYPTOPP_NOINLINE static ObjectFactoryRegistry & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT); + +private: + // use void * instead of ObjectFactory * to save code size + typedef std::map Map; + Map m_map; +}; + +template +ObjectFactoryRegistry & ObjectFactoryRegistry::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT) +{ + static ObjectFactoryRegistry s_registry; + return s_registry; +} + +/// \brief Object factory registry helper +/// \tparam AbstractClass Base class interface of the object +/// \tparam ConcreteClass Class object +/// \tparam instance unique identifier +template +struct RegisterDefaultFactoryFor +{ + RegisterDefaultFactoryFor(const char *name=NULLPTR) + { + // BCB2006 workaround + std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName()); + ObjectFactoryRegistry::Registry(). + RegisterFactory(n, new DefaultObjectFactory); + } +}; + +/// \fn RegisterAsymmetricCipherDefaultFactories +/// \brief Register asymmetric ciphers +/// \tparam SchemeClass interface of the object under a scheme +/// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), +/// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. +template +void RegisterAsymmetricCipherDefaultFactories(const char *name=NULLPTR) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +/// \fn RegisterSignatureSchemeDefaultFactories +/// \brief Register signature schemes +/// \tparam SchemeClass interface of the object under a scheme +/// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), +/// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. +template +void RegisterSignatureSchemeDefaultFactories(const char *name=NULLPTR) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +/// \fn RegisterSymmetricCipherDefaultFactories +/// \brief Register symmetric ciphers +/// \tparam SchemeClass interface of the object under a scheme +/// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), +/// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. +template +void RegisterSymmetricCipherDefaultFactories(const char *name=NULLPTR) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +/// \fn RegisterAuthenticatedSymmetricCipherDefaultFactories +/// \brief Register authenticated symmetric ciphers +/// \tparam SchemeClass interface of the object under a scheme +/// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), +/// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), +/// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. +template +void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULLPTR) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/fhmqv.h b/external/ours/library/crypto/src/shared/original/fhmqv.h new file mode 100755 index 000000000..e247e1f20 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/fhmqv.h @@ -0,0 +1,408 @@ +// fhmqv.h - written and placed in the public domain by Jeffrey Walton, Ray Clayton and Uri Blumenthal +// Shamelessly based upon Wei Dai's MQV source files + +#ifndef CRYPTOPP_FHMQV_H +#define CRYPTOPP_FHMQV_H + +/// \file fhmqv.h +/// \brief Classes for Fully Hashed Menezes-Qu-Vanstone key agreement in GF(p) +/// \since Crypto++ 5.6.4 + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Fully Hashed Menezes-Qu-Vanstone in GF(p) +/// \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's +/// A Secure and Efficient Authenticated Diffie-Hellman Protocol. +/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +/// \sa MQV, HMQV, FHMQV, and AuthenticatedKeyAgreementDomain +/// \since Crypto++ 5.6.4 +template +class FHMQV_Domain : public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef FHMQV_Domain Domain; + + virtual ~FHMQV_Domain() {} + + /// \brief Construct a FHMQV domain + /// \param clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + FHMQV_Domain(bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) {} + + /// \brief Construct a FHMQV domain + /// \param params group parameters and options + /// \param clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + /// \brief Construct a FHMQV domain + /// \param bt BufferedTransformation with group parameters and options + /// \param clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + /// \brief Construct a FHMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1 is passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + FHMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + /// \brief Construct a FHMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + /// \brief Construct a FHMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + /// \brief Construct a FHMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \tparam T4 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param v4 third parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +public: + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a const reference + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a non-const reference + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + /// \brief Retrieves the crypto parameters for this domain + /// \return the crypto parameters for this domain as a non-const reference + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + + /// \brief Provides the size of the agreed value + /// \return size of agreed value produced in this domain + /// \details The length is calculated using GetEncodedElementSize(false), + /// which means the element is encoded in a non-reversible format. A + /// non-reversible format means its a raw byte array, and it lacks presentation + /// format like an ASN.1 BIT_STRING or OCTET_STRING. + unsigned int AgreedValueLength() const + {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + + /// \brief Provides the size of the static private key + /// \return size of static private keys in this domain + /// \details The length is calculated using the byte count of the subgroup order. + unsigned int StaticPrivateKeyLength() const + {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + + /// \brief Provides the size of the static public key + /// \return size of static public keys in this domain + /// \details The length is calculated using GetEncodedElementSize(true), + /// which means the element is encoded in a reversible format. A reversible + /// format means it has a presentation format, and its an ANS.1 encoded element + /// or point. + unsigned int StaticPublicKeyLength() const + {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + /// \brief Generate static private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \details The private key is a random scalar used as an exponent in the range + /// [1,MaxExponent()]. + /// \pre COUNTOF(privateKey) == PrivateStaticKeyLength() + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + /// \brief Generate a static public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details The public key is an element or point on the curve, and its stored + /// in a revrsible format. A reversible format means it has a presentation + /// format, and its an ANS.1 encoded element or point. + /// \pre COUNTOF(publicKey) == PublicStaticKeyLength() + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + /// \brief Provides the size of the ephemeral private key + /// \return size of ephemeral private keys in this domain + /// \details An ephemeral private key is a private key and public key. + /// The serialized size is different than a static private key. + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + + /// \brief Provides the size of the ephemeral public key + /// \return size of ephemeral public keys in this domain + /// \details An ephemeral public key is a public key. + /// The serialized size is the same as a static public key. + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + /// \brief Generate ephemeral private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \pre COUNTOF(privateKey) == EphemeralPrivateKeyLength() + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + /// \brief Generate ephemeral public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \pre COUNTOF(publicKey) == EphemeralPublicKeyLength() + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + /// \brief Derive agreed value or shared secret + /// \param agreedValue the shared secret + /// \param staticPrivateKey your long term private key + /// \param ephemeralPrivateKey your ephemeral private key + /// \param staticOtherPublicKey couterparty's long term public key + /// \param ephemeralOtherPublicKey couterparty's ephemeral public key + /// \param validateStaticOtherPublicKey flag indicating validation + /// \return true upon success, false in case of failure + /// \details Agree() performs the authenticated key agreement. Agree() + /// derives a shared secret from your private keys and couterparty's + /// public keys. Each instance or run of the protocol should use a new + /// ephemeral key pair. + /// \details The other's ephemeral public key will always be validated at + /// Level 1 to ensure it is a point on the curve. + /// validateStaticOtherPublicKey determines how thoroughly other's + /// static public key is validated. If you have previously validated the + /// couterparty's static public key, then use + /// validateStaticOtherPublicKey=false to save time. + /// \pre COUNTOF(agreedValue) == AgreedValueLength() + /// \pre COUNTOF(staticPrivateKey) == StaticPrivateKeyLength() + /// \pre COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength() + /// \pre COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength() + /// \pre COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength() + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + this->GetMaterial().DoQuickSanityCheck(); + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = ephemeralOtherPublicKey; + xxs = EphemeralPublicKeyLength(); + YY = ephemeralPrivateKey + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = staticOtherPublicKey; + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = ephemeralPrivateKey + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = ephemeralOtherPublicKey; + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = staticOtherPublicKey; + bbs = StaticPublicKeyLength(); + } + + Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey); + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true); + + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + SecByteBlock dd(len), ee(len); + + Hash(NULLPTR, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + Integer d(dd.BytePtr(), dd.SizeInBytes()); + + Hash(NULLPTR, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); + Integer e(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + sigma = params.ExponentiateElement(t2, s_A); + } + + Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + CRYPTOPP_ASSERT(0); + return false; + } + return true; + } + +protected: + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, const byte* e2, size_t e2len, + const byte* s1, size_t s1len, const byte* s2, size_t s2len, + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = STDMIN(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + //Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + //SecByteBlock sbb(x.MinEncodedSize()); + //x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false)); + GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } + + hash.Update(e1, e1len); + hash.Update(e2, e2len); + hash.Update(s1, s1len); + hash.Update(s2, s2len); + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = STDMIN(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole { RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + GroupParameters m_groupParameters; + KeyAgreementRole m_role; +}; + +/// \brief Fully Hashed Menezes-Qu-Vanstone in GF(p) +/// \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's +/// A Secure and Efficient Authenticated Diffie-Hellman Protocol. +/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +/// \sa FHMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain +/// \since Crypto++ 5.6.4 +typedef FHMQV_Domain FHMQV; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/files.cpp b/external/ours/library/crypto/src/shared/original/files.cpp new file mode 100755 index 000000000..16b66480e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/files.cpp @@ -0,0 +1,300 @@ +// files.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "files.h" + +#include +#include +#include + +ANONYMOUS_NAMESPACE_BEGIN + +/// \brief Disable badbit, failbit and eof exceptions +/// \sa https://github.com/weidai11/cryptopp/pull/968 and +/// https://www.cplusplus.com/reference/ios/ios/exceptions +class IosExceptionMask +{ +public: + IosExceptionMask(std::istream& stream) : m_stream(stream) { + m_mask = m_stream.exceptions(); + m_stream.exceptions(static_cast(0)); + } + + IosExceptionMask(std::istream& stream, std::ios::iostate newMask) : m_stream(stream) { + m_mask = m_stream.exceptions(); + m_stream.exceptions(newMask); + } + + ~IosExceptionMask() { + m_stream.exceptions(m_mask); + } + +private: + std::istream& m_stream; + std::ios::iostate m_mask; +}; + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void Files_TestInstantiations() +{ + FileStore f0; + FileSource f1; + FileSink f2; +} +#endif + +void FileStore::StoreInitialize(const NameValuePairs ¶meters) +{ + m_waiting = false; + m_stream = NULLPTR; + m_file.release(); + + const char *fileName = NULLPTR; +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + const wchar_t *fileNameWide = NULLPTR; + if (!parameters.GetValue(Name::InputFileNameWide(), fileNameWide)) +#endif + if (!parameters.GetValue(Name::InputFileName(), fileName)) + { + parameters.GetValue(Name::InputStreamPointer(), m_stream); + return; + } + + std::ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? std::ios::binary : std::ios::openmode(0); + m_file.reset(new std::ifstream); +#ifdef CRYPTOPP_UNIX_AVAILABLE + std::string narrowed; + if (fileNameWide) + fileName = (narrowed = StringNarrow(fileNameWide)).c_str(); +#endif +#if _MSC_VER >= 1400 + if (fileNameWide) + { + m_file->open(fileNameWide, std::ios::in | binary); + if (!*m_file) + throw OpenErr(StringNarrow(fileNameWide, false)); + } +#endif + if (fileName) + { + m_file->open(fileName, std::ios::in | binary); + if (!*m_file) + throw OpenErr(fileName); + } + m_stream = m_file.get(); +} + +lword FileStore::MaxRetrievable() const +{ + if (!m_stream) + return 0; + + // Disable badbit, failbit and eof exceptions + IosExceptionMask guard(*m_stream); + + // Clear error bits due to seekg(). Also see + // https://github.com/weidai11/cryptopp/pull/968 + std::streampos current = m_stream->tellg(); + std::streampos end = m_stream->seekg(0, std::ios::end).tellg(); + m_stream->clear(); + m_stream->seekg(current); + m_stream->clear(); + + // Return max for a non-seekable stream + // https://www.cplusplus.com/reference/istream/istream/tellg + if (end == static_cast(-1)) + return LWORD_MAX; + + return end-current; +} + +size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (!m_stream) + { + transferBytes = 0; + return 0; + } + + lword size=transferBytes; + transferBytes = 0; + + if (m_waiting) + goto output; + + size_t spaceSize, blockedBytes; + while (size && m_stream->good()) + { + spaceSize = 1024; + m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(SIZE_MAX), size), spaceSize); + m_stream->read((char *)m_space, (std::streamsize)STDMIN(size, (lword)spaceSize)); + m_len = (size_t)m_stream->gcount(); + +output: + blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); + m_waiting = blockedBytes > 0; + if (m_waiting) + return blockedBytes; + size -= m_len; + transferBytes += m_len; + } + + if (!m_stream->good() && !m_stream->eof()) + throw ReadErr(); + + return 0; +} + +size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + if (!m_stream) + return 0; + + if (begin == 0 && end == 1) + { + int result = m_stream->peek(); + if (result == std::char_traits::eof()) + return 0; + else + { + size_t blockedBytes = target.ChannelPut(channel, byte(result), blocking); + begin += 1-blockedBytes; + return blockedBytes; + } + } + + // TODO: figure out what happens on cin + std::streampos current = m_stream->tellg(); + std::streampos endPosition = m_stream->seekg(0, std::ios::end).tellg(); + std::streampos newPosition = current + static_cast(begin); + + if (newPosition >= endPosition) + { + m_stream->seekg(current); + return 0; // don't try to seek beyond the end of file + } + m_stream->seekg(newPosition); + try + { + CRYPTOPP_ASSERT(!m_waiting); + lword copyMax = end-begin; + size_t blockedBytes = const_cast(this)->TransferTo2(target, copyMax, channel, blocking); + begin += copyMax; + if (blockedBytes) + { + const_cast(this)->m_waiting = false; + return blockedBytes; + } + } + catch(...) + { + m_stream->clear(); + m_stream->seekg(current); + throw; + } + m_stream->clear(); + m_stream->seekg(current); + + return 0; +} + +lword FileStore::Skip(lword skipMax) +{ + if (!m_stream) + return 0; + + lword oldPos = m_stream->tellg(); + std::istream::off_type offset; + if (!SafeConvert(skipMax, offset)) + throw InvalidArgument("FileStore: maximum seek offset exceeded"); + m_stream->seekg(offset, std::ios::cur); + return (lword)m_stream->tellg() - oldPos; +} + +void FileSink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_stream = NULLPTR; + m_file.release(); + + const char *fileName = NULLPTR; +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + const wchar_t *fileNameWide = NULLPTR; + if (!parameters.GetValue(Name::OutputFileNameWide(), fileNameWide)) +#endif + if (!parameters.GetValue(Name::OutputFileName(), fileName)) + { + parameters.GetValue(Name::OutputStreamPointer(), m_stream); + return; + } + + std::ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? std::ios::binary : std::ios::openmode(0); + m_file.reset(new std::ofstream); +#ifdef CRYPTOPP_UNIX_AVAILABLE + std::string narrowed; + if (fileNameWide) + fileName = (narrowed = StringNarrow(fileNameWide)).c_str(); +#elif (CRYPTOPP_MSC_VERSION >= 1400) + if (fileNameWide) + { + m_file->open(fileNameWide, std::ios::out | std::ios::trunc | binary); + if (!*m_file) + throw OpenErr(StringNarrow(fileNameWide, false)); + } +#endif + if (fileName) + { + m_file->open(fileName, std::ios::out | std::ios::trunc | binary); + if (!*m_file) + throw OpenErr(fileName); + } + m_stream = m_file.get(); +} + +bool FileSink::IsolatedFlush(bool hardFlush, bool blocking) +{ + CRYPTOPP_UNUSED(hardFlush), CRYPTOPP_UNUSED(blocking); + if (!m_stream) + throw Err("FileSink: output stream not opened"); + + m_stream->flush(); + if (!m_stream->good()) + throw WriteErr(); + + return false; +} + +size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + CRYPTOPP_UNUSED(blocking); + if (!m_stream) + throw Err("FileSink: output stream not opened"); + + while (length > 0) + { + std::streamsize size; + if (!SafeConvert(length, size)) + size = ((std::numeric_limits::max)()); + m_stream->write((const char *)inString, size); + inString += size; + length -= (size_t)size; + } + + if (messageEnd) + m_stream->flush(); + + if (!m_stream->good()) + throw WriteErr(); + + return 0; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/files.h b/external/ours/library/crypto/src/shared/original/files.h new file mode 100755 index 000000000..8ff5dc85c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/files.h @@ -0,0 +1,181 @@ +// files.h - originally written and placed in the public domain by Wei Dai + +/// \file files.h +/// \brief Classes providing file-based library services +/// \since Crypto++ 1.0 + +#ifndef CRYPTOPP_FILES_H +#define CRYPTOPP_FILES_H + +#include "cryptlib.h" +#include "filters.h" +#include "argnames.h" +#include "smartptr.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Implementation of Store interface +/// \details file-based implementation of Store interface +class CRYPTOPP_DLL FileStore : public Store, private FilterPutSpaceHelper, public NotCopyable +{ +public: + /// \brief Exception thrown when file-based error is encountered + class Err : public Exception + { + public: + Err(const std::string &s) : Exception(IO_ERROR, s) {} + }; + /// \brief Exception thrown when file-based open error is encountered + class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}}; + /// \brief Exception thrown when file-based read error is encountered + class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}}; + + /// \brief Construct a FileStore + FileStore() : m_stream(NULLPTR), m_space(NULLPTR), m_len(0), m_waiting(0) {} + + /// \brief Construct a FileStore + /// \param in an existing stream + FileStore(std::istream &in) : m_stream(NULLPTR), m_space(NULLPTR), m_len(0), m_waiting(0) + {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));} + + /// \brief Construct a FileStore + /// \param filename the narrow name of the file to open + FileStore(const char *filename) : m_stream(NULLPTR), m_space(NULLPTR), m_len(0), m_waiting(0) + {StoreInitialize(MakeParameters(Name::InputFileName(), filename ? filename : ""));} + +#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) || _MSC_VER >= 1400 + /// \brief Construct a FileStore + /// \param filename the Unicode name of the file to open + /// \details On non-Windows OS, this function assumes that setlocale() has been called. + FileStore(const wchar_t *filename) + {StoreInitialize(MakeParameters(Name::InputFileNameWide(), filename));} +#endif + + /// \brief Retrieves the internal stream + /// \return the internal stream pointer + std::istream* GetStream() {return m_stream;} + + /// \brief Retrieves the internal stream + /// \return the internal stream pointer + const std::istream* GetStream() const {return m_stream;} + + /// \brief Provides the number of bytes ready for retrieval + /// \return the number of bytes ready for retrieval + /// \details All retrieval functions return the actual number of bytes retrieved, which is + /// the lesser of the request number and MaxRetrievable() + lword MaxRetrievable() const; + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + lword Skip(lword skipMax=ULONG_MAX); + +private: + void StoreInitialize(const NameValuePairs ¶meters); + + member_ptr m_file; + std::istream *m_stream; + byte *m_space; + size_t m_len; + bool m_waiting; +}; + +/// \brief Implementation of Store interface +/// \details file-based implementation of Store interface +class CRYPTOPP_DLL FileSource : public SourceTemplate +{ +public: + typedef FileStore::Err Err; + typedef FileStore::OpenErr OpenErr; + typedef FileStore::ReadErr ReadErr; + + /// \brief Construct a FileSource + FileSource(BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {} + + /// \brief Construct a FileSource + /// \param in an existing stream + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputStreamPointer(), &in));} + + /// \brief Construct a FileSource + /// \param filename the narrow name of the file to open + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + /// \param binary flag indicating if the file is binary + FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULLPTR, bool binary=true) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileName(), filename)(Name::InputBinaryMode(), binary));} + +#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) || _MSC_VER >= 1400 + /// \brief Construct a FileSource + /// \param filename the Unicode name of the file to open + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + /// \param binary flag indicating if the file is binary + /// \details On non-Windows OS, this function assumes that setlocale() has been called. + FileSource(const wchar_t *filename, bool pumpAll, BufferedTransformation *attachment = NULLPTR, bool binary=true) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileNameWide(), filename)(Name::InputBinaryMode(), binary));} +#endif + + /// \brief Retrieves the internal stream + /// \return the internal stream pointer + std::istream* GetStream() {return m_store.GetStream();} +}; + +/// \brief Implementation of Store interface +/// \details file-based implementation of Sink interface +class CRYPTOPP_DLL FileSink : public Sink, public NotCopyable +{ +public: + /// \brief Exception thrown when file-based error is encountered + class Err : public Exception + { + public: + Err(const std::string &s) : Exception(IO_ERROR, s) {} + }; + /// \brief Exception thrown when file-based open error is encountered + class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}}; + /// \brief Exception thrown when file-based write error is encountered + class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}}; + + /// \brief Construct a FileSink + FileSink() : m_stream(NULLPTR) {} + + /// \brief Construct a FileSink + /// \param out an existing stream + FileSink(std::ostream &out) + {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));} + + /// \brief Construct a FileSink + /// \param filename the narrow name of the file to open + /// \param binary flag indicating if the file is binary + FileSink(const char *filename, bool binary=true) + {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)(Name::OutputBinaryMode(), binary));} + +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + /// \brief Construct a FileSink + /// \param filename the Unicode name of the file to open + /// \details On non-Windows OS, this function assumes that setlocale() has been called. + FileSink(const wchar_t *filename, bool binary=true) + {IsolatedInitialize(MakeParameters(Name::OutputFileNameWide(), filename)(Name::OutputBinaryMode(), binary));} +#endif + + /// \brief Retrieves the internal stream + /// \return the internal stream pointer + std::ostream* GetStream() {return m_stream;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + +private: + member_ptr m_file; + std::ostream *m_stream; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/filters.cpp b/external/ours/library/crypto/src/shared/original/filters.cpp index 852a7b7fa..228a0f778 100755 --- a/external/ours/library/crypto/src/shared/original/filters.cpp +++ b/external/ours/library/crypto/src/shared/original/filters.cpp @@ -1,424 +1,1270 @@ -// filters.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "filters.h" -#include "mqueue.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -BitBucket g_bitBucket; - -Filter::Filter(BufferedTransformation *outQ) - : m_outQueue(outQ ? outQ : new MessageQueue) -{ -} - -void Filter::Detach(BufferedTransformation *newOut) -{ - m_outQueue.reset(newOut ? newOut : new MessageQueue); - NotifyAttachmentChange(); -} - -void Filter::Insert(Filter *filter) -{ - filter->m_outQueue.reset(m_outQueue.release()); - m_outQueue.reset(filter); - NotifyAttachmentChange(); -} - -// ************************************************************* - -FilterWithBufferedInput::BlockQueue::BlockQueue(unsigned int blockSize, unsigned int maxBlocks) - : m_buffer(blockSize * maxBlocks) -{ - ResetQueue(blockSize, maxBlocks); -} - -void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int maxBlocks) -{ - m_buffer.Resize(blockSize * maxBlocks); - m_blockSize = blockSize; - m_maxBlocks = maxBlocks; - m_size = 0; - m_begin = m_buffer; -} - -const byte *FilterWithBufferedInput::BlockQueue::GetBlock() -{ - if (m_size >= m_blockSize) - { - const byte *ptr = m_begin; - if ((m_begin+=m_blockSize) == m_buffer.End()) - m_begin = m_buffer; - m_size -= m_blockSize; - return ptr; - } - else - return nullptr; -} - -const byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBlocks) -{ - numberOfBlocks = STDMIN(numberOfBlocks, STDMIN((unsigned int)(m_buffer.End()-m_begin), m_size)/m_blockSize); - const byte *ptr = m_begin; - if ((m_begin+=m_blockSize*numberOfBlocks) == m_buffer.End()) - m_begin = m_buffer; - m_size -= m_blockSize*numberOfBlocks; - return ptr; -} - -unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) -{ - unsigned int size = m_size; - unsigned int numberOfBlocks = m_maxBlocks; - const byte *ptr = GetContigousBlocks(numberOfBlocks); - memcpy(outString, ptr, numberOfBlocks*m_blockSize); - memcpy(outString+numberOfBlocks*m_blockSize, m_begin, m_size); - m_size = 0; - return size; -} - -void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length) -{ - assert(m_size + length <= m_buffer.size); - byte *end = (m_size < (unsigned)(m_buffer+m_buffer.size-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size; - unsigned int len = STDMIN(length, (unsigned int)(m_buffer+m_buffer.size-end)); - memcpy(end, inString, len); - if (len < length) - memcpy(m_buffer, inString+len, length-len); - m_size += length; -} - -FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ) - : Filter(outQ), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize) - , m_firstInputDone(false) - , m_queue(1, m_firstSize) -{ -} - -void FilterWithBufferedInput::Put(byte inByte) -{ - Put(&inByte, 1); -} - -void FilterWithBufferedInput::Put(const byte *inString, unsigned int length) -{ - if (length == 0) - return; - - unsigned int newLength = m_queue.CurrentSize() + length; - - if (!m_firstInputDone && newLength >= m_firstSize) - { - unsigned int len = m_firstSize - m_queue.CurrentSize(); - m_queue.Put(inString, len); - FirstPut(m_queue.GetContigousBlocks(m_firstSize)); - assert(m_queue.CurrentSize() == 0); - m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); - - inString += len; - newLength -= m_firstSize; - m_firstInputDone = true; - } - - if (m_firstInputDone) - { - if (m_blockSize == 1) - { - while (newLength > m_lastSize && m_queue.CurrentSize() > 0) - { - unsigned int len = newLength - m_lastSize; - const byte *ptr = m_queue.GetContigousBlocks(len); - NextPut(ptr, len); - newLength -= len; - } - - if (newLength > m_lastSize) - { - unsigned int len = newLength - m_lastSize; - NextPut(inString, len); - inString += len; - newLength -= len; - } - } - else - { - while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) - { - NextPut(m_queue.GetBlock(), m_blockSize); - newLength -= m_blockSize; - } - - if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) - { - assert(m_queue.CurrentSize() < m_blockSize); - unsigned int len = m_blockSize - m_queue.CurrentSize(); - m_queue.Put(inString, len); - inString += len; - NextPut(m_queue.GetBlock(), m_blockSize); - newLength -= m_blockSize; - } - - while (newLength >= m_blockSize + m_lastSize) - { - NextPut(inString, m_blockSize); - inString += m_blockSize; - newLength -= m_blockSize; - } - } - } - - m_queue.Put(inString, newLength - m_queue.CurrentSize()); -} - -void FilterWithBufferedInput::MessageEnd(int propagation) -{ - if (!m_firstInputDone && m_firstSize==0) - FirstPut(nullptr); - - SecByteBlock temp(m_queue.CurrentSize()); - m_queue.GetAll(temp); - LastPut(temp, temp.size); - - m_firstInputDone = false; - m_queue.ResetQueue(1, m_firstSize); - - Filter::MessageEnd(propagation); -} - -void FilterWithBufferedInput::ForceNextPut() -{ - if (m_firstInputDone && m_queue.CurrentSize() >= m_blockSize) - NextPut(m_queue.GetBlock(), m_blockSize); -} - -// ************************************************************* - - - -// ************************************************************* - -ProxyFilter::ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ) - : FilterWithBufferedInput(firstSize, 1, lastSize, outQ), m_filter(filter), m_proxy(nullptr) -{ - if (m_filter.get()) - m_filter->Attach(m_proxy = new OutputProxy(*this, false)); -} - -void ProxyFilter::Flush(bool completeFlush, int propagation) -{ - if (m_filter.get()) - { - bool passSignal = m_proxy->GetPassSignal(); - m_proxy->SetPassSignal(false); - m_filter->Flush(completeFlush, -1); - m_proxy->SetPassSignal(passSignal); - } - Filter::Flush(completeFlush, propagation); -} - -void ProxyFilter::SetFilter(Filter *filter) -{ - bool passSignal = m_proxy ? m_proxy->GetPassSignal() : false; - m_filter.reset(filter); - if (filter) - { - std::unique_ptr temp(m_proxy = new OutputProxy(*this, passSignal)); - m_filter->TransferAllTo(*m_proxy); - m_filter->Attach(temp.release()); - } - else - m_proxy=nullptr; -} - -void ProxyFilter::NextPut(const byte *s, unsigned int len) -{ - if (m_filter.get()) - m_filter->Put(s, len); -} - -// ************************************************************* - -void StreamCipherFilter::Put(const byte *inString, unsigned int length) -{ - SecByteBlock temp(length); - cipher.ProcessString(temp, inString, length); - AttachedTransformation()->Put(temp, length); -} - -void HashFilter::Put(byte inByte) -{ - m_hashModule.Update(&inByte, 1); - if (m_putMessage) - AttachedTransformation()->Put(inByte); -} - -void HashFilter::Put(const byte *inString, unsigned int length) -{ - m_hashModule.Update(inString, length); - if (m_putMessage) - AttachedTransformation()->Put(inString, length); -} - -void HashFilter::MessageEnd(int propagation) -{ - SecByteBlock buf(m_hashModule.DigestSize()); - m_hashModule.Final(buf); - AttachedTransformation()->Put(buf, buf.size); - Filter::MessageEnd(propagation); -} - -// ************************************************************* - -HashVerifier::HashVerifier(HashModule &hm, BufferedTransformation *outQueue, word32 flags) - : FilterWithBufferedInput(flags & HASH_AT_BEGIN ? hm.DigestSize() : 0, 1, flags & HASH_AT_BEGIN ? 0 : hm.DigestSize(), outQueue) - , m_hashModule(hm), m_flags(flags) - , m_expectedHash(flags & HASH_AT_BEGIN ? hm.DigestSize() : 0), m_verified(false) -{ -} - -void HashVerifier::FirstPut(const byte *inString) -{ - if (m_flags & HASH_AT_BEGIN) - { - memcpy(m_expectedHash, inString, m_expectedHash.size); - if (m_flags & PUT_HASH) - AttachedTransformation()->Put(inString, m_expectedHash.size); - } -} - -void HashVerifier::NextPut(const byte *inString, unsigned int length) -{ - m_hashModule.Update(inString, length); - if (m_flags & PUT_MESSAGE) - AttachedTransformation()->Put(inString, length); -} - -void HashVerifier::LastPut(const byte *inString, unsigned int length) -{ - if (m_flags & HASH_AT_BEGIN) - { - assert(length == 0); - m_verified = m_hashModule.Verify(m_expectedHash); - } - else - { - m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString)); - if (m_flags & PUT_HASH) - AttachedTransformation()->Put(inString, length); - } - - if (m_flags & PUT_RESULT) - AttachedTransformation()->Put(m_verified); - - if ((m_flags & THROW_EXCEPTION) && !m_verified) - throw HashVerificationFailed(); -} - -// ************************************************************* - -void SignerFilter::MessageEnd(int propagation) -{ - SecByteBlock buf(m_signer.SignatureLength()); - m_signer.Sign(m_rng, m_messageAccumulator.release(), buf); - AttachedTransformation()->Put(buf, buf.size); - Filter::MessageEnd(propagation); - m_messageAccumulator.reset(m_signer.NewMessageAccumulator()); -} - -void VerifierFilter::PutSignature(const byte *sig) -{ - memcpy(m_signature.ptr, sig, m_signature.size); -} - -void VerifierFilter::MessageEnd(int propagation) -{ - AttachedTransformation()->Put((byte)m_verifier.Verify(m_messageAccumulator.release(), m_signature)); - Filter::MessageEnd(propagation); - m_messageAccumulator.reset(m_verifier.NewMessageAccumulator()); -} - -// ************************************************************* - -void Source::PumpAll() -{ - while (PumpMessages()) {} - while (Pump()) {} -} - -StringSource::StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue) - : Source(outQueue), m_store(string) -{ - if (pumpAll) - PumpAll(); -} - -StringSource::StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue) - : Source(outQueue), m_store(string, length) -{ - if (pumpAll) - PumpAll(); -} - -bool Store::GetNextMessage() -{ - if (!m_messageEnd && !AnyRetrievable()) - { - m_messageEnd=true; - return true; - } - else - return false; -} - -unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const -{ - if (m_messageEnd || count == 0) - return 0; - else - { - CopyTo(target); - if (GetAutoSignalPropagation()) - target.MessageEnd(GetAutoSignalPropagation()-1); - return 1; - } -} - -unsigned long StringStore::TransferTo(BufferedTransformation &target, unsigned long transferMax) -{ - unsigned long result = CopyTo(target, transferMax); - m_count += result; - return result; -} - -unsigned long StringStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); - target.Put(m_store+m_count, len); - return len; -} - -unsigned long RandomNumberStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); - for (unsigned int i=0; i(this)->m_attachment.reset(NewDefaultAttachment()); + return m_attachment.get(); +} + +void Filter::Detach(BufferedTransformation *newOut) +{ + m_attachment.reset(newOut); +} + +void Filter::Insert(Filter *filter) +{ + filter->m_attachment.reset(m_attachment.release()); + m_attachment.reset(filter); +} + +size_t Filter::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking); +} + +size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking); +} + +void Filter::Initialize(const NameValuePairs ¶meters, int propagation) +{ + m_inputPosition = m_continueAt = 0; + IsolatedInitialize(parameters); + PropagateInitialize(parameters, propagation); +} + +bool Filter::Flush(bool hardFlush, int propagation, bool blocking) +{ + switch (m_continueAt) + { + case 0: + if (IsolatedFlush(hardFlush, blocking)) + return true; + // fall through + case 1: + if (OutputFlush(1, hardFlush, propagation, blocking)) + return true; + // fall through + default: ; + } + return false; +} + +bool Filter::MessageSeriesEnd(int propagation, bool blocking) +{ + switch (m_continueAt) + { + case 0: + if (IsolatedMessageSeriesEnd(blocking)) + return true; + // fall through + case 1: + if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking)) + return true; + // fall through + default: ; + } + return false; +} + +void Filter::PropagateInitialize(const NameValuePairs ¶meters, int propagation) +{ + if (propagation) + AttachedTransformation()->Initialize(parameters, propagation-1); +} + +size_t Filter::OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel) +{ + if (messageEnd) + messageEnd--; + size_t result = AttachedTransformation()->ChannelPutModifiable2(channel, inString, length, messageEnd, blocking); + m_continueAt = result ? outputSite : 0; + return result; +} + +size_t Filter::Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel) +{ + if (messageEnd) + messageEnd--; + size_t result = AttachedTransformation()->ChannelPut2(channel, inString, length, messageEnd, blocking); + m_continueAt = result ? outputSite : 0; + return result; +} + +bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel) +{ + if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking)) + { + m_continueAt = outputSite; + return true; + } + m_continueAt = 0; + return false; +} + +bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel) +{ + if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking)) + { + m_continueAt = outputSite; + return true; + } + m_continueAt = 0; + return false; +} + +// ************************************************************* + +void MeterFilter::ResetMeter() +{ + m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0; + m_rangesToSkip.clear(); +} + +void MeterFilter::AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow) +{ + MessageRange r = {message, position, size}; + m_rangesToSkip.push_back(r); + if (sortNow) + std::sort(m_rangesToSkip.begin(), m_rangesToSkip.end()); +} + +size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable) +{ + if (!m_transparent) + return 0; + + size_t t; + FILTER_BEGIN; + + m_begin = begin; + m_length = length; + + while (m_length > 0 || messageEnd) + { + if (m_length > 0 && !m_rangesToSkip.empty() && m_rangesToSkip.front().message == m_totalMessages && m_currentMessageBytes + m_length > m_rangesToSkip.front().position) + { + FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable); + + CRYPTOPP_ASSERT(t < m_length); + m_begin = PtrAdd(m_begin, t); + m_length -= t; + m_currentMessageBytes += t; + m_totalBytes += t; + + if (m_currentMessageBytes + m_length < m_rangesToSkip.front().position + m_rangesToSkip.front().size) + t = m_length; + else + { + t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position + m_rangesToSkip.front().size, m_currentMessageBytes); + CRYPTOPP_ASSERT(t <= m_length); + m_rangesToSkip.pop_front(); + } + + m_begin = PtrAdd(m_begin, t); + m_length -= t; + m_currentMessageBytes += t; + m_totalBytes += t; + } + else + { + FILTER_OUTPUT_MAYBE_MODIFIABLE(2, m_begin, m_length, messageEnd, modifiable); + + m_currentMessageBytes += m_length; + m_totalBytes += m_length; + m_length = 0; + + if (messageEnd) + { + m_currentMessageBytes = 0; + m_currentSeriesMessages++; + m_totalMessages++; + messageEnd = false; + } + } + } + + FILTER_END_NO_MESSAGE_END; +} + +size_t MeterFilter::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + return PutMaybeModifiable(const_cast(begin), length, messageEnd, blocking, false); +} + +size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking) +{ + return PutMaybeModifiable(begin, length, messageEnd, blocking, true); +} + +bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking) +{ + CRYPTOPP_UNUSED(blocking); + m_currentMessageBytes = 0; + m_currentSeriesMessages = 0; + m_totalMessageSeries++; + return false; +} + +// ************************************************************* + +void FilterWithBufferedInput::BlockQueue::ResetQueue(size_t blockSize, size_t maxBlocks) +{ + m_buffer.New(blockSize * maxBlocks); + m_blockSize = blockSize; + m_maxBlocks = maxBlocks; + m_size = 0; + m_begin = m_buffer; +} + +byte *FilterWithBufferedInput::BlockQueue::GetBlock() +{ + if (m_size >= m_blockSize) + { + byte *ptr = m_begin; + if ((m_begin = PtrAdd(m_begin, m_blockSize)) == m_buffer.end()) + m_begin = m_buffer; + m_size -= m_blockSize; + return ptr; + } + else + return NULLPTR; +} + +byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes) +{ + numberOfBytes = STDMIN(numberOfBytes, STDMIN(PtrDiff(m_buffer.end(), m_begin), m_size)); + byte *ptr = m_begin; + m_begin = PtrAdd(m_begin, numberOfBytes); + m_size -= numberOfBytes; + if (m_size == 0 || m_begin == m_buffer.end()) + m_begin = m_buffer; + return ptr; +} + +size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) +{ + // Avoid passing NULL pointer to memcpy + if (!outString) return 0; + + size_t size = m_size; + size_t numberOfBytes = m_maxBlocks*m_blockSize; + const byte *ptr = GetContigousBlocks(numberOfBytes); + memcpy(outString, ptr, numberOfBytes); + memcpy(PtrAdd(outString, numberOfBytes), m_begin, m_size); + m_size = 0; + return size; +} + +void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length) +{ + // Avoid passing NULL pointer to memcpy + if (!inString || !length) return; + + CRYPTOPP_ASSERT(m_size + length <= m_buffer.size()); + byte *end = (m_size < static_cast(PtrDiff(m_buffer.end(), m_begin)) ? + PtrAdd(m_begin, m_size) : PtrAdd(m_begin, m_size - m_buffer.size())); + size_t len = STDMIN(length, size_t(m_buffer.end()-end)); + memcpy(end, inString, len); + if (len < length) + memcpy(m_buffer, PtrAdd(inString, len), length-len); + m_size += length; +} + +FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment) + : Filter(attachment), m_firstSize(SIZE_MAX), m_blockSize(0), m_lastSize(SIZE_MAX), m_firstInputDone(false) +{ +} + +FilterWithBufferedInput::FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment) + : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize), m_firstInputDone(false) +{ + if (m_firstSize == SIZE_MAX || m_blockSize < 1 || m_lastSize == SIZE_MAX) + throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); + + m_queue.ResetQueue(1, m_firstSize); +} + +void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs ¶meters) +{ + InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize); + if (m_firstSize == SIZE_MAX || m_blockSize < 1 || m_lastSize == SIZE_MAX) + throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); + m_queue.ResetQueue(1, m_firstSize); + m_firstInputDone = false; +} + +bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("FilterWithBufferedInput"); + + if (hardFlush) + ForceNextPut(); + FlushDerived(); + + return false; +} + +size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable) +{ + if (!blocking) + throw BlockingInputOnly("FilterWithBufferedInput"); + + if (length != 0) + { + size_t newLength = m_queue.CurrentSize() + length; + + if (!m_firstInputDone && newLength >= m_firstSize) + { + size_t len = m_firstSize - m_queue.CurrentSize(); + m_queue.Put(inString, len); + FirstPut(m_queue.GetContigousBlocks(m_firstSize)); + CRYPTOPP_ASSERT(m_queue.CurrentSize() == 0); + m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); + + inString = PtrAdd(inString, len); + newLength -= m_firstSize; + m_firstInputDone = true; + } + + if (m_firstInputDone) + { + if (m_blockSize == 1) + { + while (newLength > m_lastSize && m_queue.CurrentSize() > 0) + { + size_t len = newLength - m_lastSize; + byte *ptr = m_queue.GetContigousBlocks(len); + NextPutModifiable(ptr, len); + newLength -= len; + } + + if (newLength > m_lastSize) + { + size_t len = newLength - m_lastSize; + NextPutMaybeModifiable(inString, len, modifiable); + inString = PtrAdd(inString, len); + newLength -= len; + } + } + else + { + while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) + { + NextPutModifiable(m_queue.GetBlock(), m_blockSize); + newLength -= m_blockSize; + } + + if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) + { + CRYPTOPP_ASSERT(m_queue.CurrentSize() < m_blockSize); + size_t len = m_blockSize - m_queue.CurrentSize(); + m_queue.Put(inString, len); + inString = PtrAdd(inString, len); + NextPutModifiable(m_queue.GetBlock(), m_blockSize); + newLength -= m_blockSize; + } + + if (newLength >= m_blockSize + m_lastSize) + { + size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); + NextPutMaybeModifiable(inString, len, modifiable); + inString = PtrAdd(inString, len); + newLength -= len; + } + } + } + + m_queue.Put(inString, newLength - m_queue.CurrentSize()); + } + + if (messageEnd) + { + if (!m_firstInputDone && m_firstSize==0) + FirstPut(NULLPTR); + + SecByteBlock temp(m_queue.CurrentSize()); + m_queue.GetAll(temp); + LastPut(temp, temp.size()); + + m_firstInputDone = false; + m_queue.ResetQueue(1, m_firstSize); + + // Cast to void to suppress Coverity finding + (void)Output(1, NULLPTR, 0, messageEnd, blocking); + } + return 0; +} + +void FilterWithBufferedInput::ForceNextPut() +{ + if (!m_firstInputDone) + return; + + if (m_blockSize > 1) + { + while (m_queue.CurrentSize() >= m_blockSize) + NextPutModifiable(m_queue.GetBlock(), m_blockSize); + } + else + { + size_t len; + while ((len = m_queue.CurrentSize()) > 0) + NextPutModifiable(m_queue.GetContigousBlocks(len), len); + } +} + +void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(m_blockSize > 1); // m_blockSize = 1 should always override this function + while (length > 0) + { + CRYPTOPP_ASSERT(length >= m_blockSize); + NextPutSingle(inString); + inString = PtrAdd(inString, m_blockSize); + length -= m_blockSize; + } +} + +// ************************************************************* + +void Redirector::Initialize(const NameValuePairs ¶meters, int propagation) +{ + m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULLPTR); + m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING); + + if (m_target && GetPassSignals()) + m_target->Initialize(parameters, propagation); +} + +// ************************************************************* + +ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment) + : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter) +{ + if (m_filter.get()) + m_filter->Attach(new OutputProxy(*this, false)); +} + +bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking) +{ + return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false; +} + +void ProxyFilter::SetFilter(Filter *filter) +{ + m_filter.reset(filter); + if (filter) + { + OutputProxy *proxy; + member_ptr temp(proxy = new OutputProxy(*this, false)); + m_filter->TransferAllTo(*proxy); + m_filter->Attach(temp.release()); + } +} + +void ProxyFilter::NextPutMultiple(const byte *s, size_t len) +{ + if (m_filter.get()) + m_filter->Put(s, len); +} + +void ProxyFilter::NextPutModifiable(byte *s, size_t len) +{ + if (m_filter.get()) + m_filter->PutModifiable(s, len); +} + +// ************************************************************* + +void RandomNumberSink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng); +} + +size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); + m_rng->IncorporateEntropy(begin, length); + return 0; +} + +size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); + + // Avoid passing NULL pointer to memcpy. Using memmove due to + // Valgrind finding on overlapping buffers. + size_t copied = 0; + if (m_buf && begin) + { + copied = STDMIN(length, SaturatingSubtract(m_size, m_total)); + memmove(PtrAdd(m_buf, m_total), begin, copied); + } + m_total += copied; + return length - copied; +} + +byte * ArraySink::CreatePutSpace(size_t &size) +{ + size = SaturatingSubtract(m_size, m_total); + return PtrAdd(m_buf, m_total); +} + +void ArraySink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + ByteArrayParameter array; + if (!parameters.GetValue(Name::OutputBuffer(), array)) + throw InvalidArgument("ArraySink: missing OutputBuffer argument"); + m_buf = array.begin(); + m_size = array.size(); +} + +size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); + + // Avoid passing NULL pointer to xorbuf + size_t copied = 0; + if (m_buf && begin) + { + copied = STDMIN(length, SaturatingSubtract(m_size, m_total)); + xorbuf(PtrAdd(m_buf, m_total), begin, copied); + } + m_total += copied; + return length - copied; +} + +// ************************************************************* + +StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding) + : FilterWithBufferedInput(attachment), m_cipher(c), m_padding(DEFAULT_PADDING) +{ + CRYPTOPP_ASSERT(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); + + const bool authenticatedFilter = dynamic_cast(&c) != NULLPTR; + if (authenticatedFilter) + throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher"); + + // InitializeDerivedAndReturnNewSizes may override some of these + m_mandatoryBlockSize = m_cipher.MandatoryBlockSize(); + m_optimalBufferSize = m_cipher.OptimalBlockSize(); + m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1; + m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize); + + FilterWithBufferedInput::IsolatedInitialize( + MakeParameters + (Name::BlockPaddingScheme(), padding)); +} + +StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated) + : FilterWithBufferedInput(attachment), m_cipher(c), m_padding(DEFAULT_PADDING) +{ + const bool authenticatedFilter = dynamic_cast(&c) != NULLPTR; + if (!authenticatedFilter) + { + CRYPTOPP_ASSERT(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); + } + + if (authenticatedFilter && !authenticated) + throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher"); + + // InitializeDerivedAndReturnNewSizes may override some of these + m_mandatoryBlockSize = m_cipher.MandatoryBlockSize(); + m_optimalBufferSize = m_cipher.OptimalBlockSize(); + m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1; + m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize); + + FilterWithBufferedInput::IsolatedInitialize( + MakeParameters + (Name::BlockPaddingScheme(), padding)); +} + +size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding) +{ + if (c.MinLastBlockSize() > 0) + return c.MinLastBlockSize(); + else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING) + return c.MandatoryBlockSize(); + + return 0; +} + +void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) +{ + BlockPaddingScheme padding = parameters.GetValueWithDefault(Name::BlockPaddingScheme(), DEFAULT_PADDING); + bool isBlockCipher = (m_mandatoryBlockSize > 1 && m_cipher.MinLastBlockSize() == 0); + + if (padding == DEFAULT_PADDING) + m_padding = isBlockCipher ? PKCS_PADDING : NO_PADDING; + else + m_padding = padding; + + if (!isBlockCipher) + { + if (m_padding == PKCS_PADDING) + throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING cannot be used with " + m_cipher.AlgorithmName()); + else if (m_padding == W3C_PADDING) + throw InvalidArgument("StreamTransformationFilter: W3C_PADDING cannot be used with " + m_cipher.AlgorithmName()); + else if (m_padding == ONE_AND_ZEROS_PADDING) + throw InvalidArgument("StreamTransformationFilter: ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName()); + } + + firstSize = 0; + blockSize = m_mandatoryBlockSize; + lastSize = LastBlockSize(m_cipher, m_padding); +} + +void StreamTransformationFilter::FirstPut(const byte* inString) +{ + CRYPTOPP_UNUSED(inString); + m_optimalBufferSize = STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize)); +} + +void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length) +{ + if (!length) + {return;} + + const size_t s = m_cipher.MandatoryBlockSize(); + do + { + size_t len = m_optimalBufferSize; + byte *space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, length, len); + if (len < length) + { + if (len == m_optimalBufferSize) + len -= m_cipher.GetOptimalBlockSizeUsed(); + len = RoundDownToMultipleOf(len, s); + } + else + len = length; + m_cipher.ProcessString(space, inString, len); + AttachedTransformation()->PutModifiable(space, len); + inString = PtrAdd(inString, len); + length -= len; + } + while (length > 0); +} + +void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length) +{ + m_cipher.ProcessString(inString, length); + AttachedTransformation()->PutModifiable(inString, length); +} + +void StreamTransformationFilter::LastPut(const byte *inString, size_t length) +{ + // This block is new to StreamTransformationFilter. It is somewhat of a hack and was + // added for OCB mode; see GitHub Issue 515. The rub with OCB is, its a block cipher + // and the last block size can be 0. However, "last block = 0" is not the 0 predicated + // in the original code. In the original code 0 means "nothing special" so + // DEFAULT_PADDING is applied. OCB's 0 literally means a final block size can be 0 or + // non-0; and no padding is needed in either case because OCB has its own scheme (see + // handling of P_* and A_*). + // Stream ciphers have policy objects to convey how to operate the cipher. The Crypto++ + // framework operates well when MinLastBlockSize() is 1. However, it did not appear to + // cover the OCB case either because we can't stream OCB. It needs full block sizes. In + // response we hacked a IsLastBlockSpecial(). When true StreamTransformationFilter + // defers to the mode for processing of the last block. + // The behavior supplied when IsLastBlockSpecial() will likely have to evolve to capture + // more complex cases from different authenc modes. I suspect it will have to change + // from a simple bool to something that conveys more information, like "last block + // no padding" or "custom padding applied by cipher". + // In some respect we have already hit the need for more information. For example, OCB + // calculates the checksum on the cipher text at the same time, so we don't need the + // disjoint behavior of calling "EncryptBlock" followed by a separate "AuthenticateBlock". + // Additional information may allow us to avoid the two separate calls. + if (m_isSpecial) + { + const size_t leftOver = length % m_mandatoryBlockSize; + byte* space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, m_reservedBufferSize); + length -= leftOver; + + if (length) + { + // Process full blocks + m_cipher.ProcessData(space, inString, length); + AttachedTransformation()->Put(space, length); + inString = PtrAdd(inString, length); + } + + if (leftOver) + { + // Process final partial block + length = m_cipher.ProcessLastBlock(space, m_reservedBufferSize, inString, leftOver); + AttachedTransformation()->Put(space, length); + } + else + { + // Process final empty block + length = m_cipher.ProcessLastBlock(space, m_reservedBufferSize, NULLPTR, 0); + AttachedTransformation()->Put(space, length); + } + + return; + } + + switch (m_padding) + { + case NO_PADDING: + case ZEROS_PADDING: + if (length > 0) + { + const size_t minLastBlockSize = m_cipher.MinLastBlockSize(); + const bool isForwardTransformation = m_cipher.IsForwardTransformation(); + + if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize)) + { + // do padding + size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_mandatoryBlockSize); + byte* space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize); + if (inString) {memcpy(space, inString, length);} + memset(PtrAdd(space, length), 0, blockSize - length); + size_t used = m_cipher.ProcessLastBlock(space, blockSize, space, blockSize); + AttachedTransformation()->Put(space, used); + } + else + { + if (minLastBlockSize == 0) + { + if (isForwardTransformation) + throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified"); + else + throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); + } + + byte* space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length, m_optimalBufferSize); + size_t used = m_cipher.ProcessLastBlock(space, length, inString, length); + AttachedTransformation()->Put(space, used); + } + } + break; + + case PKCS_PADDING: + case W3C_PADDING: + case ONE_AND_ZEROS_PADDING: + unsigned int s; + byte* space; + s = m_mandatoryBlockSize; + CRYPTOPP_ASSERT(s > 1); + space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, m_optimalBufferSize); + if (m_cipher.IsForwardTransformation()) + { + CRYPTOPP_ASSERT(length < s); + if (inString) {memcpy(space, inString, length);} + if (m_padding == PKCS_PADDING) + { + CRYPTOPP_ASSERT(s < 256); + byte pad = static_cast(s-length); + memset(PtrAdd(space, length), pad, s-length); + } + else if (m_padding == W3C_PADDING) + { + CRYPTOPP_ASSERT(s < 256); + memset(PtrAdd(space, length), 0, s-length-1); + space[s-1] = static_cast(s-length); + } + else + { + space[length] = 0x80; + memset(PtrAdd(space, length+1), 0, s-length-1); + } + m_cipher.ProcessData(space, space, s); + AttachedTransformation()->Put(space, s); + } + else + { + if (length != s) + throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); + m_cipher.ProcessData(space, inString, s); + if (m_padding == PKCS_PADDING) + { + byte pad = space[s-1]; + if (pad < 1 || pad > s || FindIfNot(PtrAdd(space, s-pad), PtrAdd(space, s), pad) != PtrAdd(space, s)) + throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found"); + length = s-pad; + } + else if (m_padding == W3C_PADDING) + { + byte pad = space[s - 1]; + if (pad < 1 || pad > s) + throw InvalidCiphertext("StreamTransformationFilter: invalid W3C block padding found"); + length = s - pad; + } + else + { + while (length > 1 && space[length-1] == 0) + --length; + if (space[--length] != 0x80) + throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found"); + } + AttachedTransformation()->Put(space, length); + } + break; + + default: + CRYPTOPP_ASSERT(false); + } +} + +// ************************************************************* + +HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel) + : m_hashModule(hm), m_putMessage(putMessage), m_digestSize(0), m_space(NULLPTR) + , m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel) +{ + m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize; + Detach(attachment); +} + +void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); + int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); + m_digestSize = s < 0 ? m_hashModule.DigestSize() : s; +} + +size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + if (m_putMessage) + FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel); + if (inString && length) + m_hashModule.Update(inString, length); + if (messageEnd) + { + { + size_t size; + m_space = HelpCreatePutSpace(*AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize); + m_hashModule.TruncatedFinal(m_space, m_digestSize); + } + FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel); + } + FILTER_END_NO_MESSAGE_END; +} + +// ************************************************************* + +HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize) + : FilterWithBufferedInput(attachment) + , m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false) +{ + FilterWithBufferedInput::IsolatedInitialize( + MakeParameters + (Name::HashVerificationFilterFlags(), flags) + (Name::TruncatedDigestSize(), truncatedDigestSize)); +} + +void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) +{ + m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS); + int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); + m_digestSize = s < 0 ? m_hashModule.DigestSize() : s; + m_verified = false; + firstSize = m_flags & HASH_AT_BEGIN ? m_digestSize : 0; + blockSize = 1; + lastSize = m_flags & HASH_AT_BEGIN ? 0 : m_digestSize; +} + +void HashVerificationFilter::FirstPut(const byte *inString) +{ + if (m_flags & HASH_AT_BEGIN) + { + m_expectedHash.New(m_digestSize); + if (inString) {memcpy(m_expectedHash, inString, m_expectedHash.size());} + if (m_flags & PUT_HASH) + AttachedTransformation()->Put(inString, m_expectedHash.size()); + } +} + +void HashVerificationFilter::NextPutMultiple(const byte *inString, size_t length) +{ + m_hashModule.Update(inString, length); + if (m_flags & PUT_MESSAGE) + AttachedTransformation()->Put(inString, length); +} + +void HashVerificationFilter::LastPut(const byte *inString, size_t length) +{ + if (m_flags & HASH_AT_BEGIN) + { + CRYPTOPP_ASSERT(length == 0); + m_verified = m_hashModule.TruncatedVerify(m_expectedHash, m_digestSize); + } + else + { + m_verified = (length==m_digestSize && m_hashModule.TruncatedVerify(inString, length)); + if (m_flags & PUT_HASH) + AttachedTransformation()->Put(inString, length); + } + + if (m_flags & PUT_RESULT) + AttachedTransformation()->Put(m_verified); + + if ((m_flags & THROW_EXCEPTION) && !m_verified) + throw HashVerificationFailed(); +} + +// ************************************************************* + +AuthenticatedEncryptionFilter::AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment, + bool putAAD, int truncatedDigestSize, const std::string &macChannel, BlockPaddingScheme padding) + : StreamTransformationFilter(c, attachment, padding, true) + , m_hf(c, new OutputProxy(*this, false), putAAD, truncatedDigestSize, AAD_CHANNEL, macChannel) +{ + CRYPTOPP_ASSERT(c.IsForwardTransformation()); +} + +void AuthenticatedEncryptionFilter::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_hf.IsolatedInitialize(parameters); + StreamTransformationFilter::IsolatedInitialize(parameters); +} + +byte * AuthenticatedEncryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size) +{ + if (channel.empty()) + return StreamTransformationFilter::CreatePutSpace(size); + + if (channel == AAD_CHANNEL) + return m_hf.CreatePutSpace(size); + + throw InvalidChannelName("AuthenticatedEncryptionFilter", channel); +} + +size_t AuthenticatedEncryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (channel.empty()) + return StreamTransformationFilter::Put2(begin, length, messageEnd, blocking); + + if (channel == AAD_CHANNEL) + return m_hf.Put2(begin, length, 0, blocking); + + throw InvalidChannelName("AuthenticatedEncryptionFilter", channel); +} + +void AuthenticatedEncryptionFilter::LastPut(const byte *inString, size_t length) +{ + StreamTransformationFilter::LastPut(inString, length); + m_hf.MessageEnd(); +} + +// ************************************************************* + +AuthenticatedDecryptionFilter::AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize, BlockPaddingScheme padding) + : FilterWithBufferedInput(attachment) + , m_hashVerifier(c, new OutputProxy(*this, false)) + , m_streamFilter(c, new OutputProxy(*this, false), padding, true) +{ + CRYPTOPP_ASSERT(!c.IsForwardTransformation() || c.IsSelfInverting()); + FilterWithBufferedInput::IsolatedInitialize( + MakeParameters + (Name::BlockPaddingScheme(), padding) + (Name::AuthenticatedDecryptionFilterFlags(), flags) + (Name::TruncatedDigestSize(), truncatedDigestSize)); +} + +void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) +{ + word32 flags = parameters.GetValueWithDefault(Name::AuthenticatedDecryptionFilterFlags(), (word32)DEFAULT_FLAGS); + + m_hashVerifier.Initialize(CombinedNameValuePairs(parameters, MakeParameters(Name::HashVerificationFilterFlags(), flags))); + m_streamFilter.Initialize(parameters); + + firstSize = m_hashVerifier.m_firstSize; + blockSize = 1; + lastSize = m_hashVerifier.m_lastSize; +} + +byte * AuthenticatedDecryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size) +{ + if (channel.empty()) + return m_streamFilter.CreatePutSpace(size); + + if (channel == AAD_CHANNEL) + return m_hashVerifier.CreatePutSpace(size); + + throw InvalidChannelName("AuthenticatedDecryptionFilter", channel); +} + +size_t AuthenticatedDecryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (channel.empty()) + { + if (m_lastSize > 0) + m_hashVerifier.ForceNextPut(); + return FilterWithBufferedInput::Put2(begin, length, messageEnd, blocking); + } + + if (channel == AAD_CHANNEL) + return m_hashVerifier.Put2(begin, length, 0, blocking); + + throw InvalidChannelName("AuthenticatedDecryptionFilter", channel); +} + +void AuthenticatedDecryptionFilter::FirstPut(const byte *inString) +{ + m_hashVerifier.Put(inString, m_firstSize); +} + +void AuthenticatedDecryptionFilter::NextPutMultiple(const byte *inString, size_t length) +{ + m_streamFilter.Put(inString, length); +} + +void AuthenticatedDecryptionFilter::LastPut(const byte *inString, size_t length) +{ + m_streamFilter.MessageEnd(); + m_hashVerifier.PutMessageEnd(inString, length); +} + +// ************************************************************* + +void SignerFilter::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); + m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng)); +} + +size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + m_messageAccumulator->Update(inString, length); + if (m_putMessage) + FILTER_OUTPUT(1, inString, length, 0); + if (messageEnd) + { + m_buf.New(m_signer.SignatureLength()); + m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf); + FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd); + m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng)); + } + FILTER_END_NO_MESSAGE_END; +} + +SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags) + : FilterWithBufferedInput(attachment) + , m_verifier(verifier), m_flags(0), m_verified(0) +{ + FilterWithBufferedInput::IsolatedInitialize( + MakeParameters + (Name::SignatureVerificationFilterFlags(), flags)); +} + +void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) +{ + m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS); + m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator()); + size_t size = m_verifier.SignatureLength(); + CRYPTOPP_ASSERT(size != 0); // TODO: handle recoverable signature scheme + m_verified = false; + firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0; + blockSize = 1; + lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size; +} + +void SignatureVerificationFilter::FirstPut(const byte *inString) +{ + if (m_flags & SIGNATURE_AT_BEGIN) + { + if (m_verifier.SignatureUpfront()) + m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength()); + else + { + m_signature.New(m_verifier.SignatureLength()); + if (inString) {memcpy(m_signature, inString, m_signature.size());} + } + + if (m_flags & PUT_SIGNATURE) + AttachedTransformation()->Put(inString, m_signature.size()); + } + else + { + CRYPTOPP_ASSERT(!m_verifier.SignatureUpfront()); + } +} + +void SignatureVerificationFilter::NextPutMultiple(const byte *inString, size_t length) +{ + m_messageAccumulator->Update(inString, length); + if (m_flags & PUT_MESSAGE) + AttachedTransformation()->Put(inString, length); +} + +void SignatureVerificationFilter::LastPut(const byte *inString, size_t length) +{ + if (m_flags & SIGNATURE_AT_BEGIN) + { + CRYPTOPP_ASSERT(length == 0); + m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size()); + m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator); + } + else + { + m_verifier.InputSignature(*m_messageAccumulator, inString, length); + m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator); + if (m_flags & PUT_SIGNATURE) + AttachedTransformation()->Put(inString, length); + } + + if (m_flags & PUT_RESULT) + AttachedTransformation()->Put(m_verified); + + if ((m_flags & THROW_EXCEPTION) && !m_verified) + throw SignatureVerificationFailed(); +} + +// ************************************************************* + +size_t Source::PumpAll2(bool blocking) +{ + unsigned int messageCount = UINT_MAX; + do { + RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking)); + } while(messageCount == UINT_MAX); + + return 0; +} + +bool Store::GetNextMessage() +{ + if (!m_messageEnd && !AnyRetrievable()) + { + m_messageEnd=true; + return true; + } + else + return false; +} + +unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const +{ + if (m_messageEnd || count == 0) + return 0; + else + { + CopyTo(target, ULONG_MAX, channel); + if (GetAutoSignalPropagation()) + target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1); + return 1; + } +} + +void StringStore::StoreInitialize(const NameValuePairs ¶meters) +{ + ConstByteArrayParameter array; + if (!parameters.GetValue(Name::InputBuffer(), array)) + throw InvalidArgument("StringStore: missing InputBuffer argument"); + m_store = array.begin(); + m_length = array.size(); + m_count = 0; +} + +size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + lword position = 0; + size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking); + m_count += static_cast(position); + transferBytes = position; + return blockedBytes; +} + +size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + size_t i = UnsignedMin(m_length, m_count+begin); + size_t len = UnsignedMin(m_length-i, end-begin); + size_t blockedBytes = target.ChannelPut2(channel, PtrAdd(m_store, i), len, 0, blocking); + if (!blockedBytes) + begin = PtrAdd(begin, len); + return blockedBytes; +} + +void RandomNumberStore::StoreInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng); + int length; + parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", length); + m_length = length; +} + +size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (!blocking) + throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object"); + + transferBytes = UnsignedMin(transferBytes, m_length - m_count); + m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes); + m_count += transferBytes; + + return 0; +} + +size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + static const byte nullBytes[128] = {0}; + while (begin < end) + { + size_t len = (size_t)STDMIN(end-begin, lword(128)); + size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking); + if (blockedBytes) + return blockedBytes; + begin = PtrAdd(begin, len); + } + return 0; +} + +size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + lword begin = 0; + size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking); + transferBytes = begin; m_size -= begin; + return blockedBytes; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/filters.h b/external/ours/library/crypto/src/shared/original/filters.h index b80c518a0..ee89c37a0 100755 --- a/external/ours/library/crypto/src/shared/original/filters.h +++ b/external/ours/library/crypto/src/shared/original/filters.h @@ -1,560 +1,1529 @@ -#ifndef CRYPTOPP_FILTERS_H -#define CRYPTOPP_FILTERS_H - -#include "cryptlib.h" -#include "misc.h" -#include "smartptr.h" -#include "queue.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// provides an implementation of BufferedTransformation's attachment interface -class Filter : virtual public BufferedTransformation -{ -public: - Filter(BufferedTransformation *outQ); - - bool Attachable() {return true;} - BufferedTransformation *AttachedTransformation() {return m_outQueue.get();} - const BufferedTransformation *AttachedTransformation() const {return m_outQueue.get();} - void Detach(BufferedTransformation *newOut = nullptr); - -protected: - virtual void NotifyAttachmentChange() {} - void Insert(Filter *nextFilter); // insert filter after this one - -private: - void operator=(const Filter &); // assignment not allowed - - member_ptr m_outQueue; -}; - -//! . -class TransparentFilter : public Filter -{ -public: - TransparentFilter(BufferedTransformation *outQ=nullptr) : Filter(outQ) {} - void Put(byte inByte) {AttachedTransformation()->Put(inByte);} - void Put(const byte *inString, unsigned int length) {AttachedTransformation()->Put(inString, length);} -}; - -//! . -class OpaqueFilter : public Filter -{ -public: - OpaqueFilter(BufferedTransformation *outQ=nullptr) : Filter(outQ) {} - void Put(byte inByte) {} - void Put(const byte *inString, unsigned int length) {} -}; - -/*! FilterWithBufferedInput divides up the input stream into - a first block, a number of middle blocks, and a last block. - First and last blocks are optional, and middle blocks may - be a stream instead (i.e. blockSize == 1). -*/ -class FilterWithBufferedInput : public Filter -{ -public: - /// firstSize and lastSize may be 0, blockSize must be at least 1 - FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ); - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - void MessageEnd(int propagation=-1); - - /*! the input buffer may contain more than blockSize bytes if lastSize != 0 - ForceNextPut() forces a call to NextPut() if this is the case - */ - void ForceNextPut(); - -protected: - bool DidFirstPut() {return m_firstInputDone;} - - // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize) - // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)) - virtual void FirstPut(const byte *inString) =0; - // NextPut() is called if totalLength >= firstSize+blockSize+lastSize - // length parameter is always blockSize unless blockSize == 1 - virtual void NextPut(const byte *inString, unsigned int length) =0; - // LastPut() is always called - // if totalLength < firstSize then length == totalLength - // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize - // else lastSize <= length < lastSize+blockSize - virtual void LastPut(const byte *inString, unsigned int length) =0; - -private: - class BlockQueue - { - public: - BlockQueue(unsigned int blockSize, unsigned int maxBlocks); - void ResetQueue(unsigned int blockSize, unsigned int maxBlocks); - const byte *GetBlock(); - const byte *GetContigousBlocks(unsigned int &numberOfBlocks); - unsigned int GetAll(byte *outString); - void Put(const byte *inString, unsigned int length); - unsigned int CurrentSize() const {return m_size;} - unsigned int MaxSize() const {return m_buffer.size;} - - private: - SecByteBlock m_buffer; - unsigned int m_blockSize, m_maxBlocks, m_size; - byte *m_begin; - }; - - unsigned int m_firstSize, m_blockSize, m_lastSize; - bool m_firstInputDone; - BlockQueue m_queue; -}; - -//! . -class FilterWithInputQueue : public Filter -{ -public: - FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {} - void Put(byte inByte) {m_inQueue.Put(inByte);} - void Put(const byte *inString, unsigned int length) {m_inQueue.Put(inString, length);} - -protected: - ByteQueue m_inQueue; -}; - -//! Filter Wrapper for StreamCipher -class StreamCipherFilter : public Filter -{ -public: - StreamCipherFilter(StreamCipher &c, - BufferedTransformation *outQueue = nullptr) - : cipher(c), Filter(outQueue) {} - - void Put(byte inByte) - {AttachedTransformation()->Put(cipher.ProcessByte(inByte));} - - void Put(const byte *inString, unsigned int length); - -private: - StreamCipher &cipher; -}; - -//! Filter Wrapper for HashModule -class HashFilter : public Filter -{ -public: - HashFilter(HashModule &hm, BufferedTransformation *outQueue = nullptr, bool putMessage=false) - : Filter(outQueue), m_hashModule(hm), m_putMessage(putMessage) {} - - void MessageEnd(int propagation=-1); - - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - -private: - HashModule &m_hashModule; - bool m_putMessage; -}; - -//! Filter Wrapper for HashModule -class HashVerifier : public FilterWithBufferedInput -{ -public: - class HashVerificationFailed : public BufferedTransformation::Err - { - public: - HashVerificationFailed() - : BufferedTransformation::Err(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not correct") {} - }; - - enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16}; - HashVerifier(HashModule &hm, BufferedTransformation *outQueue = nullptr, word32 flags = HASH_AT_BEGIN | PUT_RESULT); - - bool GetLastResult() const {return m_verified;} - -protected: - void FirstPut(const byte *inString); - void NextPut(const byte *inString, unsigned int length); - void LastPut(const byte *inString, unsigned int length); - -private: - HashModule &m_hashModule; - word32 m_flags; - SecByteBlock m_expectedHash; - bool m_verified; -}; - -//! Filter Wrapper for PK_Signer -class SignerFilter : public Filter -{ -public: - SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *outQueue = nullptr) - : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewMessageAccumulator()), Filter(outQueue) {} - - void MessageEnd(int propagation); - - void Put(byte inByte) - {m_messageAccumulator->Update(&inByte, 1);} - - void Put(const byte *inString, unsigned int length) - {m_messageAccumulator->Update(inString, length);} - -private: - RandomNumberGenerator &m_rng; - const PK_Signer &m_signer; - member_ptr m_messageAccumulator; -}; - -//! Filter Wrapper for PK_Verifier -class VerifierFilter : public Filter -{ -public: - VerifierFilter(const PK_Verifier &verifier, BufferedTransformation *outQueue = nullptr) - : m_verifier(verifier), m_messageAccumulator(verifier.NewMessageAccumulator()) - , m_signature(verifier.SignatureLength()), Filter(outQueue) {} - - // this function must be called before MessageEnd() - void PutSignature(const byte *sig); - - void MessageEnd(int propagation); - - void Put(byte inByte) - {m_messageAccumulator->Update(&inByte, 1);} - - void Put(const byte *inString, unsigned int length) - {m_messageAccumulator->Update(inString, length);} - -private: - const PK_Verifier &m_verifier; - member_ptr m_messageAccumulator; - SecByteBlock m_signature; -}; - -//! A BufferedTransformation that doesn't produce any retrievable output -class Sink : public BufferedTransformation -{ -}; - -//! . -class BitBucket : public Sink -{ -public: - void Put(byte) {} - void Put(const byte *, unsigned int) {} -}; - -extern BitBucket g_bitBucket; - -//! Redirect input to another BufferedTransformation without owning it -class Redirector : public Sink -{ -public: - Redirector() : m_target(nullptr), m_passSignal(true) {} - Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {} - - void Redirect(BufferedTransformation &target) {m_target = ⌖} - void StopRedirect() {m_target = nullptr;} - bool GetPassSignal() const {return m_passSignal;} - void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} - - void Put(byte b) - {if (m_target) m_target->Put(b);} - void Put(const byte *string, unsigned int len) - {if (m_target) m_target->Put(string, len);} - void Flush(bool completeFlush, int propagation=-1) - {if (m_target && m_passSignal) m_target->Flush(completeFlush, propagation);} - void MessageEnd(int propagation=-1) - {if (m_target && m_passSignal) m_target->MessageEnd(propagation);} - void MessageSeriesEnd(int propagation=-1) - {if (m_target && m_passSignal) m_target->MessageSeriesEnd(propagation);} - - void ChannelPut(const std::string &channel, byte b) - {if (m_target) m_target->ChannelPut(channel, b);} - void ChannelPut(const std::string &channel, const byte *string, unsigned int len) - {if (m_target) m_target->ChannelPut(channel, string, len);} - void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1) - {if (m_target && m_passSignal) m_target->ChannelFlush(channel, completeFlush, propagation);} - void ChannelMessageEnd(const std::string &channel, int propagation=-1) - {if (m_target && m_passSignal) m_target->ChannelMessageEnd(channel, propagation);} - void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) - {if (m_target && m_passSignal) m_target->ChannelMessageSeriesEnd(channel, propagation);} - -private: - BufferedTransformation *m_target; - bool m_passSignal; -}; - -// Used By ProxyFilter -class OutputProxy : public Sink -{ -public: - OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {} - - bool GetPassSignal() const {return m_passSignal;} - void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} - - void Put(byte b) - {m_owner.AttachedTransformation()->Put(b);} - void Put(const byte *string, unsigned int len) - {m_owner.AttachedTransformation()->Put(string, len);} - void Flush(bool completeFlush, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->Flush(completeFlush, propagation);} - void MessageEnd(int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->MessageEnd(propagation);} - void MessageSeriesEnd(int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->MessageSeriesEnd(propagation);} - - void ChannelPut(const std::string &channel, byte b) - {m_owner.AttachedTransformation()->ChannelPut(channel, b);} - void ChannelPut(const std::string &channel, const byte *string, unsigned int len) - {m_owner.AttachedTransformation()->ChannelPut(channel, string, len);} - void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation);} - void ChannelMessageEnd(const std::string &channel, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageEnd(channel, propagation);} - void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation);} - -private: - BufferedTransformation &m_owner; - bool m_passSignal; -}; - -//! Base class for Filter classes that are proxies for a chain of other filters. -class ProxyFilter : public FilterWithBufferedInput -{ -public: - ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ); - - void Flush(bool completeFlush, int propagation=-1); - - void SetFilter(Filter *filter); - void NextPut(const byte *s, unsigned int len); - -protected: - member_ptr m_filter; - OutputProxy *m_proxy; -}; - -//! Append input to a string object -template -class StringSinkTemplate : public Sink -{ -public: - // VC60 workaround: no T::char_type - typedef typename T::traits_type::char_type char_type; - - StringSinkTemplate(T &output) - : m_output(output) {assert(sizeof(output[0])==1);} - void Put(byte b) - {m_output += (char_type)b;} - void Put(const byte *str, unsigned int bc) - {m_output.append((const char_type *)str, bc);} - -private: - T &m_output; -}; - -//! Append input to an std::string -typedef StringSinkTemplate StringSink; - -//! Copy input to a memory buffer -class ArraySink : public Sink -{ -public: - ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {} - - unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);} - unsigned long TotalPutLength() {return m_total;} - - void Put(byte b) - { - if (m_total < m_size) - m_buf[m_total] = b; - m_total++; - } - - void Put(const byte *str, unsigned int len) - { - if (m_total < m_size) - memcpy(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total))); - m_total += len; - } - -protected: - byte *m_buf; - unsigned int m_size; - unsigned long m_total; -}; - -//! Xor input to a memory buffer -class ArrayXorSink : public ArraySink -{ -public: - ArrayXorSink(byte *buf, unsigned int size) - : ArraySink(buf, size) {} - - void Put(byte b) - { - if (m_total < m_size) - m_buf[m_total] ^= b; - m_total++; - } - - void Put(const byte *str, unsigned int len) - { - if (m_total < m_size) - xorbuf(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total))); - m_total += len; - } -}; - -//! Provide implementation of SetAutoSignalPropagation and GetAutoSignalPropagation -class BufferedTransformationWithAutoSignal : virtual public BufferedTransformation -{ -public: - BufferedTransformationWithAutoSignal(int propagation=-1) : m_autoSignalPropagation(propagation) {} - - void SetAutoSignalPropagation(int propagation) - {m_autoSignalPropagation = propagation;} - int GetAutoSignalPropagation() const - {return m_autoSignalPropagation;} - -private: - int m_autoSignalPropagation; -}; - -//! A BufferedTransformation that only contains pre-existing output -class Store : public BufferedTransformationWithAutoSignal -{ -public: - Store() : m_messageEnd(false) {} - - void Put(byte) - {} - void Put(const byte *, unsigned int length) - {} - - virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) =0; - virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const =0; - - unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;} - bool GetNextMessage(); - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; - -private: - bool m_messageEnd; -}; - -//! . -class StringStore : public Store -{ -public: - StringStore(const char *string) - : m_store((const byte *)string), m_length(strlen(string)), m_count(0) {} - StringStore(const byte *string, unsigned int length) - : m_store(string), m_length(length), m_count(0) {} - template StringStore(const T &string) - : m_store((const byte *)string.data()), m_length(string.length()), m_count(0) {assert(sizeof(string[0])==1);} - - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - -private: - const byte *m_store; - unsigned int m_length, m_count; -}; - -//! . -class RandomNumberStore : public Store -{ -public: - RandomNumberStore(RandomNumberGenerator &rng, unsigned long length) - : m_rng(rng), m_length(length), m_count(0) {} - - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - -private: - RandomNumberGenerator &m_rng; - unsigned long m_length, m_count; -}; - -//! A Filter that pumps data into its attachment as input -class Source : public Filter -{ -public: - Source(BufferedTransformation *outQ) - : Filter(outQ) {} - - virtual unsigned long Pump(unsigned long pumpMax=ULONG_MAX) =0; - virtual unsigned int PumpMessages(unsigned int count=UINT_MAX) {return 0;} - void PumpAll(); - - void Put(byte) - {Pump(1);} - void Put(const byte *, unsigned int length) - {Pump(length);} - void MessageEnd(int propagation=-1) - {PumpAll();} -}; - -//! Turn a Store into a Source -class GeneralSource : public Source -{ -public: - GeneralSource(BufferedTransformation &store, bool pumpAll, BufferedTransformation *outQueue = nullptr) - : Source(outQueue), m_store(store) - { - if (pumpAll) PumpAll(); - } - - unsigned long Pump(unsigned long pumpMax=ULONG_MAX) - {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} - -private: - BufferedTransformation &m_store; -}; - -//! . -class StringSource : public Source -{ -public: - StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue = nullptr); - StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = nullptr); - -#ifdef __MWERKS__ // CW60 workaround - StringSource(const std::string &string, bool pumpAll, BufferedTransformation *outQueue = nullptr) -#else - template StringSource(const T &string, bool pumpAll, BufferedTransformation *outQueue = nullptr) -#endif - : Source(outQueue), m_store(string) - { - if (pumpAll) - PumpAll(); - } - - unsigned long Pump(unsigned long pumpMax=ULONG_MAX) - {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} - -private: - StringStore m_store; -}; - -//! . -class RandomNumberSource : public Source -{ -public: - RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = nullptr); - - unsigned long Pump(unsigned long pumpMax=ULONG_MAX) - {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} - -private: - RandomNumberStore m_store; -}; - -NAMESPACE_END - -#endif +// filters.h - originally written and placed in the public domain by Wei Dai + +/// \file filters.h +/// \brief Implementation of BufferedTransformation's attachment interface. + +#ifndef CRYPTOPP_FILTERS_H +#define CRYPTOPP_FILTERS_H + +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4127 4189 4231 4275 4514) +#endif + +#include "cryptlib.h" +#include "simple.h" +#include "secblock.h" +#include "misc.h" +#include "smartptr.h" +#include "queue.h" +#include "algparam.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Implementation of BufferedTransformation's attachment interface +/// \details Filter is a cornerstone of the Pipeline trinitiy. Data flows from +/// Sources, through Filters, and then terminates in Sinks. The difference +/// between a Source and Filter is a Source \a pumps data, while a Filter does +/// not. The difference between a Filter and a Sink is a Filter allows an +/// attached transformation, while a Sink does not. +/// \details See the discussion of BufferedTransformation in cryptlib.h for +/// more details. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable +{ +public: + virtual ~Filter() {} + + /// \name ATTACHMENT + //@{ + + /// \brief Construct a Filter + /// \param attachment an optional attached transformation + /// \details attachment can be NULL. + Filter(BufferedTransformation *attachment = NULLPTR); + + /// \brief Determine if attachable + /// \return true if the object allows attached transformations, false otherwise. + /// \note Source and Filter offer attached transformations; while Sink does not. + bool Attachable() {return true;} + + /// \brief Retrieve attached transformation + /// \return pointer to a BufferedTransformation if there is an attached transformation, NULL otherwise. + BufferedTransformation *AttachedTransformation(); + + /// \brief Retrieve attached transformation + /// \return pointer to a BufferedTransformation if there is an attached transformation, NULL otherwise. + const BufferedTransformation *AttachedTransformation() const; + + /// \brief Replace an attached transformation + /// \param newAttachment an optional attached transformation + /// \details newAttachment can be a single filter, a chain of filters or NULL. + /// Pass NULL to remove an existing BufferedTransformation or chain of filters + void Detach(BufferedTransformation *newAttachment = NULLPTR); + + //@} + + /// \name RETRIEVAL OF ONE MESSAGE + //@{ + + // BufferedTransformation in cryptlib.h + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + + //@} + + /// \name SIGNALS + //@{ + + // BufferedTransformation in cryptlib.h + void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); + bool MessageSeriesEnd(int propagation=-1, bool blocking=true); + + //@} + +protected: + virtual BufferedTransformation * NewDefaultAttachment() const; + void Insert(Filter *nextFilter); // insert filter after this one + + virtual bool ShouldPropagateMessageEnd() const {return true;} + virtual bool ShouldPropagateMessageSeriesEnd() const {return true;} + + void PropagateInitialize(const NameValuePairs ¶meters, int propagation); + + /// \brief Forward processed data on to attached transformation + /// \param outputSite unknown, system crash between keyboard and chair... + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \param channel the channel to process the data + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL); + + /// \brief Output multiple bytes that may be modified by callee. + /// \param outputSite unknown, system crash between keyboard and chair... + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \param channel the channel to process the data + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL); + + /// \brief Signals the end of messages to the object + /// \param outputSite unknown, system crash between keyboard and chair... + /// \param propagation the number of attached transformations the MessageEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \param channel the channel to process the data + /// \return true is the MessageEnd signal was successful, false otherwise. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL); + + /// \brief Flush buffered input and/or output, with signal propagation + /// \param outputSite unknown, system crash between keyboard and chair... + /// \param hardFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the Flush() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \param channel the channel to process the data + /// \return true is the Flush signal was successful, false otherwise. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note Hard flushes must be used with care. It means try to process and output everything, even if + /// there may not be enough data to complete the action. For example, hard flushing a HexDecoder + /// would cause an error if you do it after inputing an odd number of hex encoded characters. + /// \note For some types of filters, like ZlibDecompressor, hard flushes can only + /// be done at "synchronization points". These synchronization points are positions in the data + /// stream that are created by hard flushes on the corresponding reverse filters, in this + /// example ZlibCompressor. This is useful when zlib compressed data is moved across a + /// network in packets and compression state is preserved across packets, as in the SSH2 protocol. + bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL); + + /// \brief Marks the end of a series of messages, with signal propagation + /// \param outputSite unknown, system crash between keyboard and chair... + /// \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \param channel the channel to process the data + /// \return true is the MessageEnd signal was successful, false otherwise. + /// \details Each object that receives the signal will perform its processing, decrement + /// propagation, and then pass the signal on to attached transformations if the value is not 0. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note There should be a MessageEnd() immediately before MessageSeriesEnd(). + bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL); + +private: + member_ptr m_attachment; + +protected: + size_t m_inputPosition; + int m_continueAt; +}; + +/// \brief Create a working space in a BufferedTransformation +struct CRYPTOPP_DLL FilterPutSpaceHelper +{ + virtual ~FilterPutSpaceHelper() {} + + /// \brief Create a working space in a BufferedTransformation + /// \param target BufferedTransformation for the working space + /// \param channel channel for the working space + /// \param minSize minimum size of the allocation, in bytes + /// \param desiredSize preferred size of the allocation, in bytes + /// \param bufferSize actual size of the allocation, in bytes + /// \pre desiredSize >= minSize and bufferSize >= minSize. + /// \details bufferSize is an IN and OUT parameter. If HelpCreatePutSpace() returns a non-NULL value, then + /// bufferSize is valid and provides the size of the working space created for the caller. + /// \details Internally, HelpCreatePutSpace() calls \ref BufferedTransformation::ChannelCreatePutSpace + /// "ChannelCreatePutSpace()" using desiredSize. If the target returns desiredSize with a size less + /// than minSize (i.e., the request could not be fulfilled), then an internal SecByteBlock + /// called m_tempSpace is resized and used for the caller. + byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t desiredSize, size_t &bufferSize) + { + CRYPTOPP_ASSERT(desiredSize >= minSize && bufferSize >= minSize); + if (m_tempSpace.size() < minSize) + { + byte *result = target.ChannelCreatePutSpace(channel, desiredSize); + if (desiredSize >= minSize) + { + bufferSize = desiredSize; + return result; + } + m_tempSpace.New(bufferSize); + } + + bufferSize = m_tempSpace.size(); + return m_tempSpace.begin(); + } + + /// \brief Create a working space in a BufferedTransformation + /// \param target the BufferedTransformation for the working space + /// \param channel channel for the working space + /// \param minSize minimum size of the allocation, in bytes + /// \return pointer to the created space + /// \details Internally, the overload calls HelpCreatePutSpace() using minSize for missing arguments. + /// \details The filter will delete the space. The caller does not need to delete the space. + byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize) + {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);} + + /// \brief Create a working space in a BufferedTransformation + /// \param target the BufferedTransformation for the working space + /// \param channel channel for the working space + /// \param minSize minimum size of the allocation, in bytes + /// \param bufferSize the actual size of the allocation, in bytes + /// \details Internally, the overload calls HelpCreatePutSpace() using minSize for missing arguments. + /// \details The filter will delete the space. The caller does not need to delete the space. + byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t bufferSize) + {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);} + + /// \brief Temporay working space + SecByteBlock m_tempSpace; +}; + +/// \brief Measure how many bytes and messages pass through the filter +/// \details measure how many bytes and messages pass through the filter. The filter also serves as valve by +/// maintaining a list of ranges to skip during processing. +class CRYPTOPP_DLL MeterFilter : public Bufferless +{ +public: + virtual ~MeterFilter() {} + + /// \brief Construct a MeterFilter + /// \param attachment an optional attached transformation + /// \param transparent flag indicating if the filter should function transparently + /// \details attachment can be NULL. The filter is transparent by default. If the filter is + /// transparent, then PutMaybeModifiable() does not process a request and always returns 0. + MeterFilter(BufferedTransformation *attachment=NULLPTR, bool transparent=true) + : m_transparent(transparent), m_currentMessageBytes(0), m_totalBytes(0) + , m_currentSeriesMessages(0), m_totalMessages(0), m_totalMessageSeries(0) + , m_begin(NULLPTR), m_length(0) {Detach(attachment); ResetMeter();} + + /// \brief Set or change the transparent mode of this object + /// \param transparent the new transparent mode + void SetTransparent(bool transparent) {m_transparent = transparent;} + + /// \brief Adds a range to skip during processing + /// \param message the message to apply the range + /// \param position the 0-based index in the current stream + /// \param size the length of the range + /// \param sortNow flag indicating whether the range should be sorted + /// \details Internally, MeterFilter maitains a deque of ranges to skip. As messages are processed, + /// ranges of bytes are skipped according to the list of ranges. + void AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow = true); + + /// \brief Resets the meter + /// \details ResetMeter() reinitializes the meter by setting counters to 0 and removing previous + /// skip ranges. + void ResetMeter(); + + // BufferedTransformation in cryptlib.h + void IsolatedInitialize(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters); ResetMeter();} + + /// \brief Number of bytes in the current message + /// \return the number of bytes in the current message + lword GetCurrentMessageBytes() const {return m_currentMessageBytes;} + + /// \brief Number of bytes processed by the filter + /// \return the number of bytes processed by the filter + lword GetTotalBytes() const {return m_totalBytes;} + + /// \brief Message number in the series + /// \return the message number in the series + unsigned int GetCurrentSeriesMessages() const {return m_currentSeriesMessages;} + + /// \brief Number of messages in the message series + /// \return the number of messages in the message series + unsigned int GetTotalMessages() const {return m_totalMessages;} + + /// \brief Number of messages processed by the filter + /// \return the number of messages processed by the filter + unsigned int GetTotalMessageSeries() const {return m_totalMessageSeries;} + + // BufferedTransformation in cryptlib.h + byte * CreatePutSpace(size_t &size) {return AttachedTransformation()->CreatePutSpace(size);} + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedMessageSeriesEnd(bool blocking); + +private: + size_t PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable); + bool ShouldPropagateMessageEnd() const {return m_transparent;} + bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;} + + struct MessageRange + { + inline bool operator<(const MessageRange &b) const // BCB2006 workaround: this has to be a member function + {return message < b.message || (message == b.message && position < b.position);} + unsigned int message; lword position; lword size; + }; + + bool m_transparent; + lword m_currentMessageBytes, m_totalBytes; + unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries; + std::deque m_rangesToSkip; + byte *m_begin; + size_t m_length; +}; + +/// \brief A transparent MeterFilter +/// \sa MeterFilter, OpaqueFilter +class CRYPTOPP_DLL TransparentFilter : public MeterFilter +{ +public: + /// \brief Construct a TransparentFilter + /// \param attachment an optional attached transformation + TransparentFilter(BufferedTransformation *attachment=NULLPTR) : MeterFilter(attachment, true) {} +}; + +/// \brief A non-transparent MeterFilter +/// \sa MeterFilter, TransparentFilter +class CRYPTOPP_DLL OpaqueFilter : public MeterFilter +{ +public: + /// \brief Construct an OpaqueFilter + /// \param attachment an optional attached transformation + OpaqueFilter(BufferedTransformation *attachment=NULLPTR) : MeterFilter(attachment, false) {} +}; + +/// \brief Divides an input stream into discrete blocks +/// \details FilterWithBufferedInput divides the input stream into a first block, a number of +/// middle blocks, and a last block. First and last blocks are optional, and middle blocks may +/// be a stream instead (i.e. blockSize == 1). +/// \sa AuthenticatedEncryptionFilter, AuthenticatedDecryptionFilter, HashVerificationFilter, +/// SignatureVerificationFilter, StreamTransformationFilter +class CRYPTOPP_DLL FilterWithBufferedInput : public Filter +{ +public: + virtual ~FilterWithBufferedInput() {} + + /// \brief Construct a FilterWithBufferedInput with an attached transformation + /// \param attachment an attached transformation + FilterWithBufferedInput(BufferedTransformation *attachment); + + /// \brief Construct a FilterWithBufferedInput with an attached transformation + /// \param firstSize the size of the first block + /// \param blockSize the size of middle blocks + /// \param lastSize the size of the last block + /// \param attachment an attached transformation + /// \details firstSize and lastSize may be 0. blockSize must be at least 1. + FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment); + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + return PutMaybeModifiable(const_cast(inString), length, messageEnd, blocking, false); + } + + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) + { + return PutMaybeModifiable(inString, length, messageEnd, blocking, true); + } + + /// \brief Flushes data buffered by this object, without signal propagation + /// \param hardFlush indicates whether all data should be flushed + /// \param blocking specifies whether the object should block when processing input + /// \return true if the Flush was successful, false otherwise + /// \details IsolatedFlush() calls ForceNextPut() if hardFlush is true + /// \note hardFlush must be used with care + bool IsolatedFlush(bool hardFlush, bool blocking); + + /// \brief Flushes data buffered by this object + /// \details The input buffer may contain more than blockSize bytes if lastSize != 0. + /// ForceNextPut() forces a call to NextPut() if this is the case. + void ForceNextPut(); + +protected: + virtual bool DidFirstPut() const {return m_firstInputDone;} + virtual size_t GetFirstPutSize() const {return m_firstSize;} + virtual size_t GetBlockPutSize() const {return m_blockSize;} + virtual size_t GetLastPutSize() const {return m_lastSize;} + + virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) + {CRYPTOPP_UNUSED(parameters); CRYPTOPP_UNUSED(firstSize); CRYPTOPP_UNUSED(blockSize); CRYPTOPP_UNUSED(lastSize); InitializeDerived(parameters);} + virtual void InitializeDerived(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters);} + // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize) + // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)). + // inString is m_firstSize in length. + virtual void FirstPut(const byte *inString) =0; + // NextPut() is called if totalLength >= firstSize+blockSize+lastSize + virtual void NextPutSingle(const byte *inString) + {CRYPTOPP_UNUSED(inString); CRYPTOPP_ASSERT(false);} + // Same as NextPut() except length can be a multiple of blockSize + // Either NextPut() or NextPutMultiple() must be overridden + virtual void NextPutMultiple(const byte *inString, size_t length); + // Same as NextPutMultiple(), but inString can be modified + virtual void NextPutModifiable(byte *inString, size_t length) + {NextPutMultiple(inString, length);} + /// \brief Input the last block of data + /// \param inString the input byte buffer + /// \param length the size of the input buffer, in bytes + /// \details LastPut() processes the last block of data and signals attached filters to do the same. + /// LastPut() is always called. The pseudo algorithm for the logic is: + ///
+	///     if totalLength < firstSize then length == totalLength
+	///     else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
+	///     else lastSize <= length < lastSize+blockSize
+	/// 
+ virtual void LastPut(const byte *inString, size_t length) =0; + virtual void FlushDerived() {} + +protected: + size_t PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable); + void NextPutMaybeModifiable(byte *inString, size_t length, bool modifiable) + { + if (modifiable) NextPutModifiable(inString, length); + else NextPutMultiple(inString, length); + } + + // This function should no longer be used, put this here to cause a compiler error + // if someone tries to override NextPut(). + virtual int NextPut(const byte *inString, size_t length) + {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_ASSERT(false); return 0;} + + class BlockQueue + { + public: + void ResetQueue(size_t blockSize, size_t maxBlocks); + byte *GetBlock(); + byte *GetContigousBlocks(size_t &numberOfBytes); + size_t GetAll(byte *outString); + void Put(const byte *inString, size_t length); + size_t CurrentSize() const {return m_size;} + size_t MaxSize() const {return m_buffer.size();} + + private: + SecByteBlock m_buffer; + size_t m_blockSize, m_maxBlocks, m_size; + byte *m_begin; + }; + + size_t m_firstSize, m_blockSize, m_lastSize; + bool m_firstInputDone; + BlockQueue m_queue; +}; + +/// \brief A filter that buffers input using a ByteQueue +/// \details FilterWithInputQueue will buffer input using a ByteQueue. When the filter receives +/// a \ref BufferedTransformation::MessageEnd() "MessageEnd()" signal it will pass the data +/// on to its attached transformation. +class CRYPTOPP_DLL FilterWithInputQueue : public Filter +{ +public: + virtual ~FilterWithInputQueue() {} + + /// \brief Construct a FilterWithInputQueue + /// \param attachment an optional attached transformation + FilterWithInputQueue(BufferedTransformation *attachment=NULLPTR) : Filter(attachment) {} + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + if (!blocking) + throw BlockingInputOnly("FilterWithInputQueue"); + + m_inQueue.Put(inString, length); + if (messageEnd) + { + IsolatedMessageEnd(blocking); + Output(0, NULLPTR, 0, messageEnd, blocking); + } + return 0; + } + +protected: + virtual bool IsolatedMessageEnd(bool blocking) =0; + void IsolatedInitialize(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters); m_inQueue.Clear();} + + ByteQueue m_inQueue; +}; + +/// \struct BlockPaddingSchemeDef +/// \brief Padding schemes used for block ciphers +/// \since Crypto++ 5.0 +struct BlockPaddingSchemeDef +{ + /// \enum BlockPaddingScheme + /// \brief Padding schemes used for block ciphers. + /// \details DEFAULT_PADDING means PKCS_PADDING if cipher.MandatoryBlockSize() > 1 && + /// cipher.MinLastBlockSize() == 0, which holds for ECB or CBC mode. Otherwise, + /// NO_PADDING for modes like OFB, CFB, CTR, CBC-CTS. + /// \sa Block Cipher Padding for + /// additional details. + /// \since Crypto++ 5.0 + enum BlockPaddingScheme { + /// \brief No padding added to a block + /// \since Crypto++ 5.0 + NO_PADDING, + /// \brief 0's padding added to a block + /// \since Crypto++ 5.0 + ZEROS_PADDING, + /// \brief PKCS padding added to a block + /// \since Crypto++ 5.0 + PKCS_PADDING, + /// \brief 1 and 0's padding added to a block + /// \since Crypto++ 5.0 + ONE_AND_ZEROS_PADDING, + /// \brief W3C padding added to a block + /// \sa XML + /// Encryption Syntax and Processing + /// \since Crypto++ 6.0 + W3C_PADDING, + /// \brief Default padding scheme + /// \since Crypto++ 5.0 + DEFAULT_PADDING + }; +}; + +/// \brief Filter wrapper for StreamTransformation +/// \details StreamTransformationFilter() is a filter wrapper for StreamTransformation(). It is used when +/// pipelining data for stream ciphers and confidentiality-only block ciphers. The filter will optionally +/// handle padding and unpadding when needed. If you are using an authenticated encryption mode of operation, +/// then use AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter() +/// \since Crypto++ 5.0 +class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper +{ +public: + virtual ~StreamTransformationFilter() {} + + /// \brief Construct a StreamTransformationFilter + /// \param c reference to a StreamTransformation + /// \param attachment an optional attached transformation + /// \param padding the \ref BlockPaddingSchemeDef "padding scheme" + /// \details This contructor creates a StreamTransformationFilter() for stream ciphers and + /// confidentiality-only block cipher modes of operation. If you are using an authenticated + /// encryption mode of operation, then use either AuthenticatedEncryptionFilter() or + /// AuthenticatedDecryptionFilter(). + /// \sa AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter() + StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULLPTR, BlockPaddingScheme padding = DEFAULT_PADDING); + + std::string AlgorithmName() const {return m_cipher.AlgorithmName();} + +protected: + + friend class AuthenticatedEncryptionFilter; + friend class AuthenticatedDecryptionFilter; + + /// \brief Construct a StreamTransformationFilter + /// \param c reference to a StreamTransformation + /// \param attachment an optional attached transformation + /// \param padding the \ref BlockPaddingSchemeDef "padding scheme" + /// \param authenticated flag indicating whether the filter should allow authenticated encryption schemes + /// \details This constructor is used for authenticated encryption mode of operation and by + /// AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter(). + StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated); + + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + void NextPutModifiable(byte *inString, size_t length); + void LastPut(const byte *inString, size_t length); + + static size_t LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding); + + StreamTransformation &m_cipher; + BlockPaddingScheme m_padding; + unsigned int m_mandatoryBlockSize; + unsigned int m_optimalBufferSize; + unsigned int m_reservedBufferSize; + bool m_isSpecial; +}; + +/// \brief Filter wrapper for HashTransformation +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL HashFilter : public Bufferless, private FilterPutSpaceHelper +{ +public: + virtual ~HashFilter() {} + + /// \brief Construct a HashFilter + /// \param hm reference to a HashTransformation + /// \param attachment an optional attached transformation + /// \param putMessage flag indicating whether the original message should be passed to an attached transformation + /// \param truncatedDigestSize the size of the digest + /// \param messagePutChannel the channel on which the message should be output + /// \param hashPutChannel the channel on which the digest should be output + HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULLPTR, bool putMessage=false, int truncatedDigestSize=-1, const std::string &messagePutChannel=DEFAULT_CHANNEL, const std::string &hashPutChannel=DEFAULT_CHANNEL); + + std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);} + +private: + HashTransformation &m_hashModule; + bool m_putMessage; + unsigned int m_digestSize; + byte *m_space; + std::string m_messagePutChannel, m_hashPutChannel; +}; + +/// \brief Filter wrapper for HashTransformation +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL HashVerificationFilter : public FilterWithBufferedInput +{ +public: + virtual ~HashVerificationFilter() {} + + /// \brief Exception thrown when a data integrity check failure is encountered + class HashVerificationFailed : public Exception + { + public: + HashVerificationFailed() + : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerificationFilter: message hash or MAC not valid") {} + }; + + /// \enum Flags + /// \brief Flags controlling filter behavior. + /// \details The flags are a bitmask and can be OR'd together. + enum Flags { + /// \brief The hash is at the end of the message (i.e., concatenation of message+hash) + HASH_AT_END=0, + /// \brief The hash is at the beginning of the message (i.e., concatenation of hash+message) + HASH_AT_BEGIN=1, + /// \brief The message should be passed to an attached transformation + PUT_MESSAGE=2, + /// \brief The hash should be passed to an attached transformation + PUT_HASH=4, + /// \brief The result of the verification should be passed to an attached transformation + PUT_RESULT=8, + /// \brief The filter should throw a HashVerificationFailed if a failure is encountered + THROW_EXCEPTION=16, + /// \brief Default flags using HASH_AT_BEGIN and PUT_RESULT + DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT + }; + + /// \brief Construct a HashVerificationFilter + /// \param hm reference to a HashTransformation + /// \param attachment an optional attached transformation + /// \param flags flags indicating behaviors for the filter + /// \param truncatedDigestSize the size of the digest + /// \details truncatedDigestSize = -1 indicates \ref HashTransformation::DigestSize() "DigestSize" should be used. + HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULLPTR, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1); + + std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} + bool GetLastResult() const {return m_verified;} + +protected: + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + void LastPut(const byte *inString, size_t length); + +private: + friend class AuthenticatedDecryptionFilter; + + HashTransformation &m_hashModule; + word32 m_flags; + unsigned int m_digestSize; + bool m_verified; + SecByteBlock m_expectedHash; +}; + +/// \brief Filter wrapper for encrypting with AuthenticatedSymmetricCipher +/// \details AuthenticatedEncryptionFilter() is a wrapper for encrypting with +/// AuthenticatedSymmetricCipher(), optionally handling padding/unpadding when needed. +/// \details AuthenticatedDecryptionFilter() for Crypto++ 8.2 and earlier +/// had a bug where a FileSource() would cause an exception, but a StringSource() +/// was OK. Also see Issue 817 and Commit ff110c6e183e. +/// \sa AuthenticatedSymmetricCipher, AuthenticatedDecryptionFilter, EAX, CCM, GCM, +/// and AadSource on the +/// Crypto++ wiki. +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL AuthenticatedEncryptionFilter : public StreamTransformationFilter +{ +public: + virtual ~AuthenticatedEncryptionFilter() {} + + /// \brief Construct a AuthenticatedEncryptionFilter + /// \param c reference to a AuthenticatedSymmetricCipher + /// \param attachment an optional attached transformation + /// \param putAAD flag indicating whether the AAD should be passed to an attached transformation + /// \param truncatedDigestSize the size of the digest + /// \param macChannel the channel on which the MAC should be output + /// \param padding the \ref BlockPaddingSchemeDef "padding scheme" + /// \details truncatedDigestSize = -1 indicates \ref HashTransformation::DigestSize() "DigestSize" should be used. + /// \since Crypto++ 5.6.0 + AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULLPTR, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding = DEFAULT_PADDING); + + void IsolatedInitialize(const NameValuePairs ¶meters); + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + + /// \brief Input the last block of data + /// \param inString the input byte buffer + /// \param length the size of the input buffer, in bytes + /// \details LastPut() processes the last block of data and signals attached filters to do the same. + /// LastPut() is always called. The pseudo algorithm for the logic is: + ///
+	///     if totalLength < firstSize then length == totalLength
+	///     else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
+	///     else lastSize <= length < lastSize+blockSize
+	/// 
+ void LastPut(const byte *inString, size_t length); + +protected: + HashFilter m_hf; +}; + +/// \brief Filter wrapper for decrypting with AuthenticatedSymmetricCipher +/// \details AuthenticatedDecryptionFilter() is a wrapper for decrypting with +/// AuthenticatedSymmetricCipher(), optionally handling padding/unpadding when +/// needed. +/// \details AuthenticatedDecryptionFilter() for Crypto++ 8.2 and earlier +/// had a bug where a FileSource() would cause an exception, but a StringSource() +/// was OK. Also see Issue 817 and Commit ff110c6e183e. +/// \sa AuthenticatedSymmetricCipher, AuthenticatedEncryptionFilter, EAX, CCM, GCM, +/// and AadSource on the +/// Crypto++ wiki. +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL AuthenticatedDecryptionFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef +{ +public: + /// \enum Flags + /// \brief Flags controlling filter behavior. + /// \details The flags are a bitmask and can be OR'd together. + enum Flags { + /// \brief The MAC is at the end of the message (i.e., concatenation of message+mac) + MAC_AT_END=0, + /// \brief The MAC is at the beginning of the message (i.e., concatenation of mac+message) + MAC_AT_BEGIN=1, + /// \brief The filter should throw a HashVerificationFailed if a failure is encountered + THROW_EXCEPTION=16, + /// \brief Default flags using THROW_EXCEPTION + DEFAULT_FLAGS = THROW_EXCEPTION + }; + + virtual ~AuthenticatedDecryptionFilter() {} + + /// \brief Construct a AuthenticatedDecryptionFilter + /// \param c reference to a AuthenticatedSymmetricCipher + /// \param attachment an optional attached transformation + /// \param flags flags indicating behaviors for the filter + /// \param truncatedDigestSize the size of the digest + /// \param padding the \ref BlockPaddingSchemeDef "padding scheme" + /// \details Additional authenticated data should be given in channel "AAD". + /// \details truncatedDigestSize = -1 indicates \ref HashTransformation::DigestSize() "DigestSize" should be used. + /// \since Crypto++ 5.6.0 + AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULLPTR, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding = DEFAULT_PADDING); + + std::string AlgorithmName() const {return m_hashVerifier.AlgorithmName();} + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + { return ChannelPut2(channel, begin, length, messageEnd, blocking); } + /// \brief Get verifier result + /// \return true if the digest on the previosus message was valid, false otherwise + bool GetLastResult() const {return m_hashVerifier.GetLastResult();} + +protected: + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + + /// \brief Input the last block of data + /// \param inString the input byte buffer + /// \param length the size of the input buffer, in bytes + /// \details LastPut() processes the last block of data and signals attached filters to do the same. + /// LastPut() is always called. The pseudo algorithm for the logic is: + ///
+	///     if totalLength < firstSize then length == totalLength
+	///     else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
+	///     else lastSize <= length < lastSize+blockSize
+	/// 
+ void LastPut(const byte *inString, size_t length); + + HashVerificationFilter m_hashVerifier; + StreamTransformationFilter m_streamFilter; +}; + +/// \brief Filter wrapper for PK_Signer +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL SignerFilter : public Unflushable +{ +public: + virtual ~SignerFilter() {} + + /// \brief Construct a SignerFilter + /// \param rng a RandomNumberGenerator derived class + /// \param signer a PK_Signer derived class + /// \param attachment an optional attached transformation + /// \param putMessage flag indicating whether the original message should be passed to an attached transformation + SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULLPTR, bool putMessage=false) + : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator(rng)), m_putMessage(putMessage) {Detach(attachment);} + + std::string AlgorithmName() const {return m_signer.AlgorithmName();} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + +private: + RandomNumberGenerator &m_rng; + const PK_Signer &m_signer; + member_ptr m_messageAccumulator; + bool m_putMessage; + SecByteBlock m_buf; +}; + +/// \brief Filter wrapper for PK_Verifier +/// \details This filter was formerly named VerifierFilter. The name changed at Crypto++ 5.0. +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL SignatureVerificationFilter : public FilterWithBufferedInput +{ +public: + /// \brief Exception thrown when an invalid signature is encountered + class SignatureVerificationFailed : public Exception + { + public: + SignatureVerificationFailed() + : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {} + }; + + /// \enum Flags + /// \brief Flags controlling filter behavior. + /// \details The flags are a bitmask and can be OR'd together. + enum Flags { + /// \brief The signature is at the end of the message (i.e., concatenation of message+signature) + SIGNATURE_AT_END=0, + /// \brief The signature is at the beginning of the message (i.e., concatenation of signature+message) + SIGNATURE_AT_BEGIN=1, + /// \brief The message should be passed to an attached transformation + PUT_MESSAGE=2, + /// \brief The signature should be passed to an attached transformation + PUT_SIGNATURE=4, + /// \brief The result of the verification should be passed to an attached transformation + PUT_RESULT=8, + /// \brief The filter should throw a HashVerificationFailed if a failure is encountered + THROW_EXCEPTION=16, + /// \brief Default flags using SIGNATURE_AT_BEGIN and PUT_RESULT + DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT + }; + + virtual ~SignatureVerificationFilter() {} + + /// \brief Construct a SignatureVerificationFilter + /// \param verifier a PK_Verifier derived class + /// \param attachment an optional attached transformation + /// \param flags flags indicating behaviors for the filter + SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULLPTR, word32 flags = DEFAULT_FLAGS); + + std::string AlgorithmName() const {return m_verifier.AlgorithmName();} + + /// \brief Retrieves the result of the last verification + /// \return true if the signature on the previosus message was valid, false otherwise + bool GetLastResult() const {return m_verified;} + +protected: + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + void LastPut(const byte *inString, size_t length); + +private: + const PK_Verifier &m_verifier; + member_ptr m_messageAccumulator; + word32 m_flags; + SecByteBlock m_signature; + bool m_verified; +}; + +/// \brief Redirect input to another BufferedTransformation without owning it +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL Redirector : public CustomSignalPropagation +{ +public: + /// \enum Behavior + /// \brief Controls signal propagation behavior + enum Behavior + { + /// \brief Pass data only + DATA_ONLY = 0x00, + /// \brief Pass signals + PASS_SIGNALS = 0x01, + /// \brief Pass wait events + PASS_WAIT_OBJECTS = 0x02, + /// \brief Pass everything + /// \details PASS_EVERYTHING is default + PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS + }; + + virtual ~Redirector() {} + + /// \brief Construct a Redirector + Redirector() : m_target(NULLPTR), m_behavior(PASS_EVERYTHING) {} + + /// \brief Construct a Redirector + /// \param target the destination BufferedTransformation + /// \param behavior Behavior "flags" specifying signal propagation + Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING) + : m_target(&target), m_behavior(behavior) {} + + /// \brief Redirect input to another BufferedTransformation + /// \param target the destination BufferedTransformation + void Redirect(BufferedTransformation &target) {m_target = ⌖} + /// \brief Stop redirecting input + void StopRedirection() {m_target = NULLPTR;} + + /// \brief Retrieve signal propagation behavior + /// \return the current signal propagation behavior + Behavior GetBehavior() {return static_cast(m_behavior);} + /// \brief Set signal propagation behavior + /// \param behavior the new signal propagation behavior + void SetBehavior(Behavior behavior) {m_behavior=behavior;} + /// \brief Retrieve signal propagation behavior + /// \return true if the Redirector passes signals, false otherwise. + bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;} + /// \brief Set signal propagation behavior + /// \param pass flag indicating if the Redirector should pass signals + void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~static_cast(PASS_SIGNALS); } + /// \brief Retrieve signal propagation behavior + /// \return true if the Redirector passes wait objects, false otherwise. + bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;} + /// \brief Set signal propagation behavior + /// \param pass flag indicating if the Redirector should pass wait objects + void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~static_cast(PASS_WAIT_OBJECTS); } + + bool CanModifyInput() const + {return m_target ? m_target->CanModifyInput() : false;} + + void Initialize(const NameValuePairs ¶meters, int propagation); + byte * CreatePutSpace(size_t &size) + { + if (m_target) + return m_target->CreatePutSpace(size); + else + { + size = 0; + return NULLPTR; + } + } + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + {return m_target ? m_target->Put2(inString, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;} + bool MessageSeriesEnd(int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;} + + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) + { + if (m_target) + return m_target->ChannelCreatePutSpace(channel, size); + else + { + size = 0; + return NULLPTR; + } + } + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} + + unsigned int GetMaxWaitObjectCount() const + { return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; } + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) + { if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container, callStack); } + +private: + BufferedTransformation *m_target; + word32 m_behavior; +}; + +/// \brief Filter class that is a proxy for a sink +/// \details Used By ProxyFilter +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation +{ +public: + virtual ~OutputProxy() {} + + /// \brief Construct an OutputProxy + /// \param owner the owning transformation + /// \param passSignal flag indicating if signals should be passed + OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {} + + /// \brief Retrieve passSignal flag + /// \return flag indicating if signals should be passed + bool GetPassSignal() const {return m_passSignal;} + /// \brief Set passSignal flag + /// \param passSignal flag indicating if signals should be passed + void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} + + byte * CreatePutSpace(size_t &size) + {return m_owner.AttachedTransformation()->CreatePutSpace(size);} + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->Put2(inString, length, m_passSignal ? messageEnd : 0, blocking);} + size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);} + void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);} + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;} + bool MessageSeriesEnd(int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;} + + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) + {return m_owner.AttachedTransformation()->ChannelCreatePutSpace(channel, size);} + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);} + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);} + bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} + +private: + BufferedTransformation &m_owner; + bool m_passSignal; +}; + +/// \brief Base class for Filter classes that are proxies for a chain of other filters +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput +{ +public: + virtual ~ProxyFilter() {} + + /// \brief Construct a ProxyFilter + /// \param filter an output filter + /// \param firstSize the first Put size + /// \param lastSize the last Put size + /// \param attachment an attached transformation + ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment); + + bool IsolatedFlush(bool hardFlush, bool blocking); + + /// \brief Sets the OutputProxy filter + /// \param filter an OutputProxy filter + void SetFilter(Filter *filter); + void NextPutMultiple(const byte *s, size_t len); + void NextPutModifiable(byte *inString, size_t length); + +protected: + member_ptr m_filter; +}; + +/// \brief Proxy filter that doesn't modify the underlying filter's input or output +/// \since Crypto++ 5.0 +class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter +{ +public: + /// \brief Construct a SimpleProxyFilter + /// \param filter an output filter + /// \param attachment an attached transformation + SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment) + : ProxyFilter(filter, 0, 0, attachment) {} + + void FirstPut(const byte * inString) + {CRYPTOPP_UNUSED(inString);} + + /// \brief Input the last block of data + /// \param inString the input byte buffer + /// \param length the size of the input buffer, in bytes + /// \details LastPut() processes the last block of data and signals attached filters to do the same. + /// LastPut() is always called. The pseudo algorithm for the logic is: + ///
+	///     if totalLength < firstSize then length == totalLength
+	///     else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
+	///     else lastSize <= length < lastSize+blockSize
+	/// 
+ void LastPut(const byte *inString, size_t length) + {CRYPTOPP_UNUSED(inString), CRYPTOPP_UNUSED(length); m_filter->MessageEnd();} +}; + +/// \brief Filter wrapper for PK_Encryptor +/// \details PK_DecryptorFilter is a proxy for the filter created by PK_Encryptor::CreateEncryptionFilter. +/// This class provides symmetry with VerifierFilter. +/// \since Crypto++ 5.0 +class CRYPTOPP_DLL PK_EncryptorFilter : public SimpleProxyFilter +{ +public: + /// \brief Construct a PK_EncryptorFilter + /// \param rng a RandomNumberGenerator derived class + /// \param encryptor a PK_Encryptor derived class + /// \param attachment an optional attached transformation + PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULLPTR) + : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {} +}; + +/// \brief Filter wrapper for PK_Decryptor +/// \details PK_DecryptorFilter is a proxy for the filter created by PK_Decryptor::CreateDecryptionFilter. +/// This class provides symmetry with SignerFilter. +/// \since Crypto++ 5.0 +class CRYPTOPP_DLL PK_DecryptorFilter : public SimpleProxyFilter +{ +public: + /// \brief Construct a PK_DecryptorFilter + /// \param rng a RandomNumberGenerator derived class + /// \param decryptor a PK_Decryptor derived class + /// \param attachment an optional attached transformation + PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULLPTR) + : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {} +}; + +/// \brief Append input to a string object +/// \tparam T std::basic_string type +/// \details StringSinkTemplate is a StringSinkTemplate typedef +/// \since Crypto++ 5.0 +template +class StringSinkTemplate : public Bufferless +{ +public: + typedef typename T::value_type value_type; + virtual ~StringSinkTemplate() {} + + /// \brief Construct a StringSinkTemplate + /// \param output std::basic_string or std::vector type + StringSinkTemplate(T &output) + : m_output(&output) {CRYPTOPP_ASSERT(sizeof(value_type)==1);} + + void IsolatedInitialize(const NameValuePairs ¶meters) + {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");} + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); + if (length > 0) + { + typename T::size_type size = m_output->size(); + if (length < size && size + length > m_output->capacity()) + m_output->reserve(2*size); + m_output->insert(m_output->end(), (const value_type *)inString, (const value_type *)inString+length); + } + return 0; + } + +private: + T *m_output; +}; + +/// \brief Append input to a string object +/// \details StringSink is a typedef for StringSinkTemplate. +/// \sa ArraySink, ArrayXorSink +/// \since Crypto++ 4.0 +DOCUMENTED_TYPEDEF(StringSinkTemplate, StringSink); +CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate; + +/// \brief Append input to a std::vector object +/// \details VectorSink is a typedef for StringSinkTemplate >. +/// \since Crypto++ 8.0 +DOCUMENTED_TYPEDEF(StringSinkTemplate >, VectorSink); +CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate >; + +/// \brief Incorporates input into RNG as additional entropy +/// \since Crypto++ 4.0 +class RandomNumberSink : public Bufferless +{ +public: + virtual ~RandomNumberSink() {} + + /// \brief Construct a RandomNumberSink + RandomNumberSink() + : m_rng(NULLPTR) {} + + /// \brief Construct a RandomNumberSink + /// \param rng a RandomNumberGenerator derived class + RandomNumberSink(RandomNumberGenerator &rng) + : m_rng(&rng) {} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + +private: + RandomNumberGenerator *m_rng; +}; + +/// \brief Copy input to a memory buffer +/// \details ArraySink wraps a fixed size buffer. The buffer is full once Put returns non-0. +/// When used in a pipleline, ArraySink silently discards input if the buffer is full. +/// AvailableSize() can be used to determine how much space remains in the buffer. +/// TotalPutLength() can be used to determine how many bytes were processed. +/// \sa StringSink, ArrayXorSink +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL ArraySink : public Bufferless +{ +public: + virtual ~ArraySink() {} + + /// \brief Construct an ArraySink + /// \param parameters a set of NameValuePairs to initialize this object + /// \details Name::OutputBuffer() is a mandatory parameter using this constructor. + ArraySink(const NameValuePairs ¶meters = g_nullNameValuePairs) + : m_buf(NULLPTR), m_size(0), m_total(0) {IsolatedInitialize(parameters);} + + /// \brief Construct an ArraySink + /// \param buf pointer to a memory buffer + /// \param size length of the memory buffer + ArraySink(byte *buf, size_t size) + : m_buf(buf), m_size(size), m_total(0) {} + + /// \brief Provides the size remaining in the Sink + /// \return size remaining in the Sink, in bytes + size_t AvailableSize() {return SaturatingSubtract(m_size, m_total);} + + /// \brief Provides the number of bytes written to the Sink + /// \return number of bytes written to the Sink, in bytes + lword TotalPutLength() {return m_total;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + byte * CreatePutSpace(size_t &size); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + +protected: + byte *m_buf; + size_t m_size; + lword m_total; +}; + +/// \brief Xor input to a memory buffer +/// \details ArrayXorSink wraps a fixed size buffer. The buffer is full once Put returns non-0. +/// When used in a pipleline, ArrayXorSink silently discards input if the buffer is full. +/// AvailableSize() can be used to determine how much space remains in the buffer. +/// TotalPutLength() can be used to determine how many bytes were processed. +/// \sa StringSink, ArraySink +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL ArrayXorSink : public ArraySink +{ +public: + virtual ~ArrayXorSink() {} + + /// \brief Construct an ArrayXorSink + /// \param buf pointer to a memory buffer + /// \param size length of the memory buffer + ArrayXorSink(byte *buf, size_t size) + : ArraySink(buf, size) {} + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);} +}; + +/// \brief String-based implementation of Store interface +/// \since Crypto++ 4.0 +class StringStore : public Store +{ +public: + /// \brief Construct a StringStore + /// \param string pointer to a C-String + StringStore(const char *string = NULLPTR) + {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} + + /// \brief Construct a StringStore + /// \param string pointer to a memory buffer + /// \param length size of the memory buffer + StringStore(const byte *string, size_t length) + {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} + + /// \brief Construct a StringStore + /// \tparam T std::basic_string type + /// \param string reference to a std::basic_string type + template StringStore(const T &string) + {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} + + CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + +private: + CRYPTOPP_DLL void StoreInitialize(const NameValuePairs ¶meters); + + const byte *m_store; + size_t m_length, m_count; +}; + +/// \brief RNG-based implementation of Source interface +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL RandomNumberStore : public Store +{ +public: + virtual ~RandomNumberStore() {} + + RandomNumberStore() + : m_rng(NULLPTR), m_length(0), m_count(0) {} + + RandomNumberStore(RandomNumberGenerator &rng, lword length) + : m_rng(&rng), m_length(length), m_count(0) {} + + bool AnyRetrievable() const {return MaxRetrievable() != 0;} + lword MaxRetrievable() const {return m_length-m_count;} + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const + { + CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(end); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking); + throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store"); + } + +private: + void StoreInitialize(const NameValuePairs ¶meters); + + RandomNumberGenerator *m_rng; + lword m_length, m_count; +}; + +/// \brief Empty store +/// \since Crypto++ 5.0 +class CRYPTOPP_DLL NullStore : public Store +{ +public: + NullStore(lword size = ULONG_MAX) : m_size(size) {} + void StoreInitialize(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters);} + lword MaxRetrievable() const {return m_size;} + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + +private: + lword m_size; +}; + +/// \brief Implementation of BufferedTransformation's attachment interface +/// \details Source is a cornerstone of the Pipeline trinitiy. Data flows from +/// Sources, through Filters, and then terminates in Sinks. The difference +/// between a Source and Filter is a Source \a pumps data, while a Filter does +/// not. The difference between a Filter and a Sink is a Filter allows an +/// attached transformation, while a Sink does not. +/// \details See the discussion of BufferedTransformation in cryptlib.h for +/// more details. +/// \sa Store and SourceTemplate +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting +{ +public: + virtual ~Source() {} + + /// \brief Construct a Source + /// \param attachment an optional attached transformation + Source(BufferedTransformation *attachment = NULLPTR) + {Source::Detach(attachment);} + + /// \name PIPELINE + //@{ + + /// \brief Pump data to attached transformation + /// \param pumpMax the maximum number of bytes to pump + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + /// \details Internally, Pump() calls Pump2(). + /// \note pumpMax is a lword, which is a 64-bit value that typically uses + /// LWORD_MAX. The default argument is SIZE_MAX, and it can be + /// 32-bits or 64-bits. + /// \sa Pump2, PumpAll, AnyRetrievable, MaxRetrievable + lword Pump(lword pumpMax=SIZE_MAX) + {Pump2(pumpMax); return pumpMax;} + + /// \brief Pump messages to attached transformation + /// \param count the maximum number of messages to pump + /// \return TODO + /// \details Internally, PumpMessages() calls PumpMessages2(). + unsigned int PumpMessages(unsigned int count=UINT_MAX) + {PumpMessages2(count); return count;} + + /// \brief Pump all data to attached transformation + /// \details Pumps all data to the attached transformation and signal the end of the current + /// message. To avoid the MessageEnd() signal call \ref Pump "Pump(LWORD_MAX)" or \ref Pump2 + /// "Pump2(LWORD_MAX, bool)". + /// \details Internally, PumpAll() calls PumpAll2(), which calls PumpMessages(). + /// \sa Pump, Pump2, AnyRetrievable, MaxRetrievable + void PumpAll() + {PumpAll2();} + + /// \brief Pump data to attached transformation + /// \param byteCount the maximum number of bytes to pump + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + /// \details byteCount is an \a IN and \a OUT parameter. When the call is made, byteCount is the + /// requested size of the pump. When the call returns, byteCount is the number of bytes that + /// were pumped. + /// \sa Pump, PumpAll, AnyRetrievable, MaxRetrievable + virtual size_t Pump2(lword &byteCount, bool blocking=true) =0; + + /// \brief Pump messages to attached transformation + /// \param messageCount the maximum number of messages to pump + /// \param blocking specifies whether the object should block when processing input + /// \details messageCount is an IN and OUT parameter. + virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) =0; + + /// \brief Pump all data to attached transformation + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed). + /// 0 indicates all bytes were processed. + /// \sa Pump, Pump2, AnyRetrievable, MaxRetrievable + virtual size_t PumpAll2(bool blocking=true); + + /// \brief Determines if the Source is exhausted + /// \return true if the source has been exhausted + virtual bool SourceExhausted() const =0; + + //@} + +protected: + void SourceInitialize(bool pumpAll, const NameValuePairs ¶meters) + { + IsolatedInitialize(parameters); + if (pumpAll) + PumpAll(); + } +}; + +/// \brief Transform a Store into a Source +/// \tparam T the class or type +/// \since Crypto++ 5.0 +template +class SourceTemplate : public Source +{ +public: + virtual ~SourceTemplate() {} + + /// \brief Construct a SourceTemplate + /// \param attachment an attached transformation + SourceTemplate(BufferedTransformation *attachment) + : Source(attachment) {} + void IsolatedInitialize(const NameValuePairs ¶meters) + {m_store.IsolatedInitialize(parameters);} + size_t Pump2(lword &byteCount, bool blocking=true) + {return m_store.TransferTo2(*AttachedTransformation(), byteCount, DEFAULT_CHANNEL, blocking);} + size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) + {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, DEFAULT_CHANNEL, blocking);} + size_t PumpAll2(bool blocking=true) + {return m_store.TransferAllTo2(*AttachedTransformation(), DEFAULT_CHANNEL, blocking);} + bool SourceExhausted() const + {return !m_store.AnyRetrievable() && !m_store.AnyMessages();} + void SetAutoSignalPropagation(int propagation) + {m_store.SetAutoSignalPropagation(propagation);} + int GetAutoSignalPropagation() const + {return m_store.GetAutoSignalPropagation();} + +protected: + T m_store; +}; + +/// \brief String-based implementation of the Source interface +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL StringSource : public SourceTemplate +{ +public: + /// \brief Construct a StringSource + /// \param attachment an optional attached transformation + StringSource(BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {} + + /// \brief Construct a StringSource + /// \param string C-String + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} + + /// \brief Construct a StringSource + /// \param string binary byte array + /// \param length size of the byte array + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} + + /// \brief Construct a StringSource + /// \param string std::string + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} +}; + +/// \brief Pointer-based implementation of the Source interface +/// \details ArraySource is a typedef for StringSource. Use the third constructor for an array source. +/// The third constructor takes a pointer and length. +/// \since Crypto++ 5.6.0 +DOCUMENTED_TYPEDEF(StringSource, ArraySource); + +/// \brief std::vector-based implementation of the Source interface +/// \since Crypto++ 8.0 +class CRYPTOPP_DLL VectorSource : public SourceTemplate +{ +public: + /// \brief Construct a VectorSource + /// \param attachment an optional attached transformation + VectorSource(BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {} + + /// \brief Construct a VectorSource + /// \param vec vector of bytes + /// \param pumpAll flag indicating if source data should be pumped to its attached transformation + /// \param attachment an optional attached transformation + VectorSource(const std::vector &vec, bool pumpAll, BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(vec)));} +}; + +/// \brief RNG-based implementation of Source interface +/// \since Crypto++ 4.0 +class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate +{ +public: + RandomNumberSource(RandomNumberGenerator &rng, int length, bool pumpAll, BufferedTransformation *attachment = NULLPTR) + : SourceTemplate(attachment) + {SourceInitialize(pumpAll, MakeParameters("RandomNumberGeneratorPointer", &rng)("RandomNumberStoreSize", length));} +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/fips140.cpp b/external/ours/library/crypto/src/shared/original/fips140.cpp new file mode 100755 index 000000000..4e137443c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/fips140.cpp @@ -0,0 +1,84 @@ +// fips140.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "fips140.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +// Define this to 1 to turn on FIPS 140-2 compliance features, including additional tests during +// startup, random number generation, and key generation. These tests may affect performance. +#ifndef CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +#define CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 0 +#endif + +#if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(OS_RNG_AVAILABLE)) +#error FIPS 140-2 compliance requires the availability of OS provided RNG. +#endif + +PowerUpSelfTestStatus g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_NOT_DONE; + +bool FIPS_140_2_ComplianceEnabled() +{ + return CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2; +} + +void SimulatePowerUpSelfTestFailure() +{ + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_FAILED; +} + +PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus() +{ + return g_powerUpSelfTestStatus; +} + +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +// One variable for all threads for compatibility. Previously this +// was a ThreadLocalStorage variable, which is per-thread. Also see +// https://github.com/weidai11/cryptopp/issues/208 +static bool s_inProgress = false; +#endif + +bool PowerUpSelfTestInProgressOnThisThread() +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + return s_inProgress; +#else + return false; +#endif +} + +void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress) +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + s_inProgress = inProgress; +#else + CRYPTOPP_UNUSED(inProgress); +#endif +} + +void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor) +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + EncryptionPairwiseConsistencyTest(encryptor, decryptor); +#else + CRYPTOPP_UNUSED(encryptor), CRYPTOPP_UNUSED(decryptor); +#endif +} + +void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier) +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + SignaturePairwiseConsistencyTest(signer, verifier); +#else + CRYPTOPP_UNUSED(signer), CRYPTOPP_UNUSED(verifier); +#endif +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/fips140.h b/external/ours/library/crypto/src/shared/original/fips140.h new file mode 100755 index 000000000..499e86801 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/fips140.h @@ -0,0 +1,112 @@ +// fips140.h - originally written and placed in the public domain by Wei Dai + +/// \file fips140.h +/// \brief Classes and functions for the FIPS 140-2 validated library +/// \details The FIPS validated library is only available on Windows as a DLL. Once compiled, +/// the library is always in FIPS mode contingent upon successful execution of +/// DoPowerUpSelfTest() or DoDllPowerUpSelfTest(). +/// \sa Visual Studio and +/// config.h on the Crypto++ wiki. + +#ifndef CRYPTOPP_FIPS140_H +#define CRYPTOPP_FIPS140_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// Exception thrown when a crypto algorithm is used after a self test fails +/// \details The self tests for an algorithm are performed by Algortihm class +/// when CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined. +class CRYPTOPP_DLL SelfTestFailure : public Exception +{ +public: + explicit SelfTestFailure(const std::string &s) : Exception(OTHER_ERROR, s) {} +}; + +/// \brief Determines whether the library provides FIPS validated cryptography +/// \return true if FIPS 140-2 validated features were enabled at compile time. +/// \details true if FIPS 140-2 validated features were enabled at compile time, +/// false otherwise. +/// \note FIPS mode is enabled at compile time. A program or other module cannot +/// arbitrarily enter or exit the mode. +CRYPTOPP_DLL bool CRYPTOPP_API FIPS_140_2_ComplianceEnabled(); + +/// \brief Status of the power-up self test +enum PowerUpSelfTestStatus { + + /// \brief The self tests have not been performed. + POWER_UP_SELF_TEST_NOT_DONE, + /// \brief The self tests were executed via DoPowerUpSelfTest() or + /// DoDllPowerUpSelfTest(), but the result was failure. + POWER_UP_SELF_TEST_FAILED, + /// \brief The self tests were executed via DoPowerUpSelfTest() or + /// DoDllPowerUpSelfTest(), and the result was success. + POWER_UP_SELF_TEST_PASSED +}; + +/// \brief Performs the power-up self test +/// \param moduleFilename the fully qualified name of the module +/// \param expectedModuleMac the expected MAC of the components protected by the integrity check +/// \details Performs the power-up self test, and sets the self test status to +/// POWER_UP_SELF_TEST_PASSED or POWER_UP_SELF_TEST_FAILED. +/// \details The self tests for an algorithm are performed by the Algortihm class +/// when CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined. +CRYPTOPP_DLL void CRYPTOPP_API DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac); + +/// \brief Performs the power-up self test on the DLL +/// \details Performs the power-up self test using the filename of this DLL and the +/// embedded module MAC, and sets the self test status to POWER_UP_SELF_TEST_PASSED or +/// POWER_UP_SELF_TEST_FAILED. +/// \details The self tests for an algorithm are performed by the Algortihm class +/// when CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined. +CRYPTOPP_DLL void CRYPTOPP_API DoDllPowerUpSelfTest(); + +/// \brief Sets the power-up self test status to POWER_UP_SELF_TEST_FAILED +/// \details Sets the power-up self test status to POWER_UP_SELF_TEST_FAILED to simulate failure. +CRYPTOPP_DLL void CRYPTOPP_API SimulatePowerUpSelfTestFailure(); + +/// \brief Provides the current power-up self test status +/// \return the current power-up self test status +CRYPTOPP_DLL PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus(); + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +typedef PowerUpSelfTestStatus (CRYPTOPP_API * PGetPowerUpSelfTestStatus)(); +#endif + +/// \brief Class object that calculates the MAC on the module +/// \return the MAC for the module +CRYPTOPP_DLL MessageAuthenticationCode * CRYPTOPP_API NewIntegrityCheckingMAC(); + +/// \brief Verifies the MAC on the module +/// \param moduleFilename the fully qualified name of the module +/// \param expectedModuleMac the expected MAC of the components protected by the integrity check +/// \param pActualMac the actual MAC of the components calculated by the integrity check +/// \param pMacFileLocation the offest of the MAC in the PE/PE+ module +/// \return true if the MAC is valid, false otherwise +CRYPTOPP_DLL bool CRYPTOPP_API IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac = NULLPTR, unsigned long *pMacFileLocation = NULLPTR); + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING +// this is used by Algorithm constructor to allow Algorithm objects to be constructed for the self test +bool PowerUpSelfTestInProgressOnThisThread(); + +void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress); + +void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier &verifier); +void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor); + +void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier); +void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor); +#endif + +/// \brief The placeholder used prior to embedding the actual MAC in the module. +/// \details After the DLL is built but before it is MAC'd, the string CRYPTOPP_DUMMY_DLL_MAC +/// is used as a placeholder for the actual MAC. A post-build step is performed which calculates +/// the MAC of the DLL and embeds it in the module. The actual MAC is written by the +/// cryptest.exe program using the mac_dll subcommand. +#define CRYPTOPP_DUMMY_DLL_MAC "MAC_51f34b8db820ae8" + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/fipsalgt.cpp b/external/ours/library/crypto/src/shared/original/fipsalgt.cpp new file mode 100755 index 000000000..db0fc5384 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/fipsalgt.cpp @@ -0,0 +1,1293 @@ +// fipsalgt.cpp - originally written and placed in the public domain by Wei Dai + +// This file implements the various algorithm tests needed to pass FIPS 140 validation. +// They're preserved here (commented out) in case Crypto++ needs to be revalidated. + +#if 0 +#ifndef CRYPTOPP_IMPORTS +#define CRYPTOPP_DEFAULT_NO_DLL +#endif + +#include "dll.h" +#include "cryptlib.h" +#include "smartptr.h" +#include "filters.h" +#include "oids.h" + +USING_NAMESPACE(CryptoPP) + +class LineBreakParser : public AutoSignaling > +{ +public: + LineBreakParser(BufferedTransformation *attachment=NULLPTR, byte lineEnd='\n') + : m_lineEnd(lineEnd) {Detach(attachment);} + + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + { + if (!blocking) + throw BlockingInputOnly("LineBreakParser"); + + unsigned int i, last = 0; + for (i=0; iPut2(begin+last, i-last, GetAutoSignalPropagation(), blocking); + last = i+1; + } + } + if (last != i) + AttachedTransformation()->Put2(begin+last, i-last, 0, blocking); + + if (messageEnd && GetAutoSignalPropagation()) + { + AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking); + AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking); + } + + return 0; + } + +private: + byte m_lineEnd; +}; + +class TestDataParser : public Unflushable +{ +public: + enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT}; + + TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment) + : m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize) + , m_firstLine(true), m_blankLineTransition(0) + { + Detach(attachment); + + m_typeToName[COUNT] = "COUNT"; + + m_nameToType["COUNT"] = COUNT; + m_nameToType["KEY"] = KEY_T; + m_nameToType["KEYs"] = KEY_T; + m_nameToType["key"] = KEY_T; + m_nameToType["Key"] = KEY_T; + m_nameToType["IV"] = IV; + m_nameToType["IV1"] = IV; + m_nameToType["CV"] = IV; + m_nameToType["CV1"] = IV; + m_nameToType["IB"] = IV; + m_nameToType["TEXT"] = INPUT; + m_nameToType["RESULT"] = OUTPUT; + m_nameToType["Msg"] = INPUT; + m_nameToType["Seed"] = INPUT; + m_nameToType["V"] = INPUT; + m_nameToType["DT"] = IV; + SetEncrypt(encrypt); + + if (m_algorithm == "DSA" || m_algorithm == "ECDSA") + { + if (m_test == "PKV") + m_trigger = "Qy"; + else if (m_test == "KeyPair") + m_trigger = "N"; + else if (m_test == "SigGen") + m_trigger = "Msg"; + else if (m_test == "SigVer") + m_trigger = "S"; + else if (m_test == "PQGGen") + m_trigger = "N"; + else if (m_test == "PQGVer") + m_trigger = "H"; + } + else if (m_algorithm == "HMAC") + m_trigger = "Msg"; + else if (m_algorithm == "SHA") + m_trigger = (m_test == "MONTE") ? "Seed" : "Msg"; + else if (m_algorithm == "RNG") + m_trigger = "V"; + else if (m_algorithm == "RSA") + m_trigger = (m_test == "Ver") ? "S" : "Msg"; + } + + void SetEncrypt(bool encrypt) + { + m_encrypt = encrypt; + if (encrypt) + { + m_nameToType["PLAINTEXT"] = INPUT; + m_nameToType["CIPHERTEXT"] = OUTPUT; + m_nameToType["PT"] = INPUT; + m_nameToType["CT"] = OUTPUT; + } + else + { + m_nameToType["PLAINTEXT"] = OUTPUT; + m_nameToType["CIPHERTEXT"] = INPUT; + m_nameToType["PT"] = OUTPUT; + m_nameToType["CT"] = INPUT; + } + + if (m_algorithm == "AES" || m_algorithm == "TDES") + { + if (encrypt) + { + m_trigger = "PLAINTEXT"; + m_typeToName[OUTPUT] = "CIPHERTEXT"; + } + else + { + m_trigger = "CIPHERTEXT"; + m_typeToName[OUTPUT] = "PLAINTEXT"; + } + m_count = 0; + } + } + +protected: + void OutputData(std::string &output, const std::string &key, const std::string &data) + { + output += key; + output += "= "; + output += data; + output += "\n"; + } + + void OutputData(std::string &output, const std::string &key, int data) + { + OutputData(output, key, IntToString(data)); + } + + void OutputData(std::string &output, const std::string &key, const SecByteBlock &data) + { + output += key; + output += "= "; + HexEncoder(new StringSink(output), false).Put(data, data.size()); + output += "\n"; + } + + void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1) + { + SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); + data.Encode(s, s.size()); + OutputData(output, key, s); + } + + void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1) + { + SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); + data.Encode(s, s.size()); + OutputData(output, key, s); + } + + void OutputData(std::string &output, DataType t, const std::string &data) + { + if (m_algorithm == "SKIPJACK") + { + if (m_test == "KAT") + { + if (t == OUTPUT) + output = m_line + data + "\n"; + } + else + { + if (t != COUNT) + { + output += m_typeToName[t]; + output += "="; + } + output += data; + output += t == OUTPUT ? "\n" : " "; + } + } + else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty()) + { + output += "KEY1 = "; + output += data.substr(0, 16); + output += "\nKEY2 = "; + output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16); + output += "\nKEY3 = "; + output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16); + output += "\n"; + } + else + { + output += m_typeToName[t]; + output += " = "; + output += data; + output += "\n"; + } + } + + void OutputData(std::string &output, DataType t, int i) + { + OutputData(output, t, IntToString(i)); + } + + void OutputData(std::string &output, DataType t, const SecByteBlock &data) + { + std::string hexData; + StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false)); + OutputData(output, t, hexData); + } + + void OutputGivenData(std::string &output, DataType t, bool optional = false) + { + if (m_data.find(m_typeToName[t]) == m_data.end()) + { + if (optional) + return; + throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]); + } + + OutputData(output, t, m_data[m_typeToName[t]]); + } + + template + BlockCipher * NewBT(T *) + { + if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC")) + return new typename T::Decryption; + else + return new typename T::Encryption; + } + + template + SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv) + { + if (!m_encrypt) + return new typename T::Decryption(bt, iv, m_feedbackSize/8); + else + return new typename T::Encryption(bt, iv, m_feedbackSize/8); + } + + static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y) + { + CRYPTOPP_ASSERT(x.size() == y.size()); + z.resize(x.size()); + xorbuf(z, x, y, x.size()); + } + + SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text) + { + unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000; + int keySize = key.size(), blockSize = text[0].size(); + SecByteBlock x(keySize); + for (int k=0; k + void EC_KeyPair(string &output, int n, const OID &oid) + { + DL_GroupParameters_EC params(oid); + for (int i=0; i priv; + DL_PublicKey_EC pub; + priv.Initialize(m_rng, params); + priv.MakePublicKey(pub); + + OutputData(output, "d ", priv.GetPrivateExponent()); + OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); + } + } + + template + void EC_SigGen(string &output, const OID &oid) + { + DL_GroupParameters_EC params(oid); + typename ECDSA::PrivateKey priv; + typename ECDSA::PublicKey pub; + priv.Initialize(m_rng, params); + priv.MakePublicKey(pub); + + typename ECDSA::Signer signer(priv); + SecByteBlock sig(signer.SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); + SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2); + + OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "R ", R); + OutputData(output, "S ", S); + } + + template + void EC_SigVer(string &output, const OID &oid) + { + SecByteBlock x(DecodeHex(m_data["Qx"])); + SecByteBlock y(DecodeHex(m_data["Qy"])); + Integer r((m_data["R"]+"h").c_str()); + Integer s((m_data["S"]+"h").c_str()); + + typename EC::FieldElement Qx(x, x.size()); + typename EC::FieldElement Qy(y, y.size()); + typename EC::Element Q(Qx, Qy); + + DL_GroupParameters_EC params(oid); + typename ECDSA::PublicKey pub; + pub.Initialize(params, Q); + typename ECDSA::Verifier verifier(pub); + + SecByteBlock sig(verifier.SignatureLength()); + r.Encode(sig, sig.size()/2); + s.Encode(sig+sig.size()/2, sig.size()/2); + + SignatureVerificationFilter filter(verifier); + filter.Put(sig, sig.size()); + StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY))); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + } + + template + static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid) + { + typename EC::FieldElement Qx(x, x.size()); + typename EC::FieldElement Qy(y, y.size()); + typename EC::Element Q(Qx, Qy); + + DL_GroupParameters_EC params(oid); + typename ECDSA::PublicKey pub; + pub.Initialize(params, Q); + return pub.Validate(rng, 3); + } + + template + Result * CreateRSA2(const std::string &standard) + { + if (typeid(Result) == typeid(PK_Verifier)) + { + if (standard == "R") + return (Result *) new typename RSASS_ISO::Verifier; + else if (standard == "P") + return (Result *) new typename RSASS::Verifier; + else if (standard == "1") + return (Result *) new typename RSASS::Verifier; + } + else if (typeid(Result) == typeid(PK_Signer)) + { + if (standard == "R") + return (Result *) new typename RSASS_ISO::Signer; + else if (standard == "P") + return (Result *) new typename RSASS::Signer; + else if (standard == "1") + return (Result *) new typename RSASS::Signer; + } + + return NULLPTR; + } + + template + Result * CreateRSA(const std::string &standard, const std::string &hash) + { + if (hash == "1") + return CreateRSA2(standard); + else if (hash == "224") + return CreateRSA2(standard); + else if (hash == "256") + return CreateRSA2(standard); + else if (hash == "384") + return CreateRSA2(standard); + else if (hash == "512") + return CreateRSA2(standard); + else + return NULLPTR; + } + + virtual void DoTest() + { + std::string output; + + if (m_algorithm == "DSA") + { + if (m_test == "KeyPair") + { + DL_GroupParameters_DSA pqg; + int modLen = atol(m_bracketString.substr(6).c_str()); + pqg.GenerateRandomWithKeySize(m_rng, modLen); + + OutputData(output, "P ", pqg.GetModulus()); + OutputData(output, "Q ", pqg.GetSubgroupOrder()); + OutputData(output, "G ", pqg.GetSubgroupGenerator()); + + int n = atol(m_data["N"].c_str()); + for (int i=0; iPut((byte *)output.data(), output.size()); + output.resize(0); + } + } + else if (m_test == "PQGGen") + { + int n = atol(m_data["N"].c_str()); + for (int i=0; iPut((byte *)output.data(), output.size()); + output.resize(0); + } + } + else if (m_test == "SigGen") + { + std::string &encodedKey = m_data["PrivKey"]; + int modLen = atol(m_bracketString.substr(6).c_str()); + DSA::PrivateKey priv; + + if (!encodedKey.empty()) + { + StringStore s(encodedKey); + priv.BERDecode(s); + if (priv.GetGroupParameters().GetModulus().BitCount() != modLen) + encodedKey.clear(); + } + + if (encodedKey.empty()) + { + priv.Initialize(m_rng, modLen); + StringSink s(encodedKey); + priv.DEREncode(s); + OutputData(output, "P ", priv.GetGroupParameters().GetModulus()); + OutputData(output, "Q ", priv.GetGroupParameters().GetSubgroupOrder()); + OutputData(output, "G ", priv.GetGroupParameters().GetSubgroupGenerator()); + } + + DSA::Signer signer(priv); + DSA::Verifier pub(signer); + OutputData(output, "Msg ", m_data["Msg"]); + OutputData(output, "Y ", pub.GetKey().GetPublicElement()); + + SecByteBlock sig(signer.SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); + SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2); + OutputData(output, "R ", R); + OutputData(output, "S ", S); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + else if (m_test == "SigVer") + { + Integer p((m_data["P"] + "h").c_str()); + Integer q((m_data["Q"] + "h").c_str()); + Integer g((m_data["G"] + "h").c_str()); + Integer y((m_data["Y"] + "h").c_str()); + DSA::Verifier verifier(p, q, g, y); + + HexDecoder filter(new SignatureVerificationFilter(verifier)); + StringSource(m_data["R"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + else if (m_test == "PQGVer") + { + Integer p((m_data["P"] + "h").c_str()); + Integer q((m_data["Q"] + "h").c_str()); + Integer g((m_data["G"] + "h").c_str()); + Integer h((m_data["H"] + "h").c_str()); + int c = atol(m_data["c"].c_str()); + SecByteBlock seed(m_data["Seed"].size()/2); + StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size()))); + + Integer p1, q1; + bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true); + result = result && (p1 == p && q1 == q); + result = result && g == a_exp_b_mod_c(h, (p-1)/q, p); + + OutputData(output, "Result ", result ? "P" : "F"); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + + return; + } + + if (m_algorithm == "ECDSA") + { + std::map name2oid; + name2oid["P-192"] = ASN1::secp192r1(); + name2oid["P-224"] = ASN1::secp224r1(); + name2oid["P-256"] = ASN1::secp256r1(); + name2oid["P-384"] = ASN1::secp384r1(); + name2oid["P-521"] = ASN1::secp521r1(); + name2oid["K-163"] = ASN1::sect163k1(); + name2oid["K-233"] = ASN1::sect233k1(); + name2oid["K-283"] = ASN1::sect283k1(); + name2oid["K-409"] = ASN1::sect409k1(); + name2oid["K-571"] = ASN1::sect571k1(); + name2oid["B-163"] = ASN1::sect163r2(); + name2oid["B-233"] = ASN1::sect233r1(); + name2oid["B-283"] = ASN1::sect283r1(); + name2oid["B-409"] = ASN1::sect409r1(); + name2oid["B-571"] = ASN1::sect571r1(); + + if (m_test == "PKV") + { + bool pass; + if (m_bracketString[0] == 'P') + pass = EC_PKV(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); + else + pass = EC_PKV(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); + + OutputData(output, "Result ", pass ? "P" : "F"); + } + else if (m_test == "KeyPair") + { + if (m_bracketString[0] == 'P') + EC_KeyPair(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); + else + EC_KeyPair(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); + } + else if (m_test == "SigGen") + { + if (m_bracketString[0] == 'P') + EC_SigGen(output, name2oid[m_bracketString]); + else + EC_SigGen(output, name2oid[m_bracketString]); + } + else if (m_test == "SigVer") + { + if (m_bracketString[0] == 'P') + EC_SigVer(output, name2oid[m_bracketString]); + else + EC_SigVer(output, name2oid[m_bracketString]); + } + + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "RSA") + { + std::string shaAlg = m_data["SHAAlg"].substr(3); + + if (m_test == "Ver") + { + Integer n((m_data["n"] + "h").c_str()); + Integer e((m_data["e"] + "h").c_str()); + RSA::PublicKey pub; + pub.Initialize(n, e); + + member_ptr pV(CreateRSA(m_mode, shaAlg)); + pV->AccessMaterial().AssignFrom(pub); + + HexDecoder filter(new SignatureVerificationFilter(*pV)); + for (unsigned int i=m_data["S"].size(); iSignatureLength()*2; i++) + filter.Put('0'); + StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + } + else + { + CRYPTOPP_ASSERT(m_test == "Gen"); + int modLen = atol(m_bracketString.substr(6).c_str()); + std::string &encodedKey = m_data["PrivKey"]; + RSA::PrivateKey priv; + + if (!encodedKey.empty()) + { + StringStore s(encodedKey); + priv.BERDecode(s); + if (priv.GetModulus().BitCount() != modLen) + encodedKey.clear(); + } + + if (encodedKey.empty()) + { + priv.Initialize(m_rng, modLen); + StringSink s(encodedKey); + priv.DEREncode(s); + OutputData(output, "n ", priv.GetModulus()); + OutputData(output, "e ", priv.GetPublicExponent(), modLen/8); + } + + member_ptr pS(CreateRSA(m_mode, shaAlg)); + pS->AccessMaterial().AssignFrom(priv); + + SecByteBlock sig(pS->SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, *pS, new ArraySink(sig, sig.size())))); + OutputData(output, "SHAAlg ", m_data["SHAAlg"]); + OutputData(output, "Msg ", m_data["Msg"]); + OutputData(output, "S ", sig); + } + + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "SHA") + { + member_ptr pHF; + + if (m_mode == "1") + pHF.reset(new SHA1); + else if (m_mode == "224") + pHF.reset(new SHA224); + else if (m_mode == "256") + pHF.reset(new SHA256); + else if (m_mode == "384") + pHF.reset(new SHA384); + else if (m_mode == "512") + pHF.reset(new SHA512); + + if (m_test == "MONTE") + { + SecByteBlock seed = m_data2[INPUT]; + SecByteBlock MD[1003]; + int i,j; + + for (j=0; j<100; j++) + { + MD[0] = MD[1] = MD[2] = seed; + for (i=3; i<1003; i++) + { + SecByteBlock Mi = MD[i-3] + MD[i-2] + MD[i-1]; + MD[i].resize(pHF->DigestSize()); + pHF->CalculateDigest(MD[i], Mi, Mi.size()); + } + seed = MD[1002]; + OutputData(output, "COUNT ", j); + OutputData(output, "MD ", seed); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + } + else + { + SecByteBlock tag(pHF->DigestSize()); + SecByteBlock &msg(m_data2[INPUT]); + int len = atol(m_data["Len"].c_str()); + StringSource(msg.begin(), len/8, true, new HashFilter(*pHF, new ArraySink(tag, tag.size()))); + OutputData(output, "MD ", tag); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + return; + } + + SecByteBlock &key = m_data2[KEY_T]; + + if (m_algorithm == "TDES") + { + if (!m_data["KEY1"].empty()) + { + const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]}; + key.resize(24); + HexDecoder hexDec(new ArraySink(key, key.size())); + for (int i=0; i<3; i++) + hexDec.Put((byte *)keys[i].data(), keys[i].size()); + + if (keys[0] == keys[2]) + { + if (keys[0] == keys[1]) + key.resize(8); + else + key.resize(16); + } + else + key.resize(24); + } + } + + if (m_algorithm == "RNG") + { + key.resize(24); + StringSource(m_data["Key1"] + m_data["Key2"] + m_data["Key3"], true, new HexDecoder(new ArraySink(key, key.size()))); + + SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8); + X917RNG rng(new DES_EDE3::Encryption(key, key.size()), seed, dt); + + if (m_test == "MCT") + { + for (int i=0; i<10000; i++) + rng.GenerateBlock(r, r.size()); + } + else + { + rng.GenerateBlock(r, r.size()); + } + + OutputData(output, "R ", r); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "HMAC") + { + member_ptr pMAC; + + if (m_bracketString == "L=20") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=28") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=32") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=48") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=64") + pMAC.reset(new HMAC); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString); + + pMAC->SetKey(key, key.size()); + int Tlen = atol(m_data["Tlen"].c_str()); + SecByteBlock tag(Tlen); + StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen))); + OutputData(output, "Mac ", tag); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + member_ptr pBT; + if (m_algorithm == "DES") + pBT.reset(NewBT((DES*)0)); + else if (m_algorithm == "TDES") + { + if (key.size() == 8) + pBT.reset(NewBT((DES*)0)); + else if (key.size() == 16) + pBT.reset(NewBT((DES_EDE2*)0)); + else + pBT.reset(NewBT((DES_EDE3*)0)); + } + else if (m_algorithm == "SKIPJACK") + pBT.reset(NewBT((SKIPJACK*)0)); + else if (m_algorithm == "AES") + pBT.reset(NewBT((AES*)0)); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm); + + if (!pBT->IsValidKeyLength(key.size())) + key.CleanNew(pBT->DefaultKeyLength()); // for Scbcvrct + pBT->SetKey(key.data(), key.size()); + + SecByteBlock &iv = m_data2[IV]; + if (iv.empty()) + iv.CleanNew(pBT->BlockSize()); + + member_ptr pCipher; + unsigned int K = m_feedbackSize; + + if (m_mode == "ECB") + pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv)); + else if (m_mode == "CBC") + pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv)); + else if (m_mode == "CFB") + pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv)); + else if (m_mode == "OFB") + pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv)); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); + + bool encrypt = m_encrypt; + + if (m_test == "MONTE") + { + SecByteBlock KEY[401]; + KEY[0] = key; + int keySize = key.size(); + int blockSize = pBT->BlockSize(); + + std::vector IB(10001), OB(10001), PT(10001), CT(10001), RESULT(10001), TXT(10001), CV(10001); + PT[0] = GetData("PLAINTEXT"); + CT[0] = GetData("CIPHERTEXT"); + CV[0] = IB[0] = iv; + TXT[0] = GetData("TEXT"); + + int outerCount = (m_algorithm == "AES") ? 100 : 400; + int innerCount = (m_algorithm == "AES") ? 1000 : 10000; + + for (int i=0; iSetKey(KEY[i], keySize); + + for (int j=0; jProcessBlock(IB[j], CT[j]); + PT[j+1] = CT[j]; + } + else + { + IB[j] = CT[j]; + PT[j].resize(blockSize); + pBT->ProcessBlock(IB[j], PT[j]); + CT[j+1] = PT[j]; + } + } + else if (m_mode == "OFB") + { + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + Xor(RESULT[j], OB[j], TXT[j]); + TXT[j+1] = IB[j]; + IB[j+1] = OB[j]; + } + else if (m_mode == "CBC") + { + if (encrypt) + { + Xor(IB[j], PT[j], CV[j]); + CT[j].resize(blockSize); + pBT->ProcessBlock(IB[j], CT[j]); + PT[j+1] = CV[j]; + CV[j+1] = CT[j]; + } + else + { + IB[j] = CT[j]; + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + Xor(PT[j], OB[j], CV[j]); + CV[j+1] = CT[j]; + CT[j+1] = PT[j]; + } + } + else if (m_mode == "CFB") + { + if (encrypt) + { + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + AssignLeftMostBits(CT[j], OB[j], K); + Xor(CT[j], CT[j], PT[j]); + AssignLeftMostBits(PT[j+1], IB[j], K); + IB[j+1].resize(blockSize); + memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); + memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); + } + else + { + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + AssignLeftMostBits(PT[j], OB[j], K); + Xor(PT[j], PT[j], CT[j]); + IB[j+1].resize(blockSize); + memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); + memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); + AssignLeftMostBits(CT[j+1], OB[j], K); + } + } + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); + } + + OutputData(output, COUNT, IntToString(i)); + OutputData(output, KEY_T, KEY[i]); + if (m_mode == "CBC") + OutputData(output, IV, CV[0]); + if (m_mode == "OFB" || m_mode == "CFB") + OutputData(output, IV, IB[0]); + if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB") + { + if (encrypt) + { + OutputData(output, INPUT, PT[0]); + OutputData(output, OUTPUT, CT[innerCount-1]); + KEY[i+1] = UpdateKey(KEY[i], &CT[0]); + } + else + { + OutputData(output, INPUT, CT[0]); + OutputData(output, OUTPUT, PT[innerCount-1]); + KEY[i+1] = UpdateKey(KEY[i], &PT[0]); + } + PT[0] = PT[innerCount]; + IB[0] = IB[innerCount]; + CV[0] = CV[innerCount]; + CT[0] = CT[innerCount]; + } + else if (m_mode == "OFB") + { + OutputData(output, INPUT, TXT[0]); + OutputData(output, OUTPUT, RESULT[innerCount-1]); + KEY[i+1] = UpdateKey(KEY[i], &RESULT[0]); + Xor(TXT[0], TXT[0], IB[innerCount-1]); + IB[0] = OB[innerCount-1]; + } + output += "\n"; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + } + else if (m_test == "MCT") + { + SecByteBlock KEY[101]; + KEY[0] = key; + int keySize = key.size(); + int blockSize = pBT->BlockSize(); + + SecByteBlock ivs[101], inputs[1001], outputs[1001]; + ivs[0] = iv; + inputs[0] = m_data2[INPUT]; + + for (int i=0; i<100; i++) + { + pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false)); + + for (int j=0; j<1000; j++) + { + outputs[j] = inputs[j]; + pCipher->ProcessString(outputs[j], outputs[j].size()); + if (K==8 && m_mode == "CFB") + { + if (j<16) + inputs[j+1].Assign(ivs[i]+j, 1); + else + inputs[j+1] = outputs[j-16]; + } + else if (m_mode == "ECB") + inputs[j+1] = outputs[j]; + else if (j == 0) + inputs[j+1] = ivs[i]; + else + inputs[j+1] = outputs[j-1]; + } + + if (m_algorithm == "AES") + OutputData(output, COUNT, m_count++); + OutputData(output, KEY_T, KEY[i]); + if (m_mode != "ECB") + OutputData(output, IV, ivs[i]); + OutputData(output, INPUT, inputs[0]); + OutputData(output, OUTPUT, outputs[999]); + output += "\n"; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + + KEY[i+1] = UpdateKey(KEY[i], outputs); + ivs[i+1].CleanNew(pCipher->IVSize()); + ivs[i+1] = UpdateKey(ivs[i+1], outputs); + if (K==8 && m_mode == "CFB") + inputs[0] = outputs[999-16]; + else if (m_mode == "ECB") + inputs[0] = outputs[999]; + else + inputs[0] = outputs[998]; + } + } + else + { + CRYPTOPP_ASSERT(m_test == "KAT"); + + SecByteBlock &input = m_data2[INPUT]; + SecByteBlock result(input.size()); + member_ptr pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING)); + StringSource(input.data(), input.size(), true, pFilter.release()); + + OutputGivenData(output, COUNT, true); + OutputData(output, KEY_T, key); + OutputGivenData(output, IV, true); + OutputGivenData(output, INPUT); + OutputData(output, OUTPUT, result); + output += "\n"; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + } + } + + std::vector Tokenize(const std::string &line) + { + std::vector result; + std::string s; + for (unsigned int i=0; i") + { + CRYPTOPP_ASSERT(m_test == "sha"); + m_bracketString = m_line.substr(2, m_line.size()-4); + m_line = m_line.substr(0, 13) + "Hashes") + copyLine = true; + + if (m_line == "Put((byte *)m_line.data(), m_line.size(), blocking); + return false; + } + + std::vector tokens = Tokenize(m_line); + + if (m_algorithm == "DSA" && m_test == "sha") + { + for (unsigned int i = 0; i < tokens.size(); i++) + { + if (tokens[i] == "^") + DoTest(); + else if (tokens[i] != "") + m_compactString.push_back(atol(tokens[i].c_str())); + } + } + else + { + if (!m_line.empty() && ((m_algorithm == "RSA" && m_test != "Gen") || m_algorithm == "RNG" || m_algorithm == "HMAC" || m_algorithm == "SHA" || (m_algorithm == "ECDSA" && m_test != "KeyPair") || (m_algorithm == "DSA" && (m_test == "PQGVer" || m_test == "SigVer")))) + { + // copy input to output + std::string output = m_line + '\n'; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + } + + for (unsigned int i = 0; i < tokens.size(); i++) + { + if (m_firstLine && m_algorithm != "DSA") + { + if (tokens[i] == "Encrypt" || tokens[i] == "OFB") + SetEncrypt(true); + else if (tokens[i] == "Decrypt") + SetEncrypt(false); + else if (tokens[i] == "Modes") + m_test = "MONTE"; + } + else + { + if (tokens[i] != "=") + continue; + + if (i == 0) + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line); + + const std::string &key = tokens[i-1]; + std::string &data = m_data[key]; + data = (tokens.size() > i+1) ? tokens[i+1] : ""; + DataType t = m_nameToType[key]; + m_typeToName[t] = key; + m_data2[t] = DecodeHex(data); + + if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty() && !isspace(m_line[0]))) + DoTest(); + } + } + } + + m_firstLine = false; + + return false; + } + + inline const SecByteBlock & GetData(const std::string &key) + { + return m_data2[m_nameToType[key]]; + } + + static SecByteBlock DecodeHex(const std::string &data) + { + SecByteBlock data2(data.size() / 2); + StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size()))); + return data2; + } + + std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger; + unsigned int m_feedbackSize, m_blankLineTransition; + bool m_encrypt, m_firstLine; + + typedef std::map NameToTypeMap; + NameToTypeMap m_nameToType; + typedef std::map TypeToNameMap; + TypeToNameMap m_typeToName; + + typedef std::map Map; + Map m_data; // raw data + typedef std::map Map2; + Map2 m_data2; + int m_count; + + AutoSeededX917RNG m_rng; + std::vector m_compactString; +}; + +int FIPS_140_AlgorithmTest(int argc, char **argv) +{ + argc--; + argv++; + + std::string algorithm = argv[1]; + std::string pathname = argv[2]; + unsigned int i = pathname.find_last_of("\\/"); + std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1); + std::string dirname = pathname.substr(0, i); + + if (algorithm == "auto") + { + string algTable[] = {"AES", "ECDSA", "DSA", "HMAC", "RNG", "RSA", "TDES", "SKIPJACK", "SHA"}; // order is important here + for (i=0; i 3) + { + std::string outDir = argv[3]; + + if (outDir == "auto") + { + if (dirname.substr(dirname.size()-3) == "req") + outDir = dirname.substr(0, dirname.size()-3) + "resp"; + } + + if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/') + outDir += '/'; + std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp"; + pSink = new FileSink(outPathname.c_str(), false); + } + else + pSink = new FileSink(cout); + + FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false); + } + catch (...) + { + cout << "file: " << filename << endl; + throw; + } + return 0; +} + +extern int (*AdhocTest)(int argc, char *argv[]); +static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0); +#endif diff --git a/external/ours/library/crypto/src/shared/original/fipstest.cpp b/external/ours/library/crypto/src/shared/original/fipstest.cpp new file mode 100755 index 000000000..3e609f88f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/fipstest.cpp @@ -0,0 +1,652 @@ +// fipstest.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#define CRYPTOPP_DEFAULT_NO_DLL +#include "dll.h" +#include "cryptlib.h" +#include "filters.h" +#include "smartptr.h" +#include "pkcspad.h" +#include "misc.h" + +// Simply disable CRYPTOPP_WIN32_AVAILABLE for Windows Phone and Windows Store apps +#ifdef CRYPTOPP_WIN32_AVAILABLE +# if defined(WINAPI_FAMILY) +# if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# undef CRYPTOPP_WIN32_AVAILABLE +# endif +# endif +#endif + +#ifdef CRYPTOPP_WIN32_AVAILABLE +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif + +#include + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# ifdef _M_IX86 +# define _CRT_DEBUGGER_HOOK _crt_debugger_hook +# else +# define _CRT_DEBUGGER_HOOK __crt_debugger_hook +# endif +# if _MSC_VER < 1900 +extern "C" {_CRTIMP void __cdecl _CRT_DEBUGGER_HOOK(int);} +# else +extern "C" {void __cdecl _CRT_DEBUGGER_HOOK(int); } +# endif +#endif +#endif // CRYPTOPP_WIN32_AVAILABLE + +#include +#include + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4100 4702) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +extern PowerUpSelfTestStatus g_powerUpSelfTestStatus; +SecByteBlock g_actualMac; +unsigned long g_macFileLocation = 0; + +// $ grep -iIR baseaddress *.*proj +// cryptdll.vcxproj: 0x42900000 +// cryptdll.vcxproj: 0x42900000 +// cryptdll.vcxproj: 0x42900000 +// cryptdll.vcxproj: 0x42900000 +const void* g_BaseAddressOfMAC = reinterpret_cast(0x42900000); + +// use a random dummy string here, to be searched/replaced later with the real MAC +static const byte s_moduleMac[CryptoPP::HMAC::DIGESTSIZE] = CRYPTOPP_DUMMY_DLL_MAC; +CRYPTOPP_COMPILE_ASSERT(sizeof(s_moduleMac) == CryptoPP::SHA1::DIGESTSIZE); + +#ifdef CRYPTOPP_WIN32_AVAILABLE +static HMODULE s_hModule = NULLPTR; +#endif + +const byte * CRYPTOPP_API GetActualMacAndLocation(unsigned int &macSize, unsigned int &fileLocation) +{ + macSize = (unsigned int)g_actualMac.size(); + fileLocation = g_macFileLocation; + return g_actualMac; +} + +void KnownAnswerTest(RandomNumberGenerator &rng, const char *output) +{ + EqualityComparisonFilter comparison; + + RandomNumberStore(rng, strlen(output)/2).TransferAllTo(comparison, "0"); + StringSource(output, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +template +void X917RNG_KnownAnswerTest( + const char *key, + const char *seed, + const char *deterministicTimeVector, + const char *output) +{ +#ifdef OS_RNG_AVAILABLE + std::string decodedKey, decodedSeed, decodedDeterministicTimeVector; + StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); + StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed))); + StringSource(deterministicTimeVector, true, new HexDecoder(new StringSink(decodedDeterministicTimeVector))); + + AutoSeededX917RNG rng(false, false); + rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), (const byte *)decodedDeterministicTimeVector.data()); + KnownAnswerTest(rng, output); +#else + throw 0; +#endif +} + +void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &decryption, const char *plaintext, const char *ciphertext) +{ + EqualityComparisonFilter comparison; + + StringSource(plaintext, true, new HexDecoder(new StreamTransformationFilter(encryption, new ChannelSwitch(comparison, "0"), StreamTransformationFilter::NO_PADDING))); + StringSource(ciphertext, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + StringSource(ciphertext, true, new HexDecoder(new StreamTransformationFilter(decryption, new ChannelSwitch(comparison, "0"), StreamTransformationFilter::NO_PADDING))); + StringSource(plaintext, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +template +void SymmetricEncryptionKnownAnswerTest( + const char *key, + const char *hexIV, + const char *plaintext, + const char *ecb, + const char *cbc, + const char *cfb, + const char *ofb, + const char *ctr) +{ + std::string decodedKey; + StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); + + typename CIPHER::Encryption encryption((const byte *)decodedKey.data(), decodedKey.size()); + typename CIPHER::Decryption decryption((const byte *)decodedKey.data(), decodedKey.size()); + + SecByteBlock iv(encryption.BlockSize()); + StringSource(hexIV, true, new HexDecoder(new ArraySink(iv, iv.size()))); + + if (ecb) + KnownAnswerTest(ECB_Mode_ExternalCipher::Encryption(encryption).Ref(), ECB_Mode_ExternalCipher::Decryption(decryption).Ref(), plaintext, ecb); + if (cbc) + KnownAnswerTest(CBC_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CBC_Mode_ExternalCipher::Decryption(decryption, iv).Ref(), plaintext, cbc); + if (cfb) + KnownAnswerTest(CFB_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CFB_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, cfb); + if (ofb) + KnownAnswerTest(OFB_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), OFB_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, ofb); + if (ctr) + KnownAnswerTest(CTR_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CTR_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, ctr); +} + +void KnownAnswerTest(HashTransformation &hash, const char *message, const char *digest) +{ + EqualityComparisonFilter comparison; + StringSource(digest, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + StringSource(message, true, new HashFilter(hash, new ChannelSwitch(comparison, "0"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +template +void SecureHashKnownAnswerTest(const char *message, const char *digest) +{ + HASH hash; + KnownAnswerTest(hash, message, digest); +} + +template +void MAC_KnownAnswerTest(const char *key, const char *message, const char *digest) +{ + std::string decodedKey; + StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); + + MAC mac((const byte *)decodedKey.data(), decodedKey.size()); + KnownAnswerTest(mac, message, digest); +} + +template +void SignatureKnownAnswerTest(const char *key, const char *message, const char *signature) +{ + typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref()); + typename SCHEME::Verifier verifier(signer); + + RandomPool rng; + EqualityComparisonFilter comparison; + + StringSource(message, true, new SignerFilter(rng, signer, new ChannelSwitch(comparison, "0"))); + StringSource(signature, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); + + SignatureVerificationFilter verifierFilter(verifier, NULLPTR, SignatureVerificationFilter::SIGNATURE_AT_BEGIN | SignatureVerificationFilter::THROW_EXCEPTION); + StringSource(signature, true, new HexDecoder(new Redirector(verifierFilter, Redirector::DATA_ONLY))); + StringSource(message, true, new Redirector(verifierFilter)); +} + +void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor) +{ + try + { + RandomPool rng; + const char *testMessage ="test message"; + std::string ciphertext, decrypted; + + StringSource( + testMessage, + true, + new PK_EncryptorFilter( + rng, + encryptor, + new StringSink(ciphertext))); + + if (ciphertext == testMessage) + throw 0; + + StringSource( + ciphertext, + true, + new PK_DecryptorFilter( + rng, + decryptor, + new StringSink(decrypted))); + + if (decrypted != testMessage) + throw 0; + } + catch (...) + { + throw SelfTestFailure(encryptor.AlgorithmName() + ": pairwise consistency test failed"); + } +} + +void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier &verifier) +{ + try + { + RandomPool rng; + + StringSource( + "test message", + true, + new SignerFilter( + rng, + signer, + new SignatureVerificationFilter(verifier, NULLPTR, SignatureVerificationFilter::THROW_EXCEPTION), + true)); + } + catch (...) + { + throw SelfTestFailure(signer.AlgorithmName() + ": pairwise consistency test failed"); + } +} + +template +void SignaturePairwiseConsistencyTest(const char *key) +{ + typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref()); + typename SCHEME::Verifier verifier(signer); + + SignaturePairwiseConsistencyTest(signer, verifier); +} + +MessageAuthenticationCode * NewIntegrityCheckingMAC() +{ + byte key[] = {0x47, 0x1E, 0x33, 0x96, 0x65, 0xB1, 0x6A, 0xED, 0x0B, 0xF8, 0x6B, 0xFD, 0x01, 0x65, 0x05, 0xCC}; + return new HMAC(key, sizeof(key)); +} + +bool IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac, unsigned long *pMacFileLocation) +{ + member_ptr mac(NewIntegrityCheckingMAC()); + unsigned int macSize = mac->DigestSize(); + + SecByteBlock tempMac; + SecByteBlock &actualMac = pActualMac ? *pActualMac : tempMac; + actualMac.resize(macSize); + + unsigned long tempLocation = 0; + unsigned long &macFileLocation = pMacFileLocation ? *pMacFileLocation : tempLocation; + macFileLocation = 0; + + MeterFilter verifier(new HashFilter(*mac, new ArraySink(actualMac, actualMac.size()))); +// MeterFilter verifier(new FileSink("c:\\dt.tmp")); + std::ifstream moduleStream; + +#ifdef CRYPTOPP_WIN32_AVAILABLE + HMODULE h = NULLPTR; + { + const size_t FIPS_MODULE_MAX_PATH = 2*MAX_PATH; + char moduleFilenameBuf[FIPS_MODULE_MAX_PATH] = ""; + if (moduleFilename == NULLPTR) + { +#if (_MSC_VER >= 1400 && !defined(_STLPORT_VERSION)) // ifstream doesn't support wide filename on other compilers + wchar_t wideModuleFilename[FIPS_MODULE_MAX_PATH]; + if (GetModuleFileNameW(s_hModule, wideModuleFilename, FIPS_MODULE_MAX_PATH) > 0) + { + moduleStream.open(wideModuleFilename, std::ios::in | std::ios::binary); + h = GetModuleHandleW(wideModuleFilename); + } + else +#endif + { + GetModuleFileNameA(s_hModule, moduleFilenameBuf, FIPS_MODULE_MAX_PATH); + moduleFilename = moduleFilenameBuf; + } + } +#endif + if (moduleFilename != NULLPTR) + { + moduleStream.open(moduleFilename, std::ios::in | std::ios::binary); +#ifdef CRYPTOPP_WIN32_AVAILABLE + h = GetModuleHandleA(moduleFilename); + moduleFilename = NULLPTR; + } +#endif + } + +#ifdef CRYPTOPP_WIN32_AVAILABLE + if (h == g_BaseAddressOfMAC) + { + std::ostringstream oss; + oss << "Crypto++ DLL loaded at base address " << std::hex << h << ".\n"; + OutputDebugStringA(oss.str().c_str()); + } + else + { + std::ostringstream oss; + oss << "Crypto++ DLL integrity check may fail. Expected module base address is "; + oss << std::hex << g_BaseAddressOfMAC << ", but module loaded at " << h << ".\n"; + OutputDebugStringA(oss.str().c_str()); + } +#endif + + if (!moduleStream) + { +#ifdef CRYPTOPP_WIN32_AVAILABLE + OutputDebugStringA("Crypto++ DLL integrity check failed. Cannot open file for reading."); +#endif + return false; + } + FileStore file(moduleStream); + +#ifdef CRYPTOPP_WIN32_AVAILABLE + // try to hash from memory first + const byte *memBase = (const byte *)h; + const IMAGE_DOS_HEADER *ph = (IMAGE_DOS_HEADER *)memBase; + const IMAGE_NT_HEADERS *phnt = (IMAGE_NT_HEADERS *)(memBase + ph->e_lfanew); + const IMAGE_SECTION_HEADER *phs = IMAGE_FIRST_SECTION(phnt); + DWORD nSections = phnt->FileHeader.NumberOfSections; + size_t currentFilePos = 0; + + size_t checksumPos = (byte *)&phnt->OptionalHeader.CheckSum - memBase; + size_t checksumSize = sizeof(phnt->OptionalHeader.CheckSum); + size_t certificateTableDirectoryPos = (byte *)&phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] - memBase; + size_t certificateTableDirectorySize = sizeof(phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]); + size_t certificateTablePos = phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress; + size_t certificateTableSize = phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size; + + verifier.AddRangeToSkip(0, checksumPos, checksumSize); + verifier.AddRangeToSkip(0, certificateTableDirectoryPos, certificateTableDirectorySize); + verifier.AddRangeToSkip(0, certificateTablePos, certificateTableSize); + + while (nSections--) + { + switch (phs->Characteristics) + { + default: + break; + case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: + case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: + unsigned int sectionSize = STDMIN(phs->SizeOfRawData, phs->Misc.VirtualSize); + const byte *sectionMemStart = memBase + phs->VirtualAddress; + unsigned int sectionFileStart = phs->PointerToRawData; + size_t subSectionStart = 0, nextSubSectionStart; + + do + { + const byte *subSectionMemStart = sectionMemStart + subSectionStart; + size_t subSectionFileStart = sectionFileStart + subSectionStart; + size_t subSectionSize = sectionSize - subSectionStart; + nextSubSectionStart = 0; + + unsigned int entriesToReadFromDisk[] = {IMAGE_DIRECTORY_ENTRY_IMPORT, IMAGE_DIRECTORY_ENTRY_IAT}; + for (unsigned int i=0; iOptionalHeader.DataDirectory[entriesToReadFromDisk[i]]; + const byte *entryMemStart = memBase + entry.VirtualAddress; + if (subSectionMemStart <= entryMemStart && entryMemStart < subSectionMemStart + subSectionSize) + { + subSectionSize = entryMemStart - subSectionMemStart; + nextSubSectionStart = entryMemStart - sectionMemStart + entry.Size; + } + } + + // Visual Studio 2019 is MSC_VER == 1920 + // https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nds +#if (_MSC_VER >= 1400 && _MSC_VER < 1920) && (defined(_M_IX86) || defined(_M_X64)) + // first byte of _CRT_DEBUGGER_HOOK gets modified in memory by the debugger invisibly, so read it from file + if (IsDebuggerPresent()) + { + if (subSectionMemStart <= (byte *)&_CRT_DEBUGGER_HOOK && (byte *)&_CRT_DEBUGGER_HOOK < subSectionMemStart + subSectionSize) + { + subSectionSize = (byte *)&_CRT_DEBUGGER_HOOK - subSectionMemStart; + nextSubSectionStart = (byte *)&_CRT_DEBUGGER_HOOK - sectionMemStart + 1; + } + } +#endif + + if (subSectionMemStart <= expectedModuleMac && expectedModuleMac < subSectionMemStart + subSectionSize) + { + // found stored MAC + macFileLocation = (unsigned long)(subSectionFileStart + (expectedModuleMac - subSectionMemStart)); + verifier.AddRangeToSkip(0, macFileLocation, macSize); + } + + file.TransferTo(verifier, subSectionFileStart - currentFilePos); + verifier.Put(subSectionMemStart, subSectionSize); + file.Skip(subSectionSize); + currentFilePos = subSectionFileStart + subSectionSize; + subSectionStart = nextSubSectionStart; + } while (nextSubSectionStart != 0); + } + phs++; + } +#endif + file.TransferAllTo(verifier); + +#ifdef CRYPTOPP_WIN32_AVAILABLE + // if that fails (could be caused by debug breakpoints or DLL base relocation modifying image in memory), + // hash from disk instead + if (!VerifyBufsEqual(expectedModuleMac, actualMac, macSize)) + { + OutputDebugStringA("Crypto++ DLL in-memory integrity check failed. This may be caused by debug breakpoints or DLL relocation.\n"); + moduleStream.clear(); + moduleStream.seekg(0); + verifier.Initialize(MakeParameters(Name::OutputBuffer(), ByteArrayParameter(actualMac, (unsigned int)actualMac.size()))); +// verifier.Initialize(MakeParameters(Name::OutputFileName(), (const char *)"c:\\dt2.tmp")); + verifier.AddRangeToSkip(0, checksumPos, checksumSize); + verifier.AddRangeToSkip(0, certificateTableDirectoryPos, certificateTableDirectorySize); + verifier.AddRangeToSkip(0, certificateTablePos, certificateTableSize); + verifier.AddRangeToSkip(0, macFileLocation, macSize); + FileStore(moduleStream).TransferAllTo(verifier); + } +#endif + + if (VerifyBufsEqual(expectedModuleMac, actualMac, macSize)) + return true; + +#ifdef CRYPTOPP_WIN32_AVAILABLE + std::string hexMac; + HexEncoder(new StringSink(hexMac)).PutMessageEnd(actualMac, actualMac.size()); + OutputDebugStringA((("Crypto++ DLL integrity check failed. Actual MAC is: " + hexMac) + ".\n").c_str()); +#endif + return false; +} + +void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac) +{ + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_NOT_DONE; + SetPowerUpSelfTestInProgressOnThisThread(true); + + try + { + if (FIPS_140_2_ComplianceEnabled() || expectedModuleMac != NULLPTR) + { + if (!IntegrityCheckModule(moduleFilename, expectedModuleMac, &g_actualMac, &g_macFileLocation)) + throw 0; // throw here so we break in the debugger, this will be caught right away + } + + // algorithm tests + + X917RNG_KnownAnswerTest( + "2b7e151628aed2a6abf7158809cf4f3c", // key + "000102030405060708090a0b0c0d0e0f", // seed + "00000000000000000000000000000001", // time vector + "D176EDD27493B0395F4D10546232B0693DC7061C03C3A554F09CECF6F6B46D945A"); // output + + SymmetricEncryptionKnownAnswerTest( + "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", + "C141B5FCCD28DC8A", + "6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68", + "64EAAD4ACBB9CEAD6C7615E7C7E4792FE587D91F20C7D2F4", + "6235A461AFD312973E3B4F7AA7D23E34E03371F8E8C376C9", + "E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B", + "E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62", + "E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371"); + + SymmetricEncryptionKnownAnswerTest( + "1555E5531C3A169B2D65", + "6EC9795701F49864", + "00AFA48E9621E52E8CBDA312660184EDDB1F33D9DACDA8DA", + "DBEC73562EFCAEB56204EB8AE9557EBF77473FBB52D17CD1", + "0C7B0B74E21F99B8F2C8DF37879F6C044967F42A796DCA8B", + "79FDDA9724E36CC2E023E9A5C717A8A8A7FDA465CADCBF63", + "79FDDA9724E36CC26CACBD83C1ABC06EAF5B249BE5B1E040", + "79FDDA9724E36CC211B0AEC607B95A96BCDA318440B82F49"); + + SymmetricEncryptionKnownAnswerTest( + "2b7e151628aed2a6abf7158809cf4f3c", + "000102030405060708090a0b0c0d0e0f", + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", // plaintext + "3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4", // ecb + "7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7", // cbc + "3b3fd92eb72dad20333449f8e83cfb4ac8a64537a0b3a93fcde3cdad9f1ce58b26751f67a3cbb140b1808cf187a4f4dfc04b05357c5d1c0eeac4c66f9ff7f2e6", // cfb + "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e", // ofb + NULLPTR); + + SymmetricEncryptionKnownAnswerTest( + "2b7e151628aed2a6abf7158809cf4f3c", + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", + NULLPTR, + NULLPTR, + NULLPTR, + NULLPTR, + "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee"); // ctr + + + SecureHashKnownAnswerTest( + "abc", + "A9993E364706816ABA3E25717850C26C9CD0D89D"); + + SecureHashKnownAnswerTest( + "abc", + "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"); + + SecureHashKnownAnswerTest( + "abc", + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + + SecureHashKnownAnswerTest( + "abc", + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"); + + SecureHashKnownAnswerTest( + "abc", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); + + MAC_KnownAnswerTest >( + "303132333435363738393a3b3c3d3e3f40414243", + "Sample #2", + "0922d3405faa3d194f82a45830737d5cc6c75d24"); + + const char *keyRSA1 = + "30820150020100300d06092a864886f70d01010105000482013a3082013602010002400a66791dc6988168de7ab77419bb7fb0" + "c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab0203010001" + "02400123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa" + "87d8862b75177691c11d757692df8881022033d48445c859e52340de704bcdda065fbb4058d740bd1d67d29e9c146c11cf61" + "0220335e8408866b0fd38dc7002d3f972c67389a65d5d8306566d5c4f2a5aa52628b0220045ec90071525325d3d46db79695e9af" + "acc4523964360e02b119baa366316241022015eb327360c7b60d12e5e2d16bdcd97981d17fba6b70db13b20b436e24eada590220" + "2ca6366d72781dfa24d34a9a24cbc2ae927a9958af426563ff63fb11658a461d"; + + const char *keyRSA2 = + "30820273020100300D06092A864886F70D01010105000482025D3082025902010002818100D40AF9" + "A2B713034249E5780056D70FC7DE75D76E44565AA6A6B8ED9646F3C19F9E254D72D7DE6E49DB2264" + "0C1D05AB9E2A5F901D8F3FE1F7AE02CEE2ECCE54A40ABAE55A004692752E70725AEEE7CDEA67628A" + "82A9239B4AB660C2BC56D9F01E90CBAAB9BF0FC8E17173CEFC5709A29391A7DDF3E0B758691AAF30" + "725B292F4F020111027F18C0BA087D082C45D75D3594E0767E4820818EB35612B80CEAB8C880ACA5" + "44B6876DFFEF85A576C0D45B551AFAA1FD63209CD745DF75C5A0F0B580296EA466CD0338207E4752" + "FF4E7DB724D8AE18CE5CF4153BB94C27869FBB50E64F02546E4B02997A0B8623E64017CC770759C6" + "695DB649EEFD829D688D441BCC4E7348F1024100EF86DD7AF3F32CDE8A9F6564E43A559A0C9F8BAD" + "36CC25330548B347AC158A345631FA90F7B873C36EFFAE2F7823227A3F580B5DD18304D5932751E7" + "43E9234F024100E2A039854B55688740E32A51DF4AF88613D91A371CF8DDD95D780A89D7CF2119A9" + "54F1AC0F3DCDB2F6959926E6D9D37D8BC07A4C634DE6F16315BD5F0DAC340102407ECEEDB9903572" + "1B76909F174BA6698DCA72953D957B22C0A871C8531EDE3A1BB52984A719BC010D1CA57A555DB83F" + "6DE54CBAB932AEC652F38D497A6F3F30CF024100854F30E4FF232E6DADB2CD99926855F484255AB7" + "01FBCDCB27EC426F33A7046972AA700ADBCA008763DF87440F52F4E070531AC385B55AAC1C2AE7DD" + "8F9278F1024100C313F4AF9E4A9DE1253C21080CE524251560C111550772FD08690F13FBE658342E" + "BD2D41C9DCB12374E871B1839E26CAE252E1AE3DAAD5F1EE1F42B4D0EE7581"; + + SignatureKnownAnswerTest >( + keyRSA1, + "Everyone gets Friday off.", + "0610761F95FFD1B8F29DA34212947EC2AA0E358866A722F03CC3C41487ADC604A48FF54F5C6BEDB9FB7BD59F82D6E55D8F3174BA361B2214B2D74E8825E04E81"); + + SignatureKnownAnswerTest >( + keyRSA2, + "test", + "32F6BA41C8930DE71EE67F2627172CC539EDE04267FDE03AC295E3C50311F26C3B275D3AF513AC96" + "8EE493BAB7DA3A754661D1A7C4A0D1A2B7EE8B313AACD8CB8BFBC5C15EFB0EF15C86A9334A1E87AD" + "291EB961B5CA0E84930429B28780816AA94F96FC2367B71E2D2E4866FA966795B147F00600E5207E" + "2F189C883B37477C"); + + SignaturePairwiseConsistencyTest( + "3082014A0201003082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0416021426EBA66E846E755169F84A1DA981D86502405DDF"); + + SignaturePairwiseConsistencyTest >( + "302D020100301006072A8648CE3D020106052B8104000404163014020101040F0070337065E1E196980A9D00E37211"); + + SignaturePairwiseConsistencyTest >( + "3039020100301306072A8648CE3D020106082A8648CE3D030101041F301D02010104182BB8A13C8B867010BD9471D9E81FDB01ABD0538C64D6249A"); + + SignaturePairwiseConsistencyTest >(keyRSA1); + } + catch (...) + { + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_FAILED; + goto done; + } + + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_PASSED; + +done: + SetPowerUpSelfTestInProgressOnThisThread(false); + return; +} + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +void DoDllPowerUpSelfTest() +{ + CryptoPP::DoPowerUpSelfTest(NULLPTR, s_moduleMac); +} + +#else + +void DoDllPowerUpSelfTest() +{ + throw NotImplemented("DoDllPowerUpSelfTest() only available on Windows"); +} + +#endif // #ifdef CRYPTOPP_WIN32_AVAILABLE + +NAMESPACE_END + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +// DllMain needs to be in the global namespace +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD dwReason, + LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + CryptoPP::s_hModule = (HMODULE)hModule; + CryptoPP::DoDllPowerUpSelfTest(); + } + return TRUE; +} + +#endif // #ifdef CRYPTOPP_WIN32_AVAILABLE + +#endif // #ifndef CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/fltrimpl.h b/external/ours/library/crypto/src/shared/original/fltrimpl.h new file mode 100755 index 000000000..4fc4224b5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/fltrimpl.h @@ -0,0 +1,87 @@ +#ifndef CRYPTOPP_FLTRIMPL_H +#define CRYPTOPP_FLTRIMPL_H + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4100) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-value" +#endif + +#define FILTER_BEGIN \ + switch (m_continueAt) \ + { \ + case 0: \ + m_inputPosition = 0; + +#define FILTER_END_NO_MESSAGE_END_NO_RETURN \ + break; \ + default: \ + CRYPTOPP_ASSERT(false); \ + } + +#define FILTER_END_NO_MESSAGE_END \ + FILTER_END_NO_MESSAGE_END_NO_RETURN \ + return 0; + +/* +#define FILTER_END \ + case -1: \ + if (messageEnd && Output(-1, NULLPTR, 0, messageEnd, blocking)) \ + return 1; \ + FILTER_END_NO_MESSAGE_END +*/ + +#define FILTER_OUTPUT3(site, statement, output, length, messageEnd, channel) \ + {\ + case site: \ + statement; \ + if (Output(site, output, length, messageEnd, blocking, channel)) \ + return STDMAX(size_t(1), length-m_inputPosition);\ + } + +#define FILTER_OUTPUT2(site, statement, output, length, messageEnd) \ + FILTER_OUTPUT3(site, statement, output, length, messageEnd, DEFAULT_CHANNEL) + +#define FILTER_OUTPUT(site, output, length, messageEnd) \ + FILTER_OUTPUT2(site, 0, output, length, messageEnd) + +#define FILTER_OUTPUT_BYTE(site, output) \ + FILTER_OUTPUT(site, &(const byte &)(byte)output, 1, 0) + +#define FILTER_OUTPUT2_MODIFIABLE(site, statement, output, length, messageEnd) \ + {\ + /* fall through */ \ + case site: \ + statement; \ + if (OutputModifiable(site, output, length, messageEnd, blocking)) \ + return STDMAX(size_t(1), length-m_inputPosition);\ + } + +#define FILTER_OUTPUT_MODIFIABLE(site, output, length, messageEnd) \ + FILTER_OUTPUT2_MODIFIABLE(site, 0, output, length, messageEnd) + +#define FILTER_OUTPUT2_MAYBE_MODIFIABLE(site, statement, output, length, messageEnd, modifiable) \ + {\ + /* fall through */ \ + case site: \ + statement; \ + if (modifiable ? OutputModifiable(site, output, length, messageEnd, blocking) : Output(site, output, length, messageEnd, blocking)) \ + return STDMAX(size_t(1), length-m_inputPosition);\ + } + +#define FILTER_OUTPUT_MAYBE_MODIFIABLE(site, output, length, messageEnd, modifiable) \ + FILTER_OUTPUT2_MAYBE_MODIFIABLE(site, 0, output, length, messageEnd, modifiable) + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gcm.cpp b/external/ours/library/crypto/src/shared/original/gcm.cpp new file mode 100755 index 000000000..380dc7802 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gcm.cpp @@ -0,0 +1,852 @@ +// gcm.cpp - originally written and placed in the public domain by Wei Dai. +// ARM and Aarch64 added by Jeffrey Walton. The ARM carryless +// multiply routines are less efficient because they shadow x86. +// The precomputed key table integration makes it tricky to use the +// more efficient ARMv8 implementation of the multiply and reduce. + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM gcm.cpp" to generate MASM code + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS +#ifndef CRYPTOPP_GENERATE_X64_MASM + +// Visual Studio .Net 2003 compiler crash +#if defined(_MSC_VER) && (_MSC_VER < 1400) +# pragma optimize("", off) +#endif + +#include "gcm.h" +#include "cpu.h" + +#if defined(CRYPTOPP_DISABLE_GCM_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +// Different assemblers accept different mnemonics: 'movd eax, xmm0' vs +// 'movd rax, xmm0' vs 'mov eax, xmm0' vs 'mov rax, xmm0' +#if defined(CRYPTOPP_DISABLE_MIXED_ASM) +// 'movd eax, xmm0' only. REG_WORD() macro not used. Clang path. +# define USE_MOVD_REG32 1 +#elif defined(__GNUC__) || defined(_MSC_VER) +// 'movd eax, xmm0' or 'movd rax, xmm0'. REG_WORD() macro supplies REG32 or REG64. +# define USE_MOVD_REG32_OR_REG64 1 +#else +// 'mov eax, xmm0' or 'mov rax, xmm0'. REG_WORD() macro supplies REG32 or REG64. +# define USE_MOV_REG32_OR_REG64 1 +#endif +#endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + +word16 GCM_Base::s_reductionTable[256]; +volatile bool GCM_Base::s_reductionTableInitialized = false; + +void GCM_Base::GCTR::IncrementCounterBy256() +{ + IncrementCounterByOne(m_counterArray+BlockSize()-4, 3); +} + +static inline void Xor16(byte *a, const byte *b, const byte *c) +{ + CRYPTOPP_ASSERT(IsAlignedOn(a,GetAlignmentOf())); + CRYPTOPP_ASSERT(IsAlignedOn(b,GetAlignmentOf())); + CRYPTOPP_ASSERT(IsAlignedOn(c,GetAlignmentOf())); + ((word64 *)(void *)a)[0] = ((word64 *)(void *)b)[0] ^ ((word64 *)(void *)c)[0]; + ((word64 *)(void *)a)[1] = ((word64 *)(void *)b)[1] ^ ((word64 *)(void *)c)[1]; +} + +#if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE +// SunCC 5.10-5.11 compiler crash. Move GCM_Xor16_SSE2 out-of-line, and place in +// a source file with a SSE architecture switch. Also see GH #226 and GH #284. +extern void GCM_Xor16_SSE2(byte *a, const byte *b, const byte *c); +#endif // SSE2 + +#if CRYPTOPP_ARM_NEON_AVAILABLE +extern void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c); +#endif + +#if CRYPTOPP_POWER8_AVAILABLE +extern void GCM_Xor16_POWER8(byte *a, const byte *b, const byte *c); +#endif + +#if CRYPTOPP_CLMUL_AVAILABLE +extern void GCM_SetKeyWithoutResync_CLMUL(const byte *hashKey, byte *mulTable, unsigned int tableSize); +extern size_t GCM_AuthenticateBlocks_CLMUL(const byte *data, size_t len, const byte *mtable, byte *hbuffer); +const unsigned int s_cltableSizeInBlocks = 8; +extern void GCM_ReverseHashBufferIfNeeded_CLMUL(byte *hashBuffer); +#endif // CRYPTOPP_CLMUL_AVAILABLE + +#if CRYPTOPP_ARM_PMULL_AVAILABLE +extern void GCM_SetKeyWithoutResync_PMULL(const byte *hashKey, byte *mulTable, unsigned int tableSize); +extern size_t GCM_AuthenticateBlocks_PMULL(const byte *data, size_t len, const byte *mtable, byte *hbuffer); +const unsigned int s_cltableSizeInBlocks = 8; +extern void GCM_ReverseHashBufferIfNeeded_PMULL(byte *hashBuffer); +#endif // CRYPTOPP_ARM_PMULL_AVAILABLE + +#if CRYPTOPP_POWER8_VMULL_AVAILABLE +extern void GCM_SetKeyWithoutResync_VMULL(const byte *hashKey, byte *mulTable, unsigned int tableSize); +extern size_t GCM_AuthenticateBlocks_VMULL(const byte *data, size_t len, const byte *mtable, byte *hbuffer); +const unsigned int s_cltableSizeInBlocks = 8; +extern void GCM_ReverseHashBufferIfNeeded_VMULL(byte *hashBuffer); +#endif // CRYPTOPP_POWER8_VMULL_AVAILABLE + +void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) +{ + BlockCipher &blockCipher = AccessBlockCipher(); + blockCipher.SetKey(userKey, keylength, params); + + // GCM is only defined for 16-byte block ciphers at the moment. + // However, variable blocksize support means we have to defer + // blocksize checks to runtime after the key is set. Also see + // https://github.com/weidai11/cryptopp/issues/408. + const unsigned int blockSize = blockCipher.BlockSize(); + CRYPTOPP_ASSERT(blockSize == REQUIRED_BLOCKSIZE); + if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE) + throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16"); + + int tableSize, i, j, k; + +#if CRYPTOPP_CLMUL_AVAILABLE + if (HasCLMUL()) + { + // Avoid "parameter not used" error and suppress Coverity finding + (void)params.GetIntValue(Name::TableSize(), tableSize); + tableSize = s_cltableSizeInBlocks * blockSize; + CRYPTOPP_ASSERT(tableSize > static_cast(blockSize)); + } + else +#elif CRYPTOPP_ARM_PMULL_AVAILABLE + if (HasPMULL()) + { + // Avoid "parameter not used" error and suppress Coverity finding + (void)params.GetIntValue(Name::TableSize(), tableSize); + tableSize = s_cltableSizeInBlocks * blockSize; + CRYPTOPP_ASSERT(tableSize > static_cast(blockSize)); + } + else +#elif CRYPTOPP_POWER8_VMULL_AVAILABLE + if (HasPMULL()) + { + // Avoid "parameter not used" error and suppress Coverity finding + (void)params.GetIntValue(Name::TableSize(), tableSize); + tableSize = s_cltableSizeInBlocks * blockSize; + CRYPTOPP_ASSERT(tableSize > static_cast(blockSize)); + } + else +#endif + { + if (params.GetIntValue(Name::TableSize(), tableSize)) + tableSize = (tableSize >= 64*1024) ? 64*1024 : 2*1024; + else + tableSize = (GetTablesOption() == GCM_64K_Tables) ? 64*1024 : 2*1024; + + //#if defined(_MSC_VER) && (_MSC_VER < 1400) + // VC 2003 workaround: compiler generates bad code for 64K tables + //tableSize = 2*1024; + //#endif + } + + m_buffer.resize(3*blockSize + tableSize); + byte *mulTable = MulTable(); + byte *hashKey = HashKey(); + memset(hashKey, 0, REQUIRED_BLOCKSIZE); + blockCipher.ProcessBlock(hashKey); + +#if CRYPTOPP_CLMUL_AVAILABLE + if (HasCLMUL()) + { + GCM_SetKeyWithoutResync_CLMUL(hashKey, mulTable, tableSize); + return; + } +#elif CRYPTOPP_ARM_PMULL_AVAILABLE + if (HasPMULL()) + { + GCM_SetKeyWithoutResync_PMULL(hashKey, mulTable, tableSize); + return; + } +#elif CRYPTOPP_POWER8_VMULL_AVAILABLE + if (HasPMULL()) + { + GCM_SetKeyWithoutResync_VMULL(hashKey, mulTable, tableSize); + return; + } +#endif + + word64 V0, V1; + typedef BlockGetAndPut Block; + Block::Get(hashKey)(V0)(V1); + + if (tableSize == 64*1024) + { + for (i=0; i<128; i++) + { + k = i%8; + Block::Put(NULLPTR, mulTable+(i/8)*256*16+(size_t(1)<<(11-k)))(V0)(V1); + + int x = (int)V1 & 1; + V1 = (V1>>1) | (V0<<63); + V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0); + } + + for (i=0; i<16; i++) + { + memset(mulTable+i*256*16, 0, 16); +#if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + for (j=2; j<=0x80; j*=2) + for (k=1; k>1) | (V0<<63); + V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0); + } + + for (i=0; i<4; i++) + { + memset(mulTable+i*256, 0, 16); + memset(mulTable+1024+i*256, 0, 16); +#if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + for (j=2; j<=8; j*=2) + for (k=1; k= HASH_BLOCKSIZE) + { + len = GCM_Base::AuthenticateBlocks(iv, len); + iv += (origLen - len); + } + + if (len > 0) + { + memcpy(m_buffer, iv, len); + memset(m_buffer+len, 0, HASH_BLOCKSIZE-len); + GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); + } + + PutBlock(NULLPTR, m_buffer)(0)(origLen*8); + GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); + + ReverseHashBufferIfNeeded(); + } + + if (m_state >= State_IVSet) + m_ctr.Resynchronize(hashBuffer, REQUIRED_BLOCKSIZE); + else + m_ctr.SetCipherWithIV(cipher, hashBuffer); + + m_ctr.Seek(HASH_BLOCKSIZE); + + memset(hashBuffer, 0, HASH_BLOCKSIZE); +} + +unsigned int GCM_Base::OptimalDataAlignment() const +{ + return +#if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) + HasSSE2() ? 16 : +#elif CRYPTOPP_ARM_NEON_AVAILABLE + HasNEON() ? 4 : +#elif CRYPTOPP_POWER8_AVAILABLE + HasPower8() ? 16 : +#endif + GetBlockCipher().OptimalDataAlignment(); +} + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code +#endif + +#endif // Not CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void GCM_AuthenticateBlocks_2K_SSE2(const byte *data, size_t blocks, word64 *hashBuffer, const word16 *reductionTable); +void GCM_AuthenticateBlocks_64K_SSE2(const byte *data, size_t blocks, word64 *hashBuffer); +} +#endif + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) +{ +#if CRYPTOPP_CLMUL_AVAILABLE + if (HasCLMUL()) + { + return GCM_AuthenticateBlocks_CLMUL(data, len, MulTable(), HashBuffer()); + } +#elif CRYPTOPP_ARM_PMULL_AVAILABLE + if (HasPMULL()) + { + return GCM_AuthenticateBlocks_PMULL(data, len, MulTable(), HashBuffer()); + } +#elif CRYPTOPP_POWER8_VMULL_AVAILABLE + if (HasPMULL()) + { + return GCM_AuthenticateBlocks_VMULL(data, len, MulTable(), HashBuffer()); + } +#endif + + typedef BlockGetAndPut Block; + word64 *hashBuffer = (word64 *)(void *)HashBuffer(); + CRYPTOPP_ASSERT(IsAlignedOn(hashBuffer,GetAlignmentOf())); + + switch (2*(m_buffer.size()>=64*1024) +#if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) + + HasSSE2() +//#elif CRYPTOPP_ARM_NEON_AVAILABLE +// + HasNEON() +#endif + ) + { + case 0: // non-SSE2 and 2K tables + { + byte *mulTable = MulTable(); + word64 x0 = hashBuffer[0], x1 = hashBuffer[1]; + + do + { + word64 y0, y1, a0, a1, b0, b1, c0, c1, d0, d1; + Block::Get(data)(y0)(y1); + x0 ^= y0; + x1 ^= y1; + + data += HASH_BLOCKSIZE; + len -= HASH_BLOCKSIZE; + + #define READ_TABLE_WORD64_COMMON(a, b, c, d) *(word64 *)(void *)(mulTable+(a*1024)+(b*256)+c+d*8) + + #if (CRYPTOPP_LITTLE_ENDIAN) + #if CRYPTOPP_BOOL_SLOW_WORD64 + word32 z0 = (word32)x0; + word32 z1 = (word32)(x0>>32); + word32 z2 = (word32)x1; + word32 z3 = (word32)(x1>>32); + #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((d%2), c, (d?(z##c>>((d?d-1:0)*4))&0xf0:(z##c&0xf)<<4), e) + #else + #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((d%2), c, ((d+8*b)?(x##a>>(((d+8*b)?(d+8*b)-1:1)*4))&0xf0:(x##a&0xf)<<4), e) + #endif + #define GF_MOST_SIG_8BITS(a) (a##1 >> 7*8) + #define GF_SHIFT_8(a) a##1 = (a##1 << 8) ^ (a##0 >> 7*8); a##0 <<= 8; + #else + #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((1-d%2), c, ((15-d-8*b)?(x##a>>(((15-d-8*b)?(15-d-8*b)-1:0)*4))&0xf0:(x##a&0xf)<<4), e) + #define GF_MOST_SIG_8BITS(a) (a##1 & 0xff) + #define GF_SHIFT_8(a) a##1 = (a##1 >> 8) ^ (a##0 << 7*8); a##0 >>= 8; + #endif + + #define GF_MUL_32BY128(op, a, b, c) \ + a0 op READ_TABLE_WORD64(a, b, c, 0, 0) ^ READ_TABLE_WORD64(a, b, c, 1, 0); \ + a1 op READ_TABLE_WORD64(a, b, c, 0, 1) ^ READ_TABLE_WORD64(a, b, c, 1, 1); \ + b0 op READ_TABLE_WORD64(a, b, c, 2, 0) ^ READ_TABLE_WORD64(a, b, c, 3, 0); \ + b1 op READ_TABLE_WORD64(a, b, c, 2, 1) ^ READ_TABLE_WORD64(a, b, c, 3, 1); \ + c0 op READ_TABLE_WORD64(a, b, c, 4, 0) ^ READ_TABLE_WORD64(a, b, c, 5, 0); \ + c1 op READ_TABLE_WORD64(a, b, c, 4, 1) ^ READ_TABLE_WORD64(a, b, c, 5, 1); \ + d0 op READ_TABLE_WORD64(a, b, c, 6, 0) ^ READ_TABLE_WORD64(a, b, c, 7, 0); \ + d1 op READ_TABLE_WORD64(a, b, c, 6, 1) ^ READ_TABLE_WORD64(a, b, c, 7, 1); \ + + GF_MUL_32BY128(=, 0, 0, 0) + GF_MUL_32BY128(^=, 0, 1, 1) + GF_MUL_32BY128(^=, 1, 0, 2) + GF_MUL_32BY128(^=, 1, 1, 3) + + word32 r = (word32)s_reductionTable[GF_MOST_SIG_8BITS(d)] << 16; + GF_SHIFT_8(d) + c0 ^= d0; c1 ^= d1; + r ^= (word32)s_reductionTable[GF_MOST_SIG_8BITS(c)] << 8; + GF_SHIFT_8(c) + b0 ^= c0; b1 ^= c1; + r ^= s_reductionTable[GF_MOST_SIG_8BITS(b)]; + GF_SHIFT_8(b) + a0 ^= b0; a1 ^= b1; + a0 ^= ConditionalByteReverse(LITTLE_ENDIAN_ORDER, r); + x0 = a0; x1 = a1; + } + while (len >= HASH_BLOCKSIZE); + + hashBuffer[0] = x0; hashBuffer[1] = x1; + return len; + } + + case 2: // non-SSE2 and 64K tables + { + byte *mulTable = MulTable(); + word64 x0 = hashBuffer[0], x1 = hashBuffer[1]; + + do + { + word64 y0, y1, a0, a1; + Block::Get(data)(y0)(y1); + x0 ^= y0; + x1 ^= y1; + + data += HASH_BLOCKSIZE; + len -= HASH_BLOCKSIZE; + + #undef READ_TABLE_WORD64_COMMON + #undef READ_TABLE_WORD64 + + #define READ_TABLE_WORD64_COMMON(a, c, d) *(word64 *)(void *)(mulTable+(a)*256*16+(c)+(d)*8) + + #if (CRYPTOPP_LITTLE_ENDIAN) + #if CRYPTOPP_BOOL_SLOW_WORD64 + word32 z0 = (word32)x0; + word32 z1 = (word32)(x0>>32); + word32 z2 = (word32)x1; + word32 z3 = (word32)(x1>>32); + #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, (d?(z##c>>((d?d:1)*8-4))&0xff0:(z##c&0xff)<<4), e) + #else + #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, ((d+4*(c%2))?(x##b>>(((d+4*(c%2))?(d+4*(c%2)):1)*8-4))&0xff0:(x##b&0xff)<<4), e) + #endif + #else + #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, ((7-d-4*(c%2))?(x##b>>(((7-d-4*(c%2))?(7-d-4*(c%2)):1)*8-4))&0xff0:(x##b&0xff)<<4), e) + #endif + + #define GF_MUL_8BY128(op, b, c, d) \ + a0 op READ_TABLE_WORD64(b, c, d, 0);\ + a1 op READ_TABLE_WORD64(b, c, d, 1);\ + + GF_MUL_8BY128(=, 0, 0, 0) + GF_MUL_8BY128(^=, 0, 0, 1) + GF_MUL_8BY128(^=, 0, 0, 2) + GF_MUL_8BY128(^=, 0, 0, 3) + GF_MUL_8BY128(^=, 0, 1, 0) + GF_MUL_8BY128(^=, 0, 1, 1) + GF_MUL_8BY128(^=, 0, 1, 2) + GF_MUL_8BY128(^=, 0, 1, 3) + GF_MUL_8BY128(^=, 1, 2, 0) + GF_MUL_8BY128(^=, 1, 2, 1) + GF_MUL_8BY128(^=, 1, 2, 2) + GF_MUL_8BY128(^=, 1, 2, 3) + GF_MUL_8BY128(^=, 1, 3, 0) + GF_MUL_8BY128(^=, 1, 3, 1) + GF_MUL_8BY128(^=, 1, 3, 2) + GF_MUL_8BY128(^=, 1, 3, 3) + + x0 = a0; x1 = a1; + } + while (len >= HASH_BLOCKSIZE); + + hashBuffer[0] = x0; hashBuffer[1] = x1; + return len; + } +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE + case 1: // SSE2 and 2K tables + GCM_AuthenticateBlocks_2K_SSE2(data, len/16, hashBuffer, s_reductionTable); + return len % 16; + case 3: // SSE2 and 64K tables + GCM_AuthenticateBlocks_64K_SSE2(data, len/16, hashBuffer); + return len % 16; +#endif + +#if CRYPTOPP_SSE2_ASM_AVAILABLE + case 1: // SSE2 and 2K tables + { + #ifdef __GNUC__ + __asm__ __volatile__ + ( + INTEL_NOPREFIX + #elif defined(CRYPTOPP_GENERATE_X64_MASM) + ALIGN 8 + GCM_AuthenticateBlocks_2K_SSE2 PROC FRAME + rex_push_reg rsi + push_reg rdi + push_reg rbx + .endprolog + mov rsi, r8 + mov r11, r9 + #else + AS2( mov WORD_REG(cx), data ) + AS2( mov WORD_REG(dx), len ) + AS2( mov WORD_REG(si), hashBuffer ) + AS2( shr WORD_REG(dx), 4 ) + #endif + + #if CRYPTOPP_BOOL_X32 + AS1(push rbx) + AS1(push rbp) + #else + AS_PUSH_IF86( bx) + AS_PUSH_IF86( bp) + #endif + + #ifdef __GNUC__ + AS2( mov AS_REG_7, WORD_REG(di)) + #elif CRYPTOPP_BOOL_X86 + AS2( lea AS_REG_7, s_reductionTable) + #endif + + AS2( movdqa xmm0, [WORD_REG(si)] ) + + #define MUL_TABLE_0 WORD_REG(si) + 32 + #define MUL_TABLE_1 WORD_REG(si) + 32 + 1024 + #define RED_TABLE AS_REG_7 + + ASL(0) + AS2( movdqu xmm4, [WORD_REG(cx)] ) + AS2( pxor xmm0, xmm4 ) + + AS2( movd ebx, xmm0 ) + AS2( mov eax, AS_HEX(f0f0f0f0) ) + AS2( and eax, ebx ) + AS2( shl ebx, 4 ) + AS2( and ebx, AS_HEX(f0f0f0f0) ) + AS2( movzx edi, ah ) + AS2( movdqa xmm5, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) + AS2( movzx edi, al ) + AS2( movdqa xmm4, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) + AS2( shr eax, 16 ) + AS2( movzx edi, ah ) + AS2( movdqa xmm3, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) + AS2( movzx edi, al ) + AS2( movdqa xmm2, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) + + #define SSE2_MUL_32BITS(i) \ + AS2( psrldq xmm0, 4 )\ + AS2( movd eax, xmm0 )\ + AS2( and eax, AS_HEX(f0f0f0f0) )\ + AS2( movzx edi, bh )\ + AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ + AS2( movzx edi, bl )\ + AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ + AS2( shr ebx, 16 )\ + AS2( movzx edi, bh )\ + AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ + AS2( movzx edi, bl )\ + AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ + AS2( movd ebx, xmm0 )\ + AS2( shl ebx, 4 )\ + AS2( and ebx, AS_HEX(f0f0f0f0) )\ + AS2( movzx edi, ah )\ + AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ + AS2( movzx edi, al )\ + AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ + AS2( shr eax, 16 )\ + AS2( movzx edi, ah )\ + AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ + AS2( movzx edi, al )\ + AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ + + SSE2_MUL_32BITS(1) + SSE2_MUL_32BITS(2) + SSE2_MUL_32BITS(3) + + AS2( movzx edi, bh ) + AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) + AS2( movzx edi, bl ) + AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) + AS2( shr ebx, 16 ) + AS2( movzx edi, bh ) + AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) + AS2( movzx edi, bl ) + AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) + + AS2( movdqa xmm0, xmm3 ) + AS2( pslldq xmm3, 1 ) + AS2( pxor xmm2, xmm3 ) + AS2( movdqa xmm1, xmm2 ) + AS2( pslldq xmm2, 1 ) + AS2( pxor xmm5, xmm2 ) + + AS2( psrldq xmm0, 15 ) +#if USE_MOVD_REG32 + AS2( movd edi, xmm0 ) +#elif USE_MOV_REG32_OR_REG64 + AS2( mov WORD_REG(di), xmm0 ) +#else // GNU Assembler + AS2( movd WORD_REG(di), xmm0 ) +#endif + AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) + AS2( shl eax, 8 ) + + AS2( movdqa xmm0, xmm5 ) + AS2( pslldq xmm5, 1 ) + AS2( pxor xmm4, xmm5 ) + + AS2( psrldq xmm1, 15 ) +#if USE_MOVD_REG32 + AS2( movd edi, xmm1 ) +#elif USE_MOV_REG32_OR_REG64 + AS2( mov WORD_REG(di), xmm1 ) +#else + AS2( movd WORD_REG(di), xmm1 ) +#endif + AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) + AS2( shl eax, 8 ) + + AS2( psrldq xmm0, 15 ) +#if USE_MOVD_REG32 + AS2( movd edi, xmm0 ) +#elif USE_MOV_REG32_OR_REG64 + AS2( mov WORD_REG(di), xmm0 ) +#else + AS2( movd WORD_REG(di), xmm0 ) +#endif + AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) + + AS2( movd xmm0, eax ) + AS2( pxor xmm0, xmm4 ) + + AS2( add WORD_REG(cx), 16 ) + AS2( sub WORD_REG(dx), 1 ) + // ATT_NOPREFIX + ASJ( jnz, 0, b ) + INTEL_NOPREFIX + AS2( movdqa [WORD_REG(si)], xmm0 ) + + #if CRYPTOPP_BOOL_X32 + AS1(pop rbp) + AS1(pop rbx) + #else + AS_POP_IF86( bp) + AS_POP_IF86( bx) + #endif + + #ifdef __GNUC__ + ATT_PREFIX + : + : "c" (data), "d" (len/16), "S" (hashBuffer), "D" (s_reductionTable) + : "memory", "cc", "%eax" + #if CRYPTOPP_BOOL_X64 + , "%ebx", "%r11" + #endif + ); + #elif defined(CRYPTOPP_GENERATE_X64_MASM) + pop rbx + pop rdi + pop rsi + ret + GCM_AuthenticateBlocks_2K_SSE2 ENDP + #endif + + return len%16; + } + case 3: // SSE2 and 64K tables + { + #ifdef __GNUC__ + __asm__ __volatile__ + ( + INTEL_NOPREFIX + #elif defined(CRYPTOPP_GENERATE_X64_MASM) + ALIGN 8 + GCM_AuthenticateBlocks_64K_SSE2 PROC FRAME + rex_push_reg rsi + push_reg rdi + .endprolog + mov rsi, r8 + #else + AS2( mov WORD_REG(cx), data ) + AS2( mov WORD_REG(dx), len ) + AS2( mov WORD_REG(si), hashBuffer ) + AS2( shr WORD_REG(dx), 4 ) + #endif + + AS2( movdqa xmm0, [WORD_REG(si)] ) + + #undef MUL_TABLE + #define MUL_TABLE(i,j) WORD_REG(si) + 32 + (i*4+j)*256*16 + + ASL(1) + AS2( movdqu xmm1, [WORD_REG(cx)] ) + AS2( pxor xmm1, xmm0 ) + AS2( pxor xmm0, xmm0 ) + + #undef SSE2_MUL_32BITS + #define SSE2_MUL_32BITS(i) \ + AS2( movd eax, xmm1 )\ + AS2( psrldq xmm1, 4 )\ + AS2( movzx edi, al )\ + AS2( add WORD_REG(di), WORD_REG(di) )\ + AS2( pxor xmm0, [MUL_TABLE(i,0) + WORD_REG(di)*8] )\ + AS2( movzx edi, ah )\ + AS2( add WORD_REG(di), WORD_REG(di) )\ + AS2( pxor xmm0, [MUL_TABLE(i,1) + WORD_REG(di)*8] )\ + AS2( shr eax, 16 )\ + AS2( movzx edi, al )\ + AS2( add WORD_REG(di), WORD_REG(di) )\ + AS2( pxor xmm0, [MUL_TABLE(i,2) + WORD_REG(di)*8] )\ + AS2( movzx edi, ah )\ + AS2( add WORD_REG(di), WORD_REG(di) )\ + AS2( pxor xmm0, [MUL_TABLE(i,3) + WORD_REG(di)*8] )\ + + SSE2_MUL_32BITS(0) + SSE2_MUL_32BITS(1) + SSE2_MUL_32BITS(2) + SSE2_MUL_32BITS(3) + + AS2( add WORD_REG(cx), 16 ) + AS2( sub WORD_REG(dx), 1 ) + // ATT_NOPREFIX + ASJ( jnz, 1, b ) + INTEL_NOPREFIX + AS2( movdqa [WORD_REG(si)], xmm0 ) + + #ifdef __GNUC__ + ATT_PREFIX + : + : "c" (data), "d" (len/16), "S" (hashBuffer) + : "memory", "cc", "%edi", "%eax" + ); + #elif defined(CRYPTOPP_GENERATE_X64_MASM) + pop rdi + pop rsi + ret + GCM_AuthenticateBlocks_64K_SSE2 ENDP + #endif + + return len%16; + } +#endif +#ifndef CRYPTOPP_GENERATE_X64_MASM + } + + return len%16; +} + +void GCM_Base::AuthenticateLastHeaderBlock() +{ + if (m_bufferedDataLength > 0) + { + memset(m_buffer+m_bufferedDataLength, 0, HASH_BLOCKSIZE-m_bufferedDataLength); + m_bufferedDataLength = 0; + GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); + } +} + +void GCM_Base::AuthenticateLastConfidentialBlock() +{ + GCM_Base::AuthenticateLastHeaderBlock(); + PutBlock(NULLPTR, m_buffer)(m_totalHeaderLength*8)(m_totalMessageLength*8); + GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); +} + +void GCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize) +{ + m_ctr.Seek(0); + ReverseHashBufferIfNeeded(); + m_ctr.ProcessData(mac, HashBuffer(), macSize); +} + +NAMESPACE_END + +#endif // Not CRYPTOPP_GENERATE_X64_MASM +#endif diff --git a/external/ours/library/crypto/src/shared/original/gcm.h b/external/ours/library/crypto/src/shared/original/gcm.h new file mode 100755 index 000000000..a9302eec5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gcm.h @@ -0,0 +1,139 @@ +// gcm.h - originally written and placed in the public domain by Wei Dai + +/// \file gcm.h +/// \brief GCM block cipher mode of operation +/// \since Crypto++ 5.6.0 + +#ifndef CRYPTOPP_GCM_H +#define CRYPTOPP_GCM_H + +#include "authenc.h" +#include "modes.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_GCM_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \enum GCM_TablesOption +/// \brief GCM table size options +enum GCM_TablesOption { + /// \brief Use a table with 2K entries + GCM_2K_Tables, + /// \brief Use a table with 64K entries + GCM_64K_Tables}; + +/// \brief GCM block cipher base implementation +/// \details Base implementation of the AuthenticatedSymmetricCipher interface +/// \since Crypto++ 5.6.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase +{ +public: + // AuthenticatedSymmetricCipher + std::string AlgorithmName() const + {return GetBlockCipher().AlgorithmName() + std::string("/GCM");} + std::string AlgorithmProvider() const + {return GetBlockCipher().AlgorithmProvider();} + size_t MinKeyLength() const + {return GetBlockCipher().MinKeyLength();} + size_t MaxKeyLength() const + {return GetBlockCipher().MaxKeyLength();} + size_t DefaultKeyLength() const + {return GetBlockCipher().DefaultKeyLength();} + size_t GetValidKeyLength(size_t n) const + {return GetBlockCipher().GetValidKeyLength(n);} + bool IsValidKeyLength(size_t n) const + {return GetBlockCipher().IsValidKeyLength(n);} + unsigned int OptimalDataAlignment() const; + IV_Requirement IVRequirement() const + {return UNIQUE_IV;} + unsigned int IVSize() const + {return 12;} + unsigned int MinIVLength() const + {return 1;} + unsigned int MaxIVLength() const + {return UINT_MAX;} // (W64LIT(1)<<61)-1 in the standard + unsigned int DigestSize() const + {return 16;} + lword MaxHeaderLength() const + {return (W64LIT(1)<<61)-1;} + lword MaxMessageLength() const + {return ((W64LIT(1)<<39)-256)/8;} + +protected: + // AuthenticatedSymmetricCipherBase + bool AuthenticationIsOnPlaintext() const + {return false;} + unsigned int AuthenticationBlockSize() const + {return HASH_BLOCKSIZE;} + void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); + void Resync(const byte *iv, size_t len); + size_t AuthenticateBlocks(const byte *data, size_t len); + void AuthenticateLastHeaderBlock(); + void AuthenticateLastConfidentialBlock(); + void AuthenticateLastFooterBlock(byte *mac, size_t macSize); + SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} + + virtual BlockCipher & AccessBlockCipher() =0; + virtual GCM_TablesOption GetTablesOption() const =0; + + const BlockCipher & GetBlockCipher() const {return const_cast(this)->AccessBlockCipher();} + byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;} + byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;} + byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;} + inline void ReverseHashBufferIfNeeded(); + + class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption + { + protected: + void IncrementCounterBy256(); + }; + + GCTR m_ctr; + static word16 s_reductionTable[256]; + static volatile bool s_reductionTableInitialized; + enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16}; +}; + +/// \brief GCM block cipher final implementation +/// \tparam T_BlockCipher block cipher +/// \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables +/// \tparam T_IsEncryption direction in which to operate the cipher +/// \since Crypto++ 5.6.0 +template +class GCM_Final : public GCM_Base +{ +public: + static std::string StaticAlgorithmName() + {return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");} + bool IsForwardTransformation() const + {return T_IsEncryption;} + +private: + GCM_TablesOption GetTablesOption() const {return T_TablesOption;} + BlockCipher & AccessBlockCipher() {return m_cipher;} + typename T_BlockCipher::Encryption m_cipher; +}; + +/// \brief GCM block cipher mode of operation +/// \tparam T_BlockCipher block cipher +/// \tparam T_TablesOption table size, either \p GCM_2K_Tables or \p GCM_64K_Tables +/// \details \p GCM provides the \p Encryption and \p Decryption typedef. See GCM_Base +/// and GCM_Final for the AuthenticatedSymmetricCipher implementation. +/// \sa GCM Mode and +/// Modes of Operation +/// on the Crypto++ wiki. +/// \since Crypto++ 5.6.0 +template +struct GCM : public AuthenticatedSymmetricCipherDocumentation +{ + typedef GCM_Final Encryption; + typedef GCM_Final Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gcm_simd.cpp b/external/ours/library/crypto/src/shared/original/gcm_simd.cpp new file mode 100755 index 000000000..32823e127 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gcm_simd.cpp @@ -0,0 +1,734 @@ +// gcm_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// Original x86 CLMUL by Wei Dai. ARM and POWER8 +// PMULL and VMULL by JW, UB and MR. +// +// This source file uses intrinsics to gain access to SSE4.2 and +// ARMv8a CRC-32 and CRC-32C instructions. A separate source file +// is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "misc.h" + +#if defined(CRYPTOPP_DISABLE_GCM_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE) +# include +# include +#endif + +#if (CRYPTOPP_CLMUL_AVAILABLE) +# include +# include +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +# include +#endif + +#if defined(CRYPTOPP_ARM_PMULL_AVAILABLE) +# include "arm_simd.h" +#endif + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# include "ppc_simd.h" +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char GCM_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// ************************* Feature Probes ************************* // + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) +bool CPU_ProbePMULL() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (CRYPTOPP_ARM_PMULL_AVAILABLE) +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + // Linaro is missing a lot of pmull gear. Also see http://github.com/weidai11/cryptopp/issues/233. + const uint64_t wa1[]={0,0x9090909090909090}, wb1[]={0,0xb0b0b0b0b0b0b0b0}; + const uint64x2_t a1=vld1q_u64(wa1), b1=vld1q_u64(wb1); + + const uint8_t wa2[]={0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0}, + wb2[]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0}; + const uint8x16_t a2=vld1q_u8(wa2), b2=vld1q_u8(wb2); + + const uint64x2_t r1 = PMULL_00(a1, b1); + const uint64x2_t r2 = PMULL_11(vreinterpretq_u64_u8(a2), + vreinterpretq_u64_u8(b2)); + + result = !!(vgetq_lane_u64(r1,0) == 0x5300530053005300 && + vgetq_lane_u64(r1,1) == 0x5300530053005300 && + vgetq_lane_u64(r2,0) == 0x6c006c006c006c00 && + vgetq_lane_u64(r2,1) == 0x6c006c006c006c00); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +# else + + // longjmp and clobber warnings. Volatile is required. + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + // Linaro is missing a lot of pmull gear. Also see http://github.com/weidai11/cryptopp/issues/233. + const uint64_t wa1[]={0,0x9090909090909090}, wb1[]={0,0xb0b0b0b0b0b0b0b0}; + const uint64x2_t a1=vld1q_u64(wa1), b1=vld1q_u64(wb1); + + const uint8_t wa2[]={0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0}, + wb2[]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0}; + const uint8x16_t a2=vld1q_u8(wa2), b2=vld1q_u8(wb2); + + const uint64x2_t r1 = PMULL_00(a1, b1); + const uint64x2_t r2 = PMULL_11(vreinterpretq_u64_u8(a2), + vreinterpretq_u64_u8(b2)); + + result = !!(vgetq_lane_u64(r1,0) == 0x5300530053005300 && + vgetq_lane_u64(r1,1) == 0x5300530053005300 && + vgetq_lane_u64(r2,0) == 0x6c006c006c006c00 && + vgetq_lane_u64(r2,1) == 0x6c006c006c006c00); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_PMULL_AVAILABLE +} +#endif // ARM32 or ARM64 + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) +bool CPU_ProbePMULL() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (CRYPTOPP_POWER8_VMULL_AVAILABLE) + // longjmp and clobber warnings. Volatile is required. + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + const uint64_t wa1[]={0,W64LIT(0x9090909090909090)}, + wb1[]={0,W64LIT(0xb0b0b0b0b0b0b0b0)}; + const uint64x2_p a1=VecLoad(wa1), b1=VecLoad(wb1); + + const uint8_t wa2[]={0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0}, + wb2[]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0}; + const uint32x4_p a2=VecLoad(wa2), b2=VecLoad(wb2); + + const uint64x2_p r1 = VecIntelMultiply11(a1, b1); + const uint64x2_p r2 = VecIntelMultiply11((uint64x2_p)a2, (uint64x2_p)b2); + + const uint64_t wc1[]={W64LIT(0x5300530053005300), W64LIT(0x5300530053005300)}, + wc2[]={W64LIT(0x6c006c006c006c00), W64LIT(0x6c006c006c006c00)}; + const uint64x2_p c1=VecLoad(wc1), c2=VecLoad(wc2); + + result = !!(VecEqual(r1, c1) && VecEqual(r2, c2)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +#else + return false; +#endif // CRYPTOPP_POWER8_VMULL_AVAILABLE +} +#endif // PPC32 or PPC64 + +// *************************** ARM NEON *************************** // + +#if CRYPTOPP_ARM_NEON_AVAILABLE +void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c) +{ + vst1q_u8(a, veorq_u8(vld1q_u8(b), vld1q_u8(c))); +} +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +#if CRYPTOPP_ARM_PMULL_AVAILABLE + +// Swaps high and low 64-bit words +inline uint64x2_t SwapWords(const uint64x2_t& data) +{ + return (uint64x2_t)vcombine_u64( + vget_high_u64(data), vget_low_u64(data)); +} + +uint64x2_t GCM_Reduce_PMULL(uint64x2_t c0, uint64x2_t c1, uint64x2_t c2, const uint64x2_t &r) +{ + c1 = veorq_u64(c1, VEXT_U8<8>(vdupq_n_u64(0), c0)); + c1 = veorq_u64(c1, PMULL_01(c0, r)); + c0 = VEXT_U8<8>(c0, vdupq_n_u64(0)); + c0 = vshlq_n_u64(veorq_u64(c0, c1), 1); + c0 = PMULL_00(c0, r); + c2 = veorq_u64(c2, c0); + c2 = veorq_u64(c2, VEXT_U8<8>(c1, vdupq_n_u64(0))); + c1 = vshrq_n_u64(vcombine_u64(vget_low_u64(c1), vget_low_u64(c2)), 63); + c2 = vshlq_n_u64(c2, 1); + + return veorq_u64(c2, c1); +} + +uint64x2_t GCM_Multiply_PMULL(const uint64x2_t &x, const uint64x2_t &h, const uint64x2_t &r) +{ + const uint64x2_t c0 = PMULL_00(x, h); + const uint64x2_t c1 = veorq_u64(PMULL_10(x, h), PMULL_01(x, h)); + const uint64x2_t c2 = PMULL_11(x, h); + + return GCM_Reduce_PMULL(c0, c1, c2, r); +} + +void GCM_SetKeyWithoutResync_PMULL(const byte *hashKey, byte *mulTable, unsigned int tableSize) +{ + const uint64x2_t r = {0xe100000000000000ull, 0xc200000000000000ull}; + const uint64x2_t t = vreinterpretq_u64_u8(vrev64q_u8(vld1q_u8(hashKey))); + const uint64x2_t h0 = vextq_u64(t, t, 1); + + uint64x2_t h = h0; + unsigned int i; + for (i=0; i= 16) + { + size_t i=0, s = UnsignedMin(len/16U, 8U); + uint64x2_t d1, d2 = vreinterpretq_u64_u8(vrev64q_u8(vld1q_u8(data+(s-1)*16U))); + uint64x2_t c0 = vdupq_n_u64(0); + uint64x2_t c1 = vdupq_n_u64(0); + uint64x2_t c2 = vdupq_n_u64(0); + + while (true) + { + const uint64x2_t h0 = vld1q_u64(CONST_UINT64_CAST(mtable+(i+0)*16)); + const uint64x2_t h1 = vld1q_u64(CONST_UINT64_CAST(mtable+(i+1)*16)); + const uint64x2_t h2 = veorq_u64(h0, h1); + + if (++i == s) + { + const uint64x2_t t1 = vreinterpretq_u64_u8(vrev64q_u8(vld1q_u8(data))); + d1 = veorq_u64(vextq_u64(t1, t1, 1), x); + c0 = veorq_u64(c0, PMULL_00(d1, h0)); + c2 = veorq_u64(c2, PMULL_10(d1, h1)); + d1 = veorq_u64(d1, SwapWords(d1)); + c1 = veorq_u64(c1, PMULL_00(d1, h2)); + + break; + } + + d1 = vreinterpretq_u64_u8(vrev64q_u8(vld1q_u8(data+(s-i)*16-8))); + c0 = veorq_u64(c0, PMULL_10(d2, h0)); + c2 = veorq_u64(c2, PMULL_10(d1, h1)); + d2 = veorq_u64(d2, d1); + c1 = veorq_u64(c1, PMULL_10(d2, h2)); + + if (++i == s) + { + const uint64x2_t t2 = vreinterpretq_u64_u8(vrev64q_u8(vld1q_u8(data))); + d1 = veorq_u64(vextq_u64(t2, t2, 1), x); + c0 = veorq_u64(c0, PMULL_01(d1, h0)); + c2 = veorq_u64(c2, PMULL_11(d1, h1)); + d1 = veorq_u64(d1, SwapWords(d1)); + c1 = veorq_u64(c1, PMULL_01(d1, h2)); + + break; + } + + const uint64x2_t t3 = vreinterpretq_u64_u8(vrev64q_u8(vld1q_u8(data+(s-i)*16-8))); + d2 = vextq_u64(t3, t3, 1); + c0 = veorq_u64(c0, PMULL_01(d1, h0)); + c2 = veorq_u64(c2, PMULL_01(d2, h1)); + d1 = veorq_u64(d1, d2); + c1 = veorq_u64(c1, PMULL_01(d1, h2)); + } + data += s*16; + len -= s*16; + + c1 = veorq_u64(veorq_u64(c1, c0), c2); + x = GCM_Reduce_PMULL(c0, c1, c2, r); + } + + vst1q_u64(UINT64_CAST(hbuffer), x); + return len; +} + +void GCM_ReverseHashBufferIfNeeded_PMULL(byte *hashBuffer) +{ + if (GetNativeByteOrder() != BIG_ENDIAN_ORDER) + { + const uint8x16_t x = vrev64q_u8(vld1q_u8(hashBuffer)); + vst1q_u8(hashBuffer, vextq_u8(x, x, 8)); + } +} +#endif // CRYPTOPP_ARM_PMULL_AVAILABLE + +// ***************************** SSE ***************************** // + +#if CRYPTOPP_SSE2_INTRIN_AVAILABLE || CRYPTOPP_SSE2_ASM_AVAILABLE +// SunCC 5.10-5.11 compiler crash. Move GCM_Xor16_SSE2 out-of-line, and place in +// a source file with a SSE architecture switch. Also see GH #226 and GH #284. +void GCM_Xor16_SSE2(byte *a, const byte *b, const byte *c) +{ +# if CRYPTOPP_SSE2_ASM_AVAILABLE && defined(__GNUC__) + asm ("movdqa %1, %%xmm0; pxor %2, %%xmm0; movdqa %%xmm0, %0;" + : "=m" (a[0]) : "m"(b[0]), "m"(c[0])); +# else // CRYPTOPP_SSE2_INTRIN_AVAILABLE + _mm_store_si128(M128_CAST(a), _mm_xor_si128( + _mm_load_si128(CONST_M128_CAST(b)), + _mm_load_si128(CONST_M128_CAST(c)))); +# endif +} +#endif // CRYPTOPP_SSE2_ASM_AVAILABLE + +#if CRYPTOPP_CLMUL_AVAILABLE + +#if 0 +// preserved for testing +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ + word64 Z0=0, Z1=0, V0, V1; + + typedef BlockGetAndPut Block; + Block::Get(a)(V0)(V1); + + for (int i=0; i<16; i++) + { + for (int j=0x80; j!=0; j>>=1) + { + int x = b[i] & j; + Z0 ^= x ? V0 : 0; + Z1 ^= x ? V1 : 0; + x = (int)V1 & 1; + V1 = (V1>>1) | (V0<<63); + V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0); + } + } + Block::Put(NULLPTR, c)(Z0)(Z1); +} + +__m128i _mm_clmulepi64_si128(const __m128i &a, const __m128i &b, int i) +{ + word64 A[1] = {ByteReverse(((word64*)&a)[i&1])}; + word64 B[1] = {ByteReverse(((word64*)&b)[i>>4])}; + + PolynomialMod2 pa((byte *)A, 8); + PolynomialMod2 pb((byte *)B, 8); + PolynomialMod2 c = pa*pb; + + __m128i output; + for (int i=0; i<16; i++) + ((byte *)&output)[i] = c.GetByte(i); + return output; +} +#endif // Testing + +// Swaps high and low 64-bit words +inline __m128i SwapWords(const __m128i& val) +{ + return _mm_shuffle_epi32(val, _MM_SHUFFLE(1, 0, 3, 2)); +} + +// SunCC 5.11-5.15 compiler crash. Make the function inline +// and parameters non-const. Also see GH #188 and GH #224. +inline __m128i GCM_Reduce_CLMUL(__m128i c0, __m128i c1, __m128i c2, const __m128i& r) +{ + /* + The polynomial to be reduced is c0 * x^128 + c1 * x^64 + c2. c0t below refers to the most + significant half of c0 as a polynomial, which, due to GCM's bit reflection, are in the + rightmost bit positions, and the lowest byte addresses. + + c1 ^= c0t * 0xc200000000000000 + c2t ^= c0t + t = shift (c1t ^ c0b) left 1 bit + c2 ^= t * 0xe100000000000000 + c2t ^= c1b + shift c2 left 1 bit and xor in lowest bit of c1t + */ + c1 = _mm_xor_si128(c1, _mm_slli_si128(c0, 8)); + c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(c0, r, 0x10)); + c0 = _mm_xor_si128(c1, _mm_srli_si128(c0, 8)); + c0 = _mm_slli_epi64(c0, 1); + c0 = _mm_clmulepi64_si128(c0, r, 0); + c2 = _mm_xor_si128(c2, c0); + c2 = _mm_xor_si128(c2, _mm_srli_si128(c1, 8)); + c1 = _mm_unpacklo_epi64(c1, c2); + c1 = _mm_srli_epi64(c1, 63); + c2 = _mm_slli_epi64(c2, 1); + return _mm_xor_si128(c2, c1); +} + +// SunCC 5.13-5.14 compiler crash. Don't make the function inline. +// This is in contrast to GCM_Reduce_CLMUL, which must be inline. +__m128i GCM_Multiply_CLMUL(const __m128i &x, const __m128i &h, const __m128i &r) +{ + const __m128i c0 = _mm_clmulepi64_si128(x,h,0); + const __m128i c1 = _mm_xor_si128(_mm_clmulepi64_si128(x,h,1), _mm_clmulepi64_si128(x,h,0x10)); + const __m128i c2 = _mm_clmulepi64_si128(x,h,0x11); + + return GCM_Reduce_CLMUL(c0, c1, c2, r); +} + +void GCM_SetKeyWithoutResync_CLMUL(const byte *hashKey, byte *mulTable, unsigned int tableSize) +{ + const __m128i r = _mm_set_epi32(0xc2000000, 0x00000000, 0xe1000000, 0x00000000); + const __m128i m = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f); + __m128i h0 = _mm_shuffle_epi8(_mm_load_si128(CONST_M128_CAST(hashKey)), m), h = h0; + + unsigned int i; + for (i=0; i= 16) + { + size_t i=0, s = UnsignedMin(len/16, 8U); + __m128i d1 = _mm_loadu_si128(CONST_M128_CAST(data+(s-1)*16)); + __m128i d2 = _mm_shuffle_epi8(d1, m2); + __m128i c0 = _mm_setzero_si128(); + __m128i c1 = _mm_setzero_si128(); + __m128i c2 = _mm_setzero_si128(); + + while (true) + { + const __m128i h0 = _mm_load_si128(CONST_M128_CAST(mtable+(i+0)*16)); + const __m128i h1 = _mm_load_si128(CONST_M128_CAST(mtable+(i+1)*16)); + const __m128i h2 = _mm_xor_si128(h0, h1); + + if (++i == s) + { + d1 = _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(data)), m1); + d1 = _mm_xor_si128(d1, x); + c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d1, h0, 0)); + c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d1, h1, 1)); + d1 = _mm_xor_si128(d1, SwapWords(d1)); + c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d1, h2, 0)); + break; + } + + d1 = _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(data+(s-i)*16-8)), m2); + c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d2, h0, 1)); + c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d1, h1, 1)); + d2 = _mm_xor_si128(d2, d1); + c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d2, h2, 1)); + + if (++i == s) + { + d1 = _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(data)), m1); + d1 = _mm_xor_si128(d1, x); + c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d1, h0, 0x10)); + c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d1, h1, 0x11)); + d1 = _mm_xor_si128(d1, SwapWords(d1)); + c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d1, h2, 0x10)); + break; + } + + d2 = _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(data+(s-i)*16-8)), m1); + c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d1, h0, 0x10)); + c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d2, h1, 0x10)); + d1 = _mm_xor_si128(d1, d2); + c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d1, h2, 0x10)); + } + data += s*16; + len -= s*16; + + c1 = _mm_xor_si128(_mm_xor_si128(c1, c0), c2); + x = GCM_Reduce_CLMUL(c0, c1, c2, r); + } + + _mm_store_si128(M128_CAST(hbuffer), x); + return len; +} + +void GCM_ReverseHashBufferIfNeeded_CLMUL(byte *hashBuffer) +{ + // SSSE3 instruction, but only used with CLMUL + const __m128i mask = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f); + _mm_storeu_si128(M128_CAST(hashBuffer), _mm_shuffle_epi8( + _mm_loadu_si128(CONST_M128_CAST(hashBuffer)), mask)); +} +#endif // CRYPTOPP_CLMUL_AVAILABLE + +// ***************************** POWER8 ***************************** // + +#if CRYPTOPP_POWER8_AVAILABLE +void GCM_Xor16_POWER8(byte *a, const byte *b, const byte *c) +{ + VecStore(VecXor(VecLoad(b), VecLoad(c)), a); +} +#endif // CRYPTOPP_POWER8_AVAILABLE + +#if CRYPTOPP_POWER8_VMULL_AVAILABLE + +uint64x2_p GCM_Reduce_VMULL(uint64x2_p c0, uint64x2_p c1, uint64x2_p c2, uint64x2_p r) +{ + const uint64x2_p m1 = {1,1}, m63 = {63,63}; + + c1 = VecXor(c1, VecShiftRightOctet<8>(c0)); + c1 = VecXor(c1, VecIntelMultiply10(c0, r)); + c0 = VecXor(c1, VecShiftLeftOctet<8>(c0)); + c0 = VecIntelMultiply00(vec_sl(c0, m1), r); + c2 = VecXor(c2, c0); + c2 = VecXor(c2, VecShiftLeftOctet<8>(c1)); + c1 = vec_sr(vec_mergeh(c1, c2), m63); + c2 = vec_sl(c2, m1); + + return VecXor(c2, c1); +} + +inline uint64x2_p GCM_Multiply_VMULL(uint64x2_p x, uint64x2_p h, uint64x2_p r) +{ + const uint64x2_p c0 = VecIntelMultiply00(x, h); + const uint64x2_p c1 = VecXor(VecIntelMultiply01(x, h), VecIntelMultiply10(x, h)); + const uint64x2_p c2 = VecIntelMultiply11(x, h); + + return GCM_Reduce_VMULL(c0, c1, c2, r); +} + +inline uint64x2_p LoadHashKey(const byte *hashKey) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint64x2_p key = (uint64x2_p)VecLoad(hashKey); + const uint8x16_p mask = {8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7}; + return VecPermute(key, key, mask); +#else + const uint64x2_p key = (uint64x2_p)VecLoad(hashKey); + const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + return VecPermute(key, key, mask); +#endif +} + +void GCM_SetKeyWithoutResync_VMULL(const byte *hashKey, byte *mulTable, unsigned int tableSize) +{ + const uint64x2_p r = {0xe100000000000000ull, 0xc200000000000000ull}; + uint64x2_p h = LoadHashKey(hashKey), h0 = h; + + unsigned int i; + uint64_t temp[2]; + + for (i=0; i +inline T SwapWords(const T& data) +{ + return (T)VecRotateLeftOctet<8>(data); +} + +inline uint64x2_p LoadBuffer1(const byte *dataBuffer) +{ +#if (CRYPTOPP_BIG_ENDIAN) + return (uint64x2_p)VecLoad(dataBuffer); +#else + const uint64x2_p data = (uint64x2_p)VecLoad(dataBuffer); + const uint8x16_p mask = {7,6,5,4, 3,2,1,0, 15,14,13,12, 11,10,9,8}; + return VecPermute(data, data, mask); +#endif +} + +inline uint64x2_p LoadBuffer2(const byte *dataBuffer) +{ +#if (CRYPTOPP_BIG_ENDIAN) + return (uint64x2_p)SwapWords(VecLoadBE(dataBuffer)); +#else + return (uint64x2_p)VecLoadBE(dataBuffer); +#endif +} + +size_t GCM_AuthenticateBlocks_VMULL(const byte *data, size_t len, const byte *mtable, byte *hbuffer) +{ + const uint64x2_p r = {0xe100000000000000ull, 0xc200000000000000ull}; + uint64x2_p x = (uint64x2_p)VecLoad(hbuffer); + + while (len >= 16) + { + size_t i=0, s = UnsignedMin(len/16, 8U); + uint64x2_p d1, d2 = LoadBuffer1(data+(s-1)*16); + uint64x2_p c0 = {0}, c1 = {0}, c2 = {0}; + + while (true) + { + const uint64x2_p h0 = (uint64x2_p)VecLoad(mtable+(i+0)*16); + const uint64x2_p h1 = (uint64x2_p)VecLoad(mtable+(i+1)*16); + const uint64x2_p h2 = (uint64x2_p)VecXor(h0, h1); + + if (++i == s) + { + d1 = LoadBuffer2(data); + d1 = VecXor(d1, x); + c0 = VecXor(c0, VecIntelMultiply00(d1, h0)); + c2 = VecXor(c2, VecIntelMultiply01(d1, h1)); + d1 = VecXor(d1, SwapWords(d1)); + c1 = VecXor(c1, VecIntelMultiply00(d1, h2)); + break; + } + + d1 = LoadBuffer1(data+(s-i)*16-8); + c0 = VecXor(c0, VecIntelMultiply01(d2, h0)); + c2 = VecXor(c2, VecIntelMultiply01(d1, h1)); + d2 = VecXor(d2, d1); + c1 = VecXor(c1, VecIntelMultiply01(d2, h2)); + + if (++i == s) + { + d1 = LoadBuffer2(data); + d1 = VecXor(d1, x); + c0 = VecXor(c0, VecIntelMultiply10(d1, h0)); + c2 = VecXor(c2, VecIntelMultiply11(d1, h1)); + d1 = VecXor(d1, SwapWords(d1)); + c1 = VecXor(c1, VecIntelMultiply10(d1, h2)); + break; + } + + d2 = LoadBuffer2(data+(s-i)*16-8); + c0 = VecXor(c0, VecIntelMultiply10(d1, h0)); + c2 = VecXor(c2, VecIntelMultiply10(d2, h1)); + d1 = VecXor(d1, d2); + c1 = VecXor(c1, VecIntelMultiply10(d1, h2)); + } + data += s*16; + len -= s*16; + + c1 = VecXor(VecXor(c1, c0), c2); + x = GCM_Reduce_VMULL(c0, c1, c2, r); + } + + VecStore(x, hbuffer); + return len; +} + +void GCM_ReverseHashBufferIfNeeded_VMULL(byte *hashBuffer) +{ + const uint64x2_p mask = {0x08090a0b0c0d0e0full, 0x0001020304050607ull}; + VecStore(VecPermute(VecLoad(hashBuffer), mask), hashBuffer); +} +#endif // CRYPTOPP_POWER8_VMULL_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/gf256.cpp b/external/ours/library/crypto/src/shared/original/gf256.cpp new file mode 100755 index 000000000..c432344f3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf256.cpp @@ -0,0 +1,34 @@ +// gf256.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "gf256.h" + +NAMESPACE_BEGIN(CryptoPP) + +GF256::Element GF256::Multiply(Element a, Element b) const +{ + word result = 0, t = b; + + for (unsigned int i=0; i<8; i++) + { + result <<= 1; + if (result & 0x100) + result ^= m_modulus; + + t <<= 1; + if (t & 0x100) + result ^= a; + } + + return (GF256::Element) result; +} + +GF256::Element GF256::MultiplicativeInverse(Element a) const +{ + Element result = a; + for (int i=1; i<7; i++) + result = Multiply(Square(result), a); + return Square(result); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/gf256.h b/external/ours/library/crypto/src/shared/original/gf256.h new file mode 100755 index 000000000..9cef8309f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf256.h @@ -0,0 +1,72 @@ +// gf256.h - originally written and placed in the public domain by Wei Dai + +/// \file gf256.h +/// \brief Classes and functions for schemes over GF(256) + +#ifndef CRYPTOPP_GF256_H +#define CRYPTOPP_GF256_H + +#include "cryptlib.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief GF(256) with polynomial basis +class GF256 +{ +public: + typedef byte Element; + typedef int RandomizationParameter; + + GF256(byte modulus) : m_modulus(modulus) {} + + Element RandomElement(RandomNumberGenerator &rng, int ignored = 0) const + {CRYPTOPP_UNUSED(ignored); return rng.GenerateByte();} + + bool Equal(Element a, Element b) const + {return a==b;} + + Element Zero() const + {return 0;} + + Element Add(Element a, Element b) const + {return a^b;} + + Element& Accumulate(Element &a, Element b) const + {return a^=b;} + + Element Inverse(Element a) const + {return a;} + + Element Subtract(Element a, Element b) const + {return a^b;} + + Element& Reduce(Element &a, Element b) const + {return a^=b;} + + Element Double(Element a) const + {CRYPTOPP_UNUSED(a); return 0;} + + Element One() const + {return 1;} + + Element Multiply(Element a, Element b) const; + + Element Square(Element a) const + {return Multiply(a, a);} + + bool IsUnit(Element a) const + {return a != 0;} + + Element MultiplicativeInverse(Element a) const; + + Element Divide(Element a, Element b) const + {return Multiply(a, MultiplicativeInverse(b));} + +private: + word m_modulus; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gf2_32.cpp b/external/ours/library/crypto/src/shared/original/gf2_32.cpp new file mode 100755 index 000000000..51d10a49d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf2_32.cpp @@ -0,0 +1,99 @@ +// gf2_32.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "misc.h" +#include "gf2_32.h" + +NAMESPACE_BEGIN(CryptoPP) + +GF2_32::Element GF2_32::Multiply(Element a, Element b) const +{ + word32 table[4]; + table[0] = 0; + table[1] = m_modulus; + if (a & 0x80000000) + { + table[2] = m_modulus ^ (a<<1); + table[3] = a<<1; + } + else + { + table[2] = a<<1; + table[3] = m_modulus ^ (a<<1); + } + +#if CRYPTOPP_FAST_ROTATE(32) + b = rotrConstant<30>(b); + word32 result = table[b&2]; + + for (int i=29; i>=0; --i) + { + b = rotlConstant<1>(b); + result = (result<<1) ^ table[(b&2) + (result>>31)]; + } + + return (b&1) ? result ^ a : result; +#else + word32 result = table[(b>>30) & 2]; + + for (int i=29; i>=0; --i) + result = (result<<1) ^ table[((b>>i)&2) + (result>>31)]; + + return (b&1) ? result ^ a : result; +#endif +} + +GF2_32::Element GF2_32::MultiplicativeInverse(Element a) const +{ + if (a <= 1) // 1 is a special case + return a; + + // warning - don't try to adapt this algorithm for another situation + word32 g0=m_modulus, g1=a, g2=a; + word32 v0=0, v1=1, v2=1; + + CRYPTOPP_ASSERT(g1); + + while (!(g2 & 0x80000000)) + { + g2 <<= 1; + v2 <<= 1; + } + + g2 <<= 1; + v2 <<= 1; + + g0 ^= g2; + v0 ^= v2; + + while (g0 != 1) + { + if (g1 < g0 || ((g0^g1) < g0 && (g0^g1) < g1)) + { + CRYPTOPP_ASSERT(BitPrecision(g1) <= BitPrecision(g0)); + g2 = g1; + v2 = v1; + } + else + { + CRYPTOPP_ASSERT(BitPrecision(g1) > BitPrecision(g0)); + g2 = g0; g0 = g1; g1 = g2; + v2 = v0; v0 = v1; v1 = v2; + } + + while ((g0^g2) >= g2) + { + CRYPTOPP_ASSERT(BitPrecision(g0) > BitPrecision(g2)); + g2 <<= 1; + v2 <<= 1; + } + + CRYPTOPP_ASSERT(BitPrecision(g0) == BitPrecision(g2)); + g0 ^= g2; + v0 ^= v2; + } + + return v0; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/gf2_32.h b/external/ours/library/crypto/src/shared/original/gf2_32.h new file mode 100755 index 000000000..f0d229dff --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf2_32.h @@ -0,0 +1,73 @@ +// gf2_32.h - originally written and placed in the public domain by Wei Dai + +/// \file gf2_32.h +/// \brief Classes and functions for schemes over GF(2^32) + +#ifndef CRYPTOPP_GF2_32_H +#define CRYPTOPP_GF2_32_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief GF(2^32) with polynomial basis +class GF2_32 +{ +public: + typedef word32 Element; + typedef int RandomizationParameter; + + GF2_32(word32 modulus=0x0000008D) : m_modulus(modulus) {} + + Element RandomElement(RandomNumberGenerator &rng, int ignored = 0) const + {CRYPTOPP_UNUSED(ignored); return rng.GenerateWord32();} + + bool Equal(Element a, Element b) const + {return a==b;} + + Element Identity() const + {return 0;} + + Element Add(Element a, Element b) const + {return a^b;} + + Element& Accumulate(Element &a, Element b) const + {return a^=b;} + + Element Inverse(Element a) const + {return a;} + + Element Subtract(Element a, Element b) const + {return a^b;} + + Element& Reduce(Element &a, Element b) const + {return a^=b;} + + Element Double(Element a) const + {CRYPTOPP_UNUSED(a); return 0;} + + Element MultiplicativeIdentity() const + {return 1;} + + Element Multiply(Element a, Element b) const; + + Element Square(Element a) const + {return Multiply(a, a);} + + bool IsUnit(Element a) const + {return a != 0;} + + Element MultiplicativeInverse(Element a) const; + + Element Divide(Element a, Element b) const + {return Multiply(a, MultiplicativeInverse(b));} + +private: + word32 m_modulus; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gf2n.cpp b/external/ours/library/crypto/src/shared/original/gf2n.cpp new file mode 100755 index 000000000..452e69825 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf2n.cpp @@ -0,0 +1,1070 @@ +// gf2n.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cryptlib.h" +#include "algebra.h" +#include "randpool.h" +#include "filters.h" +#include "smartptr.h" +#include "words.h" +#include "misc.h" +#include "gf2n.h" +#include "oids.h" +#include "asn.h" +#include "cpu.h" + +#include + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::PolynomialMod2; + +#if defined(HAVE_GCC_INIT_PRIORITY) + const PolynomialMod2 g_zero __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 60))) = PolynomialMod2(); + const PolynomialMod2 g_one __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 61))) = PolynomialMod2(1); +#elif defined(HAVE_MSC_INIT_PRIORITY) + #pragma warning(disable: 4075) + #pragma init_seg(".CRT$XCU") + const PolynomialMod2 g_zero; + const PolynomialMod2 g_one(1); + #pragma warning(default: 4075) +#elif defined(HAVE_XLC_INIT_PRIORITY) + #pragma priority(290) + const PolynomialMod2 g_zero; + const PolynomialMod2 g_one(1); +#endif + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_CLMUL_AVAILABLE) +extern CRYPTOPP_DLL void GF2NT_233_Multiply_Reduce_CLMUL(const word* pA, const word* pB, word* pC); +extern CRYPTOPP_DLL void GF2NT_233_Square_Reduce_CLMUL(const word* pA, word* pC); +#endif + +#if (CRYPTOPP_ARM_PMULL_AVAILABLE) +extern void GF2NT_233_Multiply_Reduce_ARMv8(const word* pA, const word* pB, word* pC); +extern void GF2NT_233_Square_Reduce_ARMv8(const word* pA, word* pC); +#endif + +#if (CRYPTOPP_POWER8_VMULL_AVAILABLE) && 0 +extern void GF2NT_233_Multiply_Reduce_POWER8(const word* pA, const word* pB, word* pC); +extern void GF2NT_233_Square_Reduce_POWER8(const word* pA, word* pC); +#endif + +PolynomialMod2::PolynomialMod2() +{ +} + +PolynomialMod2::PolynomialMod2(word value, size_t bitLength) + : reg(BitsToWords(bitLength)) +{ + CRYPTOPP_ASSERT(value==0 || reg.size()>0); + + if (reg.size() > 0) + { + reg[0] = value; + SetWords(reg+1, 0, reg.size()-1); + } +} + +PolynomialMod2::PolynomialMod2(const PolynomialMod2& t) + : reg(t.reg.size()) +{ + CopyWords(reg, t.reg, reg.size()); +} + +void PolynomialMod2::Randomize(RandomNumberGenerator &rng, size_t nbits) +{ + const size_t nbytes = nbits/8 + 1; + SecByteBlock buf(nbytes); + rng.GenerateBlock(buf, nbytes); + buf[0] = (byte)Crop(buf[0], nbits % 8); + Decode(buf, nbytes); +} + +PolynomialMod2 PolynomialMod2::AllOnes(size_t bitLength) +{ + PolynomialMod2 result((word)0, bitLength); + SetWords(result.reg, ~(word(0)), result.reg.size()); + if (bitLength%WORD_BITS) + result.reg[result.reg.size()-1] = (word)Crop(result.reg[result.reg.size()-1], bitLength%WORD_BITS); + return result; +} + +void PolynomialMod2::SetBit(size_t n, int value) +{ + if (value) + { + reg.CleanGrow(n/WORD_BITS + 1); + reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS)); + } + else + { + if (n/WORD_BITS < reg.size()) + reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS)); + } +} + +byte PolynomialMod2::GetByte(size_t n) const +{ + if (n/WORD_SIZE >= reg.size()) + return 0; + else + return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8)); +} + +void PolynomialMod2::SetByte(size_t n, byte value) +{ + reg.CleanGrow(BytesToWords(n+1)); + reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE)); + reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE)); +} + +PolynomialMod2 PolynomialMod2::Monomial(size_t i) +{ + PolynomialMod2 r((word)0, i+1); + r.SetBit(i); + return r; +} + +PolynomialMod2 PolynomialMod2::Trinomial(size_t t0, size_t t1, size_t t2) +{ + PolynomialMod2 r((word)0, t0+1); + r.SetBit(t0); + r.SetBit(t1); + r.SetBit(t2); + return r; +} + +PolynomialMod2 PolynomialMod2::Pentanomial(size_t t0, size_t t1, size_t t2, size_t t3, size_t t4) +{ + PolynomialMod2 r((word)0, t0+1); + r.SetBit(t0); + r.SetBit(t1); + r.SetBit(t2); + r.SetBit(t3); + r.SetBit(t4); + return r; +} + +template +struct NewPolynomialMod2 +{ + PolynomialMod2 * operator()() const + { + return new PolynomialMod2(i); + } +}; + +const PolynomialMod2 &PolynomialMod2::Zero() +{ +#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) + return g_zero; +#elif defined(CRYPTOPP_CXX11_STATIC_INIT) + static const PolynomialMod2 g_zero; + return g_zero; +#else + return Singleton().Ref(); +#endif +} + +const PolynomialMod2 &PolynomialMod2::One() +{ +#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) + return g_one; +#elif defined(CRYPTOPP_CXX11_STATIC_INIT) + static const PolynomialMod2 g_one(1); + return g_one; +#else + return Singleton >().Ref(); +#endif +} + +void PolynomialMod2::Decode(const byte *input, size_t inputLen) +{ + StringStore store(input, inputLen); + Decode(store, inputLen); +} + +void PolynomialMod2::Encode(byte *output, size_t outputLen) const +{ + ArraySink sink(output, outputLen); + Encode(sink, outputLen); +} + +void PolynomialMod2::Decode(BufferedTransformation &bt, size_t inputLen) +{ + CRYPTOPP_ASSERT(bt.MaxRetrievable() >= inputLen); + if (bt.MaxRetrievable() < inputLen) + throw InvalidArgument("PolynomialMod2: input length is too small"); + + reg.CleanNew(BytesToWords(inputLen)); + + for (size_t i=inputLen; i > 0; i--) + { + byte b; + (void)bt.Get(b); + reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; + } +} + +void PolynomialMod2::Encode(BufferedTransformation &bt, size_t outputLen) const +{ + for (size_t i=outputLen; i > 0; i--) + bt.Put(GetByte(i-1)); +} + +void PolynomialMod2::DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const +{ + DERGeneralEncoder enc(bt, OCTET_STRING); + Encode(enc, length); + enc.MessageEnd(); +} + +void PolynomialMod2::BERDecodeAsOctetString(BufferedTransformation &bt, size_t length) +{ + BERGeneralDecoder dec(bt, OCTET_STRING); + if (!dec.IsDefiniteLength() || dec.RemainingLength() != length) + BERDecodeError(); + Decode(dec, length); + dec.MessageEnd(); +} + +unsigned int PolynomialMod2::WordCount() const +{ + return (unsigned int)CountWords(reg, reg.size()); +} + +unsigned int PolynomialMod2::ByteCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]); + else + return 0; +} + +unsigned int PolynomialMod2::BitCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]); + else + return 0; +} + +unsigned int PolynomialMod2::Parity() const +{ + unsigned i; + word temp=0; + for (i=0; i= reg.size()) + { + PolynomialMod2 result((word)0, b.reg.size()*WORD_BITS); + XorWords(result.reg, reg, b.reg, reg.size()); + CopyWords(result.reg+reg.size(), b.reg+reg.size(), b.reg.size()-reg.size()); + return result; + } + else + { + PolynomialMod2 result((word)0, reg.size()*WORD_BITS); + XorWords(result.reg, reg, b.reg, b.reg.size()); + CopyWords(result.reg+b.reg.size(), reg+b.reg.size(), reg.size()-b.reg.size()); + return result; + } +} + +PolynomialMod2 PolynomialMod2::And(const PolynomialMod2 &b) const +{ + PolynomialMod2 result((word)0, WORD_BITS*STDMIN(reg.size(), b.reg.size())); + AndWords(result.reg, reg, b.reg, result.reg.size()); + return result; +} + +PolynomialMod2 PolynomialMod2::Times(const PolynomialMod2 &b) const +{ + PolynomialMod2 result((word)0, BitCount() + b.BitCount()); + + for (int i=b.Degree(); i>=0; i--) + { + result <<= 1; + if (b[i]) + XorWords(result.reg, reg, reg.size()); + } + return result; +} + +PolynomialMod2 PolynomialMod2::Squared() const +{ + static const word map[16] = {0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84, 85}; + + PolynomialMod2 result((word)0, 2*reg.size()*WORD_BITS); + + for (unsigned i=0; i> (j/2)) % 16] << j; + + for (j=0; j> (j/2 + WORD_BITS/2)) % 16] << j; + } + + return result; +} + +void PolynomialMod2::Divide(PolynomialMod2 &remainder, PolynomialMod2 "ient, + const PolynomialMod2 ÷nd, const PolynomialMod2 &divisor) +{ + if (!divisor) + throw PolynomialMod2::DivideByZero(); + + int degree = divisor.Degree(); + remainder.reg.CleanNew(BitsToWords(degree+1)); + if (dividend.BitCount() >= divisor.BitCount()) + quotient.reg.CleanNew(BitsToWords(dividend.BitCount() - divisor.BitCount() + 1)); + else + quotient.reg.CleanNew(0); + + for (int i=dividend.Degree(); i>=0; i--) + { + remainder <<= 1; + remainder.reg[0] |= dividend[i]; + if (remainder[degree]) + { + remainder -= divisor; + quotient.SetBit(i); + } + } +} + +PolynomialMod2 PolynomialMod2::DividedBy(const PolynomialMod2 &b) const +{ + PolynomialMod2 remainder, quotient; + PolynomialMod2::Divide(remainder, quotient, *this, b); + return quotient; +} + +PolynomialMod2 PolynomialMod2::Modulo(const PolynomialMod2 &b) const +{ + PolynomialMod2 remainder, quotient; + PolynomialMod2::Divide(remainder, quotient, *this, b); + return remainder; +} + +PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n) +{ +#if defined(CRYPTOPP_DEBUG) + int x=0; CRYPTOPP_UNUSED(x); + CRYPTOPP_ASSERT(SafeConvert(n,x)); +#endif + + if (!reg.size()) + return *this; + + int i; + word u; + word carry=0; + word *r=reg; + + if (n==1) // special case code for most frequent case + { + i = (int)reg.size(); + while (i--) + { + u = *r; + *r = (u << 1) | carry; + carry = u >> (WORD_BITS-1); + r++; + } + + if (carry) + { + reg.Grow(reg.size()+1); + reg[reg.size()-1] = carry; + } + + return *this; + } + + const int shiftWords = n / WORD_BITS; + const int shiftBits = n % WORD_BITS; + + if (shiftBits) + { + i = (int)reg.size(); + while (i--) + { + u = *r; + *r = (u << shiftBits) | carry; + carry = u >> (WORD_BITS-shiftBits); + r++; + } + } + + if (carry) + { + // Thanks to Apatryda, http://github.com/weidai11/cryptopp/issues/64 + const size_t carryIndex = reg.size(); + reg.Grow(reg.size()+shiftWords+!!shiftBits); + reg[carryIndex] = carry; + } + else + reg.Grow(reg.size()+shiftWords); + + if (shiftWords) + { + for (i = (int)reg.size()-1; i>=shiftWords; i--) + reg[i] = reg[i-shiftWords]; + for (; i>=0; i--) + reg[i] = 0; + } + + return *this; +} + +PolynomialMod2& PolynomialMod2::operator>>=(unsigned int n) +{ + if (!reg.size()) + return *this; + + int shiftWords = n / WORD_BITS; + int shiftBits = n % WORD_BITS; + + size_t i; + word u; + word carry=0; + word *r=reg+reg.size()-1; + + if (shiftBits) + { + i = reg.size(); + while (i--) + { + u = *r; + *r = (u >> shiftBits) | carry; + carry = u << (WORD_BITS-shiftBits); + r--; + } + } + + if (shiftWords) + { + for (i=0; i>(unsigned int n) const +{ + PolynomialMod2 result(*this); + return result>>=n; +} + +bool PolynomialMod2::operator!() const +{ + for (unsigned i=0; i s(a.BitCount()/bits+1); + unsigned i; + + static const char upper[]="0123456789ABCDEF"; + static const char lower[]="0123456789abcdef"; + const char* const vec = (out.flags() & std::ios::uppercase) ? upper : lower; + + for (i=0; i*bits < a.BitCount(); i++) + { + int digit=0; + for (int j=0; j().Gcd(a, b); +} + +PolynomialMod2 PolynomialMod2::InverseMod(const PolynomialMod2 &modulus) const +{ + typedef EuclideanDomainOf Domain; + return QuotientRing(Domain(), modulus).MultiplicativeInverse(*this); +} + +bool PolynomialMod2::IsIrreducible() const +{ + signed int d = Degree(); + if (d <= 0) + return false; + + PolynomialMod2 t(2), u(t); + for (int i=1; i<=d/2; i++) + { + u = u.Squared()%(*this); + if (!Gcd(u+t, *this).IsUnit()) + return false; + } + return true; +} + +// ******************************************************** + +GF2NP::GF2NP(const PolynomialMod2 &modulus) + : QuotientRing >(EuclideanDomainOf(), modulus), m(modulus.Degree()) +{ +} + +GF2NP::Element GF2NP::SquareRoot(const Element &a) const +{ + Element r = a; + for (unsigned int i=1; i c1 && c1 > c2 && c2==0); +} + +const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const +{ + if (t0-t1 < WORD_BITS) + return GF2NP::MultiplicativeInverse(a); + + SecWordBlock T(m_modulus.reg.size() * 4); + word *b = T; + word *c = T+m_modulus.reg.size(); + word *f = T+2*m_modulus.reg.size(); + word *g = T+3*m_modulus.reg.size(); + size_t bcLen=1, fgLen=m_modulus.reg.size(); + unsigned int k=0; + + SetWords(T, 0, 3*m_modulus.reg.size()); + b[0]=1; + CRYPTOPP_ASSERT(a.reg.size() <= m_modulus.reg.size()); + CopyWords(f, a.reg, a.reg.size()); + CopyWords(g, m_modulus.reg, m_modulus.reg.size()); + + while (1) + { + word t=f[0]; + while (!t) + { + ShiftWordsRightByWords(f, fgLen, 1); + if (c[bcLen-1]) + bcLen++; + CRYPTOPP_ASSERT(bcLen <= m_modulus.reg.size()); + ShiftWordsLeftByWords(c, bcLen, 1); + k+=WORD_BITS; + t=f[0]; + } + + unsigned int i=0; + while (t%2 == 0) + { + t>>=1; + i++; + } + k+=i; + + if (t==1 && CountWords(f, fgLen)==1) + break; + + if (i==1) + { + ShiftWordsRightByBits(f, fgLen, 1); + t=ShiftWordsLeftByBits(c, bcLen, 1); + } + else + { + ShiftWordsRightByBits(f, fgLen, i); + t=ShiftWordsLeftByBits(c, bcLen, i); + } + if (t) + { + c[bcLen] = t; + bcLen++; + CRYPTOPP_ASSERT(bcLen <= m_modulus.reg.size()); + } + + if (f[fgLen-1]==0 && g[fgLen-1]==0) + fgLen--; + + if (f[fgLen-1] < g[fgLen-1]) + { + std::swap(f, g); + std::swap(b, c); + } + + XorWords(f, g, fgLen); + XorWords(b, c, bcLen); + } + + while (k >= WORD_BITS) + { + word temp = b[0]; + // right shift b + for (unsigned i=0; i+1> j) & 1) << (t1 + j); + const unsigned int shift = t1 + j; + CRYPTOPP_ASSERT(shift < WORD_BITS); + temp ^= (shift < WORD_BITS) ? (((temp >> j) & 1) << shift) : 0; + } + else + b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; + + if (t1 % WORD_BITS) + b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS); + + if (t0%WORD_BITS) + { + b[t0/WORD_BITS-1] ^= temp << t0%WORD_BITS; + b[t0/WORD_BITS] ^= temp >> (WORD_BITS - t0%WORD_BITS); + } + else + b[t0/WORD_BITS-1] ^= temp; + + k -= WORD_BITS; + } + + if (k) + { + word temp = b[0] << (WORD_BITS - k); + ShiftWordsRightByBits(b, BitsToWords(m), k); + + if (t1 < WORD_BITS) + { + for (unsigned int j=0; j> j) & 1) << (t1 + j); + const unsigned int shift = t1 + j; + CRYPTOPP_ASSERT(shift < WORD_BITS); + temp ^= (shift < WORD_BITS) ? (((temp >> j) & 1) << shift) : 0; + } + } + else + { + b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; + } + + if (t1 % WORD_BITS) + b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS); + + if (t0%WORD_BITS) + { + b[t0/WORD_BITS-1] ^= temp << t0%WORD_BITS; + b[t0/WORD_BITS] ^= temp >> (WORD_BITS - t0%WORD_BITS); + } + else + b[t0/WORD_BITS-1] ^= temp; + } + + CopyWords(result.reg.begin(), b, result.reg.size()); + return result; +} + +const GF2NT::Element& GF2NT::Multiply(const Element &a, const Element &b) const +{ + size_t aSize = STDMIN(a.reg.size(), result.reg.size()); + Element r((word)0, m); + + for (int i=m-1; i>=0; i--) + { + if (r[m-1]) + { + ShiftWordsLeftByBits(r.reg.begin(), r.reg.size(), 1); + XorWords(r.reg.begin(), m_modulus.reg, r.reg.size()); + } + else + ShiftWordsLeftByBits(r.reg.begin(), r.reg.size(), 1); + + if (b[i]) + XorWords(r.reg.begin(), a.reg, aSize); + } + + if (m%WORD_BITS) + r.reg.begin()[r.reg.size()-1] = (word)Crop(r.reg[r.reg.size()-1], m%WORD_BITS); + + CopyWords(result.reg.begin(), r.reg.begin(), result.reg.size()); + return result; +} + +const GF2NT::Element& GF2NT::Reduced(const Element &a) const +{ + if (t0-t1 < WORD_BITS) + return m_domain.Mod(a, m_modulus); + + SecWordBlock b(a.reg); + + size_t i; + for (i=b.size()-1; i>=BitsToWords(t0); i--) + { + word temp = b[i]; + + if (t0%WORD_BITS) + { + b[i-t0/WORD_BITS] ^= temp >> t0%WORD_BITS; + b[i-t0/WORD_BITS-1] ^= temp << (WORD_BITS - t0%WORD_BITS); + } + else + b[i-t0/WORD_BITS] ^= temp; + + if ((t0-t1)%WORD_BITS) + { + b[i-(t0-t1)/WORD_BITS] ^= temp >> (t0-t1)%WORD_BITS; + b[i-(t0-t1)/WORD_BITS-1] ^= temp << (WORD_BITS - (t0-t1)%WORD_BITS); + } + else + b[i-(t0-t1)/WORD_BITS] ^= temp; + } + + if (i==BitsToWords(t0)-1 && t0%WORD_BITS) + { + word mask = ((word)1<<(t0%WORD_BITS))-1; + word temp = b[i] & ~mask; + b[i] &= mask; + + b[i-t0/WORD_BITS] ^= temp >> t0%WORD_BITS; + + if ((t0-t1)%WORD_BITS) + { + b[i-(t0-t1)/WORD_BITS] ^= temp >> (t0-t1)%WORD_BITS; + if ((t0-t1)%WORD_BITS > t0%WORD_BITS) + b[i-(t0-t1)/WORD_BITS-1] ^= temp << (WORD_BITS - (t0-t1)%WORD_BITS); + else + CRYPTOPP_ASSERT(temp << (WORD_BITS - (t0-t1)%WORD_BITS) == 0); + } + else + b[i-(t0-t1)/WORD_BITS] ^= temp; + } + + SetWords(result.reg.begin(), 0, result.reg.size()); + CopyWords(result.reg.begin(), b, STDMIN(b.size(), result.reg.size())); + return result; +} + +void GF2NP::DEREncodeElement(BufferedTransformation &out, const Element &a) const +{ + a.DEREncodeAsOctetString(out, MaxElementByteLength()); +} + +void GF2NP::BERDecodeElement(BufferedTransformation &in, Element &a) const +{ + a.BERDecodeAsOctetString(in, MaxElementByteLength()); +} + +void GF2NT::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + ASN1::characteristic_two_field().DEREncode(seq); + DERSequenceEncoder parameters(seq); + DEREncodeUnsigned(parameters, m); + ASN1::tpBasis().DEREncode(parameters); + DEREncodeUnsigned(parameters, t1); + parameters.MessageEnd(); + seq.MessageEnd(); +} + +void GF2NPP::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + ASN1::characteristic_two_field().DEREncode(seq); + DERSequenceEncoder parameters(seq); + DEREncodeUnsigned(parameters, m); + ASN1::ppBasis().DEREncode(parameters); + DERSequenceEncoder pentanomial(parameters); + DEREncodeUnsigned(pentanomial, t3); + DEREncodeUnsigned(pentanomial, t2); + DEREncodeUnsigned(pentanomial, t1); + pentanomial.MessageEnd(); + parameters.MessageEnd(); + seq.MessageEnd(); +} + +GF2NP * BERDecodeGF2NP(BufferedTransformation &bt) +{ + member_ptr result; + + BERSequenceDecoder seq(bt); + if (OID(seq) != ASN1::characteristic_two_field()) + BERDecodeError(); + BERSequenceDecoder parameters(seq); + unsigned int m; + BERDecodeUnsigned(parameters, m); + OID oid(parameters); + if (oid == ASN1::tpBasis()) + { + unsigned int t1; + BERDecodeUnsigned(parameters, t1); + result.reset(new GF2NT(m, t1, 0)); + } + else if (oid == ASN1::ppBasis()) + { + unsigned int t1, t2, t3; + BERSequenceDecoder pentanomial(parameters); + BERDecodeUnsigned(pentanomial, t3); + BERDecodeUnsigned(pentanomial, t2); + BERDecodeUnsigned(pentanomial, t1); + pentanomial.MessageEnd(); + result.reset(new GF2NPP(m, t3, t2, t1, 0)); + } + else + { + BERDecodeError(); + return NULLPTR; + } + parameters.MessageEnd(); + seq.MessageEnd(); + + return result.release(); +} + +// ******************************************************** + +GF2NT233::GF2NT233(unsigned int c0, unsigned int c1, unsigned int c2) + : GF2NT(c0, c1, c2) +{ + CRYPTOPP_ASSERT(c0 > c1 && c1 > c2 && c2==0); +} + +const GF2NT::Element& GF2NT233::Multiply(const Element &a, const Element &b) const +{ +#if (CRYPTOPP_CLMUL_AVAILABLE) + if (HasCLMUL()) + { + CRYPTOPP_ASSERT(a.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(b.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(result.reg.size()*WORD_BITS == 256); + + const word* pA = a.reg.begin(); + const word* pB = b.reg.begin(); + word* pR = result.reg.begin(); + + GF2NT_233_Multiply_Reduce_CLMUL(pA, pB, pR); + return result; + } + else +#elif (CRYPTOPP_ARM_PMULL_AVAILABLE) + if (HasPMULL()) + { + CRYPTOPP_ASSERT(a.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(b.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(result.reg.size()*WORD_BITS == 256); + + const word* pA = a.reg.begin(); + const word* pB = b.reg.begin(); + word* pR = result.reg.begin(); + + GF2NT_233_Multiply_Reduce_ARMv8(pA, pB, pR); + return result; + } + else +#elif (CRYPTOPP_POWER8_VMULL_AVAILABLE) && 0 + if (HasPMULL()) + { + CRYPTOPP_ASSERT(a.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(b.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(result.reg.size()*WORD_BITS == 256); + + const word* pA = a.reg.begin(); + const word* pB = b.reg.begin(); + word* pR = result.reg.begin(); + + GF2NT_233_Multiply_Reduce_POWER8(pA, pB, pR); + return result; + } + else +#endif + + return GF2NT::Multiply(a, b); +} + +const GF2NT::Element& GF2NT233::Square(const Element &a) const +{ +#if (CRYPTOPP_CLMUL_AVAILABLE) + if (HasCLMUL()) + { + CRYPTOPP_ASSERT(a.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(result.reg.size()*WORD_BITS == 256); + + const word* pA = a.reg.begin(); + word* pR = result.reg.begin(); + + GF2NT_233_Square_Reduce_CLMUL(pA, pR); + return result; + } + else +#elif (CRYPTOPP_ARM_PMULL_AVAILABLE) + if (HasPMULL()) + { + CRYPTOPP_ASSERT(a.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(result.reg.size()*WORD_BITS == 256); + + const word* pA = a.reg.begin(); + word* pR = result.reg.begin(); + + GF2NT_233_Square_Reduce_ARMv8(pA, pR); + return result; + } + else +#elif (CRYPTOPP_POWER8_VMULL_AVAILABLE) && 0 + if (HasPMULL()) + { + CRYPTOPP_ASSERT(a.reg.size()*WORD_BITS == 256); + CRYPTOPP_ASSERT(result.reg.size()*WORD_BITS == 256); + + const word* pA = a.reg.begin(); + word* pR = result.reg.begin(); + + GF2NT_233_Square_Reduce_POWER8(pA, pR); + return result; + } + else +#endif + + return GF2NT::Square(a); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gf2n.h b/external/ours/library/crypto/src/shared/original/gf2n.h new file mode 100755 index 000000000..86cf3b4c0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf2n.h @@ -0,0 +1,404 @@ +// gf2n.h - originally written and placed in the public domain by Wei Dai + +/// \file gf2n.h +/// \brief Classes and functions for schemes over GF(2^n) + +#ifndef CRYPTOPP_GF2N_H +#define CRYPTOPP_GF2N_H + +#include "cryptlib.h" +#include "secblock.h" +#include "algebra.h" +#include "misc.h" +#include "asn.h" + +#include + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Polynomial with Coefficients in GF(2) +/*! \nosubgrouping */ +class CRYPTOPP_DLL PolynomialMod2 +{ +public: + /// \name ENUMS, EXCEPTIONS, and TYPEDEFS + //@{ + /// \brief Excpetion thrown when divide by zero is encountered + class DivideByZero : public Exception + { + public: + DivideByZero() : Exception(OTHER_ERROR, "PolynomialMod2: division by zero") {} + }; + + typedef unsigned int RandomizationParameter; + //@} + + /// \name CREATORS + //@{ + /// \brief Construct the zero polynomial + PolynomialMod2(); + /// Copy construct a PolynomialMod2 + PolynomialMod2(const PolynomialMod2& t); + + /// \brief Construct a PolynomialMod2 from a word + /// \details value should be encoded with the least significant bit as coefficient to x^0 + /// and most significant bit as coefficient to x^(WORD_BITS-1) + /// bitLength denotes how much memory to allocate initially + PolynomialMod2(word value, size_t bitLength=WORD_BITS); + + /// \brief Construct a PolynomialMod2 from big-endian byte array + PolynomialMod2(const byte *encodedPoly, size_t byteCount) + {Decode(encodedPoly, byteCount);} + + /// \brief Construct a PolynomialMod2 from big-endian form stored in a BufferedTransformation + PolynomialMod2(BufferedTransformation &encodedPoly, size_t byteCount) + {Decode(encodedPoly, byteCount);} + + /// \brief Create a uniformly distributed random polynomial + /// \details Create a random polynomial uniformly distributed over all polynomials with degree less than bitcount + PolynomialMod2(RandomNumberGenerator &rng, size_t bitcount) + {Randomize(rng, bitcount);} + + /// \brief Provides x^i + /// \return x^i + static PolynomialMod2 CRYPTOPP_API Monomial(size_t i); + /// \brief Provides x^t0 + x^t1 + x^t2 + /// \return x^t0 + x^t1 + x^t2 + static PolynomialMod2 CRYPTOPP_API Trinomial(size_t t0, size_t t1, size_t t2); + /// \brief Provides x^t0 + x^t1 + x^t2 + x^t3 + x^t4 + /// \return x^t0 + x^t1 + x^t2 + x^t3 + x^t4 + static PolynomialMod2 CRYPTOPP_API Pentanomial(size_t t0, size_t t1, size_t t2, size_t t3, size_t t4); + /// \brief Provides x^(n-1) + ... + x + 1 + /// \return x^(n-1) + ... + x + 1 + static PolynomialMod2 CRYPTOPP_API AllOnes(size_t n); + + /// \brief The Zero polinomial + /// \return the zero polynomial + static const PolynomialMod2 & CRYPTOPP_API Zero(); + /// \brief The One polinomial + /// \return the one polynomial + static const PolynomialMod2 & CRYPTOPP_API One(); + //@} + + /// \name ENCODE/DECODE + //@{ + /// minimum number of bytes to encode this polynomial + /*! MinEncodedSize of 0 is 1 */ + unsigned int MinEncodedSize() const {return STDMAX(1U, ByteCount());} + + /// encode in big-endian format + /// \details if outputLen < MinEncodedSize, the most significant bytes will be dropped + /// if outputLen > MinEncodedSize, the most significant bytes will be padded + void Encode(byte *output, size_t outputLen) const; + /// + void Encode(BufferedTransformation &bt, size_t outputLen) const; + + /// + void Decode(const byte *input, size_t inputLen); + /// + //* Precondition: bt.MaxRetrievable() >= inputLen + void Decode(BufferedTransformation &bt, size_t inputLen); + + /// encode value as big-endian octet string + void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const; + /// decode value as big-endian octet string + void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length); + //@} + + /// \name ACCESSORS + //@{ + /// number of significant bits = Degree() + 1 + unsigned int BitCount() const; + /// number of significant bytes = ceiling(BitCount()/8) + unsigned int ByteCount() const; + /// number of significant words = ceiling(ByteCount()/sizeof(word)) + unsigned int WordCount() const; + + /// return the n-th bit, n=0 being the least significant bit + bool GetBit(size_t n) const {return GetCoefficient(n)!=0;} + /// return the n-th byte + byte GetByte(size_t n) const; + + /// the zero polynomial will return a degree of -1 + signed int Degree() const {return (signed int)(BitCount()-1U);} + /// degree + 1 + unsigned int CoefficientCount() const {return BitCount();} + /// return coefficient for x^i + int GetCoefficient(size_t i) const + {return (i/WORD_BITS < reg.size()) ? int(reg[i/WORD_BITS] >> (i % WORD_BITS)) & 1 : 0;} + /// return coefficient for x^i + int operator[](unsigned int i) const {return GetCoefficient(i);} + + /// + bool IsZero() const {return !*this;} + /// + bool Equals(const PolynomialMod2 &rhs) const; + //@} + + /// \name MANIPULATORS + //@{ + /// + PolynomialMod2& operator=(const PolynomialMod2& t); + /// + PolynomialMod2& operator&=(const PolynomialMod2& t); + /// + PolynomialMod2& operator^=(const PolynomialMod2& t); + /// + PolynomialMod2& operator+=(const PolynomialMod2& t) {return *this ^= t;} + /// + PolynomialMod2& operator-=(const PolynomialMod2& t) {return *this ^= t;} + /// + PolynomialMod2& operator*=(const PolynomialMod2& t); + /// + PolynomialMod2& operator/=(const PolynomialMod2& t); + /// + PolynomialMod2& operator%=(const PolynomialMod2& t); + /// + PolynomialMod2& operator<<=(unsigned int); + /// + PolynomialMod2& operator>>=(unsigned int); + + /// + void Randomize(RandomNumberGenerator &rng, size_t bitcount); + + /// + void SetBit(size_t i, int value = 1); + /// set the n-th byte to value + void SetByte(size_t n, byte value); + + /// + void SetCoefficient(size_t i, int value) {SetBit(i, value);} + + /// + void swap(PolynomialMod2 &a) {reg.swap(a.reg);} + //@} + + /// \name UNARY OPERATORS + //@{ + /// + bool operator!() const; + /// + PolynomialMod2 operator+() const {return *this;} + /// + PolynomialMod2 operator-() const {return *this;} + //@} + + /// \name BINARY OPERATORS + //@{ + /// + PolynomialMod2 And(const PolynomialMod2 &b) const; + /// + PolynomialMod2 Xor(const PolynomialMod2 &b) const; + /// + PolynomialMod2 Plus(const PolynomialMod2 &b) const {return Xor(b);} + /// + PolynomialMod2 Minus(const PolynomialMod2 &b) const {return Xor(b);} + /// + PolynomialMod2 Times(const PolynomialMod2 &b) const; + /// + PolynomialMod2 DividedBy(const PolynomialMod2 &b) const; + /// + PolynomialMod2 Modulo(const PolynomialMod2 &b) const; + + /// + PolynomialMod2 operator>>(unsigned int n) const; + /// + PolynomialMod2 operator<<(unsigned int n) const; + //@} + + /// \name OTHER ARITHMETIC FUNCTIONS + //@{ + /// sum modulo 2 of all coefficients + unsigned int Parity() const; + + /// check for irreducibility + bool IsIrreducible() const; + + /// is always zero since we're working modulo 2 + PolynomialMod2 Doubled() const {return Zero();} + /// + PolynomialMod2 Squared() const; + + /// only 1 is a unit + bool IsUnit() const {return Equals(One());} + /// return inverse if *this is a unit, otherwise return 0 + PolynomialMod2 MultiplicativeInverse() const {return IsUnit() ? One() : Zero();} + + /// greatest common divisor + static PolynomialMod2 CRYPTOPP_API Gcd(const PolynomialMod2 &a, const PolynomialMod2 &n); + /// calculate multiplicative inverse of *this mod n + PolynomialMod2 InverseMod(const PolynomialMod2 &) const; + + /// calculate r and q such that (a == d*q + r) && (deg(r) < deg(d)) + static void CRYPTOPP_API Divide(PolynomialMod2 &r, PolynomialMod2 &q, const PolynomialMod2 &a, const PolynomialMod2 &d); + //@} + + /// \name INPUT/OUTPUT + //@{ + /// + friend std::ostream& operator<<(std::ostream& out, const PolynomialMod2 &a); + //@} + +private: + friend class GF2NT; + friend class GF2NT233; + + SecWordBlock reg; +}; + +/// +inline bool operator==(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Equals(b);} +/// +inline bool operator!=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return !(a==b);} +/// compares degree +inline bool operator> (const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() > b.Degree();} +/// compares degree +inline bool operator>=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() >= b.Degree();} +/// compares degree +inline bool operator< (const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() < b.Degree();} +/// compares degree +inline bool operator<=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() <= b.Degree();} +/// +inline CryptoPP::PolynomialMod2 operator&(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.And(b);} +/// +inline CryptoPP::PolynomialMod2 operator^(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Xor(b);} +/// +inline CryptoPP::PolynomialMod2 operator+(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Plus(b);} +/// +inline CryptoPP::PolynomialMod2 operator-(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Minus(b);} +/// +inline CryptoPP::PolynomialMod2 operator*(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Times(b);} +/// +inline CryptoPP::PolynomialMod2 operator/(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.DividedBy(b);} +/// +inline CryptoPP::PolynomialMod2 operator%(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Modulo(b);} + +// CodeWarrior 8 workaround: put these template instantiations after overloaded operator declarations, +// but before the use of QuotientRing > for VC .NET 2003 +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain; +CRYPTOPP_DLL_TEMPLATE_CLASS EuclideanDomainOf; +CRYPTOPP_DLL_TEMPLATE_CLASS QuotientRing >; + +/// \brief GF(2^n) with Polynomial Basis +class CRYPTOPP_DLL GF2NP : public QuotientRing > +{ +public: + GF2NP(const PolynomialMod2 &modulus); + + virtual GF2NP * Clone() const {return new GF2NP(*this);} + virtual void DEREncode(BufferedTransformation &bt) const + {CRYPTOPP_UNUSED(bt); CRYPTOPP_ASSERT(false);} // no ASN.1 syntax yet for general polynomial basis + + void DEREncodeElement(BufferedTransformation &out, const Element &a) const; + void BERDecodeElement(BufferedTransformation &in, Element &a) const; + + bool Equal(const Element &a, const Element &b) const + {CRYPTOPP_ASSERT(a.Degree() < m_modulus.Degree() && b.Degree() < m_modulus.Degree()); return a.Equals(b);} + + bool IsUnit(const Element &a) const + {CRYPTOPP_ASSERT(a.Degree() < m_modulus.Degree()); return !!a;} + + unsigned int MaxElementBitLength() const + {return m;} + + unsigned int MaxElementByteLength() const + {return (unsigned int)BitsToBytes(MaxElementBitLength());} + + Element SquareRoot(const Element &a) const; + + Element HalfTrace(const Element &a) const; + + // returns z such that z^2 + z == a + Element SolveQuadraticEquation(const Element &a) const; + +protected: + unsigned int m; +}; + +/// \brief GF(2^n) with Trinomial Basis +class CRYPTOPP_DLL GF2NT : public GF2NP +{ +public: + // polynomial modulus = x^t0 + x^t1 + x^t2, t0 > t1 > t2 + GF2NT(unsigned int t0, unsigned int t1, unsigned int t2); + + GF2NP * Clone() const {return new GF2NT(*this);} + void DEREncode(BufferedTransformation &bt) const; + + const Element& Multiply(const Element &a, const Element &b) const; + + const Element& Square(const Element &a) const + {return Reduced(a.Squared());} + + const Element& MultiplicativeInverse(const Element &a) const; + +protected: + const Element& Reduced(const Element &a) const; + + unsigned int t0, t1; + mutable PolynomialMod2 result; +}; + +/// \brief GF(2^n) for b233 and k233 +/// \details GF2NT233 is a specialization of GF2NT that provides Multiply() +/// and Square() operations when carryless multiplies is available. +class CRYPTOPP_DLL GF2NT233 : public GF2NT +{ +public: + // polynomial modulus = x^t0 + x^t1 + x^t2, t0 > t1 > t2 + GF2NT233(unsigned int t0, unsigned int t1, unsigned int t2); + + GF2NP * Clone() const {return new GF2NT233(*this);} + + const Element& Multiply(const Element &a, const Element &b) const; + + const Element& Square(const Element &a) const; +}; + +/// \brief GF(2^n) with Pentanomial Basis +class CRYPTOPP_DLL GF2NPP : public GF2NP +{ +public: + // polynomial modulus = x^t0 + x^t1 + x^t2 + x^t3 + x^t4, t0 > t1 > t2 > t3 > t4 + GF2NPP(unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4) + : GF2NP(PolynomialMod2::Pentanomial(t0, t1, t2, t3, t4)), t1(t1), t2(t2), t3(t3) {} + + GF2NP * Clone() const {return new GF2NPP(*this);} + void DEREncode(BufferedTransformation &bt) const; + +private: + unsigned int t1, t2, t3; +}; + +// construct new GF2NP from the ASN.1 sequence Characteristic-two +CRYPTOPP_DLL GF2NP * CRYPTOPP_API BERDecodeGF2NP(BufferedTransformation &bt); + +NAMESPACE_END + +#ifndef __BORLANDC__ +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::PolynomialMod2 &a, CryptoPP::PolynomialMod2 &b) +{ + a.swap(b); +} +NAMESPACE_END +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gf2n_simd.cpp b/external/ours/library/crypto/src/shared/original/gf2n_simd.cpp new file mode 100755 index 000000000..e65439848 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gf2n_simd.cpp @@ -0,0 +1,614 @@ +// gf2n_simd.cpp - written and placed in the public domain by Jeffrey Walton +// Also based on PCLMULQDQ code by Jankowski, Laurent and +// O'Mahony from Intel (see reference below). +// +// This source file uses intrinsics and built-ins to gain access to +// CLMUL, ARMv8a, and Power8 instructions. A separate source file is +// needed because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. +// +// Several speedups were taken from Intel Polynomial Multiplication +// Instruction and its Usage for Elliptic Curve Cryptography, by +// Krzysztof Jankowski, Pierre Laurent and Aidan O'Mahony, +// https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/polynomial-multiplication-instructions-paper.pdf +// There may be more speedups available, see https://eprint.iacr.org/2011/589.pdf. +// The IACR paper performs some optimizations that the compiler is +// expected to perform, like Common Subexpression Elimination to save +// on variables (among others). Note that the compiler may miss the +// optimization so the IACR paper is useful. However, the code is GPL3 +// and toxic for some users of the library, so it is not used here... + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "gf2n.h" + +#if (CRYPTOPP_CLMUL_AVAILABLE) +# include +# include +#endif + +#if (CRYPTOPP_ARM_PMULL_AVAILABLE) +# include "arm_simd.h" +#endif + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char GF2N_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +// ************************** ARMv8 ************************** // + +using CryptoPP::word; + +#if (CRYPTOPP_ARM_PMULL_AVAILABLE) + +// c1c0 = a * b +inline void +F2N_Multiply_128x128_ARMv8(uint64x2_t& c1, uint64x2_t& c0, const uint64x2_t& a, const uint64x2_t& b) +{ + uint64x2_t t1, t2, z0={0}; + + c0 = PMULL_00(a, b); + c1 = PMULL_11(a, b); + t1 = vmovq_n_u64(vgetq_lane_u64(a, 1)); + t1 = veorq_u64(a, t1); + t2 = vmovq_n_u64(vgetq_lane_u64(b, 1)); + t2 = veorq_u64(b, t2); + t1 = PMULL_00(t1, t2); + t1 = veorq_u64(c0, t1); + t1 = veorq_u64(c1, t1); + t2 = t1; + t1 = vextq_u64(z0, t1, 1); + t2 = vextq_u64(t2, z0, 1); + c0 = veorq_u64(c0, t1); + c1 = veorq_u64(c1, t2); +} + +// c3c2c1c0 = a1a0 * b1b0 +inline void +F2N_Multiply_256x256_ARMv8(uint64x2_t& c3, uint64x2_t& c2, uint64x2_t& c1, uint64x2_t& c0, + const uint64x2_t& b1, const uint64x2_t& b0, const uint64x2_t& a1, const uint64x2_t& a0) +{ + uint64x2_t c4, c5; + uint64x2_t x0=a0, x1=a1, y0=b0, y1=b1; + + F2N_Multiply_128x128_ARMv8(c1, c0, x0, y0); + F2N_Multiply_128x128_ARMv8(c3, c2, x1, y1); + + x0 = veorq_u64(x0, x1); + y0 = veorq_u64(y0, y1); + + F2N_Multiply_128x128_ARMv8(c5, c4, x0, y0); + + c4 = veorq_u64(c4, c0); + c4 = veorq_u64(c4, c2); + c5 = veorq_u64(c5, c1); + c5 = veorq_u64(c5, c3); + c1 = veorq_u64(c1, c4); + c2 = veorq_u64(c2, c5); +} + +// c3c2c1c0 = a1a0 * a1a0 +inline void +F2N_Square_256_ARMv8(uint64x2_t& c3, uint64x2_t& c2, uint64x2_t& c1, + uint64x2_t& c0, const uint64x2_t& a1, const uint64x2_t& a0) +{ + c0 = PMULL_00(a0, a0); + c1 = PMULL_11(a0, a0); + c2 = PMULL_00(a1, a1); + c3 = PMULL_11(a1, a1); +} + +// x = (x << n), z = 0 +template +inline uint64x2_t ShiftLeft128_ARMv8(uint64x2_t x) +{ + uint64x2_t u=x, v, z={0}; + x = vshlq_n_u64(x, N); + u = vshrq_n_u64(u, (64-N)); + v = vcombine_u64(vget_low_u64(z), vget_low_u64(u)); + x = vorrq_u64(x, v); + return x; +} + +// c1c0 = c3c2c1c0 MOD p. This is a Barrett reduction. Reading at +// Intel paper or https://github.com/antonblanchard/crc32-vpmsum. +inline void +GF2NT_233_Reduce_ARMv8(uint64x2_t& c3, uint64x2_t& c2, uint64x2_t& c1, uint64x2_t& c0) +{ + const unsigned int mask[4] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0x000001ff, + }; + + uint64x2_t b3, b2, b1, /*b0,*/ a1, a0, m0, z0={0}; + m0 = vreinterpretq_u64_u32(vld1q_u32(mask)); + b1 = c1; a1 = c1; + a0 = vcombine_u64(vget_low_u64(c1), vget_low_u64(z0)); + a1 = vshlq_n_u64(a1, 23); + a1 = vshrq_n_u64(a1, 23); + c1 = vorrq_u64(a1, a0); + b2 = vshrq_n_u64(c2, (64-23)); + c3 = ShiftLeft128_ARMv8<23>(c3); + a0 = vcombine_u64(vget_high_u64(b2), vget_high_u64(z0)); + c3 = vorrq_u64(c3, a0); + b1 = vshrq_n_u64(b1, (64-23)); + c2 = ShiftLeft128_ARMv8<23>(c2); + a0 = vcombine_u64(vget_high_u64(b1), vget_high_u64(z0)); + c2 = vorrq_u64(c2, a0); + b3 = c3; + b2 = vshrq_n_u64(c2, (64-10)); + b3 = ShiftLeft128_ARMv8<10>(b3); + a0 = vcombine_u64(vget_high_u64(b2), vget_high_u64(z0)); + b3 = vorrq_u64(b3, a0); + a0 = vcombine_u64(vget_high_u64(c3), vget_high_u64(z0)); + b3 = veorq_u64(b3, a0); + b1 = vshrq_n_u64(b3, (64-23)); + b3 = ShiftLeft128_ARMv8<23>(b3); + b3 = vcombine_u64(vget_high_u64(b3), vget_high_u64(z0)); + b3 = vorrq_u64(b3, b1); + c2 = veorq_u64(c2, b3); + b3 = c3; + b2 = vshrq_n_u64(c2, (64-10)); + b3 = ShiftLeft128_ARMv8<10>(b3); + b2 = vcombine_u64(vget_high_u64(b2), vget_high_u64(z0)); + b3 = vorrq_u64(b3, b2); + b2 = c2; + b2 = ShiftLeft128_ARMv8<10>(b2); + a0 = vcombine_u64(vget_low_u64(z0), vget_low_u64(b2)); + c2 = veorq_u64(c2, a0); + a0 = vcombine_u64(vget_low_u64(z0), vget_low_u64(b3)); + a1 = vcombine_u64(vget_high_u64(b2), vget_high_u64(z0)); + a0 = vorrq_u64(a0, a1); + c3 = veorq_u64(c3, a0); + c0 = veorq_u64(c0, c2); + c1 = veorq_u64(c1, c3); + c1 = vandq_u64(c1, m0); +} + +#endif + +// ************************** SSE ************************** // + +#if (CRYPTOPP_CLMUL_AVAILABLE) + +using CryptoPP::word; + +// c1c0 = a * b +inline void +F2N_Multiply_128x128_CLMUL(__m128i& c1, __m128i& c0, const __m128i& a, const __m128i& b) +{ + __m128i t1, t2; + + c0 = _mm_clmulepi64_si128(a, b, 0x00); + c1 = _mm_clmulepi64_si128(a, b, 0x11); + t1 = _mm_shuffle_epi32(a, 0xEE); + t1 = _mm_xor_si128(a, t1); + t2 = _mm_shuffle_epi32(b, 0xEE); + t2 = _mm_xor_si128(b, t2); + t1 = _mm_clmulepi64_si128(t1, t2, 0x00); + t1 = _mm_xor_si128(c0, t1); + t1 = _mm_xor_si128(c1, t1); + t2 = t1; + t1 = _mm_slli_si128(t1, 8); + t2 = _mm_srli_si128(t2, 8); + c0 = _mm_xor_si128(c0, t1); + c1 = _mm_xor_si128(c1, t2); +} + +// c3c2c1c0 = a1a0 * b1b0 +inline void +F2N_Multiply_256x256_CLMUL(__m128i& c3, __m128i& c2, __m128i& c1, __m128i& c0, + const __m128i& b1, const __m128i& b0, const __m128i& a1, const __m128i& a0) +{ + __m128i c4, c5; + __m128i x0=a0, x1=a1, y0=b0, y1=b1; + + F2N_Multiply_128x128_CLMUL(c1, c0, x0, y0); + F2N_Multiply_128x128_CLMUL(c3, c2, x1, y1); + + x0 = _mm_xor_si128(x0, x1); + y0 = _mm_xor_si128(y0, y1); + + F2N_Multiply_128x128_CLMUL(c5, c4, x0, y0); + + c4 = _mm_xor_si128(c4, c0); + c4 = _mm_xor_si128(c4, c2); + c5 = _mm_xor_si128(c5, c1); + c5 = _mm_xor_si128(c5, c3); + c1 = _mm_xor_si128(c1, c4); + c2 = _mm_xor_si128(c2, c5); +} + +// c3c2c1c0 = a1a0 * a1a0 +inline void +F2N_Square_256_CLMUL(__m128i& c3, __m128i& c2, __m128i& c1, + __m128i& c0, const __m128i& a1, const __m128i& a0) +{ + c0 = _mm_clmulepi64_si128(a0, a0, 0x00); + c1 = _mm_clmulepi64_si128(a0, a0, 0x11); + c2 = _mm_clmulepi64_si128(a1, a1, 0x00); + c3 = _mm_clmulepi64_si128(a1, a1, 0x11); +} + +// x = (x << n), z = 0 +template +inline __m128i ShiftLeft128_SSE(__m128i x, const __m128i& z) +{ + __m128i u=x, v; + x = _mm_slli_epi64(x, N); + u = _mm_srli_epi64(u, (64-N)); + v = _mm_unpacklo_epi64(z, u); + x = _mm_or_si128(x, v); + return x; +} + +// c1c0 = c3c2c1c0 MOD p. This is a Barrett reduction. Reading at +// Intel paper or https://github.com/antonblanchard/crc32-vpmsum. +inline void +GF2NT_233_Reduce_CLMUL(__m128i& c3, __m128i& c2, __m128i& c1, __m128i& c0) +{ + const unsigned int m[4] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0x000001ff + }; + + __m128i b3, b2, b1, /*b0,*/ a1, a0, m0, z0; + m0 = _mm_set_epi32(m[3], m[2], m[1], m[0]); + z0 = _mm_setzero_si128(); + b1 = c1; a1 = c1; + a0 = _mm_move_epi64(c1); + a1 = _mm_slli_epi64(a1, 23); + a1 = _mm_srli_epi64(a1, 23); + c1 = _mm_or_si128(a1, a0); + b2 = _mm_srli_epi64(c2, (64-23)); + c3 = ShiftLeft128_SSE<23>(c3, z0); + a0 = _mm_unpackhi_epi64(b2, z0); + c3 = _mm_or_si128(c3, a0); + b1 = _mm_srli_epi64(b1, (64-23)); + c2 = ShiftLeft128_SSE<23>(c2, z0); + a0 = _mm_unpackhi_epi64(b1, z0); + c2 = _mm_or_si128(c2, a0); + b3 = c3; + b2 = _mm_srli_epi64(c2, (64-10)); + b3 = ShiftLeft128_SSE<10>(b3, z0); + a0 = _mm_unpackhi_epi64(b2, z0); + b3 = _mm_or_si128(b3, a0); + a0 = _mm_unpackhi_epi64(c3, z0); + b3 = _mm_xor_si128(b3, a0); + b1 = _mm_srli_epi64(b3, (64-23)); + b3 = ShiftLeft128_SSE<23>(b3, z0); + b3 = _mm_unpackhi_epi64(b3, z0); + b3 = _mm_or_si128(b3, b1); + c2 = _mm_xor_si128(c2, b3); + b3 = c3; + b2 = _mm_srli_epi64(c2, (64-10)); + b3 = ShiftLeft128_SSE<10>(b3, z0); + b2 = _mm_unpackhi_epi64(b2, z0); + b3 = _mm_or_si128(b3, b2); + b2 = c2; + b2 = ShiftLeft128_SSE<10>(b2, z0); + a0 = _mm_unpacklo_epi64(z0, b2); + c2 = _mm_xor_si128(c2, a0); + a0 = _mm_unpacklo_epi64(z0, b3); + a1 = _mm_unpackhi_epi64(b2, z0); + a0 = _mm_or_si128(a0, a1); + c3 = _mm_xor_si128(c3, a0); + c0 = _mm_xor_si128(c0, c2); + c1 = _mm_xor_si128(c1, c3); + c1 = _mm_and_si128(c1, m0); +} + +#endif + +// ************************* Power8 ************************* // + +#if (CRYPTOPP_POWER8_VMULL_AVAILABLE) && 0 + +using CryptoPP::byte; +using CryptoPP::word; +using CryptoPP::uint8x16_p; +using CryptoPP::uint64x2_p; + +using CryptoPP::VecLoad; +using CryptoPP::VecStore; + +using CryptoPP::VecOr; +using CryptoPP::VecXor; +using CryptoPP::VecAnd; + +using CryptoPP::VecPermute; +using CryptoPP::VecMergeLow; +using CryptoPP::VecMergeHigh; +using CryptoPP::VecShiftLeft; +using CryptoPP::VecShiftRight; + +using CryptoPP::VecIntelMultiply00; +using CryptoPP::VecIntelMultiply11; + +// c1c0 = a * b +inline void +F2N_Multiply_128x128_POWER8(uint64x2_p& c1, uint64x2_p& c0, const uint64x2_p& a, const uint64x2_p& b) +{ + uint64x2_p t1, t2; + const uint64x2_p z0={0}; + + c0 = VecIntelMultiply00(a, b); + c1 = VecIntelMultiply11(a, b); + t1 = VecMergeLow(a, a); + t1 = VecXor(a, t1); + t2 = VecMergeLow(b, b); + t2 = VecXor(b, t2); + t1 = VecIntelMultiply00(t1, t2); + t1 = VecXor(c0, t1); + t1 = VecXor(c1, t1); + t2 = t1; + t1 = VecMergeHigh(z0, t1); + t2 = VecMergeLow(t2, z0); + c0 = VecXor(c0, t1); + c1 = VecXor(c1, t2); +} + +// c3c2c1c0 = a1a0 * b1b0 +inline void +F2N_Multiply_256x256_POWER8(uint64x2_p& c3, uint64x2_p& c2, uint64x2_p& c1, uint64x2_p& c0, + const uint64x2_p& b1, const uint64x2_p& b0, const uint64x2_p& a1, const uint64x2_p& a0) +{ + uint64x2_p c4, c5; + uint64x2_p x0=a0, x1=a1, y0=b0, y1=b1; + + F2N_Multiply_128x128_POWER8(c1, c0, x0, y0); + F2N_Multiply_128x128_POWER8(c3, c2, x1, y1); + + x0 = VecXor(x0, x1); + y0 = VecXor(y0, y1); + + F2N_Multiply_128x128_POWER8(c5, c4, x0, y0); + + c4 = VecXor(c4, c0); + c4 = VecXor(c4, c2); + c5 = VecXor(c5, c1); + c5 = VecXor(c5, c3); + c1 = VecXor(c1, c4); + c2 = VecXor(c2, c5); +} + +// c3c2c1c0 = a1a0 * a1a0 +inline void +F2N_Square_256_POWER8(uint64x2_p& c3, uint64x2_p& c2, uint64x2_p& c1, + uint64x2_p& c0, const uint64x2_p& a1, const uint64x2_p& a0) +{ + c0 = VecIntelMultiply00(a0, a0); + c1 = VecIntelMultiply11(a0, a0); + c2 = VecIntelMultiply00(a1, a1); + c3 = VecIntelMultiply11(a1, a1); +} + +// x = (x << n), z = 0 +template +inline uint64x2_p ShiftLeft128_POWER8(uint64x2_p x) +{ + uint64x2_p u=x, v; + const uint64x2_p z={0}; + + x = VecShiftLeft(x); + u = VecShiftRight<64-N>(u); + v = VecMergeHigh(z, u); + x = VecOr(x, v); + return x; +} + +// c1c0 = c3c2c1c0 MOD p. This is a Barrett reduction. Reading at +// Intel paper or https://github.com/antonblanchard/crc32-vpmsum. +inline void +GF2NT_233_Reduce_POWER8(uint64x2_p& c3, uint64x2_p& c2, uint64x2_p& c1, uint64x2_p& c0) +{ + const uint64_t mod[] = {W64LIT(0xffffffffffffffff), W64LIT(0x01ffffffffff)}; + const uint64x2_p m0 = (uint64x2_p)VecLoad(mod); + + uint64x2_p b3, b2, b1, /*b0,*/ a1, a0; + const uint64x2_p z0={0}; + + b1 = c1; a1 = c1; + a0 = VecMergeHigh(c1, z0); + a1 = VecShiftLeft<23>(a1); + a1 = VecShiftRight<23>(a1); + c1 = VecOr(a1, a0); + b2 = VecShiftRight<64-23>(c2); + c3 = ShiftLeft128_POWER8<23>(c3); + a0 = VecMergeLow(b2, z0); + c3 = VecOr(c3, a0); + b1 = VecShiftRight<64-23>(b1); + c2 = ShiftLeft128_POWER8<23>(c2); + a0 = VecMergeLow(b1, z0); + c2 = VecOr(c2, a0); + b3 = c3; + b2 = VecShiftRight<64-10>(c2); + b3 = ShiftLeft128_POWER8<10>(b3); + a0 = VecMergeLow(b2, z0); + b3 = VecOr(b3, a0); + a0 = VecMergeLow(c3, z0); + b3 = VecXor(b3, a0); + b1 = VecShiftRight<64-23>(b3); + b3 = ShiftLeft128_POWER8<23>(b3); + b3 = VecMergeLow(b3, z0); + b3 = VecOr(b3, b1); + c2 = VecXor(c2, b3); + b3 = c3; + b2 = VecShiftRight<64-10>(c2); + b3 = ShiftLeft128_POWER8<10>(b3); + b2 = VecMergeLow(b2, z0); + b3 = VecOr(b3, b2); + b2 = c2; + b2 = ShiftLeft128_POWER8<10>(b2); + a0 = VecMergeHigh(z0, b2); + c2 = VecXor(c2, a0); + a0 = VecMergeHigh(z0, b3); + a1 = VecMergeLow(b2, z0); + a0 = VecOr(a0, a1); + c3 = VecXor(c3, a0); + c0 = VecXor(c0, c2); + c1 = VecXor(c1, c3); + c1 = VecAnd(c1, m0); +} + +#endif + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_CLMUL_AVAILABLE) + +void +GF2NT_233_Multiply_Reduce_CLMUL(const word* pA, const word* pB, word* pC) +{ + enum {S=sizeof(__m128i)/sizeof(word)}; + __m128i a0 = _mm_loadu_si128(reinterpret_cast(pA+0*S)); + __m128i a1 = _mm_loadu_si128(reinterpret_cast(pA+1*S)); + __m128i b0 = _mm_loadu_si128(reinterpret_cast(pB+0*S)); + __m128i b1 = _mm_loadu_si128(reinterpret_cast(pB+1*S)); + + __m128i c0, c1, c2, c3; + F2N_Multiply_256x256_CLMUL(c3, c2, c1, c0, a1, a0, b1, b0); + GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0); + + _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+0*S), c0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+1*S), c1); +} + +void +GF2NT_233_Square_Reduce_CLMUL(const word* pA, word* pC) +{ + enum {S=sizeof(__m128i)/sizeof(word)}; + __m128i a0 = _mm_loadu_si128(reinterpret_cast(pA+0*S)); + __m128i a1 = _mm_loadu_si128(reinterpret_cast(pA+1*S)); + + __m128i c0, c1, c2, c3; + F2N_Square_256_CLMUL(c3, c2, c1, c0, a1, a0); + GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0); + + _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+0*S), c0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+1*S), c1); +} + +#elif (CRYPTOPP_ARM_PMULL_AVAILABLE) + +void +GF2NT_233_Multiply_Reduce_ARMv8(const word* pA, const word* pB, word* pC) +{ + // word is either 32-bit or 64-bit, depending on the platform. + // Load using a 32-bit pointer to avoid possible alignment issues. + const uint32_t* pAA = reinterpret_cast(pA); + const uint32_t* pBB = reinterpret_cast(pB); + + uint64x2_t a0 = vreinterpretq_u64_u32(vld1q_u32(pAA+0)); + uint64x2_t a1 = vreinterpretq_u64_u32(vld1q_u32(pAA+4)); + uint64x2_t b0 = vreinterpretq_u64_u32(vld1q_u32(pBB+0)); + uint64x2_t b1 = vreinterpretq_u64_u32(vld1q_u32(pBB+4)); + + uint64x2_t c0, c1, c2, c3; + F2N_Multiply_256x256_ARMv8(c3, c2, c1, c0, a1, a0, b1, b0); + GF2NT_233_Reduce_ARMv8(c3, c2, c1, c0); + + uint32_t* pCC = reinterpret_cast(pC); + vst1q_u32(pCC+0, vreinterpretq_u32_u64(c0)); + vst1q_u32(pCC+4, vreinterpretq_u32_u64(c1)); +} + +void +GF2NT_233_Square_Reduce_ARMv8(const word* pA, word* pC) +{ + // word is either 32-bit or 64-bit, depending on the platform. + // Load using a 32-bit pointer to avoid possible alignment issues. + const uint32_t* pAA = reinterpret_cast(pA); + uint64x2_t a0 = vreinterpretq_u64_u32(vld1q_u32(pAA+0)); + uint64x2_t a1 = vreinterpretq_u64_u32(vld1q_u32(pAA+4)); + + uint64x2_t c0, c1, c2, c3; + F2N_Square_256_ARMv8(c3, c2, c1, c0, a1, a0); + GF2NT_233_Reduce_ARMv8(c3, c2, c1, c0); + + uint32_t* pCC = reinterpret_cast(pC); + vst1q_u32(pCC+0, vreinterpretq_u32_u64(c0)); + vst1q_u32(pCC+4, vreinterpretq_u32_u64(c1)); +} + +#elif (CRYPTOPP_POWER8_VMULL_AVAILABLE) && 0 + +void +GF2NT_233_Multiply_Reduce_POWER8(const word* pA, const word* pB, word* pC) +{ + // word is either 32-bit or 64-bit, depending on the platform. + // Load using a byte pointer to avoid possible alignment issues. + const byte* pAA = reinterpret_cast(pA); + const byte* pBB = reinterpret_cast(pB); + + uint64x2_p a0 = (uint64x2_p)VecLoad(pAA+0); + uint64x2_p a1 = (uint64x2_p)VecLoad(pAA+16); + uint64x2_p b0 = (uint64x2_p)VecLoad(pBB+0); + uint64x2_p b1 = (uint64x2_p)VecLoad(pBB+16); + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8_t mb[] = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + const uint8x16_p m = (uint8x16_p)VecLoad(mb); + a0 = VecPermute(a0, m); + a1 = VecPermute(a1, m); + b0 = VecPermute(b0, m); + b1 = VecPermute(b1, m); +#endif + + uint64x2_p c0, c1, c2, c3; + F2N_Multiply_256x256_POWER8(c3, c2, c1, c0, a1, a0, b1, b0); + GF2NT_233_Reduce_POWER8(c3, c2, c1, c0); + +#if (CRYPTOPP_BIG_ENDIAN) + c0 = VecPermute(c0, m); + c1 = VecPermute(c1, m); +#endif + + byte* pCC = reinterpret_cast(pC); + VecStore(c0, pCC+0); + VecStore(c1, pCC+16); +} + +void +GF2NT_233_Square_Reduce_POWER8(const word* pA, word* pC) +{ + // word is either 32-bit or 64-bit, depending on the platform. + // Load using a byte pointer to avoid possible alignment issues. + const byte* pAA = reinterpret_cast(pA); + uint64x2_p a0 = (uint64x2_p)VecLoad(pAA+0); + uint64x2_p a1 = (uint64x2_p)VecLoad(pAA+16); + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8_t mb[] = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + const uint8x16_p m = (uint8x16_p)VecLoad(mb); + a0 = VecPermute(a0, m); + a1 = VecPermute(a1, m); +#endif + + uint64x2_p c0, c1, c2, c3; + F2N_Square_256_POWER8(c3, c2, c1, c0, a1, a0); + GF2NT_233_Reduce_POWER8(c3, c2, c1, c0); + +#if (CRYPTOPP_BIG_ENDIAN) + c0 = VecPermute(c0, m); + c1 = VecPermute(c1, m); +#endif + + byte* pCC = reinterpret_cast(pC); + VecStore(c0, pCC+0); + VecStore(c1, pCC+16); +} + +#endif + +NAMESPACE_END + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/gfpcrypt.cpp b/external/ours/library/crypto/src/shared/original/gfpcrypt.cpp new file mode 100755 index 000000000..4c257cbdf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gfpcrypt.cpp @@ -0,0 +1,334 @@ +// dsa.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +// TODO: fix the C4589 warnings +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4189 4589) +#endif + +#ifndef CRYPTOPP_IMPORTS + +#include "gfpcrypt.h" +#include "nbtheory.h" +#include "modarith.h" +#include "integer.h" +#include "asn.h" +#include "oids.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void TestInstantiations_gfpcrypt() +{ + GDSA::Signer test; + GDSA::Verifier test1; + DSA::Signer test5(NullRNG(), 100); + DSA::Signer test2(test5); + NR::Signer test3; + NR::Verifier test4; + DLIES<>::Encryptor test6; + DLIES<>::Decryptor test7; +} +#endif + +void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + Integer p, q, g; + + if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) + { + q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); + Initialize(p, q, g); + } + else + { + int modulusSize = 2048, defaultSubgroupOrderSize; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + switch (modulusSize) + { + case 1024: + defaultSubgroupOrderSize = 160; + break; + case 2048: + defaultSubgroupOrderSize = 224; + break; + case 3072: + defaultSubgroupOrderSize = 256; + break; + default: + throw InvalidArgument("DSA: not a valid prime length"); + } + + DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false))); + } +} + +bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level); + CRYPTOPP_ASSERT(pass); + + const int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount(); + pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256)); + CRYPTOPP_ASSERT(pass); + + return pass; +} + +void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength); + CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier); + CRYPTOPP_ASSERT(recoverableMessageLength == 0); + CRYPTOPP_ASSERT(hashIdentifier.second == 0); + + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize); + + memset(representative, 0, paddingLength); + hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); + + if (digestSize*8 > representativeBitLength) + { + Integer h(representative, representativeByteLength); + h >>= representativeByteLength*8 - representativeBitLength; + h.Encode(representative, representativeByteLength); + } +} + +void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + CRYPTOPP_UNUSED(rng);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength); + CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty); + CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); + + CRYPTOPP_ASSERT(recoverableMessageLength == 0); + CRYPTOPP_ASSERT(hashIdentifier.second == 0); + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize); + + memset(representative, 0, paddingLength); + hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); + + if (digestSize*8 >= representativeBitLength) + { + Integer h(representative, representativeByteLength); + h >>= representativeByteLength*8 - representativeBitLength + 1; + h.Encode(representative, representativeByteLength); + } +} + +bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const +{ + const Integer &p = GetModulus(), &q = GetSubgroupOrder(); + bool pass = true; + + CRYPTOPP_ASSERT(p > Integer::One() && p.IsOdd()); + pass = pass && p > Integer::One() && p.IsOdd(); + + CRYPTOPP_ASSERT(q > Integer::One() && q.IsOdd()); + pass = pass && q > Integer::One() && q.IsOdd(); + + if (level >= 1) + { + CRYPTOPP_ASSERT(GetCofactor() > Integer::One()); + CRYPTOPP_ASSERT(GetGroupOrder() % q == Integer::Zero()); + + pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero(); + } + if (level >= 2) + { + CRYPTOPP_ASSERT(VerifyPrime(rng, q, level-2)); + CRYPTOPP_ASSERT(VerifyPrime(rng, p, level-2)); + + pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2); + } + + return pass; +} + +bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation *gpc) const +{ + const Integer &p = GetModulus(), &q = GetSubgroupOrder(); + bool pass = true; + + CRYPTOPP_ASSERT(GetFieldType() == 1 ? g.IsPositive() : g.NotNegative()); + pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative(); + + CRYPTOPP_ASSERT(g < p && !IsIdentity(g)); + pass = pass && g < p && !IsIdentity(g); + + if (level >= 1) + { + if (gpc) + { + CRYPTOPP_ASSERT(gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g); + pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g; + } + } + if (level >= 2) + { + if (GetFieldType() == 2) + { + CRYPTOPP_ASSERT(Jacobi(g*g-4, p)==-1); + pass = pass && Jacobi(g*g-4, p)==-1; + } + + // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly + // and at most 1 bit is leaked if it's false + bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable(); + + if (fullValidate && pass) + { + Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q); + CRYPTOPP_ASSERT(IsIdentity(gp)); + pass = pass && IsIdentity(gp); + } + else if (GetFieldType() == 1) + { + CRYPTOPP_ASSERT(Jacobi(g, p) == 1); + pass = pass && Jacobi(g, p) == 1; + } + } + + return pass; +} + +void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + Integer p, q, g; + + if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) + { + q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); + } + else + { + int modulusSize, subgroupOrderSize; + + if (!alg.GetIntValue("ModulusSize", modulusSize)) + modulusSize = alg.GetIntValueWithDefault("KeySize", 2048); + + if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize)) + subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize); + + PrimeAndGenerator pg; + pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize); + p = pg.Prime(); + q = pg.SubPrime(); + g = pg.Generator(); + } + + Initialize(p, q, g); +} + +void DL_GroupParameters_IntegerBased::EncodeElement(bool reversible, const Element &element, byte *encoded) const +{ + CRYPTOPP_UNUSED(reversible); + element.Encode(encoded, GetModulus().ByteCount()); +} + +unsigned int DL_GroupParameters_IntegerBased::GetEncodedElementSize(bool reversible) const +{ + CRYPTOPP_UNUSED(reversible); + return GetModulus().ByteCount(); +} + +Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const +{ + CRYPTOPP_UNUSED(checkForGroupMembership); + Integer g(encoded, GetModulus().ByteCount()); + if (!ValidateElement(1, g, NULLPTR)) + throw DL_BadElement(); + return g; +} + +void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder parameters(bt); + Integer p(parameters); + Integer q(parameters); + Integer g; + if (parameters.EndReached()) + { + g = q; + q = ComputeGroupOrder(p) / 2; + } + else + g.BERDecode(parameters); + parameters.MessageEnd(); + + SetModulusAndSubgroupGenerator(p, g); + SetSubgroupOrder(q); +} + +void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder parameters(bt); + GetModulus().DEREncode(parameters); + m_q.DEREncode(parameters); + GetSubgroupGenerator().DEREncode(parameters); + parameters.MessageEnd(); +} + +bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper >(this, name, valueType, pValue) + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus); +} + +void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) + ; +} + +OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const +{ + return ASN1::id_dsa(); +} + +void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const +{ + ModularArithmetic ma(GetModulus()); + ma.SimultaneousExponentiate(results, base, exponents, exponentsCount); +} + +DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const +{ + return a_times_b_mod_c(a, b, GetModulus()); +} + +DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const +{ + ModularArithmetic ma(GetModulus()); + return ma.CascadeExponentiate(element1, exponent1, element2, exponent2); +} + +Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const +{ + return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount()))); +} + +unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const +{ + return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gfpcrypt.h b/external/ours/library/crypto/src/shared/original/gfpcrypt.h new file mode 100755 index 000000000..f8fc3c5ef --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gfpcrypt.h @@ -0,0 +1,1036 @@ +// gfpcrypt.h - originally written and placed in the public domain by Wei Dai +// RFC6979 deterministic signatures added by Douglas Roark +// ECGDSA added by Jeffrey Walton + +/// \file gfpcrypt.h +/// \brief Classes and functions for schemes based on Discrete Logs (DL) over GF(p) + +#ifndef CRYPTOPP_GFPCRYPT_H +#define CRYPTOPP_GFPCRYPT_H + +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4189 4231 4275) +#endif + +#include "cryptlib.h" +#include "pubkey.h" +#include "integer.h" +#include "modexppc.h" +#include "algparam.h" +#include "smartptr.h" +#include "sha.h" +#include "asn.h" +#include "hmac.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters; + +/// \brief Integer-based GroupParameters specialization +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial > +{ + typedef DL_GroupParameters_IntegerBased ThisClass; + +public: + virtual ~DL_GroupParameters_IntegerBased() {} + + /// \brief Initialize a group parameters over integers + /// \param params the group parameters + void Initialize(const DL_GroupParameters_IntegerBased ¶ms) + {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} + + /// \brief Create a group parameters over integers + /// \param rng a RandomNumberGenerator derived class + /// \param pbits the size of p, in bits + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int pbits) + {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));} + + /// \brief Initialize a group parameters over integers + /// \param p the modulus + /// \param g the generator + void Initialize(const Integer &p, const Integer &g) + {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);} + + /// \brief Initialize a group parameters over integers + /// \param p the modulus + /// \param q the subgroup order + /// \param g the generator + void Initialize(const Integer &p, const Integer &q, const Integer &g) + {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);} + + // ASN1Object interface + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + /// \brief Generate a random key + /// \param rng a RandomNumberGenerator to produce keying material + /// \param alg additional initialization parameters + /// \details Recognised NameValuePairs are ModulusSize and + /// SubgroupOrderSize (optional) + /// \throw KeyingErr if a key can't be generated or algorithm parameters + /// are invalid + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + /// \brief Get a named value + /// \param name the name of the object or value to retrieve + /// \param valueType reference to a variable that receives the value + /// \param pValue void pointer to a variable that receives the value + /// \return true if the value was retrieved, false otherwise + /// \details GetVoidValue() retrieves the value of name if it exists. + /// \note GetVoidValue() is an internal function and should be implemented + /// by derived classes. Users should use one of the other functions instead. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + + /// \brief Initialize or reinitialize this key + /// \param source NameValuePairs to assign + void AssignFrom(const NameValuePairs &source); + + // DL_GroupParameters + const Integer & GetSubgroupOrder() const {return m_q;} + Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation *precomp) const; + + /// \brief Determine if subgroup membership check is fast + /// \return true or false + bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} + + /// \brief Encodes the element + /// \param reversible flag indicating the encoding format + /// \param element reference to the element to encode + /// \param encoded destination byte array for the encoded element + /// \details EncodeElement() must be implemented in a derived class. + /// \pre COUNTOF(encoded) == GetEncodedElementSize() + /// \sa GetEncodedElementSize(), DecodeElement(), Cygwin + /// i386 crash at -O3 + void EncodeElement(bool reversible, const Element &element, byte *encoded) const; + + /// \brief Retrieve the encoded element's size + /// \param reversible flag indicating the encoding format + /// \return encoded element's size, in bytes + /// \details The format of the encoded element varies by the underlying + /// type of the element and the reversible flag. + /// \sa EncodeElement(), DecodeElement() + unsigned int GetEncodedElementSize(bool reversible) const; + + /// \brief Decodes the element + /// \param encoded byte array with the encoded element + /// \param checkForGroupMembership flag indicating if the element should be validated + /// \return Element after decoding + /// \details DecodeElement() must be implemented in a derived class. + /// \pre COUNTOF(encoded) == GetEncodedElementSize() + /// \sa GetEncodedElementSize(), EncodeElement() + Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; + + /// \brief Converts an element to an Integer + /// \param element the element to convert to an Integer + /// \return Element after converting to an Integer + /// \details ConvertElementToInteger() must be implemented in a derived class. + Integer ConvertElementToInteger(const Element &element) const + {return element;} + + /// \brief Retrieve the maximum exponent for the group + /// \return the maximum exponent for the group + Integer GetMaxExponent() const; + + /// \brief Retrieve the OID of the algorithm + /// \return OID of the algorithm + OID GetAlgorithmID() const; + + /// \brief Retrieve the modulus for the group + /// \return the modulus for the group + virtual const Integer & GetModulus() const =0; + + /// \brief Set group parameters + /// \param p the prime modulus + /// \param g the group generator + virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; + + /// \brief Set subgroup order + /// \param q the subgroup order + void SetSubgroupOrder(const Integer &q) + {m_q = q; ParametersChanged();} + + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";} + +protected: + Integer ComputeGroupOrder(const Integer &modulus) const + {return modulus-(GetFieldType() == 1 ? 1 : -1);} + + // GF(p) = 1, GF(p^2) = 2 + virtual int GetFieldType() const =0; + virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const; + +private: + Integer m_q; +}; + +/// \brief Integer-based GroupParameters default implementation +/// \tparam GROUP_PRECOMP group parameters precomputation specialization +/// \tparam BASE_PRECOMP base class precomputation specialization +template > +class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl +{ + typedef DL_GroupParameters_IntegerBasedImpl ThisClass; + +public: + typedef typename GROUP_PRECOMP::Element Element; + + virtual ~DL_GroupParameters_IntegerBasedImpl() {} + + // GeneratibleCryptoMaterial interface + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + {return GetValueHelper(this, name, valueType, pValue).Assignable();} + + void AssignFrom(const NameValuePairs &source) + {AssignFromHelper(this, source);} + + // DL_GroupParameters + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} + + // IntegerGroupParameters + /// \brief Retrieve the modulus for the group + /// \return the modulus for the group + const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();} + + /// \brief Retrieves a reference to the group generator + /// \return const reference to the group generator + const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());} + + void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together + {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();} + + // non-inherited + bool operator==(const DL_GroupParameters_IntegerBasedImpl &rhs) const + {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} + bool operator!=(const DL_GroupParameters_IntegerBasedImpl &rhs) const + {return !operator==(rhs);} +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl; + +/// \brief GF(p) group parameters +class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl +{ +public: + virtual ~DL_GroupParameters_GFP() {} + + /// \brief Determines if an element is an identity + /// \param element element to check + /// \return true if the element is an identity, false otherwise + /// \details The identity element or or neutral element is a special element + /// in a group that leaves other elements unchanged when combined with it. + /// \details IsIdentity() must be implemented in a derived class. + bool IsIdentity(const Integer &element) const {return element == Integer::One();} + + /// \brief Exponentiates a base to multiple exponents + /// \param results an array of Elements + /// \param base the base to raise to the exponents + /// \param exponents an array of exponents + /// \param exponentsCount the number of exponents in the array + /// \details SimultaneousExponentiate() raises the base to each exponent in + /// the exponents array and stores the result at the respective position in + /// the results array. + /// \details SimultaneousExponentiate() must be implemented in a derived class. + /// \pre COUNTOF(results) == exponentsCount + /// \pre COUNTOF(exponents) == exponentsCount + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + + /// \brief Get a named value + /// \param name the name of the object or value to retrieve + /// \param valueType reference to a variable that receives the value + /// \param pValue void pointer to a variable that receives the value + /// \return true if the value was retrieved, false otherwise + /// \details GetVoidValue() retrieves the value of name if it exists. + /// \note GetVoidValue() is an internal function and should be implemented + /// by derived classes. Users should use one of the other functions instead. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue).Assignable(); + } + + // used by MQV + Element MultiplyElements(const Element &a, const Element &b) const; + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; + +protected: + int GetFieldType() const {return 1;} +}; + +/// \brief GF(p) group parameters that default to safe primes +class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP +{ +public: + typedef NoCofactorMultiplication DefaultCofactorOption; + + virtual ~DL_GroupParameters_GFP_DefaultSafePrime() {} + +protected: + unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} +}; + +/// ElGamal encryption for safe interop +/// \sa On the +/// (in)security of ElGamal in OpenPGP, +/// Issue 1059, +/// CVE-2021-40530 +/// \since Crypto++ 8.6 +class CRYPTOPP_DLL DL_GroupParameters_ElGamal : public DL_GroupParameters_GFP_DefaultSafePrime +{ +public: + typedef NoCofactorMultiplication DefaultCofactorOption; + + virtual ~DL_GroupParameters_ElGamal() {} + + Integer GetMaxExponent() const + { + return GetSubgroupOrder()-1; + } +}; + +/// \brief GDSA algorithm +/// \tparam T FieldElement type or class +/// \details FieldElement T can be Integer, ECP or EC2N. +template +class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} + + virtual ~DL_Algorithm_GDSA() {} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + r %= q; + Integer kInv = k.InverseMod(q); + s = (kInv * (x*r + e)) % q; + CRYPTOPP_ASSERT(!!r && !!s); + } + + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q || s<1) + return false; + + Integer w = s.InverseMod(q); + Integer u1 = (e * w) % q; + Integer u2 = (r * w) % q; + // verify r == (g^u1 * y^u2 mod p) mod q + return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; + } +}; + +/// \brief DSA signature algorithm based on RFC 6979 +/// \tparam T FieldElement type or class +/// \tparam H HashTransformation derived class +/// \details FieldElement T can be Integer, ECP or EC2N. +/// \sa RFC 6979, Deterministic Usage of the +/// Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) +/// \since Crypto++ 6.0 +template +class DL_Algorithm_DSA_RFC6979 : public DL_Algorithm_GDSA, public DeterministicSignatureAlgorithm +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";} + + virtual ~DL_Algorithm_DSA_RFC6979() {} + + bool IsProbabilistic() const + {return false;} + bool IsDeterministic() const + {return true;} + + // Deterministic K + Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const + { + static const byte zero = 0, one = 1; + const size_t qlen = q.BitCount(); + const size_t rlen = BitsToBytes(qlen); + + // Step (a) - formatted E(m) + SecByteBlock BH(e.MinEncodedSize()); + e.Encode(BH, BH.size()); + BH = bits2octets(BH, q); + + // Step (a) - private key to byte array + SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize())); + x.Encode(BX, BX.size()); + + // Step (b) + SecByteBlock V(H::DIGESTSIZE); + std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one); + + // Step (c) + SecByteBlock K(H::DIGESTSIZE); + std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero); + + // Step (d) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.Update(&zero, 1); + m_hmac.Update(BX, BX.size()); + m_hmac.Update(BH, BH.size()); + m_hmac.TruncatedFinal(K, K.size()); + + // Step (e) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); + + // Step (f) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.Update(&one, 1); + m_hmac.Update(BX, BX.size()); + m_hmac.Update(BH, BH.size()); + m_hmac.TruncatedFinal(K, K.size()); + + // Step (g) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); + + Integer k; + SecByteBlock temp(rlen); + for (;;) + { + // We want qlen bits, but we support only hash functions with an output length + // multiple of 8; hence, we will gather rlen bits, i.e., rolen octets. + size_t toff = 0; + while (toff < rlen) + { + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); + + size_t cc = STDMIN(V.size(), temp.size() - toff); + memcpy_s(temp+toff, temp.size() - toff, V, cc); + toff += cc; + } + + k = bits2int(temp, qlen); + if (k > 0 && k < q) + break; + + // k is not in the proper range; update K and V, and loop. + m_hmac.Update(V, V.size()); + m_hmac.Update(&zero, 1); + m_hmac.TruncatedFinal(K, K.size()); + + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); + } + + return k; + } + +protected: + + Integer bits2int(const SecByteBlock& bits, size_t qlen) const + { + Integer ret(bits, bits.size()); + size_t blen = bits.size()*8; + + if (blen > qlen) + ret >>= blen - qlen; + + return ret; + } + + // RFC 6979 support function. Takes an integer and converts it into bytes that + // are the same length as an elliptic curve's order. + SecByteBlock int2octets(const Integer& val, size_t rlen) const + { + SecByteBlock block(val.MinEncodedSize()); + val.Encode(block, val.MinEncodedSize()); + + if (block.size() == rlen) + return block; + + // The least significant bytes are the ones we need to preserve. + SecByteBlock t(rlen); + if (block.size() > rlen) + { + size_t offset = block.size() - rlen; + std::memcpy(t, block + offset, rlen); + } + else // block.size() < rlen + { + size_t offset = rlen - block.size(); + memset(t, '\x00', offset); + std::memcpy(t + offset, block, rlen - offset); + } + + return t; + } + + // Turn a stream of bits into a set of bytes with the same length as an elliptic + // curve's order. + SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const + { + Integer b2 = bits2int(in, q.BitCount()); + Integer b1 = b2 - q; + return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount()); + } + +private: + mutable H m_hash; + mutable HMAC m_hmac; +}; + +/// \brief German Digital Signature Algorithm +/// \tparam T FieldElement type or class +/// \details FieldElement T can be Integer, ECP or EC2N. +/// \details The Digital Signature Scheme ECGDSA does not define the algorithm over integers. Rather, the +/// signature algorithm is only defined over elliptic curves. However, the library design is such that the +/// generic algorithm reside in gfpcrypt.h. +/// \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf +/// The Digital Signature Scheme ECGDSA (October 24, 2006) +template +class DL_Algorithm_GDSA_ISO15946 : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";} + + virtual ~DL_Algorithm_GDSA_ISO15946() {} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + // r = x(k * G) mod q + r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q; + // s = (k * r - h(m)) * d_A mod q + s = (k * r - e) * x % q; + CRYPTOPP_ASSERT(!!r && !!s); + } + + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q || s<1) + return false; + + const Integer& rInv = r.InverseMod(q); + const Integer u1 = (rInv * e) % q; + const Integer u2 = (rInv * s) % q; + // verify x(G^u1 + P_A^u2) mod q + return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; + } +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979; + +/// \brief NR algorithm +/// \tparam T FieldElement type or class +/// \details FieldElement T can be Integer, ECP or EC2N. +template +class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";} + + virtual ~DL_Algorithm_NR() {} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + r = (r + e) % q; + s = (k - x*r) % q; + CRYPTOPP_ASSERT(!!r); + } + + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q) + return false; + + // check r == (m_g^s * m_y^r + m) mod m_q + return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; + } +}; + +/// \brief Discrete Log (DL) public key in GF(p) groups +/// \tparam GP GroupParameters derived class +/// \details DSA public key format is defined in 7.3.3 of RFC 2459. The private key format is defined in 12.9 of PKCS #11 v2.10. +template +class DL_PublicKey_GFP : public DL_PublicKeyImpl +{ +public: + virtual ~DL_PublicKey_GFP() {} + + /// \brief Initialize a public key over GF(p) + /// \param params the group parameters + /// \param y the public element + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y) + {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} + + /// \brief Initialize a public key over GF(p) + /// \param p the modulus + /// \param g the generator + /// \param y the public element + void Initialize(const Integer &p, const Integer &g, const Integer &y) + {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);} + + /// \brief Initialize a public key over GF(p) + /// \param p the modulus + /// \param q the subgroup order + /// \param g the generator + /// \param y the public element + void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y) + {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);} + + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) + {this->SetPublicElement(Integer(bt));} + void DEREncodePublicKey(BufferedTransformation &bt) const + {this->GetPublicElement().DEREncode(bt);} +}; + +/// \brief Discrete Log (DL) private key in GF(p) groups +/// \tparam GP GroupParameters derived class +template +class DL_PrivateKey_GFP : public DL_PrivateKeyImpl +{ +public: + virtual ~DL_PrivateKey_GFP(); + + /// \brief Create a private key + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulus, in bits + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {this->GenerateRandomWithKeySize(rng, modulusBits);} + + /// \brief Create a private key + /// \param rng a RandomNumberGenerator derived class + /// \param p the modulus + /// \param g the generator + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) + {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));} + + /// \brief Create a private key + /// \param rng a RandomNumberGenerator derived class + /// \param p the modulus + /// \param q the subgroup order + /// \param g the generator + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g) + {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));} + + /// \brief Initialize a private key over GF(p) + /// \param params the group parameters + /// \param x the private exponent + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x) + {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);} + + /// \brief Initialize a private key over GF(p) + /// \param p the modulus + /// \param g the generator + /// \param x the private exponent + void Initialize(const Integer &p, const Integer &g, const Integer &x) + {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} + + /// \brief Initialize a private key over GF(p) + /// \param p the modulus + /// \param q the subgroup order + /// \param g the generator + /// \param x the private exponent + void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) + {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} +}; + +// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499 +template +DL_PrivateKey_GFP::~DL_PrivateKey_GFP() {} + +/// \brief Discrete Log (DL) signing/verification keys in GF(p) groups +struct DL_SignatureKeys_GFP +{ + typedef DL_GroupParameters_GFP GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +/// \brief Discrete Log (DL) encryption/decryption keys in GF(p) groups +struct DL_CryptoKeys_GFP +{ + typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +/// ElGamal encryption keys for safe interop +/// \sa On the +/// (in)security of ElGamal in OpenPGP, +/// Issue 1059, +/// CVE-2021-40530 +/// \since Crypto++ 8.6 +struct DL_CryptoKeys_ElGamal +{ + typedef DL_GroupParameters_ElGamal GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +/// \brief DSA signature scheme +/// \tparam H HashTransformation derived class +/// \sa DSA-1363 +/// \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2 +template +struct GDSA : public DL_SS< + DL_SignatureKeys_GFP, + DL_Algorithm_GDSA, + DL_SignatureMessageEncodingMethod_DSA, + H> +{ +}; + +/// \brief NR signature scheme +/// \tparam H HashTransformation derived class +/// \sa NR +template +struct NR : public DL_SS< + DL_SignatureKeys_GFP, + DL_Algorithm_NR, + DL_SignatureMessageEncodingMethod_NR, + H> +{ +}; + +/// \brief DSA group parameters +/// \details These are GF(p) group parameters that are allowed by the DSA standard +/// \sa DL_Keys_DSA +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP +{ +public: + virtual ~DL_GroupParameters_DSA() {} + + /// \brief Check the group for errors + /// \param rng RandomNumberGenerator for objects which use randomized testing + /// \param level level of thoroughness + /// \return true if the tests succeed, false otherwise + /// \details ValidateGroup() also checks that the lengths of p and q are allowed + /// by the DSA standard. + /// \details There are four levels of thoroughness: + ///
    + ///
  • 0 - using this object won't cause a crash or exception + ///
  • 1 - this object will probably function, and encrypt, sign, other operations correctly + ///
  • 2 - ensure this object will function correctly, and perform reasonable security checks + ///
  • 3 - perform reasonable security checks, and do checks that may take a long time + ///
+ /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0. + /// Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended. + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + + /// \brief Generate a random key or crypto parameters + /// \param rng a RandomNumberGenerator to produce keying material + /// \param alg additional initialization parameters + /// \details NameValuePairs can be ModulusSize alone; or Modulus, SubgroupOrder, and + /// SubgroupGenerator. ModulusSize must be between DSA::MIN_PRIME_LENGTH and + /// DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE. + /// \details An example of changing the modulus size using NameValuePairs is shown below. + ///
+    ///  AlgorithmParameters params = MakeParameters
+    ///    (Name::ModulusSize(), 2048);
+    ///
+    ///  DL_GroupParameters_DSA groupParams;
+    ///  groupParams.GenerateRandom(prng, params);
+    /// 
+ /// \throw KeyingErr if a key can't be generated or algorithm parameters are invalid. + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + /// \brief Check the prime length for errors + /// \param pbits number of bits in the prime number + /// \return true if the tests succeed, false otherwise + static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) + {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} + + /// \brief DSA prime length + enum { + /// \brief Minimum prime length + MIN_PRIME_LENGTH = 1024, + /// \brief Maximum prime length + MAX_PRIME_LENGTH = 3072, + /// \brief Prime length multiple + PRIME_LENGTH_MULTIPLE = 1024 + }; +}; + +template +class DSA2; + +/// \brief DSA keys +/// \sa DL_GroupParameters_DSA +/// \since Crypto++ 1.0 +struct DL_Keys_DSA +{ + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 > PrivateKey; +}; + +/// \brief DSA signature scheme +/// \tparam H HashTransformation derived class +/// \details The class is named DSA2 instead of DSA for backwards compatibility because +/// DSA was a non-template class. +/// \details DSA default method GenerateRandom uses a 2048-bit modulus and a 224-bit subgoup by default. +/// The modulus can be changed using the following code: +///
+///  DSA::PrivateKey privateKey;
+///  privateKey.GenerateRandomWithKeySize(prng, 2048);
+/// 
+/// \details The subgroup order can be changed using the following code: +///
+///  AlgorithmParameters params = MakeParameters
+///    (Name::ModulusSize(), 2048)
+///    (Name::SubgroupOrderSize(), 256);
+///
+///  DSA::PrivateKey privateKey;
+///  privateKey.GenerateRandom(prng, params);
+/// 
+/// \sa DSA, as specified in FIPS 186-3, +/// Digital Signature Algorithm on the wiki, and +/// NameValuePairs on the wiki. +/// \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2, Crypto++ 6.1 for 2048-bit modulus. +template +class DSA2 : public DL_SS< + DL_Keys_DSA, + DL_Algorithm_GDSA, + DL_SignatureMessageEncodingMethod_DSA, + H, + DSA2 > +{ +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} +}; + +/// \brief DSA deterministic signature scheme +/// \tparam H HashTransformation derived class +/// \sa DSA-1363 +/// \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2 +template +struct DSA_RFC6979 : public DL_SS< + DL_SignatureKeys_GFP, + DL_Algorithm_DSA_RFC6979, + DL_SignatureMessageEncodingMethod_DSA, + H, + DSA_RFC6979 > +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();} +}; + +/// DSA with SHA-1, typedef'd for backwards compatibility +typedef DSA2 DSA; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 >; + +/// \brief P1363 based XOR Encryption Method +/// \tparam MAC MessageAuthenticationCode derived class used for MAC computation +/// \tparam DHAES_MODE flag indicating DHAES mode +/// \tparam LABEL_OCTETS flag indicating the label is octet count +/// \details DL_EncryptionAlgorithm_Xor is based on an early P1363 draft, which itself appears to be based on an +/// early Certicom SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used it in its Integrated +/// Ecryption Schemes with NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +/// \details If you need this method for Crypto++ 4.2 compatibility, then use the ECIES template class with +/// NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +/// \details If you need this method for Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES template class with +/// NoCofactorMultiplication, DHAES_MODE=ture and LABEL_OCTETS=false. +/// \details Bouncy Castle 1.54 and Botan 1.11 compatibility are the default template parameters. +/// \since Crypto++ 4.0 +template +class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm +{ +public: + virtual ~DL_EncryptionAlgorithm_Xor() {} + + bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} + size_t GetSymmetricKeyLength(size_t plaintextLength) const + {return plaintextLength + static_cast(MAC::DEFAULT_KEYLENGTH);} + size_t GetSymmetricCiphertextLength(size_t plaintextLength) const + {return plaintextLength + static_cast(MAC::DIGESTSIZE);} + size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const + {return SaturatingSubtract(ciphertextLength, static_cast(MAC::DIGESTSIZE));} + void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const + { + CRYPTOPP_UNUSED(rng); + const byte *cipherKey = NULLPTR, *macKey = NULLPTR; + if (DHAES_MODE) + { + macKey = key; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; + } + else + { + cipherKey = key; + macKey = key + plaintextLength; + } + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + if (plaintextLength) // Coverity finding + xorbuf(ciphertext, plaintext, cipherKey, plaintextLength); + + MAC mac(macKey); + mac.Update(ciphertext, plaintextLength); + mac.Update(encodingParameters.begin(), encodingParameters.size()); + if (DHAES_MODE) + { + byte L[8]; + PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); + mac.Update(L, 8); + } + mac.Final(ciphertext + plaintextLength); + } + DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const + { + size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength); + const byte *cipherKey, *macKey; + if (DHAES_MODE) + { + macKey = key; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; + } + else + { + cipherKey = key; + macKey = key + plaintextLength; + } + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + MAC mac(macKey); + mac.Update(ciphertext, plaintextLength); + mac.Update(encodingParameters.begin(), encodingParameters.size()); + if (DHAES_MODE) + { + byte L[8]; + PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); + mac.Update(L, 8); + } + if (!mac.Verify(ciphertext + plaintextLength)) + return DecodingResult(); + + if (plaintextLength) // Coverity finding + xorbuf(plaintext, ciphertext, cipherKey, plaintextLength); + + return DecodingResult(plaintextLength); + } +}; + +/// \brief P1363 based Key Derivation Method +/// \tparam T FieldElement type or class +/// \tparam DHAES_MODE flag indicating DHAES mode +/// \tparam KDF key derivation function +/// \details FieldElement T can be Integer, ECP or EC2N. +template +class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm +{ +public: + virtual ~DL_KeyDerivationAlgorithm_P1363() {} + + bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;} + void Derive(const DL_GroupParameters ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const + { + SecByteBlock agreedSecret; + if (DHAES_MODE) + { + agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false)); + params.EncodeElement(true, ephemeralPublicKey, agreedSecret); + params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true)); + } + else + { + agreedSecret.New(params.GetEncodedElementSize(false)); + params.EncodeElement(false, agreedElement, agreedSecret); + } + + ConstByteArrayParameter derivationParameters; + parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters); + KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size()); + } +}; + +/// \brief Discrete Log Integrated Encryption Scheme +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \tparam HASH HashTransformation derived class used for key drivation and MAC computation +/// \tparam DHAES_MODE flag indicating if the MAC includes addition context parameters such as the label +/// \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits +/// \details DLIES is an Integer based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation Method (KEM) +/// with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is +/// IND-CCA2, which is a strong notion of security. +/// You should prefer an Integrated Encryption Scheme over homegrown schemes. +/// \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom +/// SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used the early draft in its Integrated Ecryption +/// Schemes with NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +/// \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the DLIES template class with +/// NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +/// \details If you desire an Integrated Encryption Scheme with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the DLIES +/// template class with NoCofactorMultiplication, DHAES_MODE=true and LABEL_OCTETS=false. +/// \details The default template parameters ensure compatibility with Bouncy Castle 1.54 and Botan 1.11. The combination of +/// IncompatibleCofactorMultiplication and DHAES_MODE=true is recommended for best efficiency and security. +/// SHA1 is used for compatibility reasons, but it can be changed if desired. SHA-256 or another hash will likely improve the +/// security provided by the MAC. The hash is also used in the key derivation function as a PRF. +/// \details Below is an example of constructing a Crypto++ 4.2 compatible DLIES encryptor and decryptor. +///
+///    AutoSeededRandomPool prng;
+///    DL_PrivateKey_GFP key;
+///    key.Initialize(prng, 2048);
+///
+///    DLIES::Decryptor decryptor(key);
+///    DLIES::Encryptor encryptor(decryptor);
+/// 
+/// \sa ECIES, Discrete Log Integrated Encryption Scheme (DLIES), +/// Martínez, Encinas, and Ávila's A Survey of the Elliptic +/// Curve Integrated Encryption Schemes +/// \since Crypto++ 4.0, Crypto++ 5.7 for Bouncy Castle and Botan compatibility +template +struct DLIES + : public DL_ES< + DL_CryptoKeys_GFP, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, + DLIES<> > +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gost.cpp b/external/ours/library/crypto/src/shared/original/gost.cpp new file mode 100755 index 000000000..dbeff9111 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gost.cpp @@ -0,0 +1,123 @@ +#include "pch.h" +#include "gost.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +// these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 +const byte GOST::Base::sBox[8][16]={ + {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3}, + {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9}, + {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11}, + {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3}, + {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2}, + {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14}, + {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12}, + {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12}}; + +/* // these are the S-boxes given in the GOST source code listing in Applied + // Cryptography 2nd Ed., p. 644. they appear to be from the DES S-boxes + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }}; +*/ + +volatile bool GOST::Base::sTableCalculated = false; +word32 GOST::Base::sTable[4][256]; + +void GOST::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + PrecalculateSTable(); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_key.begin(), 8, userKey, KEYLENGTH); +} + +void GOST::Base::PrecalculateSTable() +{ + if (!sTableCalculated) + { + for (unsigned i = 0; i < 4; i++) + for (unsigned j = 0; j < 256; j++) + { + word32 temp = sBox[2*i][j%16] | (sBox[2*i+1][j/16] << 4); + sTable[i][j] = rotlMod(temp, 11+8*i); + } + + sTableCalculated=true; + } +} + +#define f(x) ( t=x, \ + sTable[3][GETBYTE(t, 3)] ^ sTable[2][GETBYTE(t, 2)] \ + ^ sTable[1][GETBYTE(t, 1)] ^ sTable[0][GETBYTE(t, 0)] ) + +typedef BlockGetAndPut Block; + +void GOST::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 n1, n2, t; + + Block::Get(inBlock)(n1)(n2); + + for (unsigned int i=0; i<3; i++) + { + n2 ^= f(n1+m_key[0]); + n1 ^= f(n2+m_key[1]); + n2 ^= f(n1+m_key[2]); + n1 ^= f(n2+m_key[3]); + n2 ^= f(n1+m_key[4]); + n1 ^= f(n2+m_key[5]); + n2 ^= f(n1+m_key[6]); + n1 ^= f(n2+m_key[7]); + } + + n2 ^= f(n1+m_key[7]); + n1 ^= f(n2+m_key[6]); + n2 ^= f(n1+m_key[5]); + n1 ^= f(n2+m_key[4]); + n2 ^= f(n1+m_key[3]); + n1 ^= f(n2+m_key[2]); + n2 ^= f(n1+m_key[1]); + n1 ^= f(n2+m_key[0]); + + Block::Put(xorBlock, outBlock)(n2)(n1); +} + +void GOST::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 n1, n2, t; + + Block::Get(inBlock)(n1)(n2); + + n2 ^= f(n1+m_key[0]); + n1 ^= f(n2+m_key[1]); + n2 ^= f(n1+m_key[2]); + n1 ^= f(n2+m_key[3]); + n2 ^= f(n1+m_key[4]); + n1 ^= f(n2+m_key[5]); + n2 ^= f(n1+m_key[6]); + n1 ^= f(n2+m_key[7]); + + for (unsigned int i=0; i<3; i++) + { + n2 ^= f(n1+m_key[7]); + n1 ^= f(n2+m_key[6]); + n2 ^= f(n1+m_key[5]); + n1 ^= f(n2+m_key[4]); + n2 ^= f(n1+m_key[3]); + n1 ^= f(n2+m_key[2]); + n2 ^= f(n1+m_key[1]); + n1 ^= f(n2+m_key[0]); + } + + Block::Put(xorBlock, outBlock)(n2)(n1); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/gost.h b/external/ours/library/crypto/src/shared/original/gost.h new file mode 100755 index 000000000..fe6e1576a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gost.h @@ -0,0 +1,66 @@ +// gost.h - originally written and placed in the public domain by Wei Dai + +/// \file gost.h +/// \brief Classes for the GIST block cipher + +#ifndef CRYPTOPP_GOST_H +#define CRYPTOPP_GOST_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief GOST block cipher information +/// \since Crypto++ 2.1 +struct GOST_Info : public FixedBlockSize<8>, public FixedKeyLength<32> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "GOST";} +}; + +/// \brief GOST block cipher +/// \sa GOST +/// \since Crypto++ 2.1 +class GOST : public GOST_Info, public BlockCipherDocumentation +{ + /// \brief GOST block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static void PrecalculateSTable(); + + static const byte sBox[8][16]; + static volatile bool sTableCalculated; + static word32 sTable[4][256]; + + FixedSizeSecBlock m_key; + }; + + /// \brief GOST block cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief GOST block cipher decryption operation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef GOST::Encryption GOSTEncryption; +typedef GOST::Decryption GOSTDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/gzip.cpp b/external/ours/library/crypto/src/shared/original/gzip.cpp new file mode 100755 index 000000000..ade1d422f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gzip.cpp @@ -0,0 +1,208 @@ +// gzip.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "gzip.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +// Checks whether the character is valid for ISO/IEC 8859-1 as required by RFC 1952 +static inline bool Is8859Character(char c) { + const unsigned char cc = static_cast(c); + return (cc >= 32 && cc <= 126) || (cc >= 160); +} + +void Gzip::IsolatedInitialize(const NameValuePairs ¶meters) +{ + Deflator::IsolatedInitialize(parameters); + + ConstByteArrayParameter v; + if (parameters.GetValue(Name::FileName(), v)) + m_filename.assign(reinterpret_cast(v.begin()), v.size()); + if (parameters.GetValue(Name::Comment(), v)) + m_comment.assign(reinterpret_cast(v.begin()), v.size()); + m_filetime = parameters.GetIntValueWithDefault(Name::FileTime(), 0); +} + +void Gzip::WritePrestreamHeader() +{ + m_totalLen = 0; + m_crc.Restart(); + + int flags = 0; + if(!m_filename.empty()) + flags |= FILENAME; + if(!m_comment.empty()) + flags |= COMMENTS; + + AttachedTransformation()->Put(MAGIC1); + AttachedTransformation()->Put(MAGIC2); + AttachedTransformation()->Put(DEFLATED); + AttachedTransformation()->Put((byte)flags); // general flag + AttachedTransformation()->PutWord32(m_filetime, LITTLE_ENDIAN_ORDER); // time stamp + byte extra = static_cast((GetDeflateLevel() == 1) ? + FAST : ((GetDeflateLevel() == 9) ? SLOW : 0)); + AttachedTransformation()->Put(extra); + AttachedTransformation()->Put(GZIP_OS_CODE); + + // Filename is NULL terminated, hence the +1 + if(!m_filename.empty()) + AttachedTransformation()->Put((const unsigned char*)m_filename.data(), m_filename.size() +1); + + // Comment is NULL terminated, hence the +1 + if(!m_comment.empty()) + AttachedTransformation()->Put((const unsigned char*)m_comment.data(), m_comment.size() +1); +} + +void Gzip::ProcessUncompressedData(const byte *inString, size_t length) +{ + m_crc.Update(inString, length); + m_totalLen += (word32)length; +} + +void Gzip::WritePoststreamTail() +{ + SecByteBlock crc(4); + m_crc.Final(crc); + AttachedTransformation()->Put(crc, 4); + AttachedTransformation()->PutWord32(m_totalLen, LITTLE_ENDIAN_ORDER); + + m_filetime = 0; + m_filename.clear(); + m_comment.clear(); +} + +void Gzip::SetComment(const std::string& comment, bool throwOnEncodingError) +{ + if(throwOnEncodingError) + { + for(size_t i = 0; i < comment.length(); i++) { + const char c = comment[i]; + if(!Is8859Character(c)) + throw InvalidDataFormat("The comment is not ISO/IEC 8859-1 encoded"); + } + } + + m_comment = comment; +} + +void Gzip::SetFilename(const std::string& filename, bool throwOnEncodingError) +{ + if(throwOnEncodingError) + { + for(size_t i = 0; i < filename.length(); i++) { + const char c = filename[i]; + if(!Is8859Character(c)) + throw InvalidDataFormat("The filename is not ISO/IEC 8859-1 encoded"); + } + } + + m_filename = filename; +} + +// ************************************************************* + +Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation) + : Inflator(attachment, repeat, propagation), m_length(0), m_filetime(0) +{ +} + +void Gunzip::ProcessPrestreamHeader() +{ + m_length = 0; + m_crc.Restart(); + + m_filetime = 0; + m_filename.clear(); + m_comment.clear(); + + byte buf[6]; + byte b, flags; + + if (m_inQueue.Get(buf, 2)!=2) throw HeaderErr(); + if (buf[0] != MAGIC1 || buf[1] != MAGIC2) throw HeaderErr(); + if (!m_inQueue.Get(b) || (b != DEFLATED)) throw HeaderErr(); // skip CM flag + if (!m_inQueue.Get(flags)) throw HeaderErr(); + if (flags & (ENCRYPTED | CONTINUED)) throw HeaderErr(); + if (m_inQueue.GetWord32(m_filetime, LITTLE_ENDIAN_ORDER) != 4) throw HeaderErr(); + if (m_inQueue.Skip(2)!=2) throw HeaderErr(); // Skip extra flags and OS type + + if (flags & EXTRA_FIELDS) // skip extra fields + { + word16 length; + if (m_inQueue.GetWord16(length, LITTLE_ENDIAN_ORDER) != 2) throw HeaderErr(); + if (m_inQueue.Skip(length)!=length) throw HeaderErr(); + } + + if (flags & FILENAME) // extract filename + { + do + { + if(!m_inQueue.Get(b)) throw HeaderErr(); + if(b) m_filename.append( 1, (char)b ); + } + while (b); + } + + if (flags & COMMENTS) // extract comments + { + do + { + if(!m_inQueue.Get(b)) throw HeaderErr(); + if(b) m_comment.append( 1, (char)b ); + } + while (b); + } +} + +void Gunzip::ProcessDecompressedData(const byte *inString, size_t length) +{ + AttachedTransformation()->Put(inString, length); + m_crc.Update(inString, length); + m_length += (word32)length; +} + +void Gunzip::ProcessPoststreamTail() +{ + SecByteBlock crc(4); + if (m_inQueue.Get(crc, 4) != 4) + throw TailErr(); + if (!m_crc.Verify(crc)) + throw CrcErr(); + + word32 lengthCheck; + if (m_inQueue.GetWord32(lengthCheck, LITTLE_ENDIAN_ORDER) != 4) + throw TailErr(); + if (lengthCheck != m_length) + throw LengthErr(); +} + +const std::string& Gunzip::GetComment(bool throwOnEncodingError) const +{ + if(throwOnEncodingError) + { + for(size_t i = 0; i < m_comment.length(); i++) { + const char c = m_comment[i]; + if(!Is8859Character(c)) + throw InvalidDataFormat("The comment is not ISO/IEC 8859-1 encoded"); + } + } + + return m_comment; +} + +const std::string& Gunzip::GetFilename(bool throwOnEncodingError) const +{ + if(throwOnEncodingError) + { + for(size_t i = 0; i < m_filename.length(); i++) { + const char c = m_filename[i]; + if(!Is8859Character(c)) + throw InvalidDataFormat("The filename is not ISO/IEC 8859-1 encoded"); + } + } + + return m_filename; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/gzip.h b/external/ours/library/crypto/src/shared/original/gzip.h new file mode 100755 index 000000000..b05feb4c4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/gzip.h @@ -0,0 +1,144 @@ +// gzip.h - originally written and placed in the public domain by Wei Dai + +/// \file gzip.h +/// \brief GZIP compression and decompression (RFC 1952) + +#ifndef CRYPTOPP_GZIP_H +#define CRYPTOPP_GZIP_H + +#include "cryptlib.h" +#include "zdeflate.h" +#include "zinflate.h" +#include "crc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief GZIP Compression (RFC 1952) +class Gzip : public Deflator +{ +public: + /// \brief Construct a Gzip compressor + /// \param attachment an attached transformation + /// \param deflateLevel the deflate level + /// \param log2WindowSize the window size + /// \param detectUncompressible flag to detect if data is compressible + /// \details detectUncompressible makes it faster to process uncompressible files, but + /// if a file has both compressible and uncompressible parts, it may fail to compress + /// some of the compressible parts. + Gzip(BufferedTransformation *attachment=NULLPTR, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true) + : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible), m_totalLen(0), m_filetime(0) { } + + /// \brief Construct a Gzip compressor + /// \param parameters a set of NameValuePairs to initialize this object + /// \param attachment an attached transformation + /// \details Possible parameter names: Log2WindowSize, DeflateLevel, DetectUncompressible + Gzip(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULLPTR) + : Deflator(parameters, attachment), m_totalLen(0), m_filetime(0) + { + IsolatedInitialize(parameters); + } + + /// \param filetime the filetime to set in the header. The application is responsible for setting it. + void SetFiletime(word32 filetime) { m_filetime = filetime; } + + /// \param filename the original filename to set in the header. The application is responsible for setting it. + /// RFC 1952 requires a ISO/IEC 8859-1 encoding. + /// \param throwOnEncodingError if throwOnEncodingError is true, then the filename is checked to ensure it is + /// ISO/IEC 8859-1 encoded. If the filename does not adhere to ISO/IEC 8859-1, then a InvalidDataFormat + /// is thrown. If throwOnEncodingError is false then the filename is not checked. + void SetFilename(const std::string& filename, bool throwOnEncodingError = false); + + /// \param comment the comment to set in the header. The application is responsible for setting it. + /// RFC 1952 requires a ISO/IEC 8859-1 encoding. + /// \param throwOnEncodingError if throwOnEncodingError is true, then the comment is checked to ensure it is + /// ISO/IEC 8859-1 encoded. If the comment does not adhere to ISO/IEC 8859-1, then a InvalidDataFormat + /// is thrown. If throwOnEncodingError is false then the comment is not checked. + void SetComment(const std::string& comment, bool throwOnEncodingError = false); + + void IsolatedInitialize(const NameValuePairs ¶meters); + +protected: + enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header + DEFLATED=8, FAST=4, SLOW=2}; + + enum FLAG_MASKS { + FILENAME=8, COMMENTS=16}; + + void WritePrestreamHeader(); + void ProcessUncompressedData(const byte *string, size_t length); + void WritePoststreamTail(); + + word32 m_totalLen; + CRC32 m_crc; + + word32 m_filetime; + std::string m_filename; + std::string m_comment; +}; + +/// \brief GZIP Decompression (RFC 1952) +class Gunzip : public Inflator +{ +public: + typedef Inflator::Err Err; + + /// \brief Exception thrown when a header decoding error occurs + class HeaderErr : public Err {public: HeaderErr() : Err(INVALID_DATA_FORMAT, "Gunzip: header decoding error") {}}; + /// \brief Exception thrown when the tail is too short + class TailErr : public Err {public: TailErr() : Err(INVALID_DATA_FORMAT, "Gunzip: tail too short") {}}; + /// \brief Exception thrown when a CRC error occurs + class CrcErr : public Err {public: CrcErr() : Err(DATA_INTEGRITY_CHECK_FAILED, "Gunzip: CRC check error") {}}; + /// \brief Exception thrown when a length error occurs + class LengthErr : public Err {public: LengthErr() : Err(DATA_INTEGRITY_CHECK_FAILED, "Gunzip: length check error") {}}; + + /// \brief Construct a Gunzip decompressor + /// \param attachment an attached transformation + /// \param repeat decompress multiple compressed streams in series + /// \param autoSignalPropagation 0 to turn off MessageEnd signal + Gunzip(BufferedTransformation *attachment = NULLPTR, bool repeat = false, int autoSignalPropagation = -1); + + /// \return the filetime of the stream as set in the header. The application is responsible for setting it on the decompressed file. + word32 GetFiletime() const { return m_filetime; } + + /// \return the filename of the stream as set in the header. The application is responsible for setting it on the decompressed file. + /// \param throwOnEncodingError if throwOnEncodingError is true, then the filename is checked to ensure it is + /// ISO/IEC 8859-1 encoded. If the filename does not adhere to ISO/IEC 8859-1, then a InvalidDataFormat is thrown. + /// If throwOnEncodingError is false then the filename is not checked. + const std::string& GetFilename(bool throwOnEncodingError = false) const; + + /// \return the comment of the stream as set in the header. + /// \param throwOnEncodingError if throwOnEncodingError is true, then the comment is checked to ensure it is + /// ISO/IEC 8859-1 encoded. If the comment does not adhere to ISO/IEC 8859-1, then a InvalidDataFormat is thrown. + /// If throwOnEncodingError is false then the comment is not checked. + const std::string& GetComment(bool throwOnEncodingError = false) const; + +protected: + enum { + /// \brief First header magic value + MAGIC1=0x1f, + /// \brief Second header magic value + MAGIC2=0x8b, + /// \brief Deflated flag + DEFLATED=8 + }; + + enum FLAG_MASKS { + CONTINUED=2, EXTRA_FIELDS=4, FILENAME=8, COMMENTS=16, ENCRYPTED=32}; + + unsigned int MaxPrestreamHeaderSize() const {return 1024;} + void ProcessPrestreamHeader(); + void ProcessDecompressedData(const byte *string, size_t length); + unsigned int MaxPoststreamTailSize() const {return 8;} + void ProcessPoststreamTail(); + + word32 m_length; + CRC32 m_crc; + + word32 m_filetime; + std::string m_filename; + std::string m_comment; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/hashfwd.h b/external/ours/library/crypto/src/shared/original/hashfwd.h new file mode 100755 index 000000000..49c2b02a2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hashfwd.h @@ -0,0 +1,38 @@ +// hashfwd.h - written and placed in the public domain by Jeffrey Walton + +/// \file hashfwd.h +/// \brief Forward declarations for hash functions used in signature encoding methods + +#ifndef CRYPTOPP_HASHFWD_H +#define CRYPTOPP_HASHFWD_H + +#include "config.h" + +NAMESPACE_BEGIN(CryptoPP) + +class SHA1; +class SHA224; +class SHA256; +class SHA384; +class SHA512; + +class SHA3_256; +class SHA3_384; +class SHA3_512; + +class SHAKE128; +class SHAKE256; + +class Tiger; +class RIPEMD128; +class RIPEMD160; +class Whirlpool; + +namespace Weak1 { + class MD2; + class MD5; +} + +NAMESPACE_END + +#endif // CRYPTOPP_HASHFWD_H diff --git a/external/ours/library/crypto/src/shared/original/hc128.cpp b/external/ours/library/crypto/src/shared/original/hc128.cpp new file mode 100755 index 000000000..74f67c171 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hc128.cpp @@ -0,0 +1,279 @@ +// hc128.cpp - written and placed in the public domain by Jeffrey Walton +// based on public domain code by Hongjun Wu. +// +// The reference materials and source files are available at +// The eSTREAM Project, http://www.ecrypt.eu.org/stream/e2-hc128.html. + +#include "pch.h" +#include "config.h" + +#include "hc128.h" +#include "secblock.h" +#include "misc.h" + +/*h1 function*/ +#define h1(x, y) { \ + byte a,c; \ + a = (byte) (x); \ + c = (byte) ((x) >> 16); \ + y = (m_T[512+a])+(m_T[512+256+c]); \ +} + +/*h2 function*/ +#define h2(x, y) { \ + byte a,c; \ + a = (byte) (x); \ + c = (byte) ((x) >> 16); \ + y = (m_T[a])+(m_T[256+c]); \ +} + +/*one step of HC-128, update P and generate 32 bits keystream*/ +#define step_P(u,v,a,b,c,d,n){ \ + word32 tem0,tem1,tem2,tem3; \ + h1(m_X[(d)],tem3); \ + tem0 = rotrConstant<23>(m_T[(v)]); \ + tem1 = rotrConstant<10>(m_X[(c)]); \ + tem2 = rotrConstant<8>(m_X[(b)]); \ + (m_T[(u)]) += tem2+(tem0 ^ tem1); \ + (m_X[(a)]) = (m_T[(u)]); \ + (n) = tem3 ^ (m_T[(u)]); \ +} + +/*one step of HC-128, update Q and generate 32 bits keystream*/ +#define step_Q(u,v,a,b,c,d,n){ \ + word32 tem0,tem1,tem2,tem3; \ + h2(m_Y[(d)],tem3); \ + tem0 = rotrConstant<(32-23)>(m_T[(v)]); \ + tem1 = rotrConstant<(32-10)>(m_Y[(c)]); \ + tem2 = rotrConstant<(32-8)>(m_Y[(b)]); \ + (m_T[(u)]) += tem2 + (tem0 ^ tem1); \ + (m_Y[(a)]) = (m_T[(u)]); \ + (n) = tem3 ^ (m_T[(u)]) ; \ +} + +/*update table P*/ +#define update_P(u,v,a,b,c,d){ \ + word32 tem0,tem1,tem2,tem3; \ + tem0 = rotrConstant<23>(m_T[(v)]); \ + tem1 = rotrConstant<10>(m_X[(c)]); \ + tem2 = rotrConstant<8>(m_X[(b)]); \ + h1(m_X[(d)],tem3); \ + (m_T[(u)]) = ((m_T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ + (m_X[(a)]) = (m_T[(u)]); \ +} + +/*update table Q*/ +#define update_Q(u,v,a,b,c,d){ \ + word32 tem0,tem1,tem2,tem3; \ + tem0 = rotrConstant<(32-23)>(m_T[(v)]); \ + tem1 = rotrConstant<(32-10)>(m_Y[(c)]); \ + tem2 = rotrConstant<(32-8)>(m_Y[(b)]); \ + h2(m_Y[(d)],tem3); \ + (m_T[(u)]) = ((m_T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ + (m_Y[(a)]) = (m_T[(u)]); \ +} + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::rotrConstant; + +inline word32 f1(word32 x) +{ + return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ ((x) >> 3); +} + +inline word32 f2(word32 x) +{ + return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ ((x) >> 10); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +/*16 steps of HC-128, generate 512 bits keystream*/ +void HC128Policy::GenerateKeystream(word32 keystream[16]) +{ + unsigned int cc = m_ctr & 0x1ff; + unsigned int dd = (cc + 16) & 0x1ff; + + if (m_ctr < 512) + { + m_ctr = (m_ctr + 16) & 0x3ff; + step_P(cc + 0, cc + 1, 0, 6, 13, 4, keystream[0]); + step_P(cc + 1, cc + 2, 1, 7, 14, 5, keystream[1]); + step_P(cc + 2, cc + 3, 2, 8, 15, 6, keystream[2]); + step_P(cc + 3, cc + 4, 3, 9, 0, 7, keystream[3]); + step_P(cc + 4, cc + 5, 4, 10, 1, 8, keystream[4]); + step_P(cc + 5, cc + 6, 5, 11, 2, 9, keystream[5]); + step_P(cc + 6, cc + 7, 6, 12, 3, 10, keystream[6]); + step_P(cc + 7, cc + 8, 7, 13, 4, 11, keystream[7]); + step_P(cc + 8, cc + 9, 8, 14, 5, 12, keystream[8]); + step_P(cc + 9, cc + 10, 9, 15, 6, 13, keystream[9]); + step_P(cc + 10, cc + 11, 10, 0, 7, 14, keystream[10]); + step_P(cc + 11, cc + 12, 11, 1, 8, 15, keystream[11]); + step_P(cc + 12, cc + 13, 12, 2, 9, 0, keystream[12]); + step_P(cc + 13, cc + 14, 13, 3, 10, 1, keystream[13]); + step_P(cc + 14, cc + 15, 14, 4, 11, 2, keystream[14]); + step_P(cc + 15, dd + 0, 15, 5, 12, 3, keystream[15]); + } + else + { + m_ctr = (m_ctr + 16) & 0x3ff; + step_Q(512 + cc + 0, 512 + cc + 1, 0, 6, 13, 4, keystream[0]); + step_Q(512 + cc + 1, 512 + cc + 2, 1, 7, 14, 5, keystream[1]); + step_Q(512 + cc + 2, 512 + cc + 3, 2, 8, 15, 6, keystream[2]); + step_Q(512 + cc + 3, 512 + cc + 4, 3, 9, 0, 7, keystream[3]); + step_Q(512 + cc + 4, 512 + cc + 5, 4, 10, 1, 8, keystream[4]); + step_Q(512 + cc + 5, 512 + cc + 6, 5, 11, 2, 9, keystream[5]); + step_Q(512 + cc + 6, 512 + cc + 7, 6, 12, 3, 10, keystream[6]); + step_Q(512 + cc + 7, 512 + cc + 8, 7, 13, 4, 11, keystream[7]); + step_Q(512 + cc + 8, 512 + cc + 9, 8, 14, 5, 12, keystream[8]); + step_Q(512 + cc + 9, 512 + cc + 10, 9, 15, 6, 13, keystream[9]); + step_Q(512 + cc + 10, 512 + cc + 11, 10, 0, 7, 14, keystream[10]); + step_Q(512 + cc + 11, 512 + cc + 12, 11, 1, 8, 15, keystream[11]); + step_Q(512 + cc + 12, 512 + cc + 13, 12, 2, 9, 0, keystream[12]); + step_Q(512 + cc + 13, 512 + cc + 14, 13, 3, 10, 1, keystream[13]); + step_Q(512 + cc + 14, 512 + cc + 15, 14, 4, 11, 2, keystream[14]); + step_Q(512 + cc + 15, 512 + dd + 0, 15, 5, 12, 3, keystream[15]); + } +} + +/*16 steps of HC-128, without generating keystream, */ +/*but use the outputs to update P and Q*/ +void HC128Policy::SetupUpdate() /*each time 16 steps*/ +{ + unsigned int cc = m_ctr & 0x1ff; + unsigned int dd = (cc + 16) & 0x1ff; + + if (m_ctr < 512) + { + m_ctr = (m_ctr + 16) & 0x3ff; + update_P(cc + 0, cc + 1, 0, 6, 13, 4); + update_P(cc + 1, cc + 2, 1, 7, 14, 5); + update_P(cc + 2, cc + 3, 2, 8, 15, 6); + update_P(cc + 3, cc + 4, 3, 9, 0, 7); + update_P(cc + 4, cc + 5, 4, 10, 1, 8); + update_P(cc + 5, cc + 6, 5, 11, 2, 9); + update_P(cc + 6, cc + 7, 6, 12, 3, 10); + update_P(cc + 7, cc + 8, 7, 13, 4, 11); + update_P(cc + 8, cc + 9, 8, 14, 5, 12); + update_P(cc + 9, cc + 10, 9, 15, 6, 13); + update_P(cc + 10, cc + 11, 10, 0, 7, 14); + update_P(cc + 11, cc + 12, 11, 1, 8, 15); + update_P(cc + 12, cc + 13, 12, 2, 9, 0); + update_P(cc + 13, cc + 14, 13, 3, 10, 1); + update_P(cc + 14, cc + 15, 14, 4, 11, 2); + update_P(cc + 15, dd + 0, 15, 5, 12, 3); + } + else + { + m_ctr = (m_ctr + 16) & 0x3ff; + update_Q(512 + cc + 0, 512 + cc + 1, 0, 6, 13, 4); + update_Q(512 + cc + 1, 512 + cc + 2, 1, 7, 14, 5); + update_Q(512 + cc + 2, 512 + cc + 3, 2, 8, 15, 6); + update_Q(512 + cc + 3, 512 + cc + 4, 3, 9, 0, 7); + update_Q(512 + cc + 4, 512 + cc + 5, 4, 10, 1, 8); + update_Q(512 + cc + 5, 512 + cc + 6, 5, 11, 2, 9); + update_Q(512 + cc + 6, 512 + cc + 7, 6, 12, 3, 10); + update_Q(512 + cc + 7, 512 + cc + 8, 7, 13, 4, 11); + update_Q(512 + cc + 8, 512 + cc + 9, 8, 14, 5, 12); + update_Q(512 + cc + 9, 512 + cc + 10, 9, 15, 6, 13); + update_Q(512 + cc + 10, 512 + cc + 11, 10, 0, 7, 14); + update_Q(512 + cc + 11, 512 + cc + 12, 11, 1, 8, 15); + update_Q(512 + cc + 12, 512 + cc + 13, 12, 2, 9, 0); + update_Q(512 + cc + 13, 512 + cc + 14, 13, 3, 10, 1); + update_Q(512 + cc + 14, 512 + cc + 15, 14, 4, 11, 2); + update_Q(512 + cc + 15, 512 + dd + 0, 15, 5, 12, 3); + } +} + +void HC128Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *userKey, size_t keylen) +{ + CRYPTOPP_UNUSED(params); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_key.begin(), 4, userKey, keylen); + for (unsigned int i = 4; i < 8; i++) + m_key[i] = m_key[i - 4]; +} + +void HC128Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + while (iterationCount--) + { + word32 keystream[16]; + GenerateKeystream(keystream); + + PutWord(false, LITTLE_ENDIAN_ORDER, output + 0, keystream[0]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 4, keystream[1]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 8, keystream[2]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 12, keystream[3]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 16, keystream[4]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 20, keystream[5]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 24, keystream[6]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 28, keystream[7]); + + PutWord(false, LITTLE_ENDIAN_ORDER, output + 32, keystream[8]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 36, keystream[9]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 40, keystream[10]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 44, keystream[11]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 48, keystream[12]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 52, keystream[13]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 56, keystream[14]); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 60, keystream[15]); + + // If AdditiveCipherTemplate does not have an accumulated keystream + // then it will ask OperateKeystream to generate one. Optionally it + // will ask for an XOR of the input with the keystream while + // writing the result to the output buffer. In all cases the + // keystream is written to the output buffer. The optional part is + // adding the input buffer and keystream. + if ((operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL)) + { + xorbuf(output, input, BYTES_PER_ITERATION); + input += BYTES_PER_ITERATION; + } + + output += BYTES_PER_ITERATION; + } +} + +void HC128Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_iv.begin(), 4, iv, length); + for (unsigned int i = 4; i < 8; i++) + m_iv[i] = m_iv[i - 4]; + + /* expand the key and IV into the table T */ + /* (expand the key and IV into the table P and Q) */ + + for (unsigned int i = 0; i < 8; i++) + m_T[i] = m_key[i]; + for (unsigned int i = 8; i < 16; i++) + m_T[i] = m_iv[i - 8]; + + for (unsigned int i = 16; i < (256 + 16); i++) + m_T[i] = f2(m_T[i - 2]) + m_T[i - 7] + f1(m_T[i - 15]) + m_T[i - 16] + i; + + for (unsigned int i = 0; i < 16; i++) + m_T[i] = m_T[256 + i]; + + for (unsigned int i = 16; i < 1024; i++) + m_T[i] = f2(m_T[i - 2]) + m_T[i - 7] + f1(m_T[i - 15]) + m_T[i - 16] + 256 + i; + + /* initialize counter1024, X and Y */ + m_ctr = 0; + for (unsigned int i = 0; i < 16; i++) + m_X[i] = m_T[512 - 16 + i]; + for (unsigned int i = 0; i < 16; i++) + m_Y[i] = m_T[512 + 512 - 16 + i]; + + /* run the cipher 1024 steps before generating the output */ + for (unsigned int i = 0; i < 64; i++) + SetupUpdate(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/hc128.h b/external/ours/library/crypto/src/shared/original/hc128.h new file mode 100755 index 000000000..a43eeeb38 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hc128.h @@ -0,0 +1,67 @@ +// hc128.h - written and placed in the public domain by Jeffrey Walton +// based on public domain code by Hongjun Wu. +// +// The reference materials and source files are available at +// The eSTREAM Project, http://www.ecrypt.eu.org/stream/e2-hc128.html. + +/// \file hc128.h +/// \brief Classes for HC-128 stream cipher +/// \sa The +/// eSTREAM Project | HC-128 and +/// Crypto++ Wiki | HC-128. +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_HC128_H +#define CRYPTOPP_HC128_H + +#include "strciphr.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief HC-128 stream cipher information +/// \since Crypto++ 8.0 +struct HC128Info : public FixedKeyLength<16, SimpleKeyingInterface::UNIQUE_IV, 16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "HC-128"; } +}; + +/// \brief HC-128 stream cipher implementation +/// \since Crypto++ 8.0 +class HC128Policy : public AdditiveCipherConcretePolicy, public HC128Info +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); + bool CanOperateKeystream() const { return true; } + bool CipherIsRandomAccess() const { return false; } + + void GenerateKeystream(word32* keystream); + void SetupUpdate(); + +private: + FixedSizeSecBlock m_X; + FixedSizeSecBlock m_Y; + FixedSizeSecBlock m_key; + FixedSizeSecBlock m_iv; + word32 m_T[1024]; + word32 m_ctr; +}; + +/// \brief HC-128 stream cipher +/// \details HC-128 is a stream cipher developed by Hongjun Wu. HC-128 is one of the +/// final four Profile 1 (software) ciphers selected for the eSTREAM portfolio. +/// \sa The +/// eSTREAM Project | HC-128 and +/// Crypto++ Wiki | HC-128. +/// \since Crypto++ 8.0 +struct HC128 : public HC128Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, HC128Info> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_HC128_H diff --git a/external/ours/library/crypto/src/shared/original/hc256.cpp b/external/ours/library/crypto/src/shared/original/hc256.cpp new file mode 100755 index 000000000..9259b87a7 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hc256.cpp @@ -0,0 +1,158 @@ +// hc256.cpp - written and placed in the public domain by Jeffrey Walton +// based on public domain code by Hongjun Wu. +// +// The reference materials and source files are available at +// The eSTREAM Project, http://www.ecrypt.eu.org/stream/hc256.html. + +#include "pch.h" +#include "config.h" + +#include "hc256.h" +#include "secblock.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::rotrConstant; + +inline word32 f1(word32 x) +{ + return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ (x >> 3); +} + +inline word32 f2(word32 x) +{ + return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ (x >> 10); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +inline word32 HC256Policy::H1(word32 u) +{ + word32 tem; + byte a, b, c, d; + a = (byte)(u); + b = (byte)(u >> 8); + c = (byte)(u >> 16); + d = (byte)(u >> 24); + tem = m_Q[a] + m_Q[256 + b] + m_Q[512 + c] + m_Q[768 + d]; + return (tem); +} + +inline word32 HC256Policy::H2(word32 u) +{ + word32 tem; + byte a, b, c, d; + a = (byte)(u); + b = (byte)(u >> 8); + c = (byte)(u >> 16); + d = (byte)(u >> 24); + tem = m_P[a] + m_P[256 + b] + m_P[512 + c] + m_P[768 + d]; + return (tem); +} + +inline word32 HC256Policy::Generate() /*one step of the cipher*/ +{ + word32 i, i3, i10, i12, i1023; + word32 output; + + i = m_ctr & 0x3ff; + i3 = (i - 3) & 0x3ff; + i10 = (i - 10) & 0x3ff; + i12 = (i - 12) & 0x3ff; + i1023 = (i - 1023) & 0x3ff; + + if (m_ctr < 1024) { + m_P[i] = m_P[i] + m_P[i10] + (rotrConstant<10>(m_P[i3]) ^ rotrConstant<23>(m_P[i1023])) + m_Q[(m_P[i3] ^ m_P[i1023]) & 0x3ff]; + output = H1(m_P[i12]) ^ m_P[i]; + } + else { + m_Q[i] = m_Q[i] + m_Q[i10] + (rotrConstant<10>(m_Q[i3]) ^ rotrConstant<23>(m_Q[i1023])) + m_P[(m_Q[i3] ^ m_Q[i1023]) & 0x3ff]; + output = H2(m_Q[i12]) ^ m_Q[i]; + } + m_ctr = (m_ctr + 1) & 0x7ff; + return (output); +} + +void HC256Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *userKey, size_t keylen) +{ + CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(keylen); + CRYPTOPP_ASSERT(keylen == 32); + + for (unsigned int i = 0; i < 8; i++) + m_key[i] = 0; + + for (unsigned int i = 0; i < 32; i++) + { + m_key[i >> 2] = m_key[i >> 2] | userKey[i]; + m_key[i >> 2] = rotlConstant<8>(m_key[i >> 2]); + } +} + +void HC256Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + while (iterationCount--) + { + PutWord(false, LITTLE_ENDIAN_ORDER, output + 0, Generate()); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 4, Generate()); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 8, Generate()); + PutWord(false, LITTLE_ENDIAN_ORDER, output + 12, Generate()); + + // If AdditiveCipherTemplate does not have an accumulated keystream + // then it will ask OperateKeystream to generate one. Optionally it + // will ask for an XOR of the input with the keystream while + // writing the result to the output buffer. In all cases the + // keystream is written to the output buffer. The optional part is + // adding the input buffer and keystream. + if ((operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL)) + { + xorbuf(output, input, BYTES_PER_ITERATION); + input += BYTES_PER_ITERATION; + } + + output += BYTES_PER_ITERATION; + } +} + +void HC256Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length == 32); + + /* initialize the iv */ + word32 W[2560]; + for (unsigned int i = 0; i < 8; i++) + m_iv[i] = 0; + + for (unsigned int i = 0; i < 32; i++) + { + m_iv[i >> 2] = m_iv[i >> 2] | iv[i]; + m_iv[i >> 2] = rotlConstant<8>(m_iv[i >> 2]); + } + + /* setup the table P and Q */ + + for (unsigned int i = 0; i < 8; i++) + W[i] = m_key[i]; + for (unsigned int i = 8; i < 16; i++) + W[i] = m_iv[i - 8]; + + for (unsigned int i = 16; i < 2560; i++) + W[i] = f2(W[i - 2]) + W[i - 7] + f1(W[i - 15]) + W[i - 16] + i; + + for (unsigned int i = 0; i < 1024; i++) + m_P[i] = W[i + 512]; + for (unsigned int i = 0; i < 1024; i++) + m_Q[i] = W[i + 1536]; + + m_ctr = 0; + + /* run the cipher 4096 steps before generating the output */ + for (unsigned int i = 0; i < 4096; i++) + Generate(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/hc256.h b/external/ours/library/crypto/src/shared/original/hc256.h new file mode 100755 index 000000000..ccd1ca050 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hc256.h @@ -0,0 +1,67 @@ +// hc256.h - written and placed in the public domain by Jeffrey Walton +// based on public domain code by Hongjun Wu. +// +// The reference materials and source files are available at +// The eSTREAM Project, http://www.ecrypt.eu.org/stream/hc256.html. + +/// \file hc256.h +/// \brief Classes for HC-256 stream cipher +/// \sa The +/// eSTREAM Project | HC-256 and +/// Crypto++ Wiki | HC-128. +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_HC256_H +#define CRYPTOPP_HC256_H + +#include "strciphr.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief HC-256 stream cipher information +/// \since Crypto++ 8.0 +struct HC256Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 32> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "HC-256"; } +}; + +/// \brief HC-256 stream cipher implementation +/// \since Crypto++ 8.0 +class HC256Policy : public AdditiveCipherConcretePolicy, public HC256Info +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); + bool CanOperateKeystream() const { return true; } + bool CipherIsRandomAccess() const { return false; } + + word32 H1(word32 u); + word32 H2(word32 u); + word32 Generate(); + +private: + FixedSizeSecBlock m_key; + FixedSizeSecBlock m_iv; + word32 m_P[1024]; + word32 m_Q[1024]; + word32 m_ctr; +}; + +/// \brief HC-256 stream cipher +/// \details HC-256 is a stream cipher developed by Hongjun Wu. HC-256 is the +/// successor to HC-128 from the eSTREAM project. +/// \sa The +/// eSTREAM Project | HC-256 and +/// Crypto++ Wiki | HC-128. +/// \since Crypto++ 8.0 +struct HC256 : public HC256Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, HC256Info> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_HC256_H diff --git a/external/ours/library/crypto/src/shared/original/hex.cpp b/external/ours/library/crypto/src/shared/original/hex.cpp new file mode 100755 index 000000000..d347241b5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hex.cpp @@ -0,0 +1,58 @@ +// hex.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "hex.h" + +NAMESPACE_BEGIN(CryptoPP) +ANONYMOUS_NAMESPACE_BEGIN + +const byte s_vecUpper[] = "0123456789ABCDEF"; +const byte s_vecLower[] = "0123456789abcdef"; +const int s_array[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +ANONYMOUS_NAMESPACE_END + +void HexEncoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_vecUpper[0] : &s_vecLower[0], false)(Name::Log2Base(), 4, true))); +} + +void HexDecoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 4, true))); +} + +// Unrolled initialization, http://github.com/weidai11/cryptopp/issues/376 +const int *HexDecoder::GetDefaultDecodingLookupArray() +{ + return s_array; +} + +NAMESPACE_END + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/hex.h b/external/ours/library/crypto/src/shared/original/hex.h new file mode 100755 index 000000000..05f106871 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hex.h @@ -0,0 +1,50 @@ +// hex.h - originally written and placed in the public domain by Wei Dai + +/// \file hex.h +/// \brief Classes for HexEncoder and HexDecoder + +#ifndef CRYPTOPP_HEX_H +#define CRYPTOPP_HEX_H + +#include "cryptlib.h" +#include "basecode.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Converts given data to base 16 +class CRYPTOPP_DLL HexEncoder : public SimpleProxyFilter +{ +public: + /// \brief Construct a HexEncoder + /// \param attachment a BufferedTrasformation to attach to this object + /// \param uppercase a flag indicating uppercase output + /// \param groupSize the size of the output grouping + /// \param separator the separator to use between groups + /// \param terminator the terminator append after processing + HexEncoder(BufferedTransformation *attachment = NULLPTR, bool uppercase = true, int groupSize = 0, const std::string &separator = ":", const std::string &terminator = "") + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), groupSize)(Name::Separator(), ConstByteArrayParameter(separator))(Name::Terminator(), ConstByteArrayParameter(terminator))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +/// \brief Decode base 16 data back to bytes +class CRYPTOPP_DLL HexDecoder : public BaseN_Decoder +{ +public: + /// \brief Construct a HexDecoder + /// \param attachment a BufferedTrasformation to attach to this object + HexDecoder(BufferedTransformation *attachment = NULLPTR) + : BaseN_Decoder(GetDefaultDecodingLookupArray(), 4, attachment) {} + + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/hight.cpp b/external/ours/library/crypto/src/shared/original/hight.cpp new file mode 100755 index 000000000..8b6f28ed1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hight.cpp @@ -0,0 +1,271 @@ +// lea.cpp - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "HIGHT: A 128-Bit Block Cipher for Fast Encryption on Common +// Processors" by Deukjo Hong, Jung-Keun Lee, Dong-Chan Kim, Daesung Kwon, +// Kwon Ho Ryu, and Dong-Geon Lee. +// +// This implementation is based on source files found in a zip file at the +// Korea Internet and Security Agency (https://www.kisa.or.kr/eng/main.jsp). +// The zip files was downloaded from the Korean language area of the site so we +// don't have a url or english zip filename to cite. The source filename from +// the zip is KISA_HIGHT_ECB.c. + +#include "pch.h" +#include "config.h" + +#include "hight.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; + +const byte DELTA[128] = { + 0x5A,0x6D,0x36,0x1B,0x0D,0x06,0x03,0x41, + 0x60,0x30,0x18,0x4C,0x66,0x33,0x59,0x2C, + 0x56,0x2B,0x15,0x4A,0x65,0x72,0x39,0x1C, + 0x4E,0x67,0x73,0x79,0x3C,0x5E,0x6F,0x37, + 0x5B,0x2D,0x16,0x0B,0x05,0x42,0x21,0x50, + 0x28,0x54,0x2A,0x55,0x6A,0x75,0x7A,0x7D, + 0x3E,0x5F,0x2F,0x17,0x4B,0x25,0x52,0x29, + 0x14,0x0A,0x45,0x62,0x31,0x58,0x6C,0x76, + 0x3B,0x1D,0x0E,0x47,0x63,0x71,0x78,0x7C, + 0x7E,0x7F,0x3F,0x1F,0x0F,0x07,0x43,0x61, + 0x70,0x38,0x5C,0x6E,0x77,0x7B,0x3D,0x1E, + 0x4F,0x27,0x53,0x69,0x34,0x1A,0x4D,0x26, + 0x13,0x49,0x24,0x12,0x09,0x04,0x02,0x01, + 0x40,0x20,0x10,0x08,0x44,0x22,0x11,0x48, + 0x64,0x32,0x19,0x0C,0x46,0x23,0x51,0x68, + 0x74,0x3A,0x5D,0x2E,0x57,0x6B,0x35,0x5A +}; + +const byte HIGHT_F0[256] = { + 0x00,0x86,0x0D,0x8B,0x1A,0x9C,0x17,0x91, + 0x34,0xB2,0x39,0xBF,0x2E,0xA8,0x23,0xA5, + 0x68,0xEE,0x65,0xE3,0x72,0xF4,0x7F,0xF9, + 0x5C,0xDA,0x51,0xD7,0x46,0xC0,0x4B,0xCD, + 0xD0,0x56,0xDD,0x5B,0xCA,0x4C,0xC7,0x41, + 0xE4,0x62,0xE9,0x6F,0xFE,0x78,0xF3,0x75, + 0xB8,0x3E,0xB5,0x33,0xA2,0x24,0xAF,0x29, + 0x8C,0x0A,0x81,0x07,0x96,0x10,0x9B,0x1D, + 0xA1,0x27,0xAC,0x2A,0xBB,0x3D,0xB6,0x30, + 0x95,0x13,0x98,0x1E,0x8F,0x09,0x82,0x04, + 0xC9,0x4F,0xC4,0x42,0xD3,0x55,0xDE,0x58, + 0xFD,0x7B,0xF0,0x76,0xE7,0x61,0xEA,0x6C, + 0x71,0xF7,0x7C,0xFA,0x6B,0xED,0x66,0xE0, + 0x45,0xC3,0x48,0xCE,0x5F,0xD9,0x52,0xD4, + 0x19,0x9F,0x14,0x92,0x03,0x85,0x0E,0x88, + 0x2D,0xAB,0x20,0xA6,0x37,0xB1,0x3A,0xBC, + 0x43,0xC5,0x4E,0xC8,0x59,0xDF,0x54,0xD2, + 0x77,0xF1,0x7A,0xFC,0x6D,0xEB,0x60,0xE6, + 0x2B,0xAD,0x26,0xA0,0x31,0xB7,0x3C,0xBA, + 0x1F,0x99,0x12,0x94,0x05,0x83,0x08,0x8E, + 0x93,0x15,0x9E,0x18,0x89,0x0F,0x84,0x02, + 0xA7,0x21,0xAA,0x2C,0xBD,0x3B,0xB0,0x36, + 0xFB,0x7D,0xF6,0x70,0xE1,0x67,0xEC,0x6A, + 0xCF,0x49,0xC2,0x44,0xD5,0x53,0xD8,0x5E, + 0xE2,0x64,0xEF,0x69,0xF8,0x7E,0xF5,0x73, + 0xD6,0x50,0xDB,0x5D,0xCC,0x4A,0xC1,0x47, + 0x8A,0x0C,0x87,0x01,0x90,0x16,0x9D,0x1B, + 0xBE,0x38,0xB3,0x35,0xA4,0x22,0xA9,0x2F, + 0x32,0xB4,0x3F,0xB9,0x28,0xAE,0x25,0xA3, + 0x06,0x80,0x0B,0x8D,0x1C,0x9A,0x11,0x97, + 0x5A,0xDC,0x57,0xD1,0x40,0xC6,0x4D,0xCB, + 0x6E,0xE8,0x63,0xE5,0x74,0xF2,0x79,0xFF +}; + +const byte HIGHT_F1[256] = { + 0x00,0x58,0xB0,0xE8,0x61,0x39,0xD1,0x89, + 0xC2,0x9A,0x72,0x2A,0xA3,0xFB,0x13,0x4B, + 0x85,0xDD,0x35,0x6D,0xE4,0xBC,0x54,0x0C, + 0x47,0x1F,0xF7,0xAF,0x26,0x7E,0x96,0xCE, + 0x0B,0x53,0xBB,0xE3,0x6A,0x32,0xDA,0x82, + 0xC9,0x91,0x79,0x21,0xA8,0xF0,0x18,0x40, + 0x8E,0xD6,0x3E,0x66,0xEF,0xB7,0x5F,0x07, + 0x4C,0x14,0xFC,0xA4,0x2D,0x75,0x9D,0xC5, + 0x16,0x4E,0xA6,0xFE,0x77,0x2F,0xC7,0x9F, + 0xD4,0x8C,0x64,0x3C,0xB5,0xED,0x05,0x5D, + 0x93,0xCB,0x23,0x7B,0xF2,0xAA,0x42,0x1A, + 0x51,0x09,0xE1,0xB9,0x30,0x68,0x80,0xD8, + 0x1D,0x45,0xAD,0xF5,0x7C,0x24,0xCC,0x94, + 0xDF,0x87,0x6F,0x37,0xBE,0xE6,0x0E,0x56, + 0x98,0xC0,0x28,0x70,0xF9,0xA1,0x49,0x11, + 0x5A,0x02,0xEA,0xB2,0x3B,0x63,0x8B,0xD3, + 0x2C,0x74,0x9C,0xC4,0x4D,0x15,0xFD,0xA5, + 0xEE,0xB6,0x5E,0x06,0x8F,0xD7,0x3F,0x67, + 0xA9,0xF1,0x19,0x41,0xC8,0x90,0x78,0x20, + 0x6B,0x33,0xDB,0x83,0x0A,0x52,0xBA,0xE2, + 0x27,0x7F,0x97,0xCF,0x46,0x1E,0xF6,0xAE, + 0xE5,0xBD,0x55,0x0D,0x84,0xDC,0x34,0x6C, + 0xA2,0xFA,0x12,0x4A,0xC3,0x9B,0x73,0x2B, + 0x60,0x38,0xD0,0x88,0x01,0x59,0xB1,0xE9, + 0x3A,0x62,0x8A,0xD2,0x5B,0x03,0xEB,0xB3, + 0xF8,0xA0,0x48,0x10,0x99,0xC1,0x29,0x71, + 0xBF,0xE7,0x0F,0x57,0xDE,0x86,0x6E,0x36, + 0x7D,0x25,0xCD,0x95,0x1C,0x44,0xAC,0xF4, + 0x31,0x69,0x81,0xD9,0x50,0x08,0xE0,0xB8, + 0xF3,0xAB,0x43,0x1B,0x92,0xCA,0x22,0x7A, + 0xB4,0xEC,0x04,0x5C,0xD5,0x8D,0x65,0x3D, + 0x76,0x2E,0xC6,0x9E,0x17,0x4F,0xA7,0xFF +}; + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void HIGHT::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + CRYPTOPP_UNUSED(keyLength); + + for(unsigned int i=0; i<4; i++) { + m_rkey[i ] = userKey[i+12]; + m_rkey[i+4] = userKey[i ]; + } + + for(unsigned int i=0; i<8; i++) { + for(unsigned int j=0; j<8; j++) { + m_rkey[8+16*i+j] = static_cast(userKey[(j-i)&7] + DELTA[16*i+j]); + } + + for(unsigned int j=0; j<8; j++) { + m_rkey[8+16*i+j+8] = static_cast(userKey[((j-i)&7)+8] + DELTA[16*i+j+8]); + } + } +} + +void HIGHT::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // First Round + m_xx[1] = inBlock[1]; + m_xx[3] = inBlock[3]; + m_xx[5] = inBlock[5]; + m_xx[7] = inBlock[7]; + + m_xx[0] = (inBlock[0] + m_rkey[0]) & 0xFF; + m_xx[2] = (inBlock[2] ^ m_rkey[1]); + m_xx[4] = (inBlock[4] + m_rkey[2]) & 0xFF; + m_xx[6] = (inBlock[6] ^ m_rkey[3]); + + // Encryption Round + #define HIGHT_ENC(k, i0,i1,i2,i3,i4,i5,i6,i7) { \ + m_xx[i0] = (m_xx[i0] ^ (HIGHT_F0[m_xx[i1]] + m_rkey[4*k+3])) & 0xFF; \ + m_xx[i2] = (m_xx[i2] + (HIGHT_F1[m_xx[i3]] ^ m_rkey[4*k+2])) & 0xFF; \ + m_xx[i4] = (m_xx[i4] ^ (HIGHT_F0[m_xx[i5]] + m_rkey[4*k+1])) & 0xFF; \ + m_xx[i6] = (m_xx[i6] + (HIGHT_F1[m_xx[i7]] ^ m_rkey[4*k+0])) & 0xFF; \ + } + + HIGHT_ENC( 2, 7,6,5,4,3,2,1,0); + HIGHT_ENC( 3, 6,5,4,3,2,1,0,7); + HIGHT_ENC( 4, 5,4,3,2,1,0,7,6); + HIGHT_ENC( 5, 4,3,2,1,0,7,6,5); + HIGHT_ENC( 6, 3,2,1,0,7,6,5,4); + HIGHT_ENC( 7, 2,1,0,7,6,5,4,3); + HIGHT_ENC( 8, 1,0,7,6,5,4,3,2); + HIGHT_ENC( 9, 0,7,6,5,4,3,2,1); + HIGHT_ENC(10, 7,6,5,4,3,2,1,0); + HIGHT_ENC(11, 6,5,4,3,2,1,0,7); + HIGHT_ENC(12, 5,4,3,2,1,0,7,6); + HIGHT_ENC(13, 4,3,2,1,0,7,6,5); + HIGHT_ENC(14, 3,2,1,0,7,6,5,4); + HIGHT_ENC(15, 2,1,0,7,6,5,4,3); + HIGHT_ENC(16, 1,0,7,6,5,4,3,2); + HIGHT_ENC(17, 0,7,6,5,4,3,2,1); + HIGHT_ENC(18, 7,6,5,4,3,2,1,0); + HIGHT_ENC(19, 6,5,4,3,2,1,0,7); + HIGHT_ENC(20, 5,4,3,2,1,0,7,6); + HIGHT_ENC(21, 4,3,2,1,0,7,6,5); + HIGHT_ENC(22, 3,2,1,0,7,6,5,4); + HIGHT_ENC(23, 2,1,0,7,6,5,4,3); + HIGHT_ENC(24, 1,0,7,6,5,4,3,2); + HIGHT_ENC(25, 0,7,6,5,4,3,2,1); + HIGHT_ENC(26, 7,6,5,4,3,2,1,0); + HIGHT_ENC(27, 6,5,4,3,2,1,0,7); + HIGHT_ENC(28, 5,4,3,2,1,0,7,6); + HIGHT_ENC(29, 4,3,2,1,0,7,6,5); + HIGHT_ENC(30, 3,2,1,0,7,6,5,4); + HIGHT_ENC(31, 2,1,0,7,6,5,4,3); + HIGHT_ENC(32, 1,0,7,6,5,4,3,2); + HIGHT_ENC(33, 0,7,6,5,4,3,2,1); + + // Final Round + outBlock[1] = static_cast(m_xx[2]); + outBlock[3] = static_cast(m_xx[4]); + outBlock[5] = static_cast(m_xx[6]); + outBlock[7] = static_cast(m_xx[0]); + + outBlock[0] = static_cast(m_xx[1] + m_rkey[4]); + outBlock[2] = static_cast(m_xx[3] ^ m_rkey[5]); + outBlock[4] = static_cast(m_xx[5] + m_rkey[6]); + outBlock[6] = static_cast(m_xx[7] ^ m_rkey[7]); + + if (xorBlock) + xorbuf(outBlock, xorBlock, 8); +} + +void HIGHT::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + m_xx[2] = static_cast(inBlock[1]); + m_xx[4] = static_cast(inBlock[3]); + m_xx[6] = static_cast(inBlock[5]); + m_xx[0] = static_cast(inBlock[7]); + + m_xx[1] = static_cast(inBlock[0] - m_rkey[4]); + m_xx[3] = static_cast(inBlock[2] ^ m_rkey[5]); + m_xx[5] = static_cast(inBlock[4] - m_rkey[6]); + m_xx[7] = static_cast(inBlock[6] ^ m_rkey[7]); + + #define HIGHT_DEC(k, i0,i1,i2,i3,i4,i5,i6,i7) { \ + m_xx[i1] = (m_xx[i1] - (HIGHT_F1[m_xx[i2]] ^ m_rkey[4*k+2])) & 0xFF; \ + m_xx[i3] = (m_xx[i3] ^ (HIGHT_F0[m_xx[i4]] + m_rkey[4*k+1])) & 0xFF; \ + m_xx[i5] = (m_xx[i5] - (HIGHT_F1[m_xx[i6]] ^ m_rkey[4*k+0])) & 0xFF; \ + m_xx[i7] = (m_xx[i7] ^ (HIGHT_F0[m_xx[i0]] + m_rkey[4*k+3])) & 0xFF; \ + } + + HIGHT_DEC(33, 7,6,5,4,3,2,1,0); + HIGHT_DEC(32, 0,7,6,5,4,3,2,1); + HIGHT_DEC(31, 1,0,7,6,5,4,3,2); + HIGHT_DEC(30, 2,1,0,7,6,5,4,3); + HIGHT_DEC(29, 3,2,1,0,7,6,5,4); + HIGHT_DEC(28, 4,3,2,1,0,7,6,5); + HIGHT_DEC(27, 5,4,3,2,1,0,7,6); + HIGHT_DEC(26, 6,5,4,3,2,1,0,7); + HIGHT_DEC(25, 7,6,5,4,3,2,1,0); + HIGHT_DEC(24, 0,7,6,5,4,3,2,1); + HIGHT_DEC(23, 1,0,7,6,5,4,3,2); + HIGHT_DEC(22, 2,1,0,7,6,5,4,3); + HIGHT_DEC(21, 3,2,1,0,7,6,5,4); + HIGHT_DEC(20, 4,3,2,1,0,7,6,5); + HIGHT_DEC(19, 5,4,3,2,1,0,7,6); + HIGHT_DEC(18, 6,5,4,3,2,1,0,7); + HIGHT_DEC(17, 7,6,5,4,3,2,1,0); + HIGHT_DEC(16, 0,7,6,5,4,3,2,1); + HIGHT_DEC(15, 1,0,7,6,5,4,3,2); + HIGHT_DEC(14, 2,1,0,7,6,5,4,3); + HIGHT_DEC(13, 3,2,1,0,7,6,5,4); + HIGHT_DEC(12, 4,3,2,1,0,7,6,5); + HIGHT_DEC(11, 5,4,3,2,1,0,7,6); + HIGHT_DEC(10, 6,5,4,3,2,1,0,7); + HIGHT_DEC( 9, 7,6,5,4,3,2,1,0); + HIGHT_DEC( 8, 0,7,6,5,4,3,2,1); + HIGHT_DEC( 7, 1,0,7,6,5,4,3,2); + HIGHT_DEC( 6, 2,1,0,7,6,5,4,3); + HIGHT_DEC( 5, 3,2,1,0,7,6,5,4); + HIGHT_DEC( 4, 4,3,2,1,0,7,6,5); + HIGHT_DEC( 3, 5,4,3,2,1,0,7,6); + HIGHT_DEC( 2, 6,5,4,3,2,1,0,7); + + outBlock[1] = static_cast(m_xx[1]); + outBlock[3] = static_cast(m_xx[3]); + outBlock[5] = static_cast(m_xx[5]); + outBlock[7] = static_cast(m_xx[7]); + + outBlock[0] = static_cast(m_xx[0] - m_rkey[0]); + outBlock[2] = static_cast(m_xx[2] ^ m_rkey[1]); + outBlock[4] = static_cast(m_xx[4] - m_rkey[2]); + outBlock[6] = static_cast(m_xx[6] ^ m_rkey[3]); + + if (xorBlock) + xorbuf(outBlock, xorBlock, 8); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/hight.h b/external/ours/library/crypto/src/shared/original/hight.h new file mode 100755 index 000000000..0262382ba --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hight.h @@ -0,0 +1,81 @@ +// hight.h - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "HIGHT: A New Block Cipher Suitable for Low-Resource Device" +// by Deukjo Hong, Jaechul Sung, Seokhie Hong, Jongin Lim, Sangjin Lee, +// Bon-Seok Koo, Changhoon Lee, Donghoon Chang, Jesang Lee, Kitae Jeong, +// Hyun Kim, Jongsung Kim, and Seongtaek Chee + +/// \file hight.h +/// \brief Classes for the HIGHT block cipher +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_HIGHT_H +#define CRYPTOPP_HIGHT_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief HIGHT block cipher information +/// \since Crypto++ 8.0 +struct HIGHT_Info : public FixedBlockSize<8>, public FixedKeyLength<16> +{ + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "HIGHT"; + } +}; + +/// \brief HIGHT 64-bit block cipher +/// \details HIGHT provides 64-bit block size. The valid key size is 128-bits. +/// \note Crypto++ provides a byte oriented implementation +/// \sa HIGHT, +/// Korea Internet & Security +/// Agency website +/// \since Crypto++ 8.0 +class CRYPTOPP_NO_VTABLE HIGHT : public HIGHT_Info, public BlockCipherDocumentation +{ +public: + /// \brief HIGHT block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + + FixedSizeSecBlock m_rkey; + mutable FixedSizeSecBlock m_xx; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef HIGHT::Encryption HIGHTEncryption; +typedef HIGHT::Decryption HIGHTDecryption; + +NAMESPACE_END + +#endif // CRYPTOPP_HIGHT_H diff --git a/external/ours/library/crypto/src/shared/original/hkdf.h b/external/ours/library/crypto/src/shared/original/hkdf.h new file mode 100755 index 000000000..c62560204 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hkdf.h @@ -0,0 +1,179 @@ +// hkdf.h - written and placed in public domain by Jeffrey Walton. + +/// \file hkdf.h +/// \brief Classes for HKDF from RFC 5869 +/// \since Crypto++ 5.6.3 + +#ifndef CRYPTOPP_HKDF_H +#define CRYPTOPP_HKDF_H + +#include "cryptlib.h" +#include "secblock.h" +#include "algparam.h" +#include "hmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Extract-and-Expand Key Derivation Function (HKDF) +/// \tparam T HashTransformation class +/// \sa Cryptographic Extraction and Key +/// Derivation: The HKDF Scheme and +/// HMAC-based Extract-and-Expand Key +/// Derivation Function (HKDF) +/// \since Crypto++ 5.6.3 +template +class HKDF : public KeyDerivationFunction +{ +public: + virtual ~HKDF() {} + + static std::string StaticAlgorithmName () { + const std::string name(std::string("HKDF(") + + std::string(T::StaticAlgorithmName()) + std::string(")")); + return name; + } + + // KeyDerivationFunction interface + std::string AlgorithmName() const { + return StaticAlgorithmName(); + } + + // KeyDerivationFunction interface + size_t MaxDerivedKeyLength() const { + return static_cast(T::DIGESTSIZE) * 255; + } + + // KeyDerivationFunction interface + size_t GetValidDerivedLength(size_t keylength) const; + + // KeyDerivationFunction interface + size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const NameValuePairs& params) const; + + /// \brief Derive a key from a seed + /// \param derived the derived output buffer + /// \param derivedLen the size of the derived buffer, in bytes + /// \param secret the seed input buffer + /// \param secretLen the size of the secret buffer, in bytes + /// \param salt the salt input buffer + /// \param saltLen the size of the salt buffer, in bytes + /// \param info the additional input buffer + /// \param infoLen the size of the info buffer, in bytes + /// \return the number of iterations performed + /// \throw InvalidDerivedKeyLength if derivedLen is invalid for the scheme + /// \details DeriveKey() provides a standard interface to derive a key from + /// a seed and other parameters. Each class that derives from KeyDerivationFunction + /// provides an overload that accepts most parameters used by the derivation function. + /// \details salt and info can be nullptr with 0 length. + /// HKDF is unusual in that a non-NULL salt with length 0 is different than a + /// NULL salt. A NULL salt causes HKDF to use a string of 0's + /// of length T::DIGESTSIZE for the salt. + /// \details HKDF always returns 1 because it only performs 1 iteration. Other + /// derivation functions, like PBKDF's, will return more interesting values. + size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const byte *salt, size_t saltLen, const byte* info, size_t infoLen) const; + +protected: + // KeyDerivationFunction interface + const Algorithm & GetAlgorithm() const { + return *this; + } + + // If salt is absent (NULL), then use the NULL vector. Missing is different than + // EMPTY (Non-NULL, 0 length). The length of s_NullVector used depends on the Hash + // function. SHA-256 will use 32 bytes of s_NullVector. + typedef byte NullVectorType[T::DIGESTSIZE]; + static const NullVectorType& GetNullVector() { + static const NullVectorType s_NullVector = {0}; + return s_NullVector; + } +}; + +template +size_t HKDF::GetValidDerivedLength(size_t keylength) const +{ + if (keylength > MaxDerivedKeyLength()) + return MaxDerivedKeyLength(); + return keylength; +} + +template +size_t HKDF::DeriveKey(byte *derived, size_t derivedLen, + const byte *secret, size_t secretLen, const NameValuePairs& params) const +{ + CRYPTOPP_ASSERT(secret && secretLen); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + ConstByteArrayParameter p; + SecByteBlock salt, info; + + if (params.GetValue("Salt", p)) + salt.Assign(p.begin(), p.size()); + else + salt.Assign(GetNullVector(), T::DIGESTSIZE); + + if (params.GetValue("Info", p)) + info.Assign(p.begin(), p.size()); + else + info.Assign(GetNullVector(), 0); + + return DeriveKey(derived, derivedLen, secret, secretLen, salt.begin(), salt.size(), info.begin(), info.size()); +} + +template +size_t HKDF::DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const byte *salt, size_t saltLen, const byte* info, size_t infoLen) const +{ + CRYPTOPP_ASSERT(secret && secretLen); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + ThrowIfInvalidDerivedKeyLength(derivedLen); + + // HKDF business logic. NULL is different than empty. + if (salt == NULLPTR) + { + salt = GetNullVector(); + saltLen = T::DIGESTSIZE; + } + + // key is PRK from the RFC, salt is IKM from the RFC + HMAC hmac; + SecByteBlock key(T::DIGESTSIZE), buffer(T::DIGESTSIZE); + + // Extract + hmac.SetKey(salt, saltLen); + hmac.CalculateDigest(key, secret, secretLen); + + // Key + hmac.SetKey(key.begin(), key.size()); + byte block = 0; + + // Expand + while (derivedLen > 0) + { + if (block++) {hmac.Update(buffer, buffer.size());} + if (infoLen) {hmac.Update(info, infoLen);} + hmac.CalculateDigest(buffer, &block, 1); + +#if CRYPTOPP_MSC_VERSION + const size_t digestSize = static_cast(T::DIGESTSIZE); + const size_t segmentLen = STDMIN(derivedLen, digestSize); + memcpy_s(derived, segmentLen, buffer, segmentLen); +#else + const size_t digestSize = static_cast(T::DIGESTSIZE); + const size_t segmentLen = STDMIN(derivedLen, digestSize); + std::memcpy(derived, buffer, segmentLen); +#endif + + derived += segmentLen; + derivedLen -= segmentLen; + } + + return 1; +} + +NAMESPACE_END + +#endif // CRYPTOPP_HKDF_H diff --git a/external/ours/library/crypto/src/shared/original/hmac.cpp b/external/ours/library/crypto/src/shared/original/hmac.cpp new file mode 100755 index 000000000..7648ea9ea --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hmac.cpp @@ -0,0 +1,90 @@ +// hmac.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "hmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +void HMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + Restart(); + + HashTransformation &hash = AccessHash(); + unsigned int blockSize = hash.BlockSize(); + + if (!blockSize) + throw InvalidArgument("HMAC: can only be used with a block-based hash function"); + + m_buf.resize(2*AccessHash().BlockSize() + AccessHash().DigestSize()); + + if (keylength <= blockSize) + { + // hmac.cpp:26:9: runtime error: null pointer passed as argument 2 + if (AccessIpad() && userKey && keylength) + memcpy(AccessIpad(), userKey, keylength); + } + else + { + AccessHash().CalculateDigest(AccessIpad(), userKey, keylength); + keylength = hash.DigestSize(); + } + + CRYPTOPP_ASSERT(keylength <= blockSize); + memset(AccessIpad()+keylength, 0, blockSize-keylength); + + for (unsigned int i=0; i, public MessageAuthenticationCode +{ +public: + virtual ~HMAC_Base() {} + + /// \brief Construct a HMAC_Base + HMAC_Base() : m_innerHashKeyed(false) {} + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + + void Restart(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int OptimalBlockSize() const {return const_cast(this)->AccessHash().OptimalBlockSize();} + unsigned int DigestSize() const {return const_cast(this)->AccessHash().DigestSize();} + +protected: + virtual HashTransformation & AccessHash() =0; + byte * AccessIpad() {return m_buf;} + byte * AccessOpad() {return m_buf + AccessHash().BlockSize();} + byte * AccessInnerHash() {return m_buf + 2*AccessHash().BlockSize();} + +private: + void KeyInnerHash(); + + SecByteBlock m_buf; + bool m_innerHashKeyed; +}; + +/// \brief HMAC +/// \tparam T HashTransformation derived class +/// \details HMAC derives from MessageAuthenticationCodeImpl. It calculates the HMAC using +/// HMAC(K, text) = H(K XOR opad, H(K XOR ipad, text)). +/// \sa HMAC +/// \since Crypto++ 2.1 +template +class HMAC : public MessageAuthenticationCodeImpl > +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE=T::DIGESTSIZE); + CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE); + + virtual ~HMAC() {} + + /// \brief Construct a HMAC + HMAC() {} + /// \brief Construct a HMAC + /// \param key the HMAC key + /// \param length the size of the HMAC key + HMAC(const byte *key, size_t length=HMAC_Base::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} + + static std::string StaticAlgorithmName() {return std::string("HMAC(") + T::StaticAlgorithmName() + ")";} + std::string AlgorithmName() const {return std::string("HMAC(") + m_hash.AlgorithmName() + ")";} + std::string AlgorithmProvider() const {return m_hash.AlgorithmProvider();} + +private: + HashTransformation & AccessHash() {return m_hash;} + + T m_hash; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/hmqv.h b/external/ours/library/crypto/src/shared/original/hmqv.h new file mode 100755 index 000000000..fb11b3107 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hmqv.h @@ -0,0 +1,417 @@ +// hmqv.h - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Wei Dai's MQV source files + +#ifndef CRYPTOPP_HMQV_H +#define CRYPTOPP_HMQV_H + +/// \file hmqv.h +/// \brief Classes for Hashed Menezes-Qu-Vanstone key agreement in GF(p) +/// \since Crypto++ 5.6.4 + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Hashed Menezes-Qu-Vanstone in GF(p) +/// \details This implementation follows Hugo Krawczyk's HMQV: A High-Performance +/// Secure Diffie-Hellman Protocol. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. +/// \sa MQV, HMQV, FHMQV, and AuthenticatedKeyAgreementDomain +/// \since Crypto++ 5.6.4 +template +class HMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef HMQV_Domain Domain; + + virtual ~HMQV_Domain() {} + + /// \brief Construct a HMQV domain + /// \param clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + HMQV_Domain(bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) {} + + /// \brief Construct a HMQV domain + /// \param params group parameters and options + /// \param clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + /// \brief Construct a HMQV domain + /// \param bt BufferedTransformation with group parameters and options + /// \param clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + /// \brief Construct a HMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1 is passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + HMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + /// \brief Construct a HMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + /// \brief Construct a HMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + /// \brief Construct a HMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \tparam T4 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param v4 third parameter + /// \param clientRole flag indicating initiator or recipient + /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +public: + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a const reference + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a non-const reference + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + /// \brief Retrieves the crypto parameters for this domain + /// \return the crypto parameters for this domain as a non-const reference + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + + /// \brief Provides the size of the agreed value + /// \return size of agreed value produced in this domain + /// \details The length is calculated using GetEncodedElementSize(false), + /// which means the element is encoded in a non-reversible format. A + /// non-reversible format means its a raw byte array, and it lacks presentation + /// format like an ASN.1 BIT_STRING or OCTET_STRING. + unsigned int AgreedValueLength() const + {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + + /// \brief Provides the size of the static private key + /// \return size of static private keys in this domain + /// \details The length is calculated using the byte count of the subgroup order. + unsigned int StaticPrivateKeyLength() const + {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + + /// \brief Provides the size of the static public key + /// \return size of static public keys in this domain + /// \details The length is calculated using GetEncodedElementSize(true), + /// which means the element is encoded in a reversible format. A reversible + /// format means it has a presentation format, and its an ANS.1 encoded element + /// or point. + unsigned int StaticPublicKeyLength() const + {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + /// \brief Generate static private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \details The private key is a random scalar used as an exponent in the range + /// [1,MaxExponent()]. + /// \pre COUNTOF(privateKey) == PrivateStaticKeyLength() + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + /// \brief Generate a static public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details The public key is an element or point on the curve, and its stored + /// in a revrsible format. A reversible format means it has a presentation + /// format, and its an ANS.1 encoded element or point. + /// \pre COUNTOF(publicKey) == PublicStaticKeyLength() + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + /// \brief Provides the size of the ephemeral private key + /// \return size of ephemeral private keys in this domain + /// \details An ephemeral private key is a private key and public key. + /// The serialized size is different than a static private key. + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + + /// \brief Provides the size of the ephemeral public key + /// \return size of ephemeral public keys in this domain + /// \details An ephemeral public key is a public key. + /// The serialized size is the same as a static public key. + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + /// \brief Generate ephemeral private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \pre COUNTOF(privateKey) == EphemeralPrivateKeyLength() + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + /// \brief Generate ephemeral public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \pre COUNTOF(publicKey) == EphemeralPublicKeyLength() + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + /// \brief Derive agreed value or shared secret + /// \param agreedValue the shared secret + /// \param staticPrivateKey your long term private key + /// \param ephemeralPrivateKey your ephemeral private key + /// \param staticOtherPublicKey couterparty's long term public key + /// \param ephemeralOtherPublicKey couterparty's ephemeral public key + /// \param validateStaticOtherPublicKey flag indicating validation + /// \return true upon success, false in case of failure + /// \details Agree() performs the authenticated key agreement. Agree() + /// derives a shared secret from your private keys and couterparty's + /// public keys. Each instance or run of the protocol should use a new + /// ephemeral key pair. + /// \details The other's ephemeral public key will always be validated at + /// Level 1 to ensure it is a point on the curve. + /// validateStaticOtherPublicKey determines how thoroughly other's + /// static public key is validated. If you have previously validated the + /// couterparty's static public key, then use + /// validateStaticOtherPublicKey=false to save time. + /// \pre COUNTOF(agreedValue) == AgreedValueLength() + /// \pre COUNTOF(staticPrivateKey) == StaticPrivateKeyLength() + /// \pre COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength() + /// \pre COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength() + /// \pre COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength() + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + this->GetMaterial().DoQuickSanityCheck(); + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = ephemeralOtherPublicKey; + xxs = EphemeralPublicKeyLength(); + YY = ephemeralPrivateKey + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = staticOtherPublicKey; + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = ephemeralPrivateKey + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = ephemeralOtherPublicKey; + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = staticOtherPublicKey; + bbs = StaticPublicKeyLength(); + } + + Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey); + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true); + + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + SecByteBlock dd(len), ee(len); + + // Compute $d = \hat{H}(X, \hat{B})$ + Hash(NULLPTR, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + Integer d(dd.BytePtr(), dd.SizeInBytes()); + + // Compute $e = \hat{H}(Y, \hat{A})$ + Hash(NULLPTR, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); + Integer e(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + // $\sigma_B}=(X \cdot A^{d})^{s_B} + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t3 = params.ExponentiateElement(B, e); + Element t4 = m_groupParameters.MultiplyElements(Y, t3); + + // $\sigma_A}=(Y \cdot B^{e})^{s_A} + sigma = params.ExponentiateElement(t4, s_A); + } + Hash(&sigma, NULLPTR, 0, NULLPTR, 0, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + CRYPTOPP_ASSERT(0); + return false; + } + return true; + } + +protected: + // Hash invocation by client and server differ only in what keys + // each provides. + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, // Ephemeral key and key length + const byte* s1, size_t s1len, // Static key and key length + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = STDMIN(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + if (e1len != 0 || s1len != 0) { + CRYPTOPP_ASSERT(0); + } + //Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + //SecByteBlock sbb(x.MinEncodedSize()); + //x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false)); + GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } else { + if (e1len == 0 || s1len == 0) { + CRYPTOPP_ASSERT(0); + } + hash.Update(e1, e1len); + hash.Update(s1, s1len); + } + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = STDMIN(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole { RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() + {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const + {return m_groupParameters;} + + GroupParameters m_groupParameters; + KeyAgreementRole m_role; +}; + +/// \brief Hashed Menezes-Qu-Vanstone in GF(p) +/// \details This implementation follows Hugo Krawczyk's HMQV: A High-Performance +/// Secure Diffie-Hellman Protocol. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. +/// \sa HMQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain +/// \since Crypto++ 5.6.4 +typedef HMQV_Domain HMQV; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/hrtimer.cpp b/external/ours/library/crypto/src/shared/original/hrtimer.cpp new file mode 100755 index 000000000..f9b8a7cdc --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hrtimer.cpp @@ -0,0 +1,174 @@ +// hrtimer.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "hrtimer.h" +#include "misc.h" + +#include // for NULL +#include + +#if defined(CRYPTOPP_WIN32_AVAILABLE) +#define WIN32_LEAN_AND_MEAN +#include +# if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)) +# include +# if defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_FAMILY_PHONE_APP)) +# include +# endif +# endif +#endif +#endif + +#if defined(CRYPTOPP_UNIX_AVAILABLE) +#include +#include +#include +#endif + +#include "trap.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_WIN32_AVAILABLE) +static TimerWord InitializePerformanceCounterFrequency() +{ + LARGE_INTEGER freq = {0,0}; + if (!QueryPerformanceFrequency(&freq)) + throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError())); + return freq.QuadPart; +} + +inline TimerWord PerformanceCounterFrequency() +{ + static const word64 freq = InitializePerformanceCounterFrequency(); + return freq; +} +#endif + +#ifndef CRYPTOPP_IMPORTS + +double TimerBase::ConvertTo(TimerWord t, Unit unit) +{ + static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; + + // When 'unit' is an enum 'Unit', a Clang warning is generated. + CRYPTOPP_ASSERT(static_cast(unit) < COUNTOF(unitsPerSecondTable)); + return static_cast(t) * unitsPerSecondTable[unit] / TicksPerSecond(); +} + +void TimerBase::StartTimer() +{ + m_last = m_start = GetCurrentTimerValue(); + m_started = true; +} + +double TimerBase::ElapsedTimeAsDouble() +{ + if (m_stuckAtZero) + return 0; + + if (m_started) + { + TimerWord now = GetCurrentTimerValue(); + if (m_last < now) // protect against OS bugs where time goes backwards + m_last = now; + return ConvertTo(m_last - m_start, m_timerUnit); + } + + StartTimer(); + return 0; +} + +unsigned long TimerBase::ElapsedTime() +{ + double elapsed = ElapsedTimeAsDouble(); + CRYPTOPP_ASSERT(elapsed <= (double)ULONG_MAX); + return (unsigned long)elapsed; +} + +TimerWord Timer::GetCurrentTimerValue() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) + // Use the first union member to avoid an uninitialized warning + LARGE_INTEGER now = {0,0}; + if (!QueryPerformanceCounter(&now)) + throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError())); + return now.QuadPart; +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + timeval now; + gettimeofday(&now, NULLPTR); + return (TimerWord)now.tv_sec * 1000000 + now.tv_usec; +#else + // clock_t now; + return clock(); +#endif +} + +TimerWord Timer::TicksPerSecond() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) + return PerformanceCounterFrequency(); +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + return 1000000; +#else + return CLOCKS_PER_SEC; +#endif +} + +#endif // #ifndef CRYPTOPP_IMPORTS + +TimerWord ThreadUserTimer::GetCurrentTimerValue() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(THREAD_TIMER_AVAILABLE) + static bool getCurrentThreadImplemented = true; + if (getCurrentThreadImplemented) + { + FILETIME now, ignored; + if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now)) + { + const DWORD lastError = GetLastError(); + if (lastError == ERROR_CALL_NOT_IMPLEMENTED) + { + getCurrentThreadImplemented = false; + goto GetCurrentThreadNotImplemented; + } + throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError)); + } + return now.dwLowDateTime + ((TimerWord)now.dwHighDateTime << 32); + } +GetCurrentThreadNotImplemented: + return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC); +#elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE) + LARGE_INTEGER now; + if (!QueryPerformanceCounter(&now)) + { + const DWORD lastError = GetLastError(); + throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: QueryPerformanceCounter failed with error " + IntToString(lastError)); + } + return now.QuadPart; +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + tms now; + times(&now); + return now.tms_utime; +#else + return clock(); +#endif +} + +TimerWord ThreadUserTimer::TicksPerSecond() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(THREAD_TIMER_AVAILABLE) + return 10*1000*1000; +#elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE) + static const TimerWord ticksPerSecond = PerformanceCounterFrequency(); + return ticksPerSecond; +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + static const long ticksPerSecond = sysconf(_SC_CLK_TCK); + return ticksPerSecond; +#else + return CLOCKS_PER_SEC; +#endif +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/hrtimer.h b/external/ours/library/crypto/src/shared/original/hrtimer.h new file mode 100755 index 000000000..a7e7d9778 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/hrtimer.h @@ -0,0 +1,134 @@ +// hrtimer.h - originally written and placed in the public domain by Wei Dai + +/// \file hrtimer.h +/// \brief Classes for timers + +#ifndef CRYPTOPP_HRTIMER_H +#define CRYPTOPP_HRTIMER_H + +#include "config.h" + +#if !defined(HIGHRES_TIMER_AVAILABLE) || (defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE)) +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef HIGHRES_TIMER_AVAILABLE + /// \brief TimerWord is a 64-bit word + typedef word64 TimerWord; +#else + /// \brief TimerWord is a clock_t + typedef clock_t TimerWord; +#endif + +/// \brief Base class for timers +/// \sa ThreadUserTimer, Timer +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase +{ +public: + /// \brief Unit of measure + /// \details Unit selects the unit of measure as returned by functions + /// ElapsedTimeAsDouble() and ElapsedTime(). + /// \sa ElapsedTimeAsDouble, ElapsedTime + enum Unit { + /// \brief Timer unit is seconds + /// \details All timers support seconds + SECONDS = 0, + /// \brief Timer unit is milliseconds + /// \details All timers support milliseconds + MILLISECONDS, + /// \brief Timer unit is microseconds + /// \details The timer requires hardware support microseconds + MICROSECONDS, + /// \brief Timer unit is nanoseconds + /// \details The timer requires hardware support nanoseconds + NANOSECONDS + }; + + /// \brief Construct a TimerBase + /// \param unit the unit of measure + /// \param stuckAtZero flag + TimerBase(Unit unit, bool stuckAtZero) + : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) + , m_start(0), m_last(0) {} + + /// \brief Retrieve the current timer value + /// \return the current timer value + virtual TimerWord GetCurrentTimerValue() =0; + + /// \brief Retrieve ticks per second + /// \return ticks per second + /// \details TicksPerSecond() is not the timer resolution. It is a + /// conversion factor into seconds. + virtual TimerWord TicksPerSecond() =0; + + /// \brief Start the timer + void StartTimer(); + + /// \brief Retrieve the elapsed time + /// \return the elapsed time as a double + /// \details The return value of ElapsedTimeAsDouble() depends upon + /// the Unit selected during construction of the timer. For example, + /// if Unit = SECONDS and ElapsedTimeAsDouble() returns 3, + /// then the timer has run for 3 seconds. If + /// Unit = MILLISECONDS and ElapsedTimeAsDouble() returns + /// 3000, then the timer has run for 3 seconds. + /// \sa Unit, ElapsedTime + double ElapsedTimeAsDouble(); + + /// \brief Retrieve the elapsed time + /// \return the elapsed time as an unsigned long + /// \details The return value of ElapsedTime() depends upon the + /// Unit selected during construction of the timer. For example, if + /// Unit = SECONDS and ElapsedTime() returns 3, then + /// the timer has run for 3 seconds. If Unit = MILLISECONDS + /// and ElapsedTime() returns 3000, then the timer has run for 3 + /// seconds. + /// \sa Unit, ElapsedTimeAsDouble + unsigned long ElapsedTime(); + +private: + double ConvertTo(TimerWord t, Unit unit); + + Unit m_timerUnit; // HPUX workaround: m_unit is a system macro on HPUX + bool m_stuckAtZero, m_started; + TimerWord m_start, m_last; +}; + +/// \brief Measure CPU time spent executing instructions of this thread +/// \details ThreadUserTimer requires support of the OS. On Unix-based it +/// reports process time. On Windows NT or later desktops and servers it +/// reports thread times with performance counter precision.. On Windows +/// Phone and Windows Store it reports wall clock time with performance +/// counter precision. On all others it reports wall clock time. +/// \note ThreadUserTimer only works correctly on Windows NT or later +/// desktops and servers. +/// \sa Timer +class ThreadUserTimer : public TimerBase +{ +public: + /// \brief Construct a ThreadUserTimer + /// \param unit the unit of measure + /// \param stuckAtZero flag + ThreadUserTimer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} + TimerWord GetCurrentTimerValue(); + TimerWord TicksPerSecond(); +}; + +/// \brief High resolution timer +/// \sa ThreadUserTimer +class CRYPTOPP_DLL Timer : public TimerBase +{ +public: + /// \brief Construct a Timer + /// \param unit the unit of measure + /// \param stuckAtZero flag + Timer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} + TimerWord GetCurrentTimerValue(); + TimerWord TicksPerSecond(); +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ida.cpp b/external/ours/library/crypto/src/shared/original/ida.cpp new file mode 100755 index 000000000..1c8b3ab29 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ida.cpp @@ -0,0 +1,418 @@ +// ida.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#include "ida.h" +#include "stdcpp.h" +#include "algebra.h" +#include "polynomi.h" +#include "polynomi.cpp" + +NAMESPACE_BEGIN(CryptoPP) + +#if (defined(_MSC_VER) && (_MSC_VER < 1400)) && !defined(__MWERKS__) + // VC60 and VC7 workaround: built-in reverse_iterator has two template parameters, Dinkumware only has one + typedef std::reverse_bidirectional_iterator RevIt; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator RevIt; +#else + typedef std::reverse_iterator RevIt; +#endif + +void RawIDA::IsolatedInitialize(const NameValuePairs ¶meters) +{ + if (!parameters.GetIntValue("RecoveryThreshold", m_threshold)) + throw InvalidArgument("RawIDA: missing RecoveryThreshold argument"); + + CRYPTOPP_ASSERT(m_threshold > 0); + if (m_threshold <= 0) + throw InvalidArgument("RawIDA: RecoveryThreshold must be greater than 0"); + + m_lastMapPosition = m_inputChannelMap.end(); + m_channelsReady = 0; + m_channelsFinished = 0; + m_w.New(m_threshold); + m_y.New(m_threshold); + m_inputQueues.reserve(m_threshold); + + m_outputChannelIds.clear(); + m_outputChannelIdStrings.clear(); + m_outputQueues.clear(); + + word32 outputChannelID; + if (parameters.GetValue("OutputChannelID", outputChannelID)) + AddOutputChannel(outputChannelID); + else + { + int nShares = parameters.GetIntValueWithDefault("NumberOfShares", m_threshold); + CRYPTOPP_ASSERT(nShares > 0); + if (nShares <= 0) {nShares = m_threshold;} + for (unsigned int i=0; i< (unsigned int)(nShares); i++) + AddOutputChannel(i); + } +} + +unsigned int RawIDA::InsertInputChannel(word32 channelId) +{ + if (m_lastMapPosition != m_inputChannelMap.end()) + { + if (m_lastMapPosition->first == channelId) + goto skipFind; + ++m_lastMapPosition; + if (m_lastMapPosition != m_inputChannelMap.end() && m_lastMapPosition->first == channelId) + goto skipFind; + } + m_lastMapPosition = m_inputChannelMap.find(channelId); + +skipFind: + if (m_lastMapPosition == m_inputChannelMap.end()) + { + if (m_inputChannelIds.size() == size_t(m_threshold)) + return m_threshold; + + m_lastMapPosition = m_inputChannelMap.insert(InputChannelMap::value_type(channelId, (unsigned int)m_inputChannelIds.size())).first; + m_inputQueues.push_back(MessageQueue()); + m_inputChannelIds.push_back(channelId); + + if (m_inputChannelIds.size() == size_t(m_threshold)) + PrepareInterpolation(); + } + return m_lastMapPosition->second; +} + +unsigned int RawIDA::LookupInputChannel(word32 channelId) const +{ + std::map::const_iterator it = m_inputChannelMap.find(channelId); + if (it == m_inputChannelMap.end()) + return m_threshold; + else + return it->second; +} + +void RawIDA::ChannelData(word32 channelId, const byte *inString, size_t length, bool messageEnd) +{ + int i = InsertInputChannel(channelId); + if (i < m_threshold) + { + lword size = m_inputQueues[i].MaxRetrievable(); + m_inputQueues[i].Put(inString, length); + if (size < 4 && size + length >= 4) + { + m_channelsReady++; + if (m_channelsReady == size_t(m_threshold)) + ProcessInputQueues(); + } + + if (messageEnd) + { + m_inputQueues[i].MessageEnd(); + if (m_inputQueues[i].NumberOfMessages() == 1) + { + m_channelsFinished++; + if (m_channelsFinished == size_t(m_threshold)) + { + m_channelsReady = 0; + for (i=0; i= m_v.size()) + { + m_v.resize(i+1); + m_outputToInput.resize(i+1); + } + + m_outputToInput[i] = LookupInputChannel(m_outputChannelIds[i]); + if (m_outputToInput[i] == size_t(m_threshold) && i * size_t(m_threshold) <= 1000*1000) + { + m_v[i].resize(m_threshold); + PrepareBulkPolynomialInterpolationAt(m_gf32, m_v[i].begin(), m_outputChannelIds[i], &(m_inputChannelIds[0]), m_w.begin(), m_threshold); + } +} + +void RawIDA::AddOutputChannel(word32 channelId) +{ + m_outputChannelIds.push_back(channelId); + m_outputChannelIdStrings.push_back(WordToString(channelId)); + m_outputQueues.push_back(ByteQueue()); + if (m_inputChannelIds.size() == size_t(m_threshold)) + ComputeV((unsigned int)m_outputChannelIds.size() - 1); +} + +void RawIDA::PrepareInterpolation() +{ + CRYPTOPP_ASSERT(m_inputChannelIds.size() == size_t(m_threshold)); + PrepareBulkPolynomialInterpolation(m_gf32, m_w.begin(), &(m_inputChannelIds[0]), (unsigned int)(m_threshold)); + for (unsigned int i=0; i 0 : m_channelsReady == size_t(m_threshold)) + { + m_channelsReady = 0; + for (i=0; i 0 || queue.MaxRetrievable() >= 4; + } + + for (i=0; (unsigned int)i 0 && m_outputQueues[0].AnyRetrievable()) + FlushOutputQueues(); + + if (finished) + { + OutputMessageEnds(); + + m_channelsReady = 0; + m_channelsFinished = 0; + m_v.clear(); + + std::vector inputQueues; + std::vector inputChannelIds; + + inputQueues.swap(m_inputQueues); + inputChannelIds.swap(m_inputChannelIds); + m_inputChannelMap.clear(); + m_lastMapPosition = m_inputChannelMap.end(); + + for (i=0; iChannelMessageEnd(m_outputChannelIdStrings[i], GetAutoSignalPropagation()-1); + } +} + +// **************************************************************** + +void SecretSharing::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_pad = parameters.GetValueWithDefault("AddPadding", true); + m_ida.IsolatedInitialize(parameters); +} + +size_t SecretSharing::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("SecretSharing"); + + SecByteBlock buf(UnsignedMin(256, length)); + unsigned int threshold = m_ida.GetThreshold(); + while (length > 0) + { + size_t len = STDMIN(length, buf.size()); + m_ida.ChannelData(0xffffffff, begin, len, false); + for (unsigned int i=0; i 0) + SecretSharing::Put(0); + } + m_ida.ChannelData(0xffffffff, NULLPTR, 0, true); + for (unsigned int i=0; iMessageEnd(GetAutoSignalPropagation()-1); +} + +// **************************************************************** + +void InformationDispersal::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_nextChannel = 0; + m_pad = parameters.GetValueWithDefault("AddPadding", true); + m_ida.IsolatedInitialize(parameters); +} + +size_t InformationDispersal::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("InformationDispersal"); + + while (length--) + { + m_ida.ChannelData(m_nextChannel, begin, 1, false); + begin++; + m_nextChannel++; + if (m_nextChannel == m_ida.GetThreshold()) + m_nextChannel = 0; + } + + if (messageEnd) + { + m_ida.SetAutoSignalPropagation(messageEnd-1); + if (m_pad) + InformationDispersal::Put(1); + for (word32 i=0; iMessageEnd(GetAutoSignalPropagation()-1); +} + +size_t PaddingRemover::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("PaddingRemover"); + + const byte *const end = begin + length; + + if (m_possiblePadding) + { + size_t len = FindIfNot(begin, end, byte(0)) - begin; + m_zeroCount += len; + begin += len; + if (begin == end) + return 0; + + AttachedTransformation()->Put(1); + while (m_zeroCount--) + AttachedTransformation()->Put(0); + AttachedTransformation()->Put(*begin++); + m_possiblePadding = false; + } + + const byte *x = FindIfNot(RevIt(end), RevIt(begin), byte(0)).base(); + if (x != begin && *(x-1) == 1) + { + AttachedTransformation()->Put(begin, x-begin-1); + m_possiblePadding = true; + m_zeroCount = end - x; + } + else + AttachedTransformation()->Put(begin, end-begin); + + if (messageEnd) + { + m_possiblePadding = false; + Output(0, begin, length, messageEnd, blocking); + } + return 0; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ida.h b/external/ours/library/crypto/src/shared/original/ida.h new file mode 100755 index 000000000..82b48df11 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ida.h @@ -0,0 +1,182 @@ +// ida.h - originally written and placed in the public domain by Wei Dai + +/// \file ida.h +/// \brief Classes for Rabin's Information Dispersal and Shamir's Secret Sharing algorithms + +#ifndef CRYPTOPP_IDA_H +#define CRYPTOPP_IDA_H + +#include "cryptlib.h" +#include "mqueue.h" +#include "filters.h" +#include "channels.h" +#include "secblock.h" +#include "gf2_32.h" +#include "stdcpp.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Secret sharing and information dispersal base class +/// \since Crypto++ 1.0 +class RawIDA : public AutoSignaling > > +{ +public: + RawIDA(BufferedTransformation *attachment=NULLPTR) + : m_channelsReady(0), m_channelsFinished(0), m_threshold (0) + {Detach(attachment);} + + unsigned int GetThreshold() const {return m_threshold;} + void AddOutputChannel(word32 channelId); + void ChannelData(word32 channelId, const byte *inString, size_t length, bool messageEnd); + lword InputBuffered(word32 channelId) const; + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + { + if (!blocking) + throw BlockingInputOnly("RawIDA"); + ChannelData(StringToWord(channel), begin, length, messageEnd != 0); + return 0; + } + +protected: + virtual void FlushOutputQueues(); + virtual void OutputMessageEnds(); + + unsigned int InsertInputChannel(word32 channelId); + unsigned int LookupInputChannel(word32 channelId) const; + void ComputeV(unsigned int); + void PrepareInterpolation(); + void ProcessInputQueues(); + + typedef std::map InputChannelMap; + InputChannelMap m_inputChannelMap; + InputChannelMap::iterator m_lastMapPosition; + std::vector m_inputQueues; + std::vector m_inputChannelIds, m_outputChannelIds, m_outputToInput; + std::vector m_outputChannelIdStrings; + std::vector m_outputQueues; + std::vector > m_v; + SecBlock m_u, m_w, m_y; + const GF2_32 m_gf32; + unsigned int m_channelsReady, m_channelsFinished; + int m_threshold; +}; + +/// \brief Shamir's Secret Sharing Algorithm +/// \details SecretSharing is a variant of Shamir's secret sharing algorithm +/// \sa SecretRecovery, SecretRecovery, InformationDispersal, InformationRecovery +/// \since Crypto++ 1.0 +class SecretSharing : public CustomFlushPropagation +{ +public: + /// \brief Construct a SecretSharing + SecretSharing(RandomNumberGenerator &rng, int threshold, int nShares, BufferedTransformation *attachment=NULLPTR, bool addPadding=true) + : m_rng(rng), m_ida(new OutputProxy(*this, true)) + { + Detach(attachment); + IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);} + +protected: + RandomNumberGenerator &m_rng; + RawIDA m_ida; + bool m_pad; +}; + +/// \brief Shamir's Secret Sharing Algorithm +/// \details SecretSharing is a variant of Shamir's secret sharing algorithm +/// \sa SecretRecovery, SecretRecovery, InformationDispersal, InformationRecovery +/// \since Crypto++ 1.0 +class SecretRecovery : public RawIDA +{ +public: + /// \brief Construct a SecretRecovery + SecretRecovery(int threshold, BufferedTransformation *attachment=NULLPTR, bool removePadding=true) + : RawIDA(attachment) + {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));} + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + +protected: + void FlushOutputQueues(); + void OutputMessageEnds(); + + bool m_pad; +}; + +/// a variant of Rabin's Information Dispersal Algorithm + +/// \brief Rabin's Information Dispersal Algorithm +/// \details InformationDispersal is a variant of Rabin's information dispersal algorithm +/// \sa SecretRecovery, SecretRecovery, InformationDispersal, InformationRecovery +/// \since Crypto++ 1.0 +class InformationDispersal : public CustomFlushPropagation +{ +public: + /// \brief Construct a InformationDispersal + InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULLPTR, bool addPadding=true) + : m_ida(new OutputProxy(*this, true)), m_pad(false), m_nextChannel(0) + { + Detach(attachment); + IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);} + +protected: + RawIDA m_ida; + bool m_pad; + unsigned int m_nextChannel; +}; + +/// \brief Rabin's Information Dispersal Algorithm +/// \details InformationDispersal is a variant of Rabin's information dispersal algorithm +/// \sa SecretRecovery, SecretRecovery, InformationDispersal, InformationRecovery +/// \since Crypto++ 1.0 +class InformationRecovery : public RawIDA +{ +public: + /// \brief Construct a InformationRecovery + InformationRecovery(int threshold, BufferedTransformation *attachment=NULLPTR, bool removePadding=true) + : RawIDA(attachment), m_pad(false) + {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));} + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + +protected: + void FlushOutputQueues(); + void OutputMessageEnds(); + + bool m_pad; + ByteQueue m_queue; +}; + +class PaddingRemover : public Unflushable +{ +public: + PaddingRemover(BufferedTransformation *attachment=NULLPTR) + : m_possiblePadding(false), m_zeroCount(0) {Detach(attachment);} + + void IsolatedInitialize(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters); m_possiblePadding = false;} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + + // GetPossiblePadding() == false at the end of a message indicates incorrect padding + bool GetPossiblePadding() const {return m_possiblePadding;} + +private: + bool m_possiblePadding; + lword m_zeroCount; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/idea.cpp b/external/ours/library/crypto/src/shared/original/idea.cpp new file mode 100755 index 000000000..dde2fdb45 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/idea.cpp @@ -0,0 +1,191 @@ +// idea.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "idea.h" +#include "misc.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const int IDEA_KEYLEN=(6*IDEA::ROUNDS+4); // key schedule length in # of word16s + +#define low16(x) ((x)&0xffff) // compiler should be able to optimize this away if word is 16 bits +#define high16(x) ((x)>>16) + +CRYPTOPP_COMPILE_ASSERT(sizeof(IDEA::Word) >= 2); + +// should use an inline function but macros are still faster in MSVC 4.0 +#define DirectMUL(a,b) \ +{ \ + word32 p=(word32)low16(a)*b; \ + \ + if (p) \ + { \ + p = low16(p) - high16(p); \ + a = (IDEA::Word)p - (IDEA::Word)high16(p); \ + } \ + else \ + a = 1-a-b; \ +} + +#ifdef IDEA_LARGECACHE +volatile bool IDEA::Base::tablesBuilt = false; +word16 IDEA::Base::log[0x10000]; +word16 IDEA::Base::antilog[0x10000]; + +void IDEA::Base::BuildLogTables() +{ + if (tablesBuilt) + return; + else + { + tablesBuilt = true; + + IDEA::Word x=1; + word32 i; + + for (i=0; i<0x10000; i++) + { + antilog[i] = (word16)x; + DirectMUL(x, 3); + } + + for (i=0; i<0x10000; i++) + log[antilog[i]] = (word16)i; + } +} + +void IDEA::Base::LookupKeyLogs() +{ + IDEA::Word* Z=key; + int r=ROUNDS; + do + { + Z[0] = log[Z[0]]; + Z[3] = log[Z[3]]; + Z[4] = log[Z[4]]; + Z[5] = log[Z[5]]; + Z+=6; + } while (--r); + Z[0] = log[Z[0]]; + Z[3] = log[Z[3]]; +} + +inline void IDEA::Base::LookupMUL(IDEA::Word &a, IDEA::Word b) +{ + a = antilog[low16(log[low16(a)]+b)]; +} +#endif // IDEA_LARGECACHE + +void IDEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + +#ifdef IDEA_LARGECACHE + BuildLogTables(); +#endif + + EnKey(userKey); + + if (!IsForwardTransformation()) + DeKey(); + +#ifdef IDEA_LARGECACHE + LookupKeyLogs(); +#endif +} + +void IDEA::Base::EnKey (const byte *userKey) +{ + unsigned int i; + + for (i=0; i<8; i++) + m_key[i] = ((IDEA::Word)userKey[2*i]<<8) | userKey[2*i+1]; + + for (; i> 7)); + } +} + +static IDEA::Word MulInv(IDEA::Word x) +{ + IDEA::Word y=x; + for (unsigned i=0; i<15; i++) + { + DirectMUL(y,low16(y)); + DirectMUL(y,x); + } + return low16(y); +} + +static inline IDEA::Word AddInv(IDEA::Word x) +{ + return low16(0-x); +} + +void IDEA::Base::DeKey() +{ + FixedSizeSecBlock tempkey; + size_t i; + + for (i=0; i0)]); + tempkey[i*6+2] = AddInv(m_key[(ROUNDS-i)*6+2-(i>0)]); + tempkey[i*6+3] = MulInv(m_key[(ROUNDS-i)*6+3]); + tempkey[i*6+4] = m_key[(ROUNDS-1-i)*6+4]; + tempkey[i*6+5] = m_key[(ROUNDS-1-i)*6+5]; + } + + tempkey[i*6+0] = MulInv(m_key[(ROUNDS-i)*6+0]); + tempkey[i*6+1] = AddInv(m_key[(ROUNDS-i)*6+1]); + tempkey[i*6+2] = AddInv(m_key[(ROUNDS-i)*6+2]); + tempkey[i*6+3] = MulInv(m_key[(ROUNDS-i)*6+3]); + + m_key = tempkey; +} + +#ifdef IDEA_LARGECACHE +#define MUL(a,b) LookupMUL(a,b) +#else +#define MUL(a,b) DirectMUL(a,b) +#endif + +void IDEA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + typedef BlockGetAndPut Block; + + const IDEA::Word *key = m_key; + IDEA::Word x0,x1,x2,x3,t0,t1; + Block::Get(inBlock)(x0)(x1)(x2)(x3); + + for (unsigned int i=0; i, public FixedKeyLength<16>, public FixedRounds<8> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "IDEA";} +}; + +/// \brief IDEA block cipher +/// \sa IDEA +/// \since Crypto++ 1.0 +class IDEA : public IDEA_Info, public BlockCipherDocumentation +{ +public: // made public for internal purposes +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + typedef word Word; +#else + typedef hword Word; +#endif + +private: + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + unsigned int OptimalDataAlignment() const {return 2;} + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + private: + void EnKey(const byte *); + void DeKey(); + FixedSizeSecBlock m_key; + + #ifdef IDEA_LARGECACHE + static inline void LookupMUL(word &a, word b); + void LookupKeyLogs(); + static void BuildLogTables(); + static volatile bool tablesBuilt; + static word16 log[0x10000], antilog[0x10000]; + #endif + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef IDEA::Encryption IDEAEncryption; +typedef IDEA::Decryption IDEADecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/integer.cpp b/external/ours/library/crypto/src/shared/original/integer.cpp new file mode 100755 index 000000000..dac3ef7c6 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/integer.cpp @@ -0,0 +1,4910 @@ +// integer.cpp - originally written and placed in the public domain by Wei Dai +// contains public domain code contributed by Alister Lee and Leonard Janke + +// Notes by JW: The Integer class needs to do two things. First, it needs +// to set function pointers on some platforms, like X86 and X64. The +// function pointers select a fast multiply and addition based on the cpu. +// Second, it wants to create Integer::Zero(), Integer::One() and +// Integer::Two(). +// The function pointers are initialized in the InitializeInteger class by +// calling SetFunctionPointers(). The call to SetFunctionPointers() is +// guarded to run once using a double-checked pattern. We don't use C++ +// std::call_once due to bad interactions between libstdc++, glibc and +// pthreads. The bad interactions were causing crashes for us on platforms +// like Sparc and PowerPC. Since we are only setting function pointers we +// don't have to worry about leaking memory. The worst case seems to be the +// pointers gets written twice until the init flag is set and visible to +// all threads. +// For Integer::Zero(), Integer::One() and Integer::Two(), we use one of three +// strategies. First, if initialization priorities are available then we use +// them. Initialization priorities are init_priority() on Linux and init_seg() +// on Windows. OS X and several other platforms lack them. Initialization +// priorities are platform specific but they are also the most trouble free +// with determisitic destruction. +// Second, if C++11 dynamic initialization is available, then we use it. After +// the std::call_once fiasco we moved to dynamic initialization to avoid +// unknown troubles platforms that are tested less frequently. In addition +// Microsoft platforms mostly do not provide dynamic initialization. +// The MSDN docs claim they do but they don't in practice because we need +// Visual Studio 2017 and Windows 10 or above. +// Third, we fall back to Wei's original code of a Singleton. Wei's original +// code was much simpler. It simply used the Singleton pattern, but it always +// produced memory findings on some platforms. The Singleton generates memory +// findings because it uses a Create On First Use pattern (a dumb Nifty +// Counter) and the compiler had to be smart enough to fold them to return +// the same object. Unix and Linux compilers do a good job of folding objects, +// but Microsoft compilers do a rather poor job for some versions of the +// compiler. +// Another problem with the Singleton is resource destruction requires running +// resource acquisition in reverse. For resources provided through the +// Singletons, there is no way to express the dependency order to safely +// destroy resources. (That's one of the problems C++11 dynamic +// intitialization with concurrent execution is supposed to solve). +// The final problem with Singletons is resource/memory exhaustion in languages +// like Java and .Net. Java and .Net load and unload a native DLL hundreds or +// thousands of times during the life of a program. Each load produces a +// memory leak and they can add up quickly. If they library is being used in +// Java or .Net then Singleton must be avoided at all costs. +// +// The code below has a path cut-in for BMI2 using mulx and adcx instructions. +// There was a modest speedup of approximately 0.03 ms in public key Integer +// operations. We had to disable BMI2 for the moment because some OS X machines +// were advertising BMI/BMI2 support but caused SIGILL's at runtime. Also see +// https://github.com/weidai11/cryptopp/issues/850. + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "integer.h" +#include "secblock.h" +#include "modarith.h" +#include "nbtheory.h" +#include "smartptr.h" +#include "algparam.h" +#include "filters.h" +#include "stdcpp.h" +#include "asn.h" +#include "oids.h" +#include "words.h" +#include "pubkey.h" // for P1363_KDF2 +#include "sha.h" +#include "cpu.h" +#include "misc.h" + +#include + +#if (_MSC_VER >= 1400) && !defined(_M_ARM) + #include +#endif + +#ifdef __DECCXX + #include +#endif + +// "Error: The operand ___LKDB cannot be assigned to", +// http://github.com/weidai11/cryptopp/issues/188 +#if (__SUNPRO_CC >= 0x5130) +# define MAYBE_CONST +# define MAYBE_UNCONST_CAST(x) const_cast(x) +#else +# define MAYBE_CONST const +# define MAYBE_UNCONST_CAST(x) x +#endif + +// "Inline assembly operands don't work with .intel_syntax", +// http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +# undef CRYPTOPP_SSSE3_ASM_AVAILABLE +#else +# define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86)) +#endif + +// ***************** C++ Static Initialization ******************** + +NAMESPACE_BEGIN(CryptoPP) + +// Function body near the middle of the file +static void SetFunctionPointers(); + +// Use a double-checked pattern. We are not leaking anything so it +// does not matter if a pointer is written twice during a race. +// Avoid std::call_once due to too many problems on platforms like +// Solaris and Sparc. Also see +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=66146 and +// http://github.com/weidai11/cryptopp/issues/707. +InitializeInteger::InitializeInteger() +{ + static bool s_flag; + MEMORY_BARRIER(); + if (s_flag == false) + { + SetFunctionPointers(); + s_flag = true; + MEMORY_BARRIER(); + } +} + +template +struct NewInteger +{ + Integer * operator()() const + { + return new Integer(i); + } +}; + +// ***************** Library code ******************** + +inline static int Compare(const word *A, const word *B, size_t N) +{ + while (N--) + if (A[N] > B[N]) + return 1; + else if (A[N] < B[N]) + return -1; + + return 0; +} + +inline static int Increment(word *A, size_t N, word B=1) +{ + CRYPTOPP_ASSERT(N); + word t = A[0]; + A[0] = t+B; + if (A[0] >= t) + return 0; + for (unsigned i=1; i>(WORD_BITS-1)); d##0 = 2*d##0 + (c>>(WORD_BITS-1)); c *= 2; + #endif + #ifndef Acc2WordsBy2 + #define Acc2WordsBy2(a, b) a##0 += b##0; a##1 += a##0 < b##0; a##1 += b##1; + #endif + #define AddWithCarry(u, a, b) {word t = a+b; u##0 = t + u##1; u##1 = (ta) + (u##0>t);} + #define GetCarry(u) u##1 + #define GetBorrow(u) u##1 +#else + #define Declare2Words(x) dword x; + #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) && (defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)) + #define MultiplyWords(p, a, b) p = __emulu(a, b); + #else + #define MultiplyWords(p, a, b) p = (dword)a*b; + #endif + #define AssignWord(a, b) a = b; + #define Add2WordsBy1(a, b, c) a = b + c; + #define Acc2WordsBy2(a, b) a += b; + #define LowWord(a) word(a) + #define HighWord(a) word(a>>WORD_BITS) + #define Double3Words(c, d) d = 2*d + (c>>(WORD_BITS-1)); c *= 2; + #define AddWithCarry(u, a, b) u = dword(a) + b + GetCarry(u); + #define SubtractWithBorrow(u, a, b) u = dword(a) - b - GetBorrow(u); + #define GetCarry(u) HighWord(u) + #define GetBorrow(u) word(u>>(WORD_BITS*2-1)) +#endif +#ifndef MulAcc + #define MulAcc(c, d, a, b) MultiplyWords(p, a, b); Acc2WordsBy1(p, c); c = LowWord(p); Acc2WordsBy1(d, HighWord(p)); +#endif +#ifndef Acc2WordsBy1 + #define Acc2WordsBy1(a, b) Add2WordsBy1(a, a, b) +#endif +#ifndef Acc3WordsBy2 + #define Acc3WordsBy2(c, d, e) Acc2WordsBy1(e, c); c = LowWord(e); Add2WordsBy1(e, d, HighWord(e)); +#endif + +class DWord +{ +public: +#if defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) + DWord() {std::memset(&m_whole, 0x00, sizeof(m_whole));} +#else + DWord() {std::memset(&m_halfs, 0x00, sizeof(m_halfs));} +#endif + +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + explicit DWord(word low) : m_whole(low) { } +#else + explicit DWord(word low) + { + m_halfs.high = 0; + m_halfs.low = low; + } +#endif + +#if defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) + DWord(word low, word high) : m_whole() +#else + DWord(word low, word high) : m_halfs() +#endif + { +#if defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) +# if (CRYPTOPP_LITTLE_ENDIAN) + const word t[2] = {low,high}; + memcpy(&m_whole, t, sizeof(m_whole)); +# else + const word t[2] = {high,low}; + memcpy(&m_whole, t, sizeof(m_whole)); +# endif +#else + m_halfs.low = low; + m_halfs.high = high; +#endif + } + + static DWord Multiply(word a, word b) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = (dword)a * b; + #elif defined(MultiplyWordsLoHi) + MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b); + #else + CRYPTOPP_ASSERT(0); + #endif + return r; + } + + static DWord MultiplyAndAdd(word a, word b, word c) + { + DWord r = Multiply(a, b); + return r += c; + } + + DWord & operator+=(word a) + { + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + m_whole = m_whole + a; + #else + m_halfs.low += a; + m_halfs.high += (m_halfs.low < a); + #endif + return *this; + } + + DWord operator+(word a) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = m_whole + a; + #else + r.m_halfs.low = m_halfs.low + a; + r.m_halfs.high = m_halfs.high + (r.m_halfs.low < a); + #endif + return r; + } + + DWord operator-(DWord a) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = m_whole - a.m_whole; + #else + r.m_halfs.low = m_halfs.low - a.m_halfs.low; + r.m_halfs.high = m_halfs.high - a.m_halfs.high - (r.m_halfs.low > m_halfs.low); + #endif + return r; + } + + DWord operator-(word a) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = m_whole - a; + #else + r.m_halfs.low = m_halfs.low - a; + r.m_halfs.high = m_halfs.high - (r.m_halfs.low > m_halfs.low); + #endif + return r; + } + + // returns quotient, which must fit in a word + word operator/(word divisor); + + word operator%(word a); + + bool operator!() const + { + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + return !m_whole; + #else + return !m_halfs.high && !m_halfs.low; + #endif + } + + // TODO: When NATIVE_DWORD is in effect, we access high and low, which are inactive + // union members, and that's UB. Also see http://stackoverflow.com/q/11373203. + word GetLowHalf() const {return m_halfs.low;} + word GetHighHalf() const {return m_halfs.high;} + word GetHighHalfAsBorrow() const {return 0-m_halfs.high;} + +private: + // Issue 274, "Types cannot be declared in anonymous union", + // http://github.com/weidai11/cryptopp/issues/274 + // Thanks to Martin Bonner at http://stackoverflow.com/a/39507183 + struct half_words + { + #if (CRYPTOPP_LITTLE_ENDIAN) + word low; + word high; + #else + word high; + word low; + #endif + }; + union + { + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + dword m_whole; + #endif + half_words m_halfs; + }; +}; + +class Word +{ +public: + Word() : m_whole(0) {} + Word(word value) : m_whole(value) {} + Word(hword low, hword high) : m_whole(low | (word(high) << (WORD_BITS/2))) {} + + static Word Multiply(hword a, hword b) + { + Word r; + r.m_whole = (word)a * b; + return r; + } + + Word operator-(Word a) + { + Word r; + r.m_whole = m_whole - a.m_whole; + return r; + } + + Word operator-(hword a) + { + Word r; + r.m_whole = m_whole - a; + return r; + } + + // returns quotient, which must fit in a word + hword operator/(hword divisor) + { + return hword(m_whole / divisor); + } + + bool operator!() const + { + return !m_whole; + } + + word GetWhole() const {return m_whole;} + hword GetLowHalf() const {return hword(m_whole);} + hword GetHighHalf() const {return hword(m_whole>>(WORD_BITS/2));} + hword GetHighHalfAsBorrow() const {return 0-hword(m_whole>>(WORD_BITS/2));} + +private: + word m_whole; +}; + +// do a 3 word by 2 word divide, returns quotient and leaves remainder in A +template +S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULLPTR) +{ + CRYPTOPP_UNUSED(dummy); + + // Assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S + CRYPTOPP_ASSERT(A[2] < B1 || (A[2]==B1 && A[1] < B0)); + + // Profiling guided the flow below. + + // estimate the quotient: do a 2 S by 1 S divide. + S Q; bool pre = (S(B1+1) == 0); + if (B1 > 0 && !pre) + Q = D(A[1], A[2]) / S(B1+1); + else if (pre) + Q = A[2]; + else + Q = D(A[0], A[1]) / B0; + + // now subtract Q*B from A + D p = D::Multiply(B0, Q); + D u = (D) A[0] - p.GetLowHalf(); + A[0] = u.GetLowHalf(); + u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + + // Q <= actual quotient, so fix it + while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) + { + u = (D) A[0] - B0; + A[0] = u.GetLowHalf(); + u = (D) A[1] - B1 - u.GetHighHalfAsBorrow(); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + Q++; + CRYPTOPP_ASSERT(Q); // shouldn't overflow + } + + return Q; +} + +// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 +template +inline D DivideFourWordsByTwo(S *T, const D &Al, const D &Ah, const D &B) +{ + // Profiling guided the flow below. + + if (!!B) + { + S Q[2]; + T[0] = Al.GetLowHalf(); + T[1] = Al.GetHighHalf(); + T[2] = Ah.GetLowHalf(); + T[3] = Ah.GetHighHalf(); + Q[1] = DivideThreeWordsByTwo(T+1, B.GetLowHalf(), B.GetHighHalf()); + Q[0] = DivideThreeWordsByTwo(T, B.GetLowHalf(), B.GetHighHalf()); + return D(Q[0], Q[1]); + } + else // if divisor is 0, we assume divisor==2**(2*WORD_BITS) + { + return D(Ah.GetLowHalf(), Ah.GetHighHalf()); + } +} + +// returns quotient, which must fit in a word +inline word DWord::operator/(word a) +{ + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + return word(m_whole / a); + #else + hword r[4]; + return DivideFourWordsByTwo(r, m_halfs.low, m_halfs.high, a).GetWhole(); + #endif +} + +inline word DWord::operator%(word a) +{ + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + return word(m_whole % a); + #else + if (a < (word(1) << (WORD_BITS/2))) + { + hword h = hword(a); + word r = m_halfs.high % h; + r = ((m_halfs.low >> (WORD_BITS/2)) + (r << (WORD_BITS/2))) % h; + return hword((hword(m_halfs.low) + (r << (WORD_BITS/2))) % h); + } + else + { + hword r[4]; + DivideFourWordsByTwo(r, m_halfs.low, m_halfs.high, a); + return Word(r[0], r[1]).GetWhole(); + } + #endif +} + +// ******************************************************** + +// Use some tricks to share assembly code between MSVC, GCC, Clang and Sun CC. +#if defined(__GNUC__) + #define AddPrologue \ + int result; \ + __asm__ __volatile__ \ + ( \ + INTEL_NOPREFIX + #define AddEpilogue \ + ATT_PREFIX \ + : "=a" (result)\ + : "d" (C), "a" (A), "D" (B), "c" (N) \ + : "%esi", "memory", "cc" \ + );\ + return result; + #define MulPrologue \ + __asm__ __volatile__ \ + ( \ + INTEL_NOPREFIX \ + AS1( push ebx) \ + AS2( mov ebx, edx) + #define MulEpilogue \ + AS1( pop ebx) \ + ATT_PREFIX \ + : \ + : "d" (s_maskLow16), "c" (C), "a" (A), "D" (B) \ + : "%esi", "memory", "cc" \ + ); + #define SquPrologue MulPrologue + #define SquEpilogue \ + AS1( pop ebx) \ + ATT_PREFIX \ + : \ + : "d" (s_maskLow16), "c" (C), "a" (A) \ + : "%esi", "%edi", "memory", "cc" \ + ); + #define TopPrologue MulPrologue + #define TopEpilogue \ + AS1( pop ebx) \ + ATT_PREFIX \ + : \ + : "d" (s_maskLow16), "c" (C), "a" (A), "D" (B), "S" (L) \ + : "memory", "cc" \ + ); +#else + #define AddPrologue \ + __asm push edi \ + __asm push esi \ + __asm mov eax, [esp+12] \ + __asm mov edi, [esp+16] + #define AddEpilogue \ + __asm pop esi \ + __asm pop edi \ + __asm ret 8 + #define SaveEBX + #define RestoreEBX + #define SquPrologue \ + AS2( mov eax, A) \ + AS2( mov ecx, C) \ + SaveEBX \ + AS2( lea ebx, s_maskLow16) + #define MulPrologue \ + AS2( mov eax, A) \ + AS2( mov edi, B) \ + AS2( mov ecx, C) \ + SaveEBX \ + AS2( lea ebx, s_maskLow16) + #define TopPrologue \ + AS2( mov eax, A) \ + AS2( mov edi, B) \ + AS2( mov ecx, C) \ + AS2( mov esi, L) \ + SaveEBX \ + AS2( lea ebx, s_maskLow16) + #define SquEpilogue RestoreEBX + #define MulEpilogue RestoreEBX + #define TopEpilogue RestoreEBX +#endif + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +int Baseline_Add(size_t N, word *C, const word *A, const word *B); +int Baseline_Sub(size_t N, word *C, const word *A, const word *B); +} +#elif defined(CRYPTOPP_X64_ASM_AVAILABLE) && defined(__GNUC__) && defined(CRYPTOPP_WORD128_AVAILABLE) +int Baseline_Add(size_t N, word *C, const word *A, const word *B) +{ + word result; + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS1( neg %1) + ASJ( jz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( add %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASL(0) + AS2( mov %0,[%3+8*%1+8]) + AS2( adc %0,[%4+8*%1+8]) + AS2( mov [%2+8*%1+8],%0) + AS2( lea %1,[%1+2]) + ASJ( jrcxz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( adc %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASJ( jmp, 0, b) + ASL(1) + AS2( mov %0, 0) + AS2( adc %0, %0) + ATT_NOPREFIX + : "=&r" (result), "+c" (N) + : "r" (C+N), "r" (A+N), "r" (B+N) + : "memory", "cc" + ); + return (int)result; +} + +int Baseline_Sub(size_t N, word *C, const word *A, const word *B) +{ + word result; + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS1( neg %1) + ASJ( jz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( sub %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASL(0) + AS2( mov %0,[%3+8*%1+8]) + AS2( sbb %0,[%4+8*%1+8]) + AS2( mov [%2+8*%1+8],%0) + AS2( lea %1,[%1+2]) + ASJ( jrcxz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( sbb %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASJ( jmp, 0, b) + ASL(1) + AS2( mov %0, 0) + AS2( adc %0, %0) + ATT_NOPREFIX + : "=&r" (result), "+c" (N) + : "r" (C+N), "r" (A+N), "r" (B+N) + : "memory", "cc" + ); + return (int)result; +} +#elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && CRYPTOPP_BOOL_X86 +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + ASJ( jecxz, 2, f) // loop until ecx overflows and becomes zero + AS2( mov esi,[eax+4*ecx]) + AS2( adc esi,[edi+4*ecx]) + AS2( mov [edx+4*ecx],esi) + AS2( mov esi,[eax+4*ecx+4]) + AS2( adc esi,[edi+4*ecx+4]) + AS2( mov [edx+4*ecx+4],esi) + ASL(1) + AS2( mov esi,[eax+4*ecx+8]) + AS2( adc esi,[edi+4*ecx+8]) + AS2( mov [edx+4*ecx+8],esi) + AS2( mov esi,[eax+4*ecx+12]) + AS2( adc esi,[edi+4*ecx+12]) + AS2( mov [edx+4*ecx+12],esi) + + AS2( lea ecx,[ecx+4]) // advance index, avoid inc which causes slowdown on Intel Core 2 + ASJ( jmp, 0, b) + + ASL(2) + AS2( mov eax, 0) + AS1( setc al) // store carry into eax (return result register) + + AddEpilogue + + // http://github.com/weidai11/cryptopp/issues/340 + CRYPTOPP_UNUSED(A); CRYPTOPP_UNUSED(B); + CRYPTOPP_UNUSED(C); CRYPTOPP_UNUSED(N); +} + +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Sub(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + ASJ( jecxz, 2, f) // loop until ecx overflows and becomes zero + AS2( mov esi,[eax+4*ecx]) + AS2( sbb esi,[edi+4*ecx]) + AS2( mov [edx+4*ecx],esi) + AS2( mov esi,[eax+4*ecx+4]) + AS2( sbb esi,[edi+4*ecx+4]) + AS2( mov [edx+4*ecx+4],esi) + ASL(1) + AS2( mov esi,[eax+4*ecx+8]) + AS2( sbb esi,[edi+4*ecx+8]) + AS2( mov [edx+4*ecx+8],esi) + AS2( mov esi,[eax+4*ecx+12]) + AS2( sbb esi,[edi+4*ecx+12]) + AS2( mov [edx+4*ecx+12],esi) + + AS2( lea ecx,[ecx+4]) // advance index, avoid inc which causes slowdown on Intel Core 2 + ASJ( jmp, 0, b) + + ASL(2) + AS2( mov eax, 0) + AS1( setc al) // store carry into eax (return result register) + + AddEpilogue + + // http://github.com/weidai11/cryptopp/issues/340 + CRYPTOPP_UNUSED(A); CRYPTOPP_UNUSED(B); + CRYPTOPP_UNUSED(C); CRYPTOPP_UNUSED(N); +} + +#if CRYPTOPP_INTEGER_SSE2 +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL SSE2_Add(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( pxor mm2, mm2) + ASJ( jz, 2, f) + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + AS2( movd mm0, DWORD PTR [eax+4*ecx]) + AS2( movd mm1, DWORD PTR [edi+4*ecx]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx], mm2) + AS2( psrlq mm2, 32) + + AS2( movd mm0, DWORD PTR [eax+4*ecx+4]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+4]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+4], mm2) + AS2( psrlq mm2, 32) + + ASL(1) + AS2( movd mm0, DWORD PTR [eax+4*ecx+8]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+8]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+8], mm2) + AS2( psrlq mm2, 32) + + AS2( movd mm0, DWORD PTR [eax+4*ecx+12]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+12]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+12], mm2) + AS2( psrlq mm2, 32) + + AS2( add ecx, 4) + ASJ( jnz, 0, b) + + ASL(2) + AS2( movd eax, mm2) + AS1( emms) + + AddEpilogue + + // http://github.com/weidai11/cryptopp/issues/340 + CRYPTOPP_UNUSED(A); CRYPTOPP_UNUSED(B); + CRYPTOPP_UNUSED(C); CRYPTOPP_UNUSED(N); +} +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL SSE2_Sub(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( pxor mm2, mm2) + ASJ( jz, 2, f) + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + AS2( movd mm0, DWORD PTR [eax+4*ecx]) + AS2( movd mm1, DWORD PTR [edi+4*ecx]) + AS2( psubq mm0, mm1) + AS2( psubq mm0, mm2) + AS2( movd DWORD PTR [edx+4*ecx], mm0) + AS2( psrlq mm0, 63) + + AS2( movd mm2, DWORD PTR [eax+4*ecx+4]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+4]) + AS2( psubq mm2, mm1) + AS2( psubq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+4], mm2) + AS2( psrlq mm2, 63) + + ASL(1) + AS2( movd mm0, DWORD PTR [eax+4*ecx+8]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+8]) + AS2( psubq mm0, mm1) + AS2( psubq mm0, mm2) + AS2( movd DWORD PTR [edx+4*ecx+8], mm0) + AS2( psrlq mm0, 63) + + AS2( movd mm2, DWORD PTR [eax+4*ecx+12]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+12]) + AS2( psubq mm2, mm1) + AS2( psubq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+12], mm2) + AS2( psrlq mm2, 63) + + AS2( add ecx, 4) + ASJ( jnz, 0, b) + + ASL(2) + AS2( movd eax, mm2) + AS1( emms) + + AddEpilogue + + // http://github.com/weidai11/cryptopp/issues/340 + CRYPTOPP_UNUSED(A); CRYPTOPP_UNUSED(B); + CRYPTOPP_UNUSED(C); CRYPTOPP_UNUSED(N); +} +#endif // CRYPTOPP_INTEGER_SSE2 +#else // CRYPTOPP_SSE2_ASM_AVAILABLE +int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) +{ + CRYPTOPP_ASSERT (N%2 == 0); + + Declare2Words(u); + AssignWord(u, 0); + for (size_t i=0; i=2 && N%2==0); + + if (N <= s_recursionLimit) + s_pMul[N/4](R, A, B); + else + { + const size_t N2 = N/2; + + size_t AN2 = Compare(A0, A1, N2) > 0 ? 0 : N2; + Subtract(R0, A + AN2, A + (N2 ^ AN2), N2); + + size_t BN2 = Compare(B0, B1, N2) > 0 ? 0 : N2; + Subtract(R1, B + BN2, B + (N2 ^ BN2), N2); + + RecursiveMultiply(R2, T2, A1, B1, N2); + RecursiveMultiply(T0, T2, R0, R1, N2); + RecursiveMultiply(R0, T2, A0, B0, N2); + + // now T[01] holds (A1-A0)*(B0-B1), R[01] holds A0*B0, R[23] holds A1*B1 + + int c2 = Add(R2, R2, R1, N2); + int c3 = c2; + c2 += Add(R1, R2, R0, N2); + c3 += Add(R2, R2, R3, N2); + + if (AN2 == BN2) + c3 -= Subtract(R1, R1, T0, N); + else + c3 += Add(R1, R1, T0, N); + + c3 += Increment(R2, N2, c2); + CRYPTOPP_ASSERT (c3 >= 0 && c3 <= 2); + Increment(R3, N2, c3); + } +} + +// R[2*N] - result = A*A +// T[2*N] - temporary work space +// A[N] --- number to be squared + +void RecursiveSquare(word *R, word *T, const word *A, size_t N) +{ + CRYPTOPP_ASSERT(N && N%2==0); + + if (N <= s_recursionLimit) + s_pSqu[N/4](R, A); + else + { + const size_t N2 = N/2; + + RecursiveSquare(R0, T2, A0, N2); + RecursiveSquare(R2, T2, A1, N2); + RecursiveMultiply(T0, T2, A0, A1, N2); + + int carry = Add(R1, R1, T0, N); + carry += Add(R1, R1, T0, N); + Increment(R3, N2, carry); + } +} + +// R[N] - bottom half of A*B +// T[3*N/2] - temporary work space +// A[N] - multiplier +// B[N] - multiplicant + +void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B, size_t N) +{ + CRYPTOPP_ASSERT(N>=2 && N%2==0); + + if (N <= s_recursionLimit) + s_pBot[N/4](R, A, B); + else + { + const size_t N2 = N/2; + + RecursiveMultiply(R, T, A0, B0, N2); + RecursiveMultiplyBottom(T0, T1, A1, B0, N2); + Add(R1, R1, T0, N2); + RecursiveMultiplyBottom(T0, T1, A0, B1, N2); + Add(R1, R1, T0, N2); + } +} + +// R[N] --- upper half of A*B +// T[2*N] - temporary work space +// L[N] --- lower half of A*B +// A[N] --- multiplier +// B[N] --- multiplicant + +void MultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, size_t N) +{ + CRYPTOPP_ASSERT(N>=2 && N%2==0); + + if (N <= s_recursionLimit) + s_pTop[N/4](R, A, B, L[N-1]); + else + { + const size_t N2 = N/2; + + size_t AN2 = Compare(A0, A1, N2) > 0 ? 0 : N2; + Subtract(R0, A + AN2, A + (N2 ^ AN2), N2); + + size_t BN2 = Compare(B0, B1, N2) > 0 ? 0 : N2; + Subtract(R1, B + BN2, B + (N2 ^ BN2), N2); + + RecursiveMultiply(T0, T2, R0, R1, N2); + RecursiveMultiply(R0, T2, A1, B1, N2); + + // now T[01] holds (A1-A0)*(B0-B1) = A1*B0+A0*B1-A1*B1-A0*B0, R[01] holds A1*B1 + + int t, c3; + int c2 = Subtract(T2, L+N2, L, N2); + + if (AN2 == BN2) + { + c2 -= Add(T2, T2, T0, N2); + t = (Compare(T2, R0, N2) == -1); + c3 = t - Subtract(T2, T2, T1, N2); + } + else + { + c2 += Subtract(T2, T2, T0, N2); + t = (Compare(T2, R0, N2) == -1); + c3 = t + Add(T2, T2, T1, N2); + } + + c2 += t; + if (c2 >= 0) + c3 += Increment(T2, N2, c2); + else + c3 -= Decrement(T2, N2, -c2); + c3 += Add(R0, T2, R1, N2); + + CRYPTOPP_ASSERT (c3 >= 0 && c3 <= 2); + Increment(R1, N2, c3); + } +} + +inline void Multiply(word *R, word *T, const word *A, const word *B, size_t N) +{ + RecursiveMultiply(R, T, A, B, N); +} + +inline void Square(word *R, word *T, const word *A, size_t N) +{ + RecursiveSquare(R, T, A, N); +} + +inline void MultiplyBottom(word *R, word *T, const word *A, const word *B, size_t N) +{ + RecursiveMultiplyBottom(R, T, A, B, N); +} + +// R[NA+NB] - result = A*B +// T[NA+NB] - temporary work space +// A[NA] ---- multiplier +// B[NB] ---- multiplicant + +void AsymmetricMultiply(word *R, word *T, const word *A, size_t NA, const word *B, size_t NB) +{ + if (NA == NB) + { + // Profiling guided the flow below. + if (A != B) + Multiply(R, T, A, B, NA); + else + Square(R, T, A, NA); + + return; + } + + if (NA > NB) + { + std::swap(A, B); + std::swap(NA, NB); + } + + CRYPTOPP_ASSERT(NB % NA == 0); + + if (NA==2 && !A[1]) + { + // Profiling guided the flow below. + switch (A[0]) + { + default: + R[NB] = LinearMultiply(R, B, A[0], NB); + R[NB+1] = 0; + return; + case 0: + SetWords(R, 0, NB+2); + return; + case 1: + CopyWords(R, B, NB); + R[NB] = R[NB+1] = 0; + return; + } + } + + size_t i; + if ((NB/NA)%2 == 0) + { + Multiply(R, T, A, B, NA); + CopyWords(T+2*NA, R+NA, NA); + + for (i=2*NA; i=4); + +#define M0 M +#define M1 (M+N2) +#define V0 V +#define V1 (V+N2) + +#define X0 X +#define X1 (X+N2) +#define X2 (X+N) +#define X3 (X+N+N2) + + const size_t N2 = N/2; + Multiply(T0, T2, V0, X3, N2); + int c2 = Add(T0, T0, X0, N); + MultiplyBottom(T3, T2, T0, U, N2); + MultiplyTop(T2, R, T0, T3, M0, N2); + c2 -= Subtract(T2, T1, T2, N2); + Multiply(T0, R, T3, M1, N2); + c2 -= Subtract(T0, T2, T0, N2); + int c3 = -(int)Subtract(T1, X2, T1, N2); + Multiply(R0, T2, V1, X3, N2); + c3 += Add(R, R, T, N); + + if (c2>0) + c3 += Increment(R1, N2); + else if (c2<0) + c3 -= Decrement(R1, N2, -c2); + + CRYPTOPP_ASSERT(c3>=-1 && c3<=1); + if (c3>0) + Subtract(R, R, M, N); + else if (c3<0) + Add(R, R, M, N); + +#undef M0 +#undef M1 +#undef V0 +#undef V1 + +#undef X0 +#undef X1 +#undef X2 +#undef X3 +} + +#undef A0 +#undef A1 +#undef B0 +#undef B1 + +#undef T0 +#undef T1 +#undef T2 +#undef T3 + +#undef R0 +#undef R1 +#undef R2 +#undef R3 + +/* +// do a 3 word by 2 word divide, returns quotient and leaves remainder in A +static word SubatomicDivide(word *A, word B0, word B1) +{ + // Assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a word + CRYPTOPP_ASSERT(A[2] < B1 || (A[2]==B1 && A[1] < B0)); + + // estimate the quotient: do a 2 word by 1 word divide + word Q; + if (B1+1 == 0) + Q = A[2]; + else + Q = DWord(A[1], A[2]).DividedBy(B1+1); + + // now subtract Q*B from A + DWord p = DWord::Multiply(B0, Q); + DWord u = (DWord) A[0] - p.GetLowHalf(); + A[0] = u.GetLowHalf(); + u = (DWord) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - DWord::Multiply(B1, Q); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + + // Q <= actual quotient, so fix it + while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) + { + u = (DWord) A[0] - B0; + A[0] = u.GetLowHalf(); + u = (DWord) A[1] - B1 - u.GetHighHalfAsBorrow(); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + Q++; + CRYPTOPP_ASSERT(Q); // shouldn't overflow + } + + return Q; +} + +// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 +static inline void AtomicDivide(word *Q, const word *A, const word *B) +{ + if (!B[0] && !B[1]) // if divisor is 0, we assume divisor==2**(2*WORD_BITS) + { + Q[0] = A[2]; + Q[1] = A[3]; + } + else + { + word T[4]; + T[0] = A[0]; T[1] = A[1]; T[2] = A[2]; T[3] = A[3]; + Q[1] = SubatomicDivide(T+1, B[0], B[1]); + Q[0] = SubatomicDivide(T, B[0], B[1]); + +#if defined(CRYPTOPP_DEBUG) + // multiply quotient and divisor and add remainder, make sure it equals dividend + CRYPTOPP_ASSERT(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0](T, DWord(A[0], A[1]), DWord(A[2], A[3]), DWord(B[0], B[1])); + Q[0] = q.GetLowHalf(); + Q[1] = q.GetHighHalf(); + +#if defined(CRYPTOPP_DEBUG) + if (B[0] || B[1]) + { + // multiply quotient and divisor and add remainder, make sure it equals dividend + CRYPTOPP_ASSERT(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0]= 0) + { + R[N] -= Subtract(R, R, B, N); + Q[1] += (++Q[0]==0); + CRYPTOPP_ASSERT(Q[0] || Q[1]); // no overflow + } +} + +// R[NB] -------- remainder = A%B +// Q[NA-NB+2] --- quotient = A/B +// T[NA+3*(NB+2)] - temp work space +// A[NA] -------- dividend +// B[NB] -------- divisor + +void Divide(word *R, word *Q, word *T, const word *A, size_t NA, const word *B, size_t NB) +{ + CRYPTOPP_ASSERT(NA && NB && NA%2==0 && NB%2==0); + CRYPTOPP_ASSERT(B[NB-1] || B[NB-2]); + CRYPTOPP_ASSERT(NB <= NA); + + // set up temporary work space + word *const TA=T; + word *const TB=T+NA+2; + word *const TP=T+NA+2+NB; + + // copy B into TB and normalize it so that TB has highest bit set to 1 + unsigned shiftWords = (B[NB-1]==0); + TB[0] = TB[NB-1] = 0; + CopyWords(TB+shiftWords, B, NB-shiftWords); + unsigned shiftBits = WORD_BITS - BitPrecision(TB[NB-1]); + CRYPTOPP_ASSERT(shiftBits < WORD_BITS); + ShiftWordsLeftByBits(TB, NB, shiftBits); + + // copy A into TA and normalize it + TA[0] = TA[NA] = TA[NA+1] = 0; + CopyWords(TA+shiftWords, A, NA); + ShiftWordsLeftByBits(TA, NA+2, shiftBits); + + if (TA[NA+1]==0 && TA[NA] <= 1) + { + Q[NA-NB+1] = Q[NA-NB] = 0; + while (TA[NA] || Compare(TA+NA-NB, TB, NB) >= 0) + { + TA[NA] -= Subtract(TA+NA-NB, TA+NA-NB, TB, NB); + ++Q[NA-NB]; + } + } + else + { + NA+=2; + CRYPTOPP_ASSERT(Compare(TA+NA-NB, TB, NB) < 0); + } + + word BT[2]; + BT[0] = TB[NB-2] + 1; + BT[1] = TB[NB-1] + (BT[0]==0); + + // start reducing TA mod TB, 2 words at a time + for (size_t i=NA-2; i>=NB; i-=2) + { + AtomicDivide(Q+i-NB, TA+i-2, BT); + CorrectQuotientEstimate(TA+i-NB, TP, Q+i-NB, TB, NB); + } + + // copy TA into R, and denormalize it + CopyWords(R, TA+shiftWords, NB); + ShiftWordsRightByBits(R, NB, shiftBits); +} + +static inline size_t EvenWordCount(const word *X, size_t N) +{ + while (N && X[N-2]==0 && X[N-1]==0) + N-=2; + return N; +} + +// return k +// R[N] --- result = A^(-1) * 2^k mod M +// T[4*N] - temporary work space +// A[NA] -- number to take inverse of +// M[N] --- modulus + +unsigned int AlmostInverse(word *R, word *T, const word *A, size_t NA, const word *M, size_t N) +{ + CRYPTOPP_ASSERT(NA<=N && N && N%2==0); + + word *b = T; + word *c = T+N; + word *f = T+2*N; + word *g = T+3*N; + size_t bcLen=2, fgLen=EvenWordCount(M, N); + unsigned int k=0; + bool s=false; + + SetWords(T, 0, 3*N); + b[0]=1; + CopyWords(f, A, NA); + CopyWords(g, M, N); + + while (1) + { + word t=f[0]; + while (!t) + { + if (EvenWordCount(f, fgLen)==0) + { + SetWords(R, 0, N); + return 0; + } + + ShiftWordsRightByWords(f, fgLen, 1); + bcLen += 2 * (c[bcLen-1] != 0); + CRYPTOPP_ASSERT(bcLen <= N); + ShiftWordsLeftByWords(c, bcLen, 1); + k+=WORD_BITS; + t=f[0]; + } + + // t must be non-0; otherwise undefined. + unsigned int i = TrailingZeros(t); + t >>= i; + k += i; + + if (t==1 && f[1]==0 && EvenWordCount(f+2, fgLen-2)==0) + { + if (s) + Subtract(R, M, b, N); + else + CopyWords(R, b, N); + return k; + } + + ShiftWordsRightByBits(f, fgLen, i); + t = ShiftWordsLeftByBits(c, bcLen, i); + c[bcLen] += t; + bcLen += 2 * (t!=0); + CRYPTOPP_ASSERT(bcLen <= N); + + bool swap = Compare(f, g, fgLen)==-1; + ConditionalSwapPointers(swap, f, g); + ConditionalSwapPointers(swap, b, c); + s ^= swap; + + fgLen -= 2 * !(f[fgLen-2] | f[fgLen-1]); + + Subtract(f, f, g, fgLen); + t = Add(b, b, c, bcLen); + b[bcLen] += t; + bcLen += 2*t; + CRYPTOPP_ASSERT(bcLen <= N); + } +} + +// R[N] - result = A/(2^k) mod M +// A[N] - input +// M[N] - modulus + +void DivideByPower2Mod(word *R, const word *A, size_t k, const word *M, size_t N) +{ + CopyWords(R, A, N); + + while (k--) + { + if (R[0]%2==0) + ShiftWordsRightByBits(R, N, 1); + else + { + word carry = Add(R, R, M, N); + ShiftWordsRightByBits(R, N, 1); + R[N-1] += carry<<(WORD_BITS-1); + } + } +} + +// R[N] - result = A*(2^k) mod M +// A[N] - input +// M[N] - modulus + +void MultiplyByPower2Mod(word *R, const word *A, size_t k, const word *M, size_t N) +{ + CopyWords(R, A, N); + + while (k--) + if (ShiftWordsLeftByBits(R, N, 1) || Compare(R, M, N)>=0) + Subtract(R, R, M, N); +} + +// ****************************************************************** + +static const unsigned int RoundupSizeTable[] = {2, 2, 2, 4, 4, 8, 8, 8, 8}; + +static inline size_t RoundupSize(size_t n) +{ + if (n<=8) + return RoundupSizeTable[n]; + else if (n<=16) + return 16; + else if (n<=32) + return 32; + else if (n<=64) + return 64; + else + return size_t(1) << BitPrecision(n-1); +} + +Integer::Integer() + : reg(2), sign(POSITIVE) +{ + reg[0] = reg[1] = 0; +} + +Integer::Integer(const Integer& t) + : reg(RoundupSize(t.WordCount())), sign(t.sign) +{ + CopyWords(reg, t.reg, reg.size()); +} + +Integer::Integer(Sign s, lword value) + : reg(2), sign(s) +{ + reg[0] = word(value); + reg[1] = word(SafeRightShift(value)); +} + +Integer::Integer(signed long value) + : reg(2) +{ + if (value >= 0) + sign = POSITIVE; + else + { + sign = NEGATIVE; + value = -value; + } + reg[0] = word(value); + reg[1] = word(SafeRightShift((unsigned long)value)); +} + +Integer::Integer(Sign s, word high, word low) + : reg(2), sign(s) +{ + reg[0] = low; + reg[1] = high; +} + +bool Integer::IsConvertableToLong() const +{ + if (ByteCount() > sizeof(long)) + return false; + + unsigned long value = (unsigned long)reg[0]; + value += SafeLeftShift((unsigned long)reg[1]); + + if (sign==POSITIVE) + return (signed long)value >= 0; + else + return -(signed long)value < 0; +} + +signed long Integer::ConvertToLong() const +{ + CRYPTOPP_ASSERT(IsConvertableToLong()); + + unsigned long value = (unsigned long)reg[0]; + value += SafeLeftShift((unsigned long)reg[1]); + return sign==POSITIVE ? value : -(signed long)value; +} + +Integer::Integer(BufferedTransformation &encodedInteger, size_t byteCount, Signedness s, ByteOrder o) +{ + CRYPTOPP_ASSERT(o == BIG_ENDIAN_ORDER || o == LITTLE_ENDIAN_ORDER); + + if (o != LITTLE_ENDIAN_ORDER) + { + Decode(encodedInteger, byteCount, s); + } + else + { + SecByteBlock block(byteCount); + encodedInteger.Get(block, block.size()); + std::reverse(block.begin(), block.begin()+block.size()); + + Decode(block.begin(), block.size(), s); + } +} + +Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s, ByteOrder o) +{ + CRYPTOPP_ASSERT(encodedInteger && byteCount); // NULL buffer + CRYPTOPP_ASSERT(o == BIG_ENDIAN_ORDER || o == LITTLE_ENDIAN_ORDER); + + if (o != LITTLE_ENDIAN_ORDER) + { + Decode(encodedInteger, byteCount, s); + } + else + { + SecByteBlock block(byteCount); +#if (_MSC_VER >= 1500) + std::reverse_copy(encodedInteger, encodedInteger+byteCount, + stdext::make_checked_array_iterator(block.begin(), block.size())); +#else + std::reverse_copy(encodedInteger, encodedInteger+byteCount, block.begin()); +#endif + Decode(block.begin(), block.size(), s); + return; + } +} + +Integer::Integer(BufferedTransformation &bt) +{ + // Make explicit call to avoid virtual-dispatch findings in ctor + Integer::BERDecode(bt); +} + +Integer::Integer(RandomNumberGenerator &rng, size_t bitcount) +{ + Randomize(rng, bitcount); +} + +Integer::Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod) +{ + if (!Randomize(rng, min, max, rnType, equiv, mod)) + throw Integer::RandomNumberNotFound(); +} + +Integer Integer::Power2(size_t e) +{ + Integer r((word)0, BitsToWords(e+1)); + r.SetBit(e); + return r; +} + +bool Integer::operator!() const +{ + return IsNegative() ? false : (reg[0]==0 && WordCount()==0); +} + +Integer& Integer::operator=(const Integer& t) +{ + if (this != &t) + { + if (reg.size() != t.reg.size() || t.reg[t.reg.size()/2] == 0) + reg.New(RoundupSize(t.WordCount())); + CopyWords(reg, t.reg, reg.size()); + sign = t.sign; + } + return *this; +} + +bool Integer::GetBit(size_t n) const +{ + // Profiling guided the flow below. + if (n/WORD_BITS < reg.size()) + return bool((reg[n/WORD_BITS] >> (n % WORD_BITS)) & 1); + else + return 0; +} + +void Integer::SetBit(size_t n, bool value) +{ + if (value) + { + reg.CleanGrow(RoundupSize(BitsToWords(n+1))); + reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS)); + } + else + { + if (n/WORD_BITS < reg.size()) + reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS)); + } +} + +byte Integer::GetByte(size_t n) const +{ + // Profiling guided the flow below. + if (n/WORD_SIZE < reg.size()) + return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8)); + else + return 0; +} + +void Integer::SetByte(size_t n, byte value) +{ + reg.CleanGrow(RoundupSize(BytesToWords(n+1))); + reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE)); + reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE)); +} + +lword Integer::GetBits(size_t i, size_t n) const +{ + lword v = 0; + CRYPTOPP_ASSERT(n <= sizeof(v)*8); + for (unsigned int j=0; j +static Integer StringToInteger(const T *str, ByteOrder order) +{ + CRYPTOPP_ASSERT( order == BIG_ENDIAN_ORDER || order == LITTLE_ENDIAN_ORDER ); + + int radix, sign = 1; + // GCC workaround + // std::char_traits::length() not defined in GCC 3.2 and STLport 4.5.3 + unsigned int length; + for (length = 0; str[length] != 0; length++) {} + + Integer v; + + if (length == 0) + return Integer::Zero(); + + // 'str' is of length 1 or more + switch (str[length-1]) + { + case 'h': + case 'H': + radix=16; + break; + case 'o': + case 'O': + radix=8; + break; + case 'b': + case 'B': + radix=2; + break; + default: + radix=10; + } + + // 'str' is of length 1 or more + if (str[0] == '-') + { + sign = -1; + str += 1, length -= 1; + } + + // Recognize common prefixes for hexadecimal, octal and decimal. + // Microsoft's MASM also recognizes 0t for octal, but not here. + if (length > 2 && str[0] == '0') + { + if (str[1] == 'x' || str[1] == 'X') + { + radix = 16; + str += 2, length -= 2; + } + else if (str[1] == 'n' || str[1] == 'N') + { + radix = 10; + str += 2, length -= 2; + } + else if (str[1] == 'o' || str[1] == 'O') + { + radix = 8; + str += 2, length -= 2; + } + } + + if (order == BIG_ENDIAN_ORDER) + { + for (unsigned int i=0; i(str[i]); + + // Profiling guided the flow below. + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else + digit = radix; + + if (digit < radix) + { + v *= radix; + v += digit; + } + } + } + else if (radix == 16 && order == LITTLE_ENDIAN_ORDER) + { + // Nibble high, low and count + unsigned int nh = 0, nl = 0, nc = 0; + Integer position(Integer::One()); + + for (unsigned int i=0; i(str[i]); + + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else + digit = radix; + + if (digit < radix) + { + if (nc++ == 0) + nh = digit; + else + nl = digit; + + if (nc == 2) + { + v += position * (nh << 4 | nl); + nc = 0, position <<= 8; + } + } + } + + if (nc == 1) + v += nh * position; + } + else // LITTLE_ENDIAN_ORDER && radix != 16 + { + for (int i=static_cast(length)-1; i>=0; i--) + { + int digit, ch = static_cast(str[i]); + + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else + digit = radix; + + if (digit < radix) + { + v *= radix; + v += digit; + } + } + } + + if (sign == -1) + v.Negate(); + + return v; +} + +Integer::Integer(const char *str, ByteOrder order) + : reg(2), sign(POSITIVE) +{ + *this = StringToInteger(str,order); +} + +Integer::Integer(const wchar_t *str, ByteOrder order) + : reg(2), sign(POSITIVE) +{ + *this = StringToInteger(str,order); +} + +unsigned int Integer::WordCount() const +{ + return (unsigned int)CountWords(reg, reg.size()); +} + +unsigned int Integer::ByteCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]); + else + return 0; +} + +unsigned int Integer::BitCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]); + else + return 0; +} + +void Integer::Decode(const byte *input, size_t inputLen, Signedness s) +{ + CRYPTOPP_ASSERT(input && inputLen); // NULL buffer + StringStore store(input, inputLen); + Decode(store, inputLen, s); +} + +void Integer::Decode(BufferedTransformation &bt, size_t inputLen, Signedness s) +{ + CRYPTOPP_ASSERT(bt.MaxRetrievable() >= inputLen); + if (bt.MaxRetrievable() < inputLen) + throw InvalidArgument("Integer: input length is too small"); + + byte b; + bt.Peek(b); + sign = ((s==SIGNED) && (b & 0x80)) ? NEGATIVE : POSITIVE; + + while (inputLen>0 && (sign==POSITIVE ? b==0 : b==0xff)) + { + bt.Skip(1); + inputLen--; + bt.Peek(b); + } + + reg.CleanNew(RoundupSize(BytesToWords(inputLen))); + for (size_t i=inputLen; i > 0; i--) + { + (void)bt.Get(b); + reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; + } + + if (sign == NEGATIVE) + { + for (size_t i=inputLen; i 0; i--) + bt.Put(GetByte(i-1)); + } + else + { + // take two's complement of *this + Integer temp = Integer::Power2(8*STDMAX((size_t)ByteCount(), outputLen)) + *this; + temp.Encode(bt, outputLen, UNSIGNED); + } +} + +void Integer::DEREncode(BufferedTransformation &bt) const +{ + DERGeneralEncoder enc(bt, INTEGER); + Encode(enc, MinEncodedSize(SIGNED), SIGNED); + enc.MessageEnd(); +} + +void Integer::BERDecode(const byte *input, size_t len) +{ + CRYPTOPP_ASSERT(input && len); // NULL buffer + StringStore store(input, len); + BERDecode(store); +} + +void Integer::BERDecode(BufferedTransformation &bt) +{ + BERGeneralDecoder dec(bt, INTEGER); + if (!dec.IsDefiniteLength() || dec.MaxRetrievable() < dec.RemainingLength()) + BERDecodeError(); + Decode(dec, (size_t)dec.RemainingLength(), SIGNED); + dec.MessageEnd(); +} + +void Integer::DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const +{ + DERGeneralEncoder enc(bt, OCTET_STRING); + Encode(enc, length); + enc.MessageEnd(); +} + +void Integer::BERDecodeAsOctetString(BufferedTransformation &bt, size_t length) +{ + BERGeneralDecoder dec(bt, OCTET_STRING); + if (!dec.IsDefiniteLength() || dec.RemainingLength() != length) + BERDecodeError(); + Decode(dec, length); + dec.MessageEnd(); +} + +size_t Integer::OpenPGPEncode(byte *output, size_t bufferSize) const +{ + CRYPTOPP_ASSERT(output && bufferSize); // NULL buffer + CRYPTOPP_ASSERT(bufferSize >= 2+ByteCount()); // Undersized buffer + ArraySink sink(output, bufferSize); + return OpenPGPEncode(sink); +} + +size_t Integer::OpenPGPEncode(BufferedTransformation &bt) const +{ + word16 bitCount = word16(BitCount()); + bt.PutWord16(bitCount); + size_t byteCount = BitsToBytes(bitCount); + Encode(bt, byteCount); + return 2 + byteCount; +} + +void Integer::OpenPGPDecode(const byte *input, size_t len) +{ + CRYPTOPP_ASSERT(input && len); // NULL buffer + StringStore store(input, len); + OpenPGPDecode(store); +} + +void Integer::OpenPGPDecode(BufferedTransformation &bt) +{ + word16 bitCount; + if (bt.GetWord16(bitCount) != 2 || bt.MaxRetrievable() < BitsToBytes(bitCount)) + throw OpenPGPDecodeErr(); + Decode(bt, BitsToBytes(bitCount)); +} + +void Integer::Randomize(RandomNumberGenerator &rng, size_t nbits) +{ + const size_t nbytes = nbits/8 + 1; + SecByteBlock buf(nbytes); + rng.GenerateBlock(buf, nbytes); + if (nbytes) + buf[0] = (byte)Crop(buf[0], nbits % 8); + Decode(buf, nbytes, UNSIGNED); +} + +void Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max) +{ + if (min > max) + throw InvalidArgument("Integer: Min must be no greater than Max"); + + Integer range = max - min; + const unsigned int nbits = range.BitCount(); + + do + { + Randomize(rng, nbits); + } + while (*this > range); + + *this += min; +} + +bool Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod) +{ + return GenerateRandomNoThrow(rng, MakeParameters("Min", min)("Max", max) + ("RandomNumberType", rnType)("EquivalentTo", equiv)("Mod", mod)); +} + +class KDF2_RNG : public RandomNumberGenerator +{ +public: + KDF2_RNG(const byte *seed, size_t seedSize) + : m_counter(0), m_counterAndSeed(ClampSize(seedSize) + 4) + { + memcpy(m_counterAndSeed + 4, seed, ClampSize(seedSize)); + } + + void GenerateBlock(byte *output, size_t size) + { + CRYPTOPP_ASSERT(output && size); // NULL buffer + PutWord(false, BIG_ENDIAN_ORDER, m_counterAndSeed, m_counter); + ++m_counter; + P1363_KDF2::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULLPTR, 0); + } + + // UBsan finding, -Wstringop-overflow + inline size_t ClampSize(size_t req) const + { + // Clamp at 16 MB + if (req > 16U*1024*1024) + return 16U*1024*1024; + return req; + } + +private: + word32 m_counter; + SecByteBlock m_counterAndSeed; +}; + +bool Integer::GenerateRandomNoThrow(RandomNumberGenerator &i_rng, const NameValuePairs ¶ms) +{ + Integer min = params.GetValueWithDefault("Min", Integer::Zero()); + Integer max; + if (!params.GetValue("Max", max)) + { + int bitLength; + if (params.GetIntValue("BitLength", bitLength)) + max = Integer::Power2(bitLength); + else + throw InvalidArgument("Integer: missing Max argument"); + } + if (min > max) + throw InvalidArgument("Integer: Min must be no greater than Max"); + + Integer equiv = params.GetValueWithDefault("EquivalentTo", Integer::Zero()); + Integer mod = params.GetValueWithDefault("Mod", Integer::One()); + + if (equiv.IsNegative() || equiv >= mod) + throw InvalidArgument("Integer: invalid EquivalentTo and/or Mod argument"); + + Integer::RandomNumberType rnType = params.GetValueWithDefault("RandomNumberType", Integer::ANY); + + member_ptr kdf2Rng; + ConstByteArrayParameter seed; + if (params.GetValue(Name::Seed(), seed)) + { + ByteQueue bq; + DERSequenceEncoder seq(bq); + min.DEREncode(seq); + max.DEREncode(seq); + equiv.DEREncode(seq); + mod.DEREncode(seq); + DEREncodeUnsigned(seq, rnType); + DEREncodeOctetString(seq, seed.begin(), seed.size()); + seq.MessageEnd(); + + SecByteBlock finalSeed((size_t)bq.MaxRetrievable()); + bq.Get(finalSeed, finalSeed.size()); + kdf2Rng.reset(new KDF2_RNG(finalSeed.begin(), finalSeed.size())); + } + RandomNumberGenerator &rng = kdf2Rng.get() ? (RandomNumberGenerator &)*kdf2Rng : i_rng; + + switch (rnType) + { + case ANY: + if (mod == One()) + Randomize(rng, min, max); + else + { + Integer min1 = min + (equiv-min)%mod; + if (max < min1) + return false; + Randomize(rng, Zero(), (max - min1) / mod); + *this *= mod; + *this += min1; + } + return true; + + case PRIME: + { + const PrimeSelector *pSelector = params.GetValueWithDefault(Name::PointerToPrimeSelector(), (const PrimeSelector *)NULLPTR); + + int i; + i = 0; + while (1) + { + if (++i==16) + { + // check if there are any suitable primes in [min, max] + Integer first = min; + if (FirstPrime(first, max, equiv, mod, pSelector)) + { + // if there is only one suitable prime, we're done + *this = first; + if (!FirstPrime(first, max, equiv, mod, pSelector)) + return true; + } + else + return false; + } + + Randomize(rng, min, max); + if (FirstPrime(*this, STDMIN(*this+mod*PrimeSearchInterval(max), max), equiv, mod, pSelector)) + return true; + } + } + + default: + throw InvalidArgument("Integer: invalid RandomNumberType argument"); + } +} + +std::istream& operator>>(std::istream& in, Integer &a) +{ + char c; + unsigned int length = 0; + SecBlock str(length + 16); + + std::ws(in); + + do + { + in.read(&c, 1); + str[length++] = c; + if (length >= str.size()) + str.Grow(length + 16); + } + while (in && (c=='-' || c=='x' || (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F') || c=='h' || c=='H' || c=='o' || c=='O' || c==',' || c=='.')); + + if (in.gcount()) + in.putback(c); + str[length-1] = '\0'; + a = Integer(str); + + return in; +} + +// Ensure base 10 is default +inline int FlagToBase(long f) { + return f == std::ios::hex ? 16 : (f == std::ios::oct ? 8 : 10); +} + +inline char FlagToSuffix(long f) { + return f == std::ios::hex ? 'h' : (f == std::ios::oct ? 'o' : '.'); +} + +// Ensure base 10 is default +std::ostream& operator<<(std::ostream& out, const Integer &a) +{ + // Get relevant conversion specifications from ostream. + const long f = out.flags() & std::ios::basefield; + const int base = FlagToBase(f); + const char suffix = FlagToSuffix(f); + + Integer temp1=a, temp2; + if (a.IsNegative()) + { + out << '-'; + temp1.Negate(); + } + + if (!a) + out << '0'; + + static const char upper[]="0123456789ABCDEF"; + static const char lower[]="0123456789abcdef"; + + const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower; + unsigned int i=0; + SecBlock s(a.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1); + + while (!!temp1) + { + word digit; + Integer::Divide(digit, temp2, temp1, base); + s[i++]=vec[digit]; + temp1.swap(temp2); + } + + while (i--) + { + out << s[i]; + } + +#ifdef CRYPTOPP_USE_STD_SHOWBASE + if (out.flags() & std::ios_base::showbase) + out << suffix; + + return out; +#else + return out << suffix; +#endif +} + +Integer& Integer::operator++() +{ + if (NotNegative()) + { + if (Increment(reg, reg.size())) + { + reg.CleanGrow(2*reg.size()); + reg[reg.size()/2]=1; + } + } + else + { + word borrow = Decrement(reg, reg.size()); + CRYPTOPP_ASSERT(!borrow); CRYPTOPP_UNUSED(borrow); + + if (WordCount()==0) + *this = Zero(); + } + return *this; +} + +Integer& Integer::operator--() +{ + if (IsNegative()) + { + if (Increment(reg, reg.size())) + { + reg.CleanGrow(2*reg.size()); + reg[reg.size()/2]=1; + } + } + else + { + if (Decrement(reg, reg.size())) + *this = -One(); + } + return *this; +} + +// This is a bit operation. We set sign to POSITIVE, so there's no need to +// worry about negative zero. Also see http://stackoverflow.com/q/11644362. +Integer Integer::And(const Integer& t) const +{ + if (this == &t) + { + return AbsoluteValue(); + } + else if (reg.size() >= t.reg.size()) + { + Integer result(t); + AndWords(result.reg, reg, t.reg.size()); + + result.sign = POSITIVE; + return result; + } + else // reg.size() < t.reg.size() + { + Integer result(*this); + AndWords(result.reg, t.reg, reg.size()); + + result.sign = POSITIVE; + return result; + } +} + +// This is a bit operation. We set sign to POSITIVE, so there's no need to +// worry about negative zero. Also see http://stackoverflow.com/q/11644362. +Integer Integer::Or(const Integer& t) const +{ + if (this == &t) + { + return AbsoluteValue(); + } + else if (reg.size() >= t.reg.size()) + { + Integer result(*this); + OrWords(result.reg, t.reg, t.reg.size()); + + result.sign = POSITIVE; + return result; + } + else // reg.size() < t.reg.size() + { + Integer result(t); + OrWords(result.reg, reg, reg.size()); + + result.sign = POSITIVE; + return result; + } +} + +// This is a bit operation. We set sign to POSITIVE, so there's no need to +// worry about negative zero. Also see http://stackoverflow.com/q/11644362. +Integer Integer::Xor(const Integer& t) const +{ + if (this == &t) + { + return Integer::Zero(); + } + else if (reg.size() >= t.reg.size()) + { + Integer result(*this); + XorWords(result.reg, t.reg, t.reg.size()); + + result.sign = POSITIVE; + return result; + } + else // reg.size() < t.reg.size() + { + Integer result(t); + XorWords(result.reg, reg, reg.size()); + + result.sign = POSITIVE; + return result; + } +} + +void PositiveAdd(Integer &sum, const Integer &a, const Integer& b) +{ + // Profiling guided the flow below. + int carry; const bool pre = (a.reg.size() == b.reg.size()); + if (!pre && a.reg.size() > b.reg.size()) + { + carry = Add(sum.reg, a.reg, b.reg, b.reg.size()); + CopyWords(sum.reg+b.reg.size(), a.reg+b.reg.size(), a.reg.size()-b.reg.size()); + carry = Increment(sum.reg+b.reg.size(), a.reg.size()-b.reg.size(), carry); + } + else if (pre) + { + carry = Add(sum.reg, a.reg, b.reg, a.reg.size()); + } + else + { + carry = Add(sum.reg, a.reg, b.reg, a.reg.size()); + CopyWords(sum.reg+a.reg.size(), b.reg+a.reg.size(), b.reg.size()-a.reg.size()); + carry = Increment(sum.reg+a.reg.size(), b.reg.size()-a.reg.size(), carry); + } + + if (carry) + { + sum.reg.CleanGrow(2*sum.reg.size()); + sum.reg[sum.reg.size()/2] = 1; + } + sum.sign = Integer::POSITIVE; +} + +void PositiveSubtract(Integer &diff, const Integer &a, const Integer& b) +{ + unsigned aSize = a.WordCount(); + aSize += aSize%2; + unsigned bSize = b.WordCount(); + bSize += bSize%2; + + // Profiling guided the flow below. + if (aSize > bSize) + { + word borrow = Subtract(diff.reg, a.reg, b.reg, bSize); + CopyWords(diff.reg+bSize, a.reg+bSize, aSize-bSize); + borrow = Decrement(diff.reg+bSize, aSize-bSize, borrow); + CRYPTOPP_ASSERT(!borrow); CRYPTOPP_UNUSED(borrow); + diff.sign = Integer::POSITIVE; + } + else if (aSize == bSize) + { + if (Compare(a.reg, b.reg, aSize) >= 0) + { + Subtract(diff.reg, a.reg, b.reg, aSize); + diff.sign = Integer::POSITIVE; + } + else + { + Subtract(diff.reg, b.reg, a.reg, aSize); + diff.sign = Integer::NEGATIVE; + } + } + else + { + word borrow = Subtract(diff.reg, b.reg, a.reg, aSize); + CopyWords(diff.reg+aSize, b.reg+aSize, bSize-aSize); + borrow = Decrement(diff.reg+aSize, bSize-aSize, borrow); + CRYPTOPP_ASSERT(!borrow); CRYPTOPP_UNUSED(borrow); + diff.sign = Integer::NEGATIVE; + } +} + +// MSVC .NET 2003 workaround +template inline const T& STDMAX2(const T& a, const T& b) +{ + return a < b ? b : a; +} + +Integer Integer::Plus(const Integer& b) const +{ + Integer sum((word)0, STDMAX2(reg.size(), b.reg.size())); + if (NotNegative()) + { + if (b.NotNegative()) + PositiveAdd(sum, *this, b); + else + PositiveSubtract(sum, *this, b); + } + else + { + if (b.NotNegative()) + PositiveSubtract(sum, b, *this); + else + { + PositiveAdd(sum, *this, b); + sum.sign = Integer::NEGATIVE; + } + } + return sum; +} + +Integer& Integer::operator+=(const Integer& t) +{ + reg.CleanGrow(t.reg.size()); + if (NotNegative()) + { + if (t.NotNegative()) + PositiveAdd(*this, *this, t); + else + PositiveSubtract(*this, *this, t); + } + else + { + if (t.NotNegative()) + PositiveSubtract(*this, t, *this); + else + { + PositiveAdd(*this, *this, t); + sign = Integer::NEGATIVE; + } + } + return *this; +} + +Integer Integer::Minus(const Integer& b) const +{ + Integer diff((word)0, STDMAX2(reg.size(), b.reg.size())); + if (NotNegative()) + { + if (b.NotNegative()) + PositiveSubtract(diff, *this, b); + else + PositiveAdd(diff, *this, b); + } + else + { + if (b.NotNegative()) + { + PositiveAdd(diff, *this, b); + diff.sign = Integer::NEGATIVE; + } + else + PositiveSubtract(diff, b, *this); + } + return diff; +} + +Integer& Integer::operator-=(const Integer& t) +{ + reg.CleanGrow(t.reg.size()); + if (NotNegative()) + { + if (t.NotNegative()) + PositiveSubtract(*this, *this, t); + else + PositiveAdd(*this, *this, t); + } + else + { + if (t.NotNegative()) + { + PositiveAdd(*this, *this, t); + sign = Integer::NEGATIVE; + } + else + PositiveSubtract(*this, t, *this); + } + return *this; +} + +Integer& Integer::operator<<=(size_t n) +{ + const size_t wordCount = WordCount(); + const size_t shiftWords = n / WORD_BITS; + const unsigned int shiftBits = (unsigned int)(n % WORD_BITS); + + reg.CleanGrow(RoundupSize(wordCount+BitsToWords(n))); + ShiftWordsLeftByWords(reg, wordCount + shiftWords, shiftWords); + ShiftWordsLeftByBits(reg+shiftWords, wordCount+BitsToWords(shiftBits), shiftBits); + return *this; +} + +Integer& Integer::operator>>=(size_t n) +{ + const size_t wordCount = WordCount(); + const size_t shiftWords = n / WORD_BITS; + const unsigned int shiftBits = (unsigned int)(n % WORD_BITS); + + ShiftWordsRightByWords(reg, wordCount, shiftWords); + if (wordCount > shiftWords) + ShiftWordsRightByBits(reg, wordCount-shiftWords, shiftBits); + if (IsNegative() && WordCount()==0) // avoid -0 + *this = Zero(); + return *this; +} + +Integer& Integer::operator&=(const Integer& t) +{ + if (this != &t) + { + const size_t size = STDMIN(reg.size(), t.reg.size()); + reg.resize(size); + AndWords(reg, t.reg, size); + } + sign = POSITIVE; + return *this; +} + +Integer& Integer::operator|=(const Integer& t) +{ + if (this != &t) + { + if (reg.size() >= t.reg.size()) + { + OrWords(reg, t.reg, t.reg.size()); + } + else // reg.size() < t.reg.size() + { + const size_t head = reg.size(); + const size_t tail = t.reg.size() - reg.size(); + reg.resize(head+tail); + OrWords(reg, t.reg, head); + CopyWords(reg+head,t.reg+head,tail); + } + } + sign = POSITIVE; + return *this; +} + +Integer& Integer::operator^=(const Integer& t) +{ + if (this == &t) + { + *this = Zero(); + } + else + { + if (reg.size() >= t.reg.size()) + { + XorWords(reg, t.reg, t.reg.size()); + } + else // reg.size() < t.reg.size() + { + const size_t head = reg.size(); + const size_t tail = t.reg.size() - reg.size(); + reg.resize(head+tail); + XorWords(reg, t.reg, head); + CopyWords(reg+head,t.reg+head,tail); + } + } + sign = POSITIVE; + return *this; +} + +void PositiveMultiply(Integer &product, const Integer &a, const Integer &b) +{ + size_t aSize = RoundupSize(a.WordCount()); + size_t bSize = RoundupSize(b.WordCount()); + + product.reg.CleanNew(RoundupSize(aSize+bSize)); + product.sign = Integer::POSITIVE; + + IntegerSecBlock workspace(aSize + bSize); + AsymmetricMultiply(product.reg, workspace, a.reg, aSize, b.reg, bSize); +} + +void Multiply(Integer &product, const Integer &a, const Integer &b) +{ + PositiveMultiply(product, a, b); + + if (a.NotNegative() != b.NotNegative()) + product.Negate(); +} + +Integer Integer::Times(const Integer &b) const +{ + Integer product; + Multiply(product, *this, b); + return product; +} + +/* +void PositiveDivide(Integer &remainder, Integer "ient, + const Integer ÷nd, const Integer &divisor) +{ + remainder.reg.CleanNew(divisor.reg.size()); + remainder.sign = Integer::POSITIVE; + quotient.reg.New(0); + quotient.sign = Integer::POSITIVE; + unsigned i=dividend.BitCount(); + while (i--) + { + word overflow = ShiftWordsLeftByBits(remainder.reg, remainder.reg.size(), 1); + remainder.reg[0] |= dividend[i]; + if (overflow || remainder >= divisor) + { + Subtract(remainder.reg, remainder.reg, divisor.reg, remainder.reg.size()); + quotient.SetBit(i); + } + } +} +*/ + +void PositiveDivide(Integer &remainder, Integer "ient, + const Integer &a, const Integer &b) +{ + unsigned aSize = a.WordCount(); + unsigned bSize = b.WordCount(); + + if (!bSize) + throw Integer::DivideByZero(); + + if (aSize < bSize) + { + remainder = a; + remainder.sign = Integer::POSITIVE; + quotient = Integer::Zero(); + return; + } + + aSize += aSize%2; // round up to next even number + bSize += bSize%2; + + remainder.reg.CleanNew(RoundupSize(bSize)); + remainder.sign = Integer::POSITIVE; + quotient.reg.CleanNew(RoundupSize(aSize-bSize+2)); + quotient.sign = Integer::POSITIVE; + + IntegerSecBlock T(aSize+3*(bSize+2)); + Divide(remainder.reg, quotient.reg, T, a.reg, aSize, b.reg, bSize); +} + +void Integer::Divide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor) +{ + PositiveDivide(remainder, quotient, dividend, divisor); + + if (dividend.IsNegative()) + { + quotient.Negate(); + if (remainder.NotZero()) + { + --quotient; + remainder = divisor.AbsoluteValue() - remainder; + } + } + + if (divisor.IsNegative()) + quotient.Negate(); +} + +void Integer::DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n) +{ + q = a; + q >>= n; + + const size_t wordCount = BitsToWords(n); + if (wordCount <= a.WordCount()) + { + r.reg.resize(RoundupSize(wordCount)); + CopyWords(r.reg, a.reg, wordCount); + SetWords(r.reg+wordCount, 0, r.reg.size()-wordCount); + if (n % WORD_BITS != 0) + r.reg[wordCount-1] %= (word(1) << (n % WORD_BITS)); + } + else + { + r.reg.resize(RoundupSize(a.WordCount())); + CopyWords(r.reg, a.reg, r.reg.size()); + } + r.sign = POSITIVE; + + if (a.IsNegative() && r.NotZero()) + { + --q; + r = Power2(n) - r; + } +} + +Integer Integer::DividedBy(const Integer &b) const +{ + Integer remainder, quotient; + Integer::Divide(remainder, quotient, *this, b); + return quotient; +} + +Integer Integer::Modulo(const Integer &b) const +{ + Integer remainder, quotient; + Integer::Divide(remainder, quotient, *this, b); + return remainder; +} + +void Integer::Divide(word &remainder, Integer "ient, const Integer ÷nd, word divisor) +{ + if (!divisor) + throw Integer::DivideByZero(); + + // IsPowerOf2 uses BMI on x86 if available. There is a small + // but measurable improvement during decryption and signing. + if (IsPowerOf2(divisor)) + { + quotient = dividend >> (BitPrecision(divisor)-1); + remainder = dividend.reg[0] & (divisor-1); + return; + } + + unsigned int i = dividend.WordCount(); + quotient.reg.CleanNew(RoundupSize(i)); + remainder = 0; + while (i--) + { + quotient.reg[i] = DWord(dividend.reg[i], remainder) / divisor; + remainder = DWord(dividend.reg[i], remainder) % divisor; + } + + if (dividend.NotNegative()) + quotient.sign = POSITIVE; + else + { + quotient.sign = NEGATIVE; + if (remainder) + { + --quotient; + remainder = divisor - remainder; + } + } +} + +Integer Integer::DividedBy(word b) const +{ + word remainder; + Integer quotient; + Integer::Divide(remainder, quotient, *this, b); + return quotient; +} + +word Integer::Modulo(word divisor) const +{ + if (!divisor) + throw Integer::DivideByZero(); + + word remainder; + + // Profiling guided the flow below. + if ((divisor & (divisor-1)) != 0) // divisor is not a power of 2 + { + // Profiling guided the flow below. + unsigned int i = WordCount(); + if (divisor > 5) + { + remainder = 0; + while (i--) + remainder = DWord(reg[i], remainder) % divisor; + } + else + { + DWord sum(0, 0); + while (i--) + sum += reg[i]; + remainder = sum % divisor; + } + } + else // divisor is a power of 2 + { + remainder = reg[0] & (divisor-1); + } + + if (IsNegative() && remainder) + remainder = divisor - remainder; + + return remainder; +} + +void Integer::Negate() +{ + if (!!(*this)) // don't flip sign if *this==0 + sign = Sign(1-sign); +} + +int Integer::PositiveCompare(const Integer& t) const +{ + // Profiling guided the flow below. + const unsigned size = WordCount(), tSize = t.WordCount(); + if (size != tSize) + return size > tSize ? 1 : -1; + else + return CryptoPP::Compare(reg, t.reg, size); +} + +int Integer::Compare(const Integer& t) const +{ + if (NotNegative()) + { + if (t.NotNegative()) + return PositiveCompare(t); + else + return 1; + } + else + { + if (t.NotNegative()) + return -1; + else + return -PositiveCompare(t); + } +} + +Integer Integer::SquareRoot() const +{ + if (!IsPositive()) + return Zero(); + + // overestimate square root + Integer x, y = Power2((BitCount()+1)/2); + CRYPTOPP_ASSERT(y*y >= *this); + + do + { + x = y; + y = (x + *this/x) >> 1; + } while (y().Gcd(a, b); +} + +Integer Integer::InverseMod(const Integer &m) const +{ + CRYPTOPP_ASSERT(m.NotNegative()); + CRYPTOPP_ASSERT(m.NotZero()); + + if (IsNegative()) + return Modulo(m).InverseModNext(m); + + // http://github.com/weidai11/cryptopp/issues/602 + if (*this >= m) + return Modulo(m).InverseModNext(m); + + return InverseModNext(m); +} + +Integer Integer::InverseModNext(const Integer &m) const +{ + CRYPTOPP_ASSERT(m.NotNegative()); + CRYPTOPP_ASSERT(m.NotZero()); + + if (m.IsEven()) + { + if (!m || IsEven()) + return Zero(); // no inverse + if (*this == One()) + return One(); + + Integer u = m.Modulo(*this).InverseModNext(*this); + return !u ? Zero() : (m*(*this-u)+1)/(*this); + } + + // AlmostInverse requires a 4x workspace + IntegerSecBlock T(m.reg.size() * 4); + Integer r((word)0, m.reg.size()); + unsigned k = AlmostInverse(r.reg, T, reg, reg.size(), m.reg, m.reg.size()); + DivideByPower2Mod(r.reg, r.reg, k, m.reg, m.reg.size()); + return r; +} + +word Integer::InverseMod(word mod) const +{ + CRYPTOPP_ASSERT(mod != 0); + + word g0 = mod, g1 = *this % mod; + word v0 = 0, v1 = 1; + word y; + + while (g1) + { + if (g1 == 1) + return v1; + y = g0 / g1; + g0 = g0 % g1; + v0 += y * v1; + + if (!g0) + break; + if (g0 == 1) + return mod-v0; + y = g1 / g0; + g1 = g1 % g0; + v1 += y * v0; + } + return 0; +} + +// ******************************************************** + +ModularArithmetic::ModularArithmetic(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + OID oid(seq); + if (oid != ASN1::prime_field()) + BERDecodeError(); + m_modulus.BERDecode(seq); + seq.MessageEnd(); + m_result.reg.resize(m_modulus.reg.size()); +} + +void ModularArithmetic::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + ASN1::prime_field().DEREncode(seq); + m_modulus.DEREncode(seq); + seq.MessageEnd(); +} + +void ModularArithmetic::DEREncodeElement(BufferedTransformation &out, const Element &a) const +{ + a.DEREncodeAsOctetString(out, MaxElementByteLength()); +} + +void ModularArithmetic::BERDecodeElement(BufferedTransformation &in, Element &a) const +{ + a.BERDecodeAsOctetString(in, MaxElementByteLength()); +} + +const Integer& ModularArithmetic::Half(const Integer &a) const +{ + if (a.reg.size()==m_modulus.reg.size()) + { + CryptoPP::DivideByPower2Mod(m_result.reg.begin(), a.reg, 1, m_modulus.reg, a.reg.size()); + return m_result; + } + else + return m_result1 = (a.IsEven() ? (a >> 1) : ((a+m_modulus) >> 1)); +} + +const Integer& ModularArithmetic::Add(const Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Add(m_result.reg.begin(), a.reg, b.reg, a.reg.size()) + || Compare(m_result.reg, m_modulus.reg, a.reg.size()) >= 0) + { + CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); + } + return m_result; + } + else + { + m_result1 = a+b; + if (m_result1 >= m_modulus) + m_result1 -= m_modulus; + return m_result1; + } +} + +Integer& ModularArithmetic::Accumulate(Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Add(a.reg, a.reg, b.reg, a.reg.size()) + || Compare(a.reg, m_modulus.reg, a.reg.size()) >= 0) + { + CryptoPP::Subtract(a.reg, a.reg, m_modulus.reg, a.reg.size()); + } + } + else + { + a+=b; + if (a>=m_modulus) + a-=m_modulus; + } + + return a; +} + +const Integer& ModularArithmetic::Subtract(const Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Subtract(m_result.reg.begin(), a.reg, b.reg, a.reg.size())) + CryptoPP::Add(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); + return m_result; + } + else + { + m_result1 = a-b; + if (m_result1.IsNegative()) + m_result1 += m_modulus; + return m_result1; + } +} + +Integer& ModularArithmetic::Reduce(Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Subtract(a.reg, a.reg, b.reg, a.reg.size())) + CryptoPP::Add(a.reg, a.reg, m_modulus.reg, a.reg.size()); + } + else + { + a-=b; + if (a.IsNegative()) + a+=m_modulus; + } + + return a; +} + +const Integer& ModularArithmetic::Inverse(const Integer &a) const +{ + if (!a) + return a; + + CopyWords(m_result.reg.begin(), m_modulus.reg, m_modulus.reg.size()); + if (CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, a.reg, a.reg.size())) + Decrement(m_result.reg.begin()+a.reg.size(), m_modulus.reg.size()-a.reg.size()); + + return m_result; +} + +Integer ModularArithmetic::CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const +{ + if (m_modulus.IsOdd()) + { + MontgomeryRepresentation dr(m_modulus); + return dr.ConvertOut(dr.CascadeExponentiate(dr.ConvertIn(x), e1, dr.ConvertIn(y), e2)); + } + else + return AbstractRing::CascadeExponentiate(x, e1, y, e2); +} + +void ModularArithmetic::SimultaneousExponentiate(Integer *results, const Integer &base, const Integer *exponents, unsigned int exponentsCount) const +{ + if (m_modulus.IsOdd()) + { + MontgomeryRepresentation dr(m_modulus); + dr.SimultaneousExponentiate(results, dr.ConvertIn(base), exponents, exponentsCount); + for (unsigned int i=0; i::SimultaneousExponentiate(results, base, exponents, exponentsCount); +} + +MontgomeryRepresentation::MontgomeryRepresentation(const Integer &m) // modulus must be odd + : ModularArithmetic(m), + m_u((word)0, m_modulus.reg.size()), + m_workspace(5*m_modulus.reg.size()) +{ + if (!m_modulus.IsOdd()) + throw InvalidArgument("MontgomeryRepresentation: Montgomery representation requires an odd modulus"); + + RecursiveInverseModPower2(m_u.reg, m_workspace, m_modulus.reg, m_modulus.reg.size()); +} + +const Integer& MontgomeryRepresentation::Multiply(const Integer &a, const Integer &b) const +{ + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + CRYPTOPP_ASSERT(a.reg.size()<=N && b.reg.size()<=N); + + AsymmetricMultiply(T, T+2*N, a.reg, a.reg.size(), b.reg, b.reg.size()); + SetWords(T+a.reg.size()+b.reg.size(), 0, 2*N-a.reg.size()-b.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; +} + +const Integer& MontgomeryRepresentation::Square(const Integer &a) const +{ + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + CRYPTOPP_ASSERT(a.reg.size()<=N); + + CryptoPP::Square(T, T+2*N, a.reg, a.reg.size()); + SetWords(T+2*a.reg.size(), 0, 2*N-2*a.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; +} + +Integer MontgomeryRepresentation::ConvertOut(const Integer &a) const +{ + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + CRYPTOPP_ASSERT(a.reg.size()<=N); + + CopyWords(T, a.reg, a.reg.size()); + SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; +} + +const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a) const +{ +// return (EuclideanMultiplicativeInverse(a, modulus)<<(2*WORD_BITS*modulus.reg.size()))%modulus; + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + CRYPTOPP_ASSERT(a.reg.size()<=N); + + CopyWords(T, a.reg, a.reg.size()); + SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + unsigned k = AlmostInverse(R, T, R, N, m_modulus.reg, N); + +// cout << "k=" << k << " N*32=" << 32*N << endl; + + if (k>N*WORD_BITS) + DivideByPower2Mod(R, R, k-N*WORD_BITS, m_modulus.reg, N); + else + MultiplyByPower2Mod(R, R, N*WORD_BITS-k, m_modulus.reg, N); + + return m_result; +} + +// Specialization declared in misc.h to allow us to print integers +// with additional control options, like arbirary bases and uppercase. +template <> CRYPTOPP_DLL +std::string IntToString(Integer value, unsigned int base) +{ + // Hack... set the high bit for uppercase. Set the next bit fo a suffix. + static const unsigned int BIT_32 = (1U << 31); + const bool UPPER = !!(base & BIT_32); + static const unsigned int BIT_31 = (1U << 30); + const bool BASE = !!(base & BIT_31); + + const char CH = UPPER ? 'A' : 'a'; + base &= ~(BIT_32|BIT_31); + CRYPTOPP_ASSERT(base >= 2 && base <= 32); + + if (value == 0) + return "0"; + + bool negative = false, zero = false; + if (value.IsNegative()) + { + negative = true; + value.Negate(); + } + + if (!value) + zero = true; + + SecBlock s(value.BitCount() / (SaturatingSubtract1(BitPrecision(base),1U)) + 1); + Integer temp; + + unsigned int i=0; + while (!!value) + { + word digit; + Integer::Divide(digit, temp, value, word(base)); + s[i++]=char((digit < 10 ? '0' : (CH - 10)) + digit); + value.swap(temp); + } + + std::string result; + result.reserve(i+2); + + if (negative) + result += '-'; + + if (zero) + result += '0'; + + while (i--) + result += s[i]; + + if (BASE) + { + if (base == 10) + result += '.'; + else if (base == 16) + result += 'h'; + else if (base == 8) + result += 'o'; + else if (base == 2) + result += 'b'; + } + + return result; +} + +// Specialization declared in misc.h to avoid Coverity findings. +template <> CRYPTOPP_DLL +std::string IntToString(word64 value, unsigned int base) +{ + // Hack... set the high bit for uppercase. + static const unsigned int HIGH_BIT = (1U << 31); + const char CH = !!(base & HIGH_BIT) ? 'A' : 'a'; + base &= ~HIGH_BIT; + + CRYPTOPP_ASSERT(base >= 2); + if (value == 0) + return "0"; + + std::string result; + while (value > 0) + { + word64 digit = value % base; + result = char((digit < 10 ? '0' : (CH - 10)) + digit) + result; + value /= base; + } + return result; +} + +#ifndef CRYPTOPP_NO_ASSIGN_TO_INTEGER +// Allow the linker to discard Integer code if not needed. +// Also see http://github.com/weidai11/cryptopp/issues/389. +bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt) +{ + if (valueType != typeid(Integer)) + return false; + *reinterpret_cast(pInteger) = *reinterpret_cast(pInt); + return true; +} +#endif // CRYPTOPP_NO_ASSIGN_TO_INTEGER + +// *************************** C++ Static Initialization *************************** + +class InitInteger +{ +public: + InitInteger() + { + SetFunctionPointers(); + } +}; + +// This is not really needed because each Integer can dynamically initialize +// itself, but we take a peephole optimization and initialize the class once +// if init priorities are available. Dynamic initialization will be used if +// init priorities are not available. + +#if defined(HAVE_GCC_INIT_PRIORITY) + const InitInteger s_init __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 10))) = InitInteger(); + const Integer g_zero __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 11))) = Integer(0L); + const Integer g_one __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 12))) = Integer(1L); + const Integer g_two __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 13))) = Integer(2L); +#elif defined(HAVE_MSC_INIT_PRIORITY) + #pragma warning(disable: 4075) + #pragma init_seg(".CRT$XCU") + const InitInteger s_init; + const Integer g_zero(0L); + const Integer g_one(1L); + const Integer g_two(2L); + #pragma warning(default: 4075) +#elif HAVE_XLC_INIT_PRIORITY + // XLC needs constant, not a define + #pragma priority(280) + const InitInteger s_init; + const Integer g_zero(0L); + const Integer g_one(1L); + const Integer g_two(2L); +#else + const InitInteger s_init; +#endif + +// ***************** Library code ******************** + +const Integer &Integer::Zero() +{ +#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) + return g_zero; +#elif defined(CRYPTOPP_CXX11_STATIC_INIT) + static const Integer s_zero(0L); + return s_zero; +#else // Potential memory leak. Avoid if possible. + return Singleton >().Ref(); +#endif +} + +const Integer &Integer::One() +{ +#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) + return g_one; +#elif defined(CRYPTOPP_CXX11_STATIC_INIT) + static const Integer s_one(1L); + return s_one; +#else // Potential memory leak. Avoid if possible. + return Singleton >().Ref(); +#endif +} + +const Integer &Integer::Two() +{ +#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) + return g_two; +#elif defined(CRYPTOPP_CXX11_STATIC_INIT) + static const Integer s_two(2L); + return s_two; +#else // Potential memory leak. Avoid if possible. + return Singleton >().Ref(); +#endif +} + +NAMESPACE_END + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/integer.h b/external/ours/library/crypto/src/shared/original/integer.h new file mode 100755 index 000000000..d727bdf78 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/integer.h @@ -0,0 +1,837 @@ +// integer.h - originally written and placed in the public domain by Wei Dai + +/// \file integer.h +/// \brief Multiple precision integer with arithmetic operations +/// \details The Integer class can represent positive and negative integers +/// with absolute value less than (256**sizeof(word))(256**sizeof(int)). +/// \details Internally, the library uses a sign magnitude representation, and the class +/// has two data members. The first is a IntegerSecBlock (a SecBlock) and it is +/// used to hold the representation. The second is a Sign (an enumeration), and it is +/// used to track the sign of the Integer. +/// \details For details on how the Integer class initializes its function pointers using +/// InitializeInteger and how it creates Integer::Zero(), Integer::One(), and +/// Integer::Two(), then see the comments at the top of integer.cpp. +/// \since Crypto++ 1.0 + +#ifndef CRYPTOPP_INTEGER_H +#define CRYPTOPP_INTEGER_H + +#include "cryptlib.h" +#include "secblock.h" +#include "stdcpp.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// \struct InitializeInteger +/// \brief Performs static initialization of the Integer class +struct InitializeInteger +{ + InitializeInteger(); +}; + +// Always align, http://github.com/weidai11/cryptopp/issues/256 +typedef SecBlock > IntegerSecBlock; + +/// \brief Multiple precision integer with arithmetic operations +/// \details The Integer class can represent positive and negative integers +/// with absolute value less than (256**sizeof(word))(256**sizeof(int)). +/// \details Internally, the library uses a sign magnitude representation, and the class +/// has two data members. The first is a IntegerSecBlock (a SecBlock) and it is +/// used to hold the representation. The second is a Sign (an enumeration), and it is +/// used to track the sign of the Integer. +/// \details For details on how the Integer class initializes its function pointers using +/// InitializeInteger and how it creates Integer::Zero(), Integer::One(), and +/// Integer::Two(), then see the comments at the top of integer.cpp. +/// \since Crypto++ 1.0 +/// \nosubgrouping +class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object +{ +public: + /// \name ENUMS, EXCEPTIONS, and TYPEDEFS + //@{ + /// \brief Exception thrown when division by 0 is encountered + class DivideByZero : public Exception + { + public: + DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {} + }; + + /// \brief Exception thrown when a random number cannot be found that + /// satisfies the condition + class RandomNumberNotFound : public Exception + { + public: + RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {} + }; + + /// \enum Sign + /// \brief Used internally to represent the integer + /// \details Sign is used internally to represent the integer. It is also used in a few API functions. + /// \sa SetPositive(), SetNegative(), Signedness + enum Sign { + /// \brief the value is positive or 0 + POSITIVE=0, + /// \brief the value is negative + NEGATIVE=1}; + + /// \enum Signedness + /// \brief Used when importing and exporting integers + /// \details Signedness is usually used in API functions. + /// \sa Sign + enum Signedness { + /// \brief an unsigned value + UNSIGNED, + /// \brief a signed value + SIGNED}; + + /// \enum RandomNumberType + /// \brief Properties of a random integer + enum RandomNumberType { + /// \brief a number with no special properties + ANY, + /// \brief a number which is probabilistically prime + PRIME}; + //@} + + /// \name CREATORS + //@{ + /// \brief Creates the zero integer + Integer(); + + /// copy constructor + Integer(const Integer& t); + + /// \brief Convert from signed long + Integer(signed long value); + + /// \brief Convert from lword + /// \param sign enumeration indicating Sign + /// \param value the long word + Integer(Sign sign, lword value); + + /// \brief Convert from two words + /// \param sign enumeration indicating Sign + /// \param highWord the high word + /// \param lowWord the low word + Integer(Sign sign, word highWord, word lowWord); + + /// \brief Convert from a C-string + /// \param str C-string value + /// \param order the ByteOrder of the string to be processed + /// \details \p str can be in base 2, 8, 10, or 16. Base is determined by a case + /// insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10. + /// \details Byte order was added at Crypto++ 5.7 to allow use of little-endian + /// integers with curve25519, Poly1305 and Microsoft CAPI. + explicit Integer(const char *str, ByteOrder order = BIG_ENDIAN_ORDER); + + /// \brief Convert from a wide C-string + /// \param str wide C-string value + /// \param order the ByteOrder of the string to be processed + /// \details \p str can be in base 2, 8, 10, or 16. Base is determined by a case + /// insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10. + /// \details Byte order was added at Crypto++ 5.7 to allow use of little-endian + /// integers with curve25519, Poly1305 and Microsoft CAPI. + explicit Integer(const wchar_t *str, ByteOrder order = BIG_ENDIAN_ORDER); + + /// \brief Convert from a big-endian byte array + /// \param encodedInteger big-endian byte array + /// \param byteCount length of the byte array + /// \param sign enumeration indicating Signedness + /// \param order the ByteOrder of the array to be processed + /// \details Byte order was added at Crypto++ 5.7 to allow use of little-endian + /// integers with curve25519, Poly1305 and Microsoft CAPI. + Integer(const byte *encodedInteger, size_t byteCount, Signedness sign=UNSIGNED, ByteOrder order = BIG_ENDIAN_ORDER); + + /// \brief Convert from a big-endian array + /// \param bt BufferedTransformation object with big-endian byte array + /// \param byteCount length of the byte array + /// \param sign enumeration indicating Signedness + /// \param order the ByteOrder of the data to be processed + /// \details Byte order was added at Crypto++ 5.7 to allow use of little-endian + /// integers with curve25519, Poly1305 and Microsoft CAPI. + Integer(BufferedTransformation &bt, size_t byteCount, Signedness sign=UNSIGNED, ByteOrder order = BIG_ENDIAN_ORDER); + + /// \brief Convert from a BER encoded byte array + /// \param bt BufferedTransformation object with BER encoded byte array + explicit Integer(BufferedTransformation &bt); + + /// \brief Create a random integer + /// \param rng RandomNumberGenerator used to generate material + /// \param bitCount the number of bits in the resulting integer + /// \details The random integer created is uniformly distributed over [0, 2bitCount]. + Integer(RandomNumberGenerator &rng, size_t bitCount); + + /// \brief Integer representing 0 + /// \return an Integer representing 0 + /// \details Zero() avoids calling constructors for frequently used integers + static const Integer & CRYPTOPP_API Zero(); + /// \brief Integer representing 1 + /// \return an Integer representing 1 + /// \details One() avoids calling constructors for frequently used integers + static const Integer & CRYPTOPP_API One(); + /// \brief Integer representing 2 + /// \return an Integer representing 2 + /// \details Two() avoids calling constructors for frequently used integers + static const Integer & CRYPTOPP_API Two(); + + /// \brief Create a random integer of special form + /// \param rng RandomNumberGenerator used to generate material + /// \param min the minimum value + /// \param max the maximum value + /// \param rnType RandomNumberType to specify the type + /// \param equiv the equivalence class based on the parameter \p mod + /// \param mod the modulus used to reduce the equivalence class + /// \throw RandomNumberNotFound if the set is empty. + /// \details Ideally, the random integer created should be uniformly distributed + /// over {x | min \<= x \<= max and \p x is of rnType and x \% mod == equiv}. + /// However the actual distribution may not be uniform because sequential + /// search is used to find an appropriate number from a random starting + /// point. + /// \details May return (with very small probability) a pseudoprime when a prime + /// is requested and max \> lastSmallPrime*lastSmallPrime. \p lastSmallPrime + /// is declared in nbtheory.h. + Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One()); + + /// \brief Exponentiates to a power of 2 + /// \return the Integer 2e + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + static Integer CRYPTOPP_API Power2(size_t e); + //@} + + /// \name ENCODE/DECODE + //@{ + /// \brief Minimum number of bytes to encode this integer + /// \param sign enumeration indicating Signedness + /// \note The MinEncodedSize() of 0 is 1. + size_t MinEncodedSize(Signedness sign=UNSIGNED) const; + + /// \brief Encode in big-endian format + /// \param output big-endian byte array + /// \param outputLen length of the byte array + /// \param sign enumeration indicating Signedness + /// \details Unsigned means encode absolute value, signed means encode two's complement if negative. + /// \details outputLen can be used to ensure an Integer is encoded to an exact size (rather than a + /// minimum size). An exact size is useful, for example, when encoding to a field element size. + void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const; + + /// \brief Encode in big-endian format + /// \param bt BufferedTransformation object + /// \param outputLen length of the encoding + /// \param sign enumeration indicating Signedness + /// \details Unsigned means encode absolute value, signed means encode two's complement if negative. + /// \details outputLen can be used to ensure an Integer is encoded to an exact size (rather than a + /// minimum size). An exact size is useful, for example, when encoding to a field element size. + void Encode(BufferedTransformation &bt, size_t outputLen, Signedness sign=UNSIGNED) const; + + /// \brief Encode in DER format + /// \param bt BufferedTransformation object + /// \details Encodes the Integer using Distinguished Encoding Rules + /// The result is placed into a BufferedTransformation object + void DEREncode(BufferedTransformation &bt) const; + + /// \brief Encode absolute value as big-endian octet string + /// \param bt BufferedTransformation object + /// \param length the number of mytes to decode + void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const; + + /// \brief Encode absolute value in OpenPGP format + /// \param output big-endian byte array + /// \param bufferSize length of the byte array + /// \return length of the output + /// \details OpenPGPEncode places result into the buffer and returns the + /// number of bytes used for the encoding + size_t OpenPGPEncode(byte *output, size_t bufferSize) const; + + /// \brief Encode absolute value in OpenPGP format + /// \param bt BufferedTransformation object + /// \return length of the output + /// \details OpenPGPEncode places result into a BufferedTransformation object and returns the + /// number of bytes used for the encoding + size_t OpenPGPEncode(BufferedTransformation &bt) const; + + /// \brief Decode from big-endian byte array + /// \param input big-endian byte array + /// \param inputLen length of the byte array + /// \param sign enumeration indicating Signedness + void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED); + + /// \brief Decode nonnegative value from big-endian byte array + /// \param bt BufferedTransformation object + /// \param inputLen length of the byte array + /// \param sign enumeration indicating Signedness + /// \note bt.MaxRetrievable() \>= inputLen. + void Decode(BufferedTransformation &bt, size_t inputLen, Signedness sign=UNSIGNED); + + /// \brief Decode from BER format + /// \param input big-endian byte array + /// \param inputLen length of the byte array + void BERDecode(const byte *input, size_t inputLen); + + /// \brief Decode from BER format + /// \param bt BufferedTransformation object + void BERDecode(BufferedTransformation &bt); + + /// \brief Decode nonnegative value from big-endian octet string + /// \param bt BufferedTransformation object + /// \param length length of the byte array + void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length); + + /// \brief Exception thrown when an error is encountered decoding an OpenPGP integer + class OpenPGPDecodeErr : public Exception + { + public: + OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {} + }; + + /// \brief Decode from OpenPGP format + /// \param input big-endian byte array + /// \param inputLen length of the byte array + void OpenPGPDecode(const byte *input, size_t inputLen); + /// \brief Decode from OpenPGP format + /// \param bt BufferedTransformation object + void OpenPGPDecode(BufferedTransformation &bt); + //@} + + /// \name ACCESSORS + //@{ + /// \brief Determines if the Integer is convertable to Long + /// \return true if *this can be represented as a signed long + /// \sa ConvertToLong() + bool IsConvertableToLong() const; + /// \brief Convert the Integer to Long + /// \return equivalent signed long if possible, otherwise undefined + /// \sa IsConvertableToLong() + signed long ConvertToLong() const; + + /// \brief Determines the number of bits required to represent the Integer + /// \return number of significant bits + /// \details BitCount is calculated as floor(log2(abs(*this))) + 1. + unsigned int BitCount() const; + /// \brief Determines the number of bytes required to represent the Integer + /// \return number of significant bytes + /// \details ByteCount is calculated as ceiling(BitCount()/8). + unsigned int ByteCount() const; + /// \brief Determines the number of words required to represent the Integer + /// \return number of significant words + /// \details WordCount is calculated as ceiling(ByteCount()/sizeof(word)). + unsigned int WordCount() const; + + /// \brief Provides the i-th bit of the Integer + /// \return the i-th bit, i=0 being the least significant bit + bool GetBit(size_t i) const; + /// \brief Provides the i-th byte of the Integer + /// \return the i-th byte + byte GetByte(size_t i) const; + /// \brief Provides the low order bits of the Integer + /// \return n lowest bits of *this >> i + lword GetBits(size_t i, size_t n) const; + + /// \brief Determines if the Integer is 0 + /// \return true if the Integer is 0, false otherwise + bool IsZero() const {return !*this;} + /// \brief Determines if the Integer is non-0 + /// \return true if the Integer is non-0, false otherwise + bool NotZero() const {return !IsZero();} + /// \brief Determines if the Integer is negative + /// \return true if the Integer is negative, false otherwise + bool IsNegative() const {return sign == NEGATIVE;} + /// \brief Determines if the Integer is non-negative + /// \return true if the Integer is non-negative, false otherwise + bool NotNegative() const {return !IsNegative();} + /// \brief Determines if the Integer is positive + /// \return true if the Integer is positive, false otherwise + bool IsPositive() const {return NotNegative() && NotZero();} + /// \brief Determines if the Integer is non-positive + /// \return true if the Integer is non-positive, false otherwise + bool NotPositive() const {return !IsPositive();} + /// \brief Determines if the Integer is even parity + /// \return true if the Integer is even, false otherwise + bool IsEven() const {return GetBit(0) == 0;} + /// \brief Determines if the Integer is odd parity + /// \return true if the Integer is odd, false otherwise + bool IsOdd() const {return GetBit(0) == 1;} + //@} + + /// \name MANIPULATORS + //@{ + /// \brief Assignment + /// \param t the other Integer + /// \return the result of assignment + Integer& operator=(const Integer& t); + /// \brief Addition Assignment + /// \param t the other Integer + /// \return the result of *this + t + Integer& operator+=(const Integer& t); + /// \brief Subtraction Assignment + /// \param t the other Integer + /// \return the result of *this - t + Integer& operator-=(const Integer& t); + /// \brief Multiplication Assignment + /// \param t the other Integer + /// \return the result of *this * t + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer& operator*=(const Integer& t) {return *this = Times(t);} + /// \brief Division Assignment + /// \param t the other Integer + /// \return the result of *this / t + Integer& operator/=(const Integer& t) {return *this = DividedBy(t);} + /// \brief Remainder Assignment + /// \param t the other Integer + /// \return the result of *this % t + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer& operator%=(const Integer& t) {return *this = Modulo(t);} + /// \brief Division Assignment + /// \param t the other word + /// \return the result of *this / t + Integer& operator/=(word t) {return *this = DividedBy(t);} + /// \brief Remainder Assignment + /// \param t the other word + /// \return the result of *this % t + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));} + + /// \brief Left-shift Assignment + /// \param n number of bits to shift + /// \return reference to this Integer + Integer& operator<<=(size_t n); + /// \brief Right-shift Assignment + /// \param n number of bits to shift + /// \return reference to this Integer + Integer& operator>>=(size_t n); + + /// \brief Bitwise AND Assignment + /// \param t the other Integer + /// \return the result of *this & t + /// \details operator&=() performs a bitwise AND on *this. Missing bits are truncated + /// at the most significant bit positions, so the result is as small as the + /// smaller of the operands. + /// \details Internally, Crypto++ uses a sign-magnitude representation. The library + /// does not attempt to interpret bits, and the result is always POSITIVE. If needed, + /// the integer should be converted to a 2's compliment representation before performing + /// the operation. + /// \since Crypto++ 6.0 + Integer& operator&=(const Integer& t); + /// \brief Bitwise OR Assignment + /// \param t the second Integer + /// \return the result of *this | t + /// \details operator|=() performs a bitwise OR on *this. Missing bits are shifted in + /// at the most significant bit positions, so the result is as large as the + /// larger of the operands. + /// \details Internally, Crypto++ uses a sign-magnitude representation. The library + /// does not attempt to interpret bits, and the result is always POSITIVE. If needed, + /// the integer should be converted to a 2's compliment representation before performing + /// the operation. + /// \since Crypto++ 6.0 + Integer& operator|=(const Integer& t); + /// \brief Bitwise XOR Assignment + /// \param t the other Integer + /// \return the result of *this ^ t + /// \details operator^=() performs a bitwise XOR on *this. Missing bits are shifted + /// in at the most significant bit positions, so the result is as large as the + /// larger of the operands. + /// \details Internally, Crypto++ uses a sign-magnitude representation. The library + /// does not attempt to interpret bits, and the result is always POSITIVE. If needed, + /// the integer should be converted to a 2's compliment representation before performing + /// the operation. + /// \since Crypto++ 6.0 + Integer& operator^=(const Integer& t); + + /// \brief Set this Integer to random integer + /// \param rng RandomNumberGenerator used to generate material + /// \param bitCount the number of bits in the resulting integer + /// \details The random integer created is uniformly distributed over [0, 2bitCount]. + void Randomize(RandomNumberGenerator &rng, size_t bitCount); + + /// \brief Set this Integer to random integer + /// \param rng RandomNumberGenerator used to generate material + /// \param min the minimum value + /// \param max the maximum value + /// \details The random integer created is uniformly distributed over [min, max]. + void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max); + + /// \brief Set this Integer to random integer of special form + /// \param rng RandomNumberGenerator used to generate material + /// \param min the minimum value + /// \param max the maximum value + /// \param rnType RandomNumberType to specify the type + /// \param equiv the equivalence class based on the parameter \p mod + /// \param mod the modulus used to reduce the equivalence class + /// \throw RandomNumberNotFound if the set is empty. + /// \details Ideally, the random integer created should be uniformly distributed + /// over {x | min \<= x \<= max and \p x is of rnType and x \% mod == equiv}. + /// However the actual distribution may not be uniform because sequential + /// search is used to find an appropriate number from a random starting + /// point. + /// \details May return (with very small probability) a pseudoprime when a prime + /// is requested and max \> lastSmallPrime*lastSmallPrime. \p lastSmallPrime + /// is declared in nbtheory.h. + bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One()); + + /// \brief Generate a random number + /// \param rng RandomNumberGenerator used to generate material + /// \param params additional parameters that cannot be passed directly to the function + /// \return true if a random number was generated, false otherwise + /// \details GenerateRandomNoThrow attempts to generate a random number according to the + /// parameters specified in params. The function does not throw RandomNumberNotFound. + /// \details The example below generates a prime number using NameValuePairs that Integer + /// class recognizes. The names are not provided in argnames.h. + ///
+		///     AutoSeededRandomPool prng;
+		///     AlgorithmParameters params = MakeParameters("BitLength", 2048)
+		///                                                ("RandomNumberType", Integer::PRIME);
+		///     Integer x;
+		///     if (x.GenerateRandomNoThrow(prng, params) == false)
+		///         throw std::runtime_error("Failed to generate prime number");
+		/// 
+ bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs); + + /// \brief Generate a random number + /// \param rng RandomNumberGenerator used to generate material + /// \param params additional parameters that cannot be passed directly to the function + /// \throw RandomNumberNotFound if a random number is not found + /// \details GenerateRandom attempts to generate a random number according to the + /// parameters specified in params. + /// \details The example below generates a prime number using NameValuePairs that Integer + /// class recognizes. The names are not provided in argnames.h. + ///
+		///     AutoSeededRandomPool prng;
+		///     AlgorithmParameters params = MakeParameters("BitLength", 2048)
+		///                                                ("RandomNumberType", Integer::PRIME);
+		///     Integer x;
+		///     try { x.GenerateRandom(prng, params); }
+		///     catch (RandomNumberNotFound&) { x = -1; }
+		/// 
+ void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) + { + if (!GenerateRandomNoThrow(rng, params)) + throw RandomNumberNotFound(); + } + + /// \brief Set the n-th bit to value + /// \details 0-based numbering. + void SetBit(size_t n, bool value=1); + + /// \brief Set the n-th byte to value + /// \details 0-based numbering. + void SetByte(size_t n, byte value); + + /// \brief Reverse the Sign of the Integer + void Negate(); + + /// \brief Sets the Integer to positive + void SetPositive() {sign = POSITIVE;} + + /// \brief Sets the Integer to negative + void SetNegative() {if (!!(*this)) sign = NEGATIVE;} + + /// \brief Swaps this Integer with another Integer + void swap(Integer &a); + //@} + + /// \name UNARY OPERATORS + //@{ + /// \brief Negation + bool operator!() const; + /// \brief Addition + Integer operator+() const {return *this;} + /// \brief Subtraction + Integer operator-() const; + /// \brief Pre-increment + Integer& operator++(); + /// \brief Pre-decrement + Integer& operator--(); + /// \brief Post-increment + Integer operator++(int) {Integer temp = *this; ++*this; return temp;} + /// \brief Post-decrement + Integer operator--(int) {Integer temp = *this; --*this; return temp;} + //@} + + /// \name BINARY OPERATORS + //@{ + /// \brief Perform signed comparison + /// \param a the Integer to comapre + /// \retval -1 if *this < a + /// \retval 0 if *this = a + /// \retval 1 if *this > a + int Compare(const Integer& a) const; + + /// \brief Addition + Integer Plus(const Integer &b) const; + /// \brief Subtraction + Integer Minus(const Integer &b) const; + /// \brief Multiplication + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer Times(const Integer &b) const; + /// \brief Division + Integer DividedBy(const Integer &b) const; + /// \brief Remainder + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer Modulo(const Integer &b) const; + /// \brief Division + Integer DividedBy(word b) const; + /// \brief Remainder + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + word Modulo(word b) const; + + /// \brief Bitwise AND + /// \param t the other Integer + /// \return the result of *this & t + /// \details And() performs a bitwise AND on the operands. Missing bits are truncated + /// at the most significant bit positions, so the result is as small as the + /// smaller of the operands. + /// \details Internally, Crypto++ uses a sign-magnitude representation. The library + /// does not attempt to interpret bits, and the result is always POSITIVE. If needed, + /// the integer should be converted to a 2's compliment representation before performing + /// the operation. + /// \since Crypto++ 6.0 + Integer And(const Integer& t) const; + + /// \brief Bitwise OR + /// \param t the other Integer + /// \return the result of *this | t + /// \details Or() performs a bitwise OR on the operands. Missing bits are shifted in + /// at the most significant bit positions, so the result is as large as the + /// larger of the operands. + /// \details Internally, Crypto++ uses a sign-magnitude representation. The library + /// does not attempt to interpret bits, and the result is always POSITIVE. If needed, + /// the integer should be converted to a 2's compliment representation before performing + /// the operation. + /// \since Crypto++ 6.0 + Integer Or(const Integer& t) const; + + /// \brief Bitwise XOR + /// \param t the other Integer + /// \return the result of *this ^ t + /// \details Xor() performs a bitwise XOR on the operands. Missing bits are shifted in + /// at the most significant bit positions, so the result is as large as the + /// larger of the operands. + /// \details Internally, Crypto++ uses a sign-magnitude representation. The library + /// does not attempt to interpret bits, and the result is always POSITIVE. If needed, + /// the integer should be converted to a 2's compliment representation before performing + /// the operation. + /// \since Crypto++ 6.0 + Integer Xor(const Integer& t) const; + + /// \brief Right-shift + Integer operator>>(size_t n) const {return Integer(*this)>>=n;} + /// \brief Left-shift + Integer operator<<(size_t n) const {return Integer(*this)<<=n;} + //@} + + /// \name OTHER ARITHMETIC FUNCTIONS + //@{ + /// \brief Retrieve the absolute value of this integer + Integer AbsoluteValue() const; + /// \brief Add this integer to itself + Integer Doubled() const {return Plus(*this);} + /// \brief Multiply this integer by itself + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer Squared() const {return Times(*this);} + /// \brief Extract square root + /// \details if negative return 0, else return floor of square root + Integer SquareRoot() const; + /// \brief Determine whether this integer is a perfect square + bool IsSquare() const; + + /// \brief Determine if 1 or -1 + /// \return true if this integer is 1 or -1, false otherwise + bool IsUnit() const; + /// \brief Calculate multiplicative inverse + /// \return MultiplicativeInverse inverse if 1 or -1, otherwise return 0. + Integer MultiplicativeInverse() const; + + /// \brief Extended Division + /// \param r a reference for the remainder + /// \param q a reference for the quotient + /// \param a a reference to the dividend + /// \param d a reference to the divisor + /// \details Divide calculates r and q such that (a == d*q + r) && (0 <= r < abs(d)). + static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d); + + /// \brief Extended Division + /// \param r a reference for the remainder + /// \param q a reference for the quotient + /// \param a a reference to the dividend + /// \param d a reference to the divisor + /// \details Divide calculates r and q such that (a == d*q + r) && (0 <= r < abs(d)). + /// This overload uses a faster division algorithm because the divisor is short. + static void CRYPTOPP_API Divide(word &r, Integer &q, const Integer &a, word d); + + /// \brief Extended Division + /// \param r a reference for the remainder + /// \param q a reference for the quotient + /// \param a a reference to the dividend + /// \param n a reference to the divisor + /// \details DivideByPowerOf2 calculates r and q such that (a == d*q + r) && (0 <= r < abs(d)). + /// It returns same result as Divide(r, q, a, Power2(n)), but faster. + /// This overload uses a faster division algorithm because the divisor is a power of 2. + static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n); + + /// \brief Calculate greatest common divisor + /// \param a a reference to the first number + /// \param n a reference to the secind number + /// \return the greatest common divisor a and n. + static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n); + + /// \brief Calculate multiplicative inverse + /// \param n a reference to the modulus + /// \return an Integer *this % n. + /// \details InverseMod returns the multiplicative inverse of the Integer *this + /// modulo the Integer n. If no Integer exists then Integer 0 is returned. + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + Integer InverseMod(const Integer &n) const; + + /// \brief Calculate multiplicative inverse + /// \param n the modulus + /// \return a word *this % n. + /// \details InverseMod returns the multiplicative inverse of the Integer *this + /// modulo the word n. If no Integer exists then word 0 is returned. + /// \sa a_times_b_mod_c() and a_exp_b_mod_c() + word InverseMod(word n) const; + //@} + + /// \name INPUT/OUTPUT + //@{ + /// \brief Extraction operator + /// \param in a reference to a std::istream + /// \param a a reference to an Integer + /// \return a reference to a std::istream reference + friend CRYPTOPP_DLL std::istream& CRYPTOPP_API operator>>(std::istream& in, Integer &a); + + /// \brief Insertion operator + /// \param out a reference to a std::ostream + /// \param a a constant reference to an Integer + /// \return a reference to a std::ostream reference + /// \details The output integer responds to std::hex, std::oct, std::hex, std::upper and + /// std::lower. The output includes the suffix \a h (for hex), \a . (\a dot, for dec) + /// and \a o (for octal). There is currently no way to suppress the suffix. + /// \details If you want to print an Integer without the suffix or using an arbitrary base, then + /// use IntToString(). + /// \sa IntToString + friend CRYPTOPP_DLL std::ostream& CRYPTOPP_API operator<<(std::ostream& out, const Integer &a); + //@} + + /// \brief Modular multiplication + /// \param x a reference to the first term + /// \param y a reference to the second term + /// \param m a reference to the modulus + /// \return an Integer (a * b) % m. + CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m); + /// \brief Modular exponentiation + /// \param x a reference to the base + /// \param e a reference to the exponent + /// \param m a reference to the modulus + /// \return an Integer (a ^ b) % m. + CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m); + +protected: + + // http://github.com/weidai11/cryptopp/issues/602 + Integer InverseModNext(const Integer &n) const; + +private: + + Integer(word value, size_t length); + int PositiveCompare(const Integer &t) const; + + IntegerSecBlock reg; + Sign sign; + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + friend class ModularArithmetic; + friend class MontgomeryRepresentation; + friend class HalfMontgomeryRepresentation; + + friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b); + friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b); + friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b); + friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor); +#endif +}; + +/// \brief Comparison +inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;} +/// \brief Comparison +inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;} +/// \brief Comparison +inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;} +/// \brief Comparison +inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;} +/// \brief Comparison +inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;} +/// \brief Comparison +inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;} +/// \brief Addition +inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);} +/// \brief Subtraction +inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);} +/// \brief Multiplication +/// \sa a_times_b_mod_c() and a_exp_b_mod_c() +inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);} +/// \brief Division +inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);} +/// \brief Remainder +/// \sa a_times_b_mod_c() and a_exp_b_mod_c() +inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);} +/// \brief Division +inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);} +/// \brief Remainder +/// \sa a_times_b_mod_c() and a_exp_b_mod_c() +inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);} + +/// \brief Bitwise AND +/// \param a the first Integer +/// \param b the second Integer +/// \return the result of a & b +/// \details operator&() performs a bitwise AND on the operands. Missing bits are truncated +/// at the most significant bit positions, so the result is as small as the +/// smaller of the operands. +/// \details Internally, Crypto++ uses a sign-magnitude representation. The library +/// does not attempt to interpret bits, and the result is always POSITIVE. If needed, +/// the integer should be converted to a 2's compliment representation before performing +/// the operation. +/// \since Crypto++ 6.0 +inline CryptoPP::Integer operator&(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.And(b);} + +/// \brief Bitwise OR +/// \param a the first Integer +/// \param b the second Integer +/// \return the result of a | b +/// \details operator|() performs a bitwise OR on the operands. Missing bits are shifted in +/// at the most significant bit positions, so the result is as large as the +/// larger of the operands. +/// \details Internally, Crypto++ uses a sign-magnitude representation. The library +/// does not attempt to interpret bits, and the result is always POSITIVE. If needed, +/// the integer should be converted to a 2's compliment representation before performing +/// the operation. +/// \since Crypto++ 6.0 +inline CryptoPP::Integer operator|(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Or(b);} + +/// \brief Bitwise XOR +/// \param a the first Integer +/// \param b the second Integer +/// \return the result of a ^ b +/// \details operator^() performs a bitwise XOR on the operands. Missing bits are shifted +/// in at the most significant bit positions, so the result is as large as the +/// larger of the operands. +/// \details Internally, Crypto++ uses a sign-magnitude representation. The library +/// does not attempt to interpret bits, and the result is always POSITIVE. If needed, +/// the integer should be converted to a 2's compliment representation before performing +/// the operation. +/// \since Crypto++ 6.0 +inline CryptoPP::Integer operator^(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Xor(b);} + +NAMESPACE_END + +#ifndef __BORLANDC__ +NAMESPACE_BEGIN(std) +inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b) +{ + a.swap(b); +} +NAMESPACE_END +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/iterhash.cpp b/external/ours/library/crypto/src/shared/original/iterhash.cpp index 1730ce941..938a0faca 100755 --- a/external/ours/library/crypto/src/shared/original/iterhash.cpp +++ b/external/ours/library/crypto/src/shared/original/iterhash.cpp @@ -1,14 +1,200 @@ -// iterhash.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef WORD64_AVAILABLE -template class IteratedHashBase; -#endif - -template class IteratedHashBase; - -NAMESPACE_END +// iterhash.cpp - originally written and placed in the public domain by Wei Dai + +#ifndef __GNUC__ +#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#endif + +#include "iterhash.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +template void IteratedHashBase::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); + if (length == 0) { return; } + + HashWordType oldCountLo = m_countLo, oldCountHi = m_countHi; + if ((m_countLo = oldCountLo + HashWordType(length)) < oldCountLo) + m_countHi++; // carry from low to high + m_countHi += (HashWordType)SafeRightShift<8*sizeof(HashWordType)>(length); + if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(length) != 0) + throw HashInputTooLong(this->AlgorithmName()); + + const unsigned int blockSize = this->BlockSize(); + unsigned int num = ModPowerOf2(oldCountLo, blockSize); + + T* dataBuf = this->DataBuf(); + byte* data = (byte *)dataBuf; + + if (num != 0) // process left over data + { + if (num+length >= blockSize) + { + if (input) + {std::memcpy(data+num, input, blockSize-num);} + + HashBlock(dataBuf); + input += (blockSize-num); + length -= (blockSize-num); + num = 0; + // drop through and do the rest + } + else + { + if (input && length) + {std::memcpy(data+num, input, length);} + return; + } + } + + // now process the input data in blocks of blockSize bytes and save the leftovers to m_data + if (length >= blockSize) + { + if (input == data) + { + CRYPTOPP_ASSERT(length == blockSize); + HashBlock(dataBuf); + return; + } + else if (IsAligned(input)) + { + size_t leftOver = HashMultipleBlocks((T *)(void*)input, length); + input += (length - leftOver); + length = leftOver; + } + else + { + do + { // copy input first if it's not aligned correctly + if (input) + { std::memcpy(data, input, blockSize); } + + HashBlock(dataBuf); + input+=blockSize; + length-=blockSize; + } while (length >= blockSize); + } + } + + if (input && data != input) + std::memcpy(data, input, length); +} + +template byte * IteratedHashBase::CreateUpdateSpace(size_t &size) +{ + unsigned int blockSize = this->BlockSize(); + unsigned int num = ModPowerOf2(m_countLo, blockSize); + size = blockSize - num; + return (byte *)DataBuf() + num; +} + +template size_t IteratedHashBase::HashMultipleBlocks(const T *input, size_t length) +{ + const unsigned int blockSize = this->BlockSize(); + bool noReverse = NativeByteOrderIs(this->GetByteOrder()); + T* dataBuf = this->DataBuf(); + + // Alignment checks due to http://github.com/weidai11/cryptopp/issues/690. + // Sparc requires 8-byte aligned buffer when HashWordType is word64. + // We also had to provide a GetAlignmentOf specialization for word64 on Sparc. + + do + { + if (noReverse) + { + if (IsAligned(input)) + { + // Sparc bus error with non-aligned input. + this->HashEndianCorrectedBlock(input); + } + else + { + std::memcpy(dataBuf, input, blockSize); + this->HashEndianCorrectedBlock(dataBuf); + } + } + else + { + if (IsAligned(input)) + { + // Sparc bus error with non-aligned input. + ByteReverse(dataBuf, input, blockSize); + this->HashEndianCorrectedBlock(dataBuf); + } + else + { + std::memcpy(dataBuf, input, blockSize); + ByteReverse(dataBuf, dataBuf, blockSize); + this->HashEndianCorrectedBlock(dataBuf); + } + } + + input += blockSize/sizeof(T); + length -= blockSize; + } + while (length >= blockSize); + return length; +} + +template void IteratedHashBase::PadLastBlock(unsigned int lastBlockSize, byte padFirst) +{ + unsigned int blockSize = this->BlockSize(); + unsigned int num = ModPowerOf2(m_countLo, blockSize); + T* dataBuf = this->DataBuf(); + byte* data = (byte *)dataBuf; + + data[num++] = padFirst; + if (num <= lastBlockSize) + memset(data+num, 0, lastBlockSize-num); + else + { + memset(data+num, 0, blockSize-num); + HashBlock(dataBuf); + memset(data, 0, lastBlockSize); + } +} + +template void IteratedHashBase::Restart() +{ + m_countLo = m_countHi = 0; + Init(); +} + +template void IteratedHashBase::TruncatedFinal(byte *digest, size_t size) +{ + CRYPTOPP_ASSERT(digest != NULLPTR); + this->ThrowIfInvalidTruncatedSize(size); + + T* dataBuf = this->DataBuf(); + T* stateBuf = this->StateBuf(); + unsigned int blockSize = this->BlockSize(); + ByteOrder order = this->GetByteOrder(); + + PadLastBlock(blockSize - 2*sizeof(HashWordType)); + dataBuf[blockSize/sizeof(T)-2+order] = ConditionalByteReverse(order, this->GetBitCountLo()); + dataBuf[blockSize/sizeof(T)-1-order] = ConditionalByteReverse(order, this->GetBitCountHi()); + + HashBlock(dataBuf); + + if (IsAligned(digest) && size%sizeof(HashWordType)==0) + ConditionalByteReverse(order, (HashWordType *)(void*)digest, stateBuf, size); + else + { + ConditionalByteReverse(order, stateBuf, stateBuf, this->DigestSize()); + std::memcpy(digest, stateBuf, size); + } + + this->Restart(); // reinit for next use +} + +#if defined(__GNUC__) || defined(__clang__) + template class IteratedHashBase; + template class IteratedHashBase; + + template class IteratedHashBase; + template class IteratedHashBase; +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/iterhash.h b/external/ours/library/crypto/src/shared/original/iterhash.h index a0abd0e73..49d325857 100755 --- a/external/ours/library/crypto/src/shared/original/iterhash.h +++ b/external/ours/library/crypto/src/shared/original/iterhash.h @@ -1,187 +1,218 @@ -#ifndef CRYPTOPP_ITERHASH_H -#define CRYPTOPP_ITERHASH_H - -#include "cryptlib.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -/*! The following classes are explicitly instantiated in iterhash.cpp - - IteratedHashBase - IteratedHashBase // #ifdef WORD64_AVAILABLE -*/ -template -class IteratedHashBase : public virtual HashModule -{ -public: - typedef T HashWordType; - - IteratedHashBase(unsigned int blockSize, unsigned int digestSize); - unsigned int DigestSize() const {return digest.size * sizeof(T);}; - void Update(const byte *input, unsigned int length); - -protected: - virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); - void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); - void Reinit(); - virtual void Init() =0; - virtual void HashBlock(const T *input) =0; - - unsigned int blockSize; - word32 countLo, countHi; // 64-bit bit count - SecBlock data; // Data buffer - SecBlock digest; // Message digest -}; - -template -IteratedHashBase::IteratedHashBase(unsigned int blockSize, unsigned int digestSize) - : blockSize(blockSize), countLo(0), countHi(0) - , data(blockSize/sizeof(T)), digest(digestSize/sizeof(T)) -{ -} - -template void IteratedHashBase::Update(const byte *input, unsigned int len) -{ - HashWordType tmp = countLo; - if ((countLo = tmp + ((word32)len << 3)) < tmp) - countHi++; // Carry from low to high - - int rshift = (8*sizeof(HashWordType)-3); - if (rshift<32) - { - countHi += len >> rshift; - } - - assert((blockSize & (blockSize-1)) == 0); // blockSize is a power of 2 - unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1); - - if (num != 0) - { - if ((num+len) >= blockSize) - { - memcpy((byte *)data.ptr+num, input, blockSize-num); - HashBlock(data); - input += (blockSize-num); - len-=(blockSize - num); - num=0; - // drop through and do the rest - } - else - { - memcpy((byte *)data.ptr+num, input, len); - return; - } - } - - // we now can process the input data in blocks of blockSize - // chars and save the leftovers to this->data. - if (len >= blockSize) - { - if (IsAligned(input)) - { - unsigned int leftOver = HashMultipleBlocks((T *)input, len); - input += (len - leftOver); - len = leftOver; - } - else - do - { // copy input first if it's not aligned correctly - memcpy(data, input, blockSize); - HashBlock(data); - input+=blockSize; - len-=blockSize; - } while (len >= blockSize); - } - - memcpy(data, input, len); -} - -template unsigned int IteratedHashBase::HashMultipleBlocks(const T *input, unsigned int length) -{ - do - { - HashBlock(input); - input += blockSize/sizeof(T); - length -= blockSize; - } - while (length >= blockSize); - return length; -} - -template void IteratedHashBase::PadLastBlock(unsigned int lastBlockSize, byte padFirst) -{ - unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1); - assert(num < blockSize); - ((byte *)data.ptr)[num++]=padFirst; - if (num <= lastBlockSize) - memset((byte *)data.ptr+num, 0, lastBlockSize-num); - else - { - memset((byte *)data.ptr+num, 0, blockSize-num); - HashBlock(data); - memset(data, 0, lastBlockSize); - } -} - -template void IteratedHashBase::Reinit() -{ - countLo = countHi = 0; - Init(); -} - -// provide empty definitions to avoid instantiation warnings -template void IteratedHashBase::Init() {} -template void IteratedHashBase::HashBlock(const T *input) {} - -//! . -template -class IteratedHash : public IteratedHashBase -{ -public: - typedef T HashWordType; - enum {HIGHFIRST = H, BLOCKSIZE = S}; - - IteratedHash(unsigned int digestSize) : IteratedHashBase(BLOCKSIZE, digestSize) {} - - inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount) - { - if (!CheckEndianess(HIGHFIRST)) - byteReverse(out, in, byteCount); - else if (in!=out) - memcpy(out, in, byteCount); - } - - void Final(byte *hash) - { - this->PadLastBlock(BLOCKSIZE - 2*sizeof(HashWordType)); - CorrectEndianess(this->data, this->data, BLOCKSIZE - 2*sizeof(HashWordType)); - - this->data[this->data.size-2] = HIGHFIRST ? this->countHi : this->countLo; - this->data[this->data.size-1] = HIGHFIRST ? this->countLo : this->countHi; - - vTransform(this->data); - CorrectEndianess(this->digest, this->digest, this->DigestSize()); - memcpy(hash, this->digest, this->DigestSize()); - - this->Reinit(); // reinit for next use - } - -protected: - void HashBlock(const HashWordType *input) - { - if (CheckEndianess(HIGHFIRST)) - vTransform(input); - else - { - byteReverse(this->data.ptr, input, (unsigned int)BLOCKSIZE); - vTransform(this->data); - } - } - - virtual void vTransform(const HashWordType *data) =0; -}; - -NAMESPACE_END - -#endif +// iterhash.h - originally written and placed in the public domain by Wei Dai + +/// \file iterhash.h +/// \brief Base classes for iterated hashes + +#ifndef CRYPTOPP_ITERHASH_H +#define CRYPTOPP_ITERHASH_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" +#include "simple.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6011 6386 28193) +# endif +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Exception thrown when trying to hash more data than is allowed by a hash function +class CRYPTOPP_DLL HashInputTooLong : public InvalidDataFormat +{ +public: + explicit HashInputTooLong(const std::string &alg) + : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) {} +}; + +/// \brief Iterated hash base class +/// \tparam T Hash word type +/// \tparam BASE HashTransformation derived class +/// \details IteratedHashBase provides an interface for block-based iterated hashes +/// \sa HashTransformation, MessageAuthenticationCode +template +class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE +{ +public: + typedef T HashWordType; + + virtual ~IteratedHashBase() {} + + /// \brief Construct an IteratedHashBase + IteratedHashBase() : m_countLo(0), m_countHi(0) {} + + /// \brief Provides the input block size most efficient for this cipher. + /// \return The input block size that is most efficient for the cipher + /// \details The base class implementation returns MandatoryBlockSize(). + /// \note Optimal input length is + /// n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n \> 0. + unsigned int OptimalBlockSize() const {return this->BlockSize();} + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \details OptimalDataAlignment returns the natural alignment of the hash word. + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + /// \brief Updates a hash with additional input + /// \param input the additional input as a buffer + /// \param length the size of the buffer, in bytes + void Update(const byte *input, size_t length); + + /// \brief Requests space which can be written into by the caller + /// \param size the requested size of the buffer + /// \details The purpose of this method is to help avoid extra memory allocations. + /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, + /// size is the requested size of the buffer. When the call returns, size is the size of + /// the array returned to the caller. + /// \details The base class implementation sets size to 0 and returns NULL. + /// \note Some objects, like ArraySink, cannot create a space because its fixed. + byte * CreateUpdateSpace(size_t &size); + + /// \brief Restart the hash + /// \details Discards the current state, and restart for a new message + void Restart(); + + /// \brief Computes the hash of the current message + /// \param digest a pointer to the buffer to receive the hash + /// \param digestSize the size of the truncated digest, in bytes + /// \details TruncatedFinal() calls Final() and then copies digestSize bytes to digest. + /// The hash is restarted the hash for the next message. + void TruncatedFinal(byte *digest, size_t digestSize); + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \note Provider is not universally implemented yet. + virtual std::string AlgorithmProvider() const { return "C++"; } + +protected: + inline T GetBitCountHi() const + {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} + inline T GetBitCountLo() const + {return m_countLo << 3;} + + void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); + virtual void Init() =0; + + virtual ByteOrder GetByteOrder() const =0; + virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; + virtual size_t HashMultipleBlocks(const T *input, size_t length); + void HashBlock(const HashWordType *input) + {HashMultipleBlocks(input, this->BlockSize());} + + virtual T* DataBuf() =0; + virtual T* StateBuf() =0; + +private: + T m_countLo, m_countHi; +}; + +/// \brief Iterated hash base class +/// \tparam T_HashWordType Hash word type +/// \tparam T_Endianness Endianness type of hash +/// \tparam T_BlockSize Block size of the hash +/// \tparam T_Base HashTransformation derived class +/// \details IteratedHash provides a default implementation for block-based iterated hashes +/// \sa HashTransformation, MessageAuthenticationCode +template +class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase +{ +public: + typedef T_Endianness ByteOrderClass; + typedef T_HashWordType HashWordType; + + CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize); + // BCB2006 workaround: can't use BLOCKSIZE here + CRYPTOPP_COMPILE_ASSERT((T_BlockSize & (T_BlockSize - 1)) == 0); // blockSize is a power of 2 + + virtual ~IteratedHash() {} + + /// \brief Provides the block size of the hash + /// \return the block size of the hash, in bytes + /// \details BlockSize() returns T_BlockSize. + unsigned int BlockSize() const {return T_BlockSize;} + + /// \brief Provides the byte order of the hash + /// \return the byte order of the hash as an enumeration + /// \details GetByteOrder() returns T_Endianness::ToEnum(). + /// \sa ByteOrder() + ByteOrder GetByteOrder() const {return T_Endianness::ToEnum();} + + /// \brief Adjusts the byte ordering of the hash + /// \param out the output buffer + /// \param in the input buffer + /// \param byteCount the size of the buffers, in bytes + /// \details CorrectEndianess() calls ConditionalByteReverse() using T_Endianness. + inline void CorrectEndianess(HashWordType *out, const HashWordType *in, size_t byteCount) + { + CRYPTOPP_ASSERT(in != NULLPTR); + CRYPTOPP_ASSERT(out != NULLPTR); + CRYPTOPP_ASSERT(IsAligned(in)); + CRYPTOPP_ASSERT(IsAligned(out)); + + ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount); + } + +protected: + enum { Blocks = T_BlockSize/sizeof(T_HashWordType) }; + T_HashWordType* DataBuf() {return this->m_data;} + FixedSizeSecBlock m_data; +}; + +/// \brief Iterated hash with a static transformation function +/// \tparam T_HashWordType Hash word type +/// \tparam T_Endianness Endianness type of hash +/// \tparam T_BlockSize Block size of the hash +/// \tparam T_StateSize Internal state size of the hash +/// \tparam T_Transform HashTransformation derived class +/// \tparam T_DigestSize Digest size of the hash +/// \tparam T_StateAligned Flag indicating if state is 16-byte aligned +/// \sa HashTransformation, MessageAuthenticationCode +template +class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform + : public ClonableImpl, T_Transform> > +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize); + + virtual ~IteratedHashWithStaticTransform() {} + + /// \brief Provides the digest size of the hash + /// \return the digest size of the hash, in bytes + /// \details DigestSize() returns DIGESTSIZE. + unsigned int DigestSize() const {return DIGESTSIZE;} + +protected: + // https://github.com/weidai11/cryptopp/issues/147#issuecomment-766231864 + IteratedHashWithStaticTransform() {IteratedHashWithStaticTransform::Init();} + void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);} + void Init() {T_Transform::InitState(this->m_state);} + + enum { Blocks = T_BlockSize/sizeof(T_HashWordType) }; + T_HashWordType* StateBuf() {return this->m_state;} + FixedSizeAlignedSecBlock m_state; +}; + +#if !defined(__GNUC__) && !defined(__clang__) + CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; + CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; + + CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; + CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; +#endif + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/kalyna.cpp b/external/ours/library/crypto/src/shared/original/kalyna.cpp new file mode 100755 index 000000000..14d411e13 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/kalyna.cpp @@ -0,0 +1,1362 @@ +// kalyna.cpp - written and placed in the public domain by Jeffrey Walton +// This code relied upon three sources. First was Oliynykov, Gorbenko, Kazymyrov, Ruzhentsev, +// Kuznetsov, Gorbenko, Dyrda, Dolgov, Pushkaryov, Mordvinov and Kaidalov's "A New Encryption +// Standard of Ukraine: The Kalyna Block Cipher" (http://eprint.iacr.org/2015/650.pdf). Second +// was Roman Oliynykov and Oleksandr Kazymyrov's GitHub with the reference implementation +// (http://github.com/Roman-Oliynykov/Kalyna-reference). The third and most utilized resource +// was Keru Kuro's public domain implementation of Kalyna in CppCrypto +// (http://sourceforge.net/projects/cppcrypto/). Kuro has an outstanding implementation that +// performed better than the reference implementation and our initial attempts. The only downside +// was the missing big endian port. + +#include "pch.h" +#include "config.h" + +#include "kalyna.h" +#include "argnames.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(KalynaTab) + +// T can be shared between Kupyna and Kalyna; IT, S and IS are Kalyna specific +extern const word64 T[8][256]; // Columns +extern const word64 IT[8][256]; // Inverse +extern const byte S[4][256]; // Substitution +extern const byte IS[4][256]; // Inverse + +NAMESPACE_END +NAMESPACE_END + +ANONYMOUS_NAMESPACE_BEGIN + +// The typedef here is to sidestep problems with byte in the global namespace +typedef unsigned char byte; + +using CryptoPP::word64; +using CryptoPP::KalynaTab::T; +using CryptoPP::KalynaTab::S; +using CryptoPP::KalynaTab::IT; +using CryptoPP::KalynaTab::IS; + +template +inline void MakeOddKey(const word64 evenkey[NB], word64 oddkey[NB]) +{ +#if (CRYPTOPP_BIG_ENDIAN) + if (NB == 2) + { + oddkey[0] = (evenkey[1] << 8) | (evenkey[0] >> 56); + oddkey[1] = (evenkey[0] << 8) | (evenkey[1] >> 56); + } + else if (NB == 4) + { + oddkey[0] = (evenkey[2] << 40) | (evenkey[1] >> 24); + oddkey[1] = (evenkey[3] << 40) | (evenkey[2] >> 24); + oddkey[2] = (evenkey[0] << 40) | (evenkey[3] >> 24); + oddkey[3] = (evenkey[1] << 40) | (evenkey[0] >> 24); + } + else if (NB == 8) + { + oddkey[0] = (evenkey[3] << 40) | (evenkey[2] >> 24); + oddkey[1] = (evenkey[4] << 40) | (evenkey[3] >> 24); + oddkey[2] = (evenkey[5] << 40) | (evenkey[4] >> 24); + oddkey[3] = (evenkey[6] << 40) | (evenkey[5] >> 24); + + oddkey[4] = (evenkey[7] << 40) | (evenkey[6] >> 24); + oddkey[5] = (evenkey[0] << 40) | (evenkey[7] >> 24); + oddkey[6] = (evenkey[1] << 40) | (evenkey[0] >> 24); + oddkey[7] = (evenkey[2] << 40) | (evenkey[1] >> 24); + } + else + { + CRYPTOPP_ASSERT(0); + } +#else + static const unsigned int U = (NB == 2) ? 16 : (NB == 4) ? 32 : (NB == 8) ? 64 : -1; + static const unsigned int V = (NB == 2) ? 7 : (NB == 4) ? 11 : (NB == 8) ? 19 : -1; + + const byte* even = reinterpret_cast(evenkey); + byte* odd = reinterpret_cast(oddkey); + + memcpy(odd, even + V, U - V); + memcpy(odd + U - V, even, V); +#endif +} + +template +inline void SwapBlocks(word64 k[NB]) +{ + const word64 t = k[0]; + k[0] = k[1]; + + if (NB > 2) + { + k[1] = k[2]; + k[2] = k[3]; + } + + if (NB > 4) + { + k[3] = k[4]; + k[4] = k[5]; + k[5] = k[6]; + k[6] = k[7]; + } + + k[NB - 1] = t; +} + +template +inline void AddKey(const word64 x[NB], word64 y[NB], const word64 k[NB]) +{ + y[0] = x[0] + k[0]; + y[1] = x[1] + k[1]; + + if (NB > 2) + { + y[2] = x[2] + k[2]; + y[3] = x[3] + k[3]; + } + + if (NB > 4) + { + y[4] = x[4] + k[4]; + y[5] = x[5] + k[5]; + y[6] = x[6] + k[6]; + y[7] = x[7] + k[7]; + } +} + +template +inline void SubKey(const word64 x[NB], word64 y[NB], const word64 k[NB]) +{ + y[0] = x[0] - k[0]; + y[1] = x[1] - k[1]; + + if (NB > 2) + { + y[2] = x[2] - k[2]; + y[3] = x[3] - k[3]; + } + + if (NB > 4) + { + y[4] = x[4] - k[4]; + y[5] = x[5] - k[5]; + y[6] = x[6] - k[6]; + y[7] = x[7] - k[7]; + } +} + +template +static inline void AddConstant(word64 src[NB], word64 dst[NB], word64 constant) +{ + dst[0] = src[0] + constant; + dst[1] = src[1] + constant; + + if (NB > 2) + { + dst[2] = src[2] + constant; + dst[3] = src[3] + constant; + } + + if (NB > 4) + { + dst[4] = src[4] + constant; + dst[5] = src[5] + constant; + dst[6] = src[6] + constant; + dst[7] = src[7] + constant; + } +} + +inline void G0128(const word64 x[2], word64 y[2]) +{ + y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; + y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; +} + +inline void G0256(const word64 x[4], word64 y[4]) +{ + y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ + T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; + y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; + y[2] = T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; + y[3] = T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; +} + +inline void G0512(const word64 x[8], word64 y[8]) +{ + y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^ + T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; + y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^ + T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; + y[2] = T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^ + T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; + y[3] = T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]; + y[4] = T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]; + y[5] = T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]; + y[6] = T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ + T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]; + y[7] = T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^ + T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; +} + +inline void GL128(const word64 x[2], word64 y[2], const word64 k[2]) +{ + y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]); + y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]); +} + +inline void GL256(const word64 x[4], word64 y[4], const word64 k[4]) +{ + y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ + T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]); + y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]); + y[2] = k[2] + (T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]); + y[3] = k[3] + (T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]); +} + +inline void GL512(const word64 x[8], word64 y[8], const word64 k[8]) +{ + y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^ + T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]); + y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^ + T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]); + y[2] = k[2] + (T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^ + T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]); + y[3] = k[3] + (T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]); + y[4] = k[4] + (T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]); + y[5] = k[5] + (T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]); + y[6] = k[6] + (T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ + T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]); + y[7] = k[7] + (T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^ + T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]); +} + +inline void IMC128(word64 x[2]) +{ + x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^ + IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]]; + x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^ + IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]]; +} + +inline void IMC256(word64 x[4]) +{ + x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^ + IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]]; + x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^ + IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]]; + x[2] = IT[0][S[0][(byte)x[2]]] ^ IT[1][S[1][(byte)(x[2] >> 8)]] ^ IT[2][S[2][(byte)(x[2] >> 16)]] ^ IT[3][S[3][(byte)(x[2] >> 24)]] ^ + IT[4][S[0][(byte)(x[2] >> 32)]] ^ IT[5][S[1][(byte)(x[2] >> 40)]] ^ IT[6][S[2][(byte)(x[2] >> 48)]] ^ IT[7][S[3][(byte)(x[2] >> 56)]]; + x[3] = IT[0][S[0][(byte)x[3]]] ^ IT[1][S[1][(byte)(x[3] >> 8)]] ^ IT[2][S[2][(byte)(x[3] >> 16)]] ^ IT[3][S[3][(byte)(x[3] >> 24)]] ^ + IT[4][S[0][(byte)(x[3] >> 32)]] ^ IT[5][S[1][(byte)(x[3] >> 40)]] ^ IT[6][S[2][(byte)(x[3] >> 48)]] ^ IT[7][S[3][(byte)(x[3] >> 56)]]; +} + +inline void IMC512(word64 x[8]) +{ + x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^ + IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]]; + x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^ + IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]]; + x[2] = IT[0][S[0][(byte)x[2]]] ^ IT[1][S[1][(byte)(x[2] >> 8)]] ^ IT[2][S[2][(byte)(x[2] >> 16)]] ^ IT[3][S[3][(byte)(x[2] >> 24)]] ^ + IT[4][S[0][(byte)(x[2] >> 32)]] ^ IT[5][S[1][(byte)(x[2] >> 40)]] ^ IT[6][S[2][(byte)(x[2] >> 48)]] ^ IT[7][S[3][(byte)(x[2] >> 56)]]; + x[3] = IT[0][S[0][(byte)x[3]]] ^ IT[1][S[1][(byte)(x[3] >> 8)]] ^ IT[2][S[2][(byte)(x[3] >> 16)]] ^ IT[3][S[3][(byte)(x[3] >> 24)]] ^ + IT[4][S[0][(byte)(x[3] >> 32)]] ^ IT[5][S[1][(byte)(x[3] >> 40)]] ^ IT[6][S[2][(byte)(x[3] >> 48)]] ^ IT[7][S[3][(byte)(x[3] >> 56)]]; + x[4] = IT[0][S[0][(byte)x[4]]] ^ IT[1][S[1][(byte)(x[4] >> 8)]] ^ IT[2][S[2][(byte)(x[4] >> 16)]] ^ IT[3][S[3][(byte)(x[4] >> 24)]] ^ + IT[4][S[0][(byte)(x[4] >> 32)]] ^ IT[5][S[1][(byte)(x[4] >> 40)]] ^ IT[6][S[2][(byte)(x[4] >> 48)]] ^ IT[7][S[3][(byte)(x[4] >> 56)]]; + x[5] = IT[0][S[0][(byte)x[5]]] ^ IT[1][S[1][(byte)(x[5] >> 8)]] ^ IT[2][S[2][(byte)(x[5] >> 16)]] ^ IT[3][S[3][(byte)(x[5] >> 24)]] ^ + IT[4][S[0][(byte)(x[5] >> 32)]] ^ IT[5][S[1][(byte)(x[5] >> 40)]] ^ IT[6][S[2][(byte)(x[5] >> 48)]] ^ IT[7][S[3][(byte)(x[5] >> 56)]]; + x[6] = IT[0][S[0][(byte)x[6]]] ^ IT[1][S[1][(byte)(x[6] >> 8)]] ^ IT[2][S[2][(byte)(x[6] >> 16)]] ^ IT[3][S[3][(byte)(x[6] >> 24)]] ^ + IT[4][S[0][(byte)(x[6] >> 32)]] ^ IT[5][S[1][(byte)(x[6] >> 40)]] ^ IT[6][S[2][(byte)(x[6] >> 48)]] ^ IT[7][S[3][(byte)(x[6] >> 56)]]; + x[7] = IT[0][S[0][(byte)x[7]]] ^ IT[1][S[1][(byte)(x[7] >> 8)]] ^ IT[2][S[2][(byte)(x[7] >> 16)]] ^ IT[3][S[3][(byte)(x[7] >> 24)]] ^ + IT[4][S[0][(byte)(x[7] >> 32)]] ^ IT[5][S[1][(byte)(x[7] >> 40)]] ^ IT[6][S[2][(byte)(x[7] >> 48)]] ^ IT[7][S[3][(byte)(x[7] >> 56)]]; +} + +inline void IG128(const word64 x[2], word64 y[2], const word64 k[2]) +{ + y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^ + IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[1] >> 56)]; + y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^ + IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[0] >> 56)]; +} + +inline void IG256(const word64 x[4], word64 y[4], const word64 k[4]) +{ + y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^ + IT[4][(byte)(x[2] >> 32)] ^ IT[5][(byte)(x[2] >> 40)] ^ IT[6][(byte)(x[3] >> 48)] ^ IT[7][(byte)(x[3] >> 56)]; + y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[2] >> 16)] ^ IT[3][(byte)(x[2] >> 24)] ^ + IT[4][(byte)(x[3] >> 32)] ^ IT[5][(byte)(x[3] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[0] >> 56)]; + y[2] = k[2] ^ IT[0][(byte)x[2]] ^ IT[1][(byte)(x[2] >> 8)] ^ IT[2][(byte)(x[3] >> 16)] ^ IT[3][(byte)(x[3] >> 24)] ^ + IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[1] >> 56)]; + y[3] = k[3] ^ IT[0][(byte)x[3]] ^ IT[1][(byte)(x[3] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^ + IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[2] >> 48)] ^ IT[7][(byte)(x[2] >> 56)]; +} + +inline void IG512(const word64 x[8], word64 y[8], const word64 k[8]) +{ + y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[2] >> 16)] ^ IT[3][(byte)(x[3] >> 24)] ^ + IT[4][(byte)(x[4] >> 32)] ^ IT[5][(byte)(x[5] >> 40)] ^ IT[6][(byte)(x[6] >> 48)] ^ IT[7][(byte)(x[7] >> 56)]; + y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[2] >> 8)] ^ IT[2][(byte)(x[3] >> 16)] ^ IT[3][(byte)(x[4] >> 24)] ^ + IT[4][(byte)(x[5] >> 32)] ^ IT[5][(byte)(x[6] >> 40)] ^ IT[6][(byte)(x[7] >> 48)] ^ IT[7][(byte)(x[0] >> 56)]; + y[2] = k[2] ^ IT[0][(byte)x[2]] ^ IT[1][(byte)(x[3] >> 8)] ^ IT[2][(byte)(x[4] >> 16)] ^ IT[3][(byte)(x[5] >> 24)] ^ + IT[4][(byte)(x[6] >> 32)] ^ IT[5][(byte)(x[7] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[1] >> 56)]; + y[3] = k[3] ^ IT[0][(byte)x[3]] ^ IT[1][(byte)(x[4] >> 8)] ^ IT[2][(byte)(x[5] >> 16)] ^ IT[3][(byte)(x[6] >> 24)] ^ + IT[4][(byte)(x[7] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[2] >> 56)]; + y[4] = k[4] ^ IT[0][(byte)x[4]] ^ IT[1][(byte)(x[5] >> 8)] ^ IT[2][(byte)(x[6] >> 16)] ^ IT[3][(byte)(x[7] >> 24)] ^ + IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[2] >> 48)] ^ IT[7][(byte)(x[3] >> 56)]; + y[5] = k[5] ^ IT[0][(byte)x[5]] ^ IT[1][(byte)(x[6] >> 8)] ^ IT[2][(byte)(x[7] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^ + IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[2] >> 40)] ^ IT[6][(byte)(x[3] >> 48)] ^ IT[7][(byte)(x[4] >> 56)]; + y[6] = k[6] ^ IT[0][(byte)x[6]] ^ IT[1][(byte)(x[7] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^ + IT[4][(byte)(x[2] >> 32)] ^ IT[5][(byte)(x[3] >> 40)] ^ IT[6][(byte)(x[4] >> 48)] ^ IT[7][(byte)(x[5] >> 56)]; + y[7] = k[7] ^ IT[0][(byte)x[7]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[2] >> 24)] ^ + IT[4][(byte)(x[3] >> 32)] ^ IT[5][(byte)(x[4] >> 40)] ^ IT[6][(byte)(x[5] >> 48)] ^ IT[7][(byte)(x[6] >> 56)]; +} + +inline void IGL128(const word64 x[2], word64 y[2], const word64 k[2]) +{ + y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[0]; + y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1]; +} + +inline void IGL256(const word64 x[4], word64 y[4], const word64 k[4]) +{ + y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[2] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[2] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[3] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[3] >> 56)]) << 56) - k[0]; + y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[2] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[2] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[3] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[3] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1]; + y[2] = (word64(IS[0][(byte)x[2]]) ^ word64(IS[1][(byte)(x[2] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[3] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[3] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[2]; + y[3] = (word64(IS[0][(byte)x[3]]) ^ word64(IS[1][(byte)(x[3] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[2] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[2] >> 56)]) << 56) - k[3]; +} + +inline void IGL512(const word64 x[8], word64 y[8], const word64 k[8]) +{ + y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[2] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[3] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[4] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[5] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[6] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[7] >> 56)]) << 56) - k[0]; + y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[2] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[3] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[4] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[5] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[6] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[7] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1]; + y[2] = (word64(IS[0][(byte)x[2]]) ^ word64(IS[1][(byte)(x[3] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[4] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[5] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[6] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[7] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[2]; + y[3] = (word64(IS[0][(byte)x[3]]) ^ word64(IS[1][(byte)(x[4] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[5] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[6] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[7] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[2] >> 56)]) << 56) - k[3]; + y[4] = (word64(IS[0][(byte)x[4]]) ^ word64(IS[1][(byte)(x[5] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[6] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[7] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[2] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[3] >> 56)]) << 56) - k[4]; + y[5] = (word64(IS[0][(byte)x[5]]) ^ word64(IS[1][(byte)(x[6] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[7] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[2] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[3] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[4] >> 56)]) << 56) - k[5]; + y[6] = (word64(IS[0][(byte)x[6]]) ^ word64(IS[1][(byte)(x[7] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[2] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[3] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[4] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[5] >> 56)]) << 56) - k[6]; + y[7] = (word64(IS[0][(byte)x[7]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[2] >> 24)]) << 24 ^ + word64(IS[0][(byte)(x[3] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[4] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[5] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[6] >> 56)]) << 56) - k[7]; +} + +inline void G128(const word64 x[2], word64 y[2], const word64 k[2]) +{ + y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; + y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; +} + +inline void G256(const word64 x[4], word64 y[4], const word64 k[4]) +{ + y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ + T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; + y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; + y[2] = k[2] ^ T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; + y[3] = k[3] ^ T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; +} + +inline void G512(const word64 x[8], word64 y[8], const word64 k[8]) +{ + y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^ + T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]; + y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^ + T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]; + y[2] = k[2] ^ T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^ + T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]; + y[3] = k[3] ^ T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^ + T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]; + y[4] = k[4] ^ T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^ + T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]; + y[5] = k[5] ^ T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^ + T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]; + y[6] = k[6] ^ T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^ + T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]; + y[7] = k[7] ^ T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^ + T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +// *********************** UncheckedSetKey specializations *********************** // + +void Kalyna128::Base::SetKey_22(const word64 key[2]) +{ + word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4; + word64 *t2 = m_wspace+6, *k = m_wspace+8, *kswapped = m_wspace+10; + + memset(t1, 0, 2*8); + t1[0] = (128 + 128 + 64) / 64; + + AddKey<2>(t1, t2, key); + G128(t2, t1, key); + GL128(t1, t2, key); + G0128(t2, ks); + + word64 constant = W64LIT(0x0001000100010001); + + // round 0 + memcpy(k, key, 16); + kswapped[1] = k[0]; + kswapped[0] = k[1]; + + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[0], ksc); + MakeOddKey<2>(&m_rkeys[0], &m_rkeys[2]); + + // round 2 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(kswapped, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[4], ksc); + MakeOddKey<2>(&m_rkeys[4], &m_rkeys[6]); + + // round 4 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[8], ksc); + MakeOddKey<2>(&m_rkeys[8], &m_rkeys[10]); + + // round 6 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(kswapped, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[12], ksc); + MakeOddKey<2>(&m_rkeys[12], &m_rkeys[14]); + + // round 8 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[16], ksc); + MakeOddKey<2>(&m_rkeys[16], &m_rkeys[18]); + + // round 10 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(kswapped, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[20], ksc); + + if (!IsForwardTransformation()) + { + IMC128(&m_rkeys[18]); IMC128(&m_rkeys[16]); + IMC128(&m_rkeys[14]); IMC128(&m_rkeys[12]); + IMC128(&m_rkeys[10]); IMC128(&m_rkeys[ 8]); + IMC128(&m_rkeys[ 6]); IMC128(&m_rkeys[ 4]); + IMC128(&m_rkeys[ 2]); + } +} + +void Kalyna128::Base::SetKey_24(const word64 key[4]) +{ + word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4, *t2 = m_wspace+6; + word64 *k = m_wspace+8, *ka = m_wspace+12, *ko = m_wspace+14; + + memset(t1, 0, 2*8); + t1[0] = (128 + 256 + 64) / 64; + memcpy(ka, key, 16); + memcpy(ko, key + 2, 16); + + AddKey<2>(t1, t2, ka); + G128(t2, t1, ko); + GL128(t1, t2, ka); + G0128(t2, ks); + + word64 constant = W64LIT(0x0001000100010001); + + // round 0 + memcpy(k, key, 256 / 8); + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[0], ksc); + MakeOddKey<2>(&m_rkeys[0], &m_rkeys[2]); + + // round 2 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k + 2, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[4], ksc); + MakeOddKey<2>(&m_rkeys[4], &m_rkeys[6]); + + // round 4 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[8], ksc); + MakeOddKey<2>(&m_rkeys[8], &m_rkeys[10]); + + // round 6 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k + 2, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[12], ksc); + MakeOddKey<2>(&m_rkeys[12], &m_rkeys[14]); + + // round 8 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[16], ksc); + MakeOddKey<2>(&m_rkeys[16], &m_rkeys[18]); + + // round 10 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k + 2, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[20], ksc); + MakeOddKey<2>(&m_rkeys[20], &m_rkeys[22]); + + // round 12 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[24], ksc); + MakeOddKey<2>(&m_rkeys[24], &m_rkeys[26]); + + // round 14 + constant <<= 1; + AddConstant<2>(ks, ksc, constant); + AddKey<2>(k + 2, t2, ksc); + G128(t2, t1, ksc); + GL128(t1, &m_rkeys[28], ksc); + + if (!IsForwardTransformation()) + { + IMC128(&m_rkeys[26]); + IMC128(&m_rkeys[24]); + IMC128(&m_rkeys[22]); + IMC128(&m_rkeys[20]); + IMC128(&m_rkeys[18]); + IMC128(&m_rkeys[16]); + IMC128(&m_rkeys[14]); + IMC128(&m_rkeys[12]); + IMC128(&m_rkeys[10]); + IMC128(&m_rkeys[8]); + IMC128(&m_rkeys[6]); + IMC128(&m_rkeys[4]); + IMC128(&m_rkeys[2]); + } +} + +void Kalyna256::Base::SetKey_44(const word64 key[4]) +{ + word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8; + word64 *t2 = m_wspace+12, *k = m_wspace+16; + + memset(t1, 0, 32); + t1[0] = (256 + 256 + 64) / 64; + + AddKey<4>(t1, t2, key); + G256(t2, t1, key); + GL256(t1, t2, key); + G0256(t2, ks); + + word64 constant = W64LIT(0x0001000100010001); + + // round 0 + memcpy(k, key, 32); + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[0], ksc); + MakeOddKey<4>(&m_rkeys[0], &m_rkeys[4]); + + // round 2 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[8], ksc); + MakeOddKey<4>(&m_rkeys[8], &m_rkeys[12]); + + // round 4 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[16], ksc); + MakeOddKey<4>(&m_rkeys[16], &m_rkeys[20]); + + // round 6 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[24], ksc); + MakeOddKey<4>(&m_rkeys[24], &m_rkeys[28]); + + // round 8 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[32], ksc); + MakeOddKey<4>(&m_rkeys[32], &m_rkeys[36]); + + // round 10 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[40], ksc); + MakeOddKey<4>(&m_rkeys[40], &m_rkeys[44]); + + // round 12 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[48], ksc); + MakeOddKey<4>(&m_rkeys[48], &m_rkeys[52]); + + // round 14 + SwapBlocks<4>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[56], ksc); + + if (!IsForwardTransformation()) + { + IMC256(&m_rkeys[52]); + IMC256(&m_rkeys[48]); + IMC256(&m_rkeys[44]); + IMC256(&m_rkeys[40]); + IMC256(&m_rkeys[36]); + IMC256(&m_rkeys[32]); + IMC256(&m_rkeys[28]); + IMC256(&m_rkeys[24]); + IMC256(&m_rkeys[20]); + IMC256(&m_rkeys[16]); + IMC256(&m_rkeys[12]); + IMC256(&m_rkeys[8]); + IMC256(&m_rkeys[4]); + } +} + +void Kalyna256::Base::SetKey_48(const word64 key[8]) +{ + word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8, *t2 = m_wspace+12; + word64 *k = m_wspace+16, *ka = m_wspace+24, *ko = m_wspace+28; + + memset(t1, 0, 4*8); + t1[0] = (512 + 256 + 64) / 64; + memcpy(ka, key, 32); + memcpy(ko, key+4, 32); + + AddKey<4>(t1, t2, ka); + G256(t2, t1, ko); + GL256(t1, t2, ka); + G0256(t2, ks); + + word64 constant = W64LIT(0x0001000100010001); + + // round 0 + memcpy(k, key, 512 / 8); + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[0], ksc); + MakeOddKey<4>(&m_rkeys[0], &m_rkeys[4]); + + // round 2 + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k+4, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[8], ksc); + MakeOddKey<4>(&m_rkeys[8], &m_rkeys[12]); + + // round 4 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[16], ksc); + MakeOddKey<4>(&m_rkeys[16], &m_rkeys[20]); + + // round 6 + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k+4, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[24], ksc); + MakeOddKey<4>(&m_rkeys[24], &m_rkeys[28]); + + // round 8 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[32], ksc); + MakeOddKey<4>(&m_rkeys[32], &m_rkeys[36]); + + // round 10 + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k+4, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[40], ksc); + MakeOddKey<4>(&m_rkeys[40], &m_rkeys[44]); + + // round 12 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[48], ksc); + MakeOddKey<4>(&m_rkeys[48], &m_rkeys[52]); + + // round 14 + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k+4, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[56], ksc); + MakeOddKey<4>(&m_rkeys[56], &m_rkeys[60]); + + // round 16 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[64], ksc); + MakeOddKey<4>(&m_rkeys[64], &m_rkeys[68]); + + // round 18 + constant <<= 1; + AddConstant<4>(ks, ksc, constant); + AddKey<4>(k+4, t2, ksc); + G256(t2, t1, ksc); + GL256(t1, &m_rkeys[72], ksc); + + if (!IsForwardTransformation()) + { + IMC256(&m_rkeys[68]); + IMC256(&m_rkeys[64]); + IMC256(&m_rkeys[60]); + IMC256(&m_rkeys[56]); + IMC256(&m_rkeys[52]); + IMC256(&m_rkeys[48]); + IMC256(&m_rkeys[44]); + IMC256(&m_rkeys[40]); + IMC256(&m_rkeys[36]); + IMC256(&m_rkeys[32]); + IMC256(&m_rkeys[28]); + IMC256(&m_rkeys[24]); + IMC256(&m_rkeys[20]); + IMC256(&m_rkeys[16]); + IMC256(&m_rkeys[12]); + IMC256(&m_rkeys[8]); + IMC256(&m_rkeys[4]); + } +} + +void Kalyna512::Base::SetKey_88(const word64 key[8]) +{ + word64 *ks = m_wspace+0, *ksc = m_wspace+8, *t1 = m_wspace+16; + word64 *t2 = m_wspace+24, *k = m_wspace+32; + + memset(t1, 0, 8*8); + t1[0] = (512 + 512 + 64) / 64; + + AddKey<8>(t1, t2, key); + G512(t2, t1, key); + GL512(t1, t2, key); + G0512(t2, ks); + + word64 constant = W64LIT(0x0001000100010001); + + // round 0 + memcpy(k, key, 512 / 8); + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[0], ksc); + MakeOddKey<8>(&m_rkeys[0], &m_rkeys[8]); + + // round 2 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[16], ksc); + MakeOddKey<8>(&m_rkeys[16], &m_rkeys[24]); + + // round 4 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[32], ksc); + MakeOddKey<8>(&m_rkeys[32], &m_rkeys[40]); + + // round 6 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[48], ksc); + MakeOddKey<8>(&m_rkeys[48], &m_rkeys[56]); + + // round 8 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[64], ksc); + MakeOddKey<8>(&m_rkeys[64], &m_rkeys[72]); + + // round 10 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[80], ksc); + MakeOddKey<8>(&m_rkeys[80], &m_rkeys[88]); + + // round 12 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[96], ksc); + MakeOddKey<8>(&m_rkeys[96], &m_rkeys[104]); + + // round 14 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[112], ksc); + MakeOddKey<8>(&m_rkeys[112], &m_rkeys[120]); + + // round 16 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[128], ksc); + MakeOddKey<8>(&m_rkeys[128], &m_rkeys[136]); + + // round 18 + SwapBlocks<8>(k); + constant <<= 1; + AddConstant<8>(ks, ksc, constant); + AddKey<8>(k, t2, ksc); + G512(t2, t1, ksc); + GL512(t1, &m_rkeys[144], ksc); + + if (!IsForwardTransformation()) + { + IMC512(&m_rkeys[136]); IMC512(&m_rkeys[128]); IMC512(&m_rkeys[120]); IMC512(&m_rkeys[112]); + IMC512(&m_rkeys[104]); IMC512(&m_rkeys[ 96]); IMC512(&m_rkeys[ 88]); IMC512(&m_rkeys[ 80]); + IMC512(&m_rkeys[ 72]); IMC512(&m_rkeys[ 64]); IMC512(&m_rkeys[ 56]); IMC512(&m_rkeys[ 48]); + IMC512(&m_rkeys[ 40]); IMC512(&m_rkeys[ 32]); IMC512(&m_rkeys[ 24]); IMC512(&m_rkeys[ 16]); + IMC512(&m_rkeys[ 8]); + } +} + +// *********************** ProcessAndXorBlock specializations *********************** // + +void Kalyna128::Base::ProcessBlock_22(const byte* inBlock, const byte* xorBlock, byte* outBlock) const +{ + word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4; + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(msg[0])(msg[1]); + + if (IsForwardTransformation()) + { + AddKey<2>(msg, t1, m_rkeys); + G128(t1, t2, &m_rkeys[2]); // 1 + G128(t2, t1, &m_rkeys[4]); // 2 + G128(t1, t2, &m_rkeys[6]); // 3 + G128(t2, t1, &m_rkeys[8]); // 4 + G128(t1, t2, &m_rkeys[10]); // 5 + G128(t2, t1, &m_rkeys[12]); // 6 + G128(t1, t2, &m_rkeys[14]); // 7 + G128(t2, t1, &m_rkeys[16]); // 8 + G128(t1, t2, &m_rkeys[18]); // 9 + GL128(t2, t1, &m_rkeys[20]); // 10 + } + else + { + SubKey<2>(msg, t1, &m_rkeys[20]); + IMC128(t1); + IG128(t1, t2, &m_rkeys[18]); + IG128(t2, t1, &m_rkeys[16]); + IG128(t1, t2, &m_rkeys[14]); + IG128(t2, t1, &m_rkeys[12]); + IG128(t1, t2, &m_rkeys[10]); + IG128(t2, t1, &m_rkeys[8]); + IG128(t1, t2, &m_rkeys[6]); + IG128(t2, t1, &m_rkeys[4]); + IG128(t1, t2, &m_rkeys[2]); + IGL128(t2, t1, &m_rkeys[0]); + } + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(t1[0])(t1[1]); +} + +void Kalyna128::Base::ProcessBlock_24(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4; + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(msg[0])(msg[1]); + + if (IsForwardTransformation()) + { + AddKey<2>(msg, t1, m_rkeys); + G128(t1, t2, &m_rkeys[ 2]); // 1 + G128(t2, t1, &m_rkeys[ 4]); // 2 + G128(t1, t2, &m_rkeys[ 6]); // 3 + G128(t2, t1, &m_rkeys[ 8]); // 4 + G128(t1, t2, &m_rkeys[10]); // 5 + G128(t2, t1, &m_rkeys[12]); // 6 + G128(t1, t2, &m_rkeys[14]); // 7 + G128(t2, t1, &m_rkeys[16]); // 8 + G128(t1, t2, &m_rkeys[18]); // 9 + G128(t2, t1, &m_rkeys[20]); // 10 + G128(t1, t2, &m_rkeys[22]); // 11 + G128(t2, t1, &m_rkeys[24]); // 12 + G128(t1, t2, &m_rkeys[26]); // 13 + GL128(t2, t1, &m_rkeys[28]); // 14 + } + else + { + SubKey<2>(msg, t1, &m_rkeys[28]); + IMC128(t1); + IG128(t1, t2, &m_rkeys[26]); + IG128(t2, t1, &m_rkeys[24]); + IG128(t1, t2, &m_rkeys[22]); + IG128(t2, t1, &m_rkeys[20]); + IG128(t1, t2, &m_rkeys[18]); + IG128(t2, t1, &m_rkeys[16]); + IG128(t1, t2, &m_rkeys[14]); + IG128(t2, t1, &m_rkeys[12]); + IG128(t1, t2, &m_rkeys[10]); + IG128(t2, t1, &m_rkeys[8]); + IG128(t1, t2, &m_rkeys[6]); + IG128(t2, t1, &m_rkeys[4]); + IG128(t1, t2, &m_rkeys[2]); + IGL128(t2, t1, &m_rkeys[0]); + } + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(t1[0])(t1[1]); +} + +void Kalyna256::Base::ProcessBlock_44(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8; + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(msg[0])(msg[1])(msg[2])(msg[3]); + + if (IsForwardTransformation()) + { + AddKey<4>(msg, t1, m_rkeys); + G256(t1, t2, &m_rkeys[4]); // 1 + G256(t2, t1, &m_rkeys[8]); // 2 + G256(t1, t2, &m_rkeys[12]); // 3 + G256(t2, t1, &m_rkeys[16]); // 4 + G256(t1, t2, &m_rkeys[20]); // 5 + G256(t2, t1, &m_rkeys[24]); // 6 + G256(t1, t2, &m_rkeys[28]); // 7 + G256(t2, t1, &m_rkeys[32]); // 8 + G256(t1, t2, &m_rkeys[36]); // 9 + G256(t2, t1, &m_rkeys[40]); // 10 + G256(t1, t2, &m_rkeys[44]); // 11 + G256(t2, t1, &m_rkeys[48]); // 12 + G256(t1, t2, &m_rkeys[52]); // 13 + GL256(t2, t1, &m_rkeys[56]); // 14 + } + else + { + SubKey<4>(msg, t1, &m_rkeys[56]); + IMC256(t1); + IG256(t1, t2, &m_rkeys[52]); + IG256(t2, t1, &m_rkeys[48]); + IG256(t1, t2, &m_rkeys[44]); + IG256(t2, t1, &m_rkeys[40]); + IG256(t1, t2, &m_rkeys[36]); + IG256(t2, t1, &m_rkeys[32]); + IG256(t1, t2, &m_rkeys[28]); + IG256(t2, t1, &m_rkeys[24]); + IG256(t1, t2, &m_rkeys[20]); + IG256(t2, t1, &m_rkeys[16]); + IG256(t1, t2, &m_rkeys[12]); + IG256(t2, t1, &m_rkeys[8]); + IG256(t1, t2, &m_rkeys[4]); + IGL256(t2, t1, &m_rkeys[0]); + } + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(t1[0])(t1[1])(t1[2])(t1[3]); +} + +void Kalyna256::Base::ProcessBlock_48(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8; + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(msg[0])(msg[1])(msg[2])(msg[3]); + + if (IsForwardTransformation()) + { + AddKey<4>(msg, t1, m_rkeys); + G256(t1, t2, &m_rkeys[4]); // 1 + G256(t2, t1, &m_rkeys[8]); // 2 + G256(t1, t2, &m_rkeys[12]); // 3 + G256(t2, t1, &m_rkeys[16]); // 4 + G256(t1, t2, &m_rkeys[20]); // 5 + G256(t2, t1, &m_rkeys[24]); // 6 + G256(t1, t2, &m_rkeys[28]); // 7 + G256(t2, t1, &m_rkeys[32]); // 8 + G256(t1, t2, &m_rkeys[36]); // 9 + G256(t2, t1, &m_rkeys[40]); // 10 + G256(t1, t2, &m_rkeys[44]); // 11 + G256(t2, t1, &m_rkeys[48]); // 12 + G256(t1, t2, &m_rkeys[52]); // 13 + G256(t2, t1, &m_rkeys[56]); // 14 + G256(t1, t2, &m_rkeys[60]); // 15 + G256(t2, t1, &m_rkeys[64]); // 16 + G256(t1, t2, &m_rkeys[68]); // 17 + GL256(t2, t1, &m_rkeys[72]); // 18 + } + else + { + SubKey<4>(msg, t1, &m_rkeys[72]); + IMC256(t1); + IG256(t1, t2, &m_rkeys[68]); + IG256(t2, t1, &m_rkeys[64]); + IG256(t1, t2, &m_rkeys[60]); + IG256(t2, t1, &m_rkeys[56]); + IG256(t1, t2, &m_rkeys[52]); + IG256(t2, t1, &m_rkeys[48]); + IG256(t1, t2, &m_rkeys[44]); + IG256(t2, t1, &m_rkeys[40]); + IG256(t1, t2, &m_rkeys[36]); + IG256(t2, t1, &m_rkeys[32]); + IG256(t1, t2, &m_rkeys[28]); + IG256(t2, t1, &m_rkeys[24]); + IG256(t1, t2, &m_rkeys[20]); + IG256(t2, t1, &m_rkeys[16]); + IG256(t1, t2, &m_rkeys[12]); + IG256(t2, t1, &m_rkeys[8]); + IG256(t1, t2, &m_rkeys[4]); + IGL256(t2, t1, &m_rkeys[0]); + } + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(t1[0])(t1[1])(t1[2])(t1[3]); +} + +void Kalyna512::Base::ProcessBlock_88(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 *t1 = m_wspace+0, *t2 = m_wspace+8, *msg = m_wspace+16; + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(msg[0])(msg[1])(msg[2])(msg[3])(msg[4])(msg[5])(msg[6])(msg[7]); + + if (IsForwardTransformation()) + { + AddKey<8>(msg, t1, m_rkeys); + G512(t1, t2, &m_rkeys[8]); // 1 + G512(t2, t1, &m_rkeys[16]); // 2 + G512(t1, t2, &m_rkeys[24]); // 3 + G512(t2, t1, &m_rkeys[32]); // 4 + G512(t1, t2, &m_rkeys[40]); // 5 + G512(t2, t1, &m_rkeys[48]); // 6 + G512(t1, t2, &m_rkeys[56]); // 7 + G512(t2, t1, &m_rkeys[64]); // 8 + G512(t1, t2, &m_rkeys[72]); // 9 + G512(t2, t1, &m_rkeys[80]); // 10 + G512(t1, t2, &m_rkeys[88]); // 11 + G512(t2, t1, &m_rkeys[96]); // 12 + G512(t1, t2, &m_rkeys[104]); // 13 + G512(t2, t1, &m_rkeys[112]); // 14 + G512(t1, t2, &m_rkeys[120]); // 15 + G512(t2, t1, &m_rkeys[128]); // 16 + G512(t1, t2, &m_rkeys[136]); // 17 + GL512(t2, t1, &m_rkeys[144]); // 18 + } + else + { + SubKey<8>(msg, t1, &m_rkeys[144]); + IMC512(t1); + IG512(t1, t2, &m_rkeys[136]); + IG512(t2, t1, &m_rkeys[128]); + IG512(t1, t2, &m_rkeys[120]); + IG512(t2, t1, &m_rkeys[112]); + IG512(t1, t2, &m_rkeys[104]); + IG512(t2, t1, &m_rkeys[96]); + IG512(t1, t2, &m_rkeys[88]); + IG512(t2, t1, &m_rkeys[80]); + IG512(t1, t2, &m_rkeys[72]); + IG512(t2, t1, &m_rkeys[64]); + IG512(t1, t2, &m_rkeys[56]); + IG512(t2, t1, &m_rkeys[48]); + IG512(t1, t2, &m_rkeys[40]); + IG512(t2, t1, &m_rkeys[32]); + IG512(t1, t2, &m_rkeys[24]); + IG512(t2, t1, &m_rkeys[16]); + IG512(t1, t2, &m_rkeys[8]); + IGL512(t2, t1, &m_rkeys[0]); + } + + // Reverse bytes on BigEndian; Align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(t1[0])(t1[1])(t1[2])(t1[3])(t1[4])(t1[5])(t1[6])(t1[7]); +} + +// *********************** Library routines *********************** // + +void Kalyna128::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + m_nb = static_cast(16U / sizeof(word64)); + m_nk = static_cast(keylen / sizeof(word64)); + + switch (keylen) + { + case 16: // 128 + m_kl = 16; + m_mkey.New(2); + m_rkeys.New(11*2); + m_wspace.New(2*6); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16); + SetKey_22(m_mkey.begin()); + break; + case 32: // 256 + m_kl = 32; + m_mkey.New(4); + m_rkeys.New(15*2); + m_wspace.New(6*2+4); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32); + SetKey_24(m_mkey.begin()); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void Kalyna128::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Timing attack countermeasure. see comments in Rijndael for more details + const int cacheLineSize = GetCacheLineSize(); + volatile word64 _u = 0; + word64 u = _u; + + const byte* p = reinterpret_cast(KalynaTab::S); + for (unsigned int i=0; i<256; i+=cacheLineSize) + u ^= *reinterpret_cast(p+i); + m_wspace[0] = u; + + switch ((m_nb << 8) | m_nk) + { + case (2 << 8) | 2: + ProcessBlock_22(inBlock, xorBlock, outBlock); + break; + case (2 << 8) | 4: + ProcessBlock_24(inBlock, xorBlock, outBlock); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void Kalyna256::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + m_nb = static_cast(32U / sizeof(word64)); + m_nk = static_cast(keylen / sizeof(word64)); + + switch (keylen) + { + case 32: // 256 + m_kl = 32; + m_mkey.New(4); + m_rkeys.New(15*4); + m_wspace.New(5*4); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32); + SetKey_44(m_mkey.begin()); + break; + case 64: // 512 + m_kl = 64; + m_mkey.New(8); + m_rkeys.New(19*4); + m_wspace.New(6*4+8); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64); + SetKey_48(m_mkey.begin()); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void Kalyna256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Timing attack countermeasure. see comments in Rijndael for more details + const int cacheLineSize = GetCacheLineSize(); + volatile word64 _u = 0; + word64 u = _u; + + const byte* p = reinterpret_cast(KalynaTab::S); + for (unsigned int i=0; i<256; i+=cacheLineSize) + u ^= *reinterpret_cast(p+i); + m_wspace[0] = u; + + switch ((m_nb << 8) | m_nk) + { + case (4 << 8) | 4: + ProcessBlock_44(inBlock, xorBlock, outBlock); + break; + case (4 << 8) | 8: + ProcessBlock_48(inBlock, xorBlock, outBlock); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void Kalyna512::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + m_nb = static_cast(64U / sizeof(word64)); + m_nk = static_cast(keylen / sizeof(word64)); + + switch (keylen) + { + case 64: // 512 + m_kl = 64; + m_nb = static_cast(64U / sizeof(word64)); + m_nk = static_cast(keylen / sizeof(word64)); + + m_mkey.New(8); + m_rkeys.New(19*8); + m_wspace.New(5*8); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64); + SetKey_88(m_mkey.begin()); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void Kalyna512::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Timing attack countermeasure. see comments in Rijndael for more details + const int cacheLineSize = GetCacheLineSize(); + volatile word64 _u = 0; + word64 u = _u; + + const byte* p = reinterpret_cast(KalynaTab::S); + for (unsigned int i=0; i<256; i+=cacheLineSize) + u ^= *reinterpret_cast(p+i); + m_wspace[0] = u; + + ProcessBlock_88(inBlock, xorBlock, outBlock); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/kalyna.h b/external/ours/library/crypto/src/shared/original/kalyna.h new file mode 100755 index 000000000..277fccb52 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/kalyna.h @@ -0,0 +1,218 @@ +// kalyna.h - written and placed in the public domain by Jeffrey Walton +// Based on public domain code by Keru Kuro. + +/// \file kalyna.h +/// \brief Classes for the Kalyna block cipher +/// \details The Crypto++ implementation relied upon three sources. First was Oliynykov, Gorbenko, Kazymyrov, +/// Ruzhentsev, Kuznetsov, Gorbenko, Dyrda, Dolgov, Pushkaryov, Mordvinov and Kaidalov's "A New Encryption +/// Standard of Ukraine: The Kalyna Block Cipher" (http://eprint.iacr.org/2015/650.pdf). Second was Roman +/// Oliynykov and Oleksandr Kazymyrov's GitHub with the reference implementation +/// (http://github.com/Roman-Oliynykov/Kalyna-reference). The third resource was Keru Kuro's implementation +/// of Kalyna in CppCrypto (http://sourceforge.net/projects/cppcrypto/). Kuro has an outstanding +/// implementation that performed better than the reference implementation and our initial attempts. + +#ifndef CRYPTOPP_KALYNA_H +#define CRYPTOPP_KALYNA_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Kalyna-128 block cipher information +/// \since Crypto++ 6.0 +struct CRYPTOPP_NO_VTABLE Kalyna128_Info : public FixedBlockSize<16>, VariableKeyLength<16, 16, 32> +{ + static const char* StaticAlgorithmName() + { + // Format is Cipher-Blocksize(Keylength) + return "Kalyna-128"; + } +}; + +/// \brief Kalyna-256 block cipher information +/// \since Crypto++ 6.0 +struct CRYPTOPP_NO_VTABLE Kalyna256_Info : public FixedBlockSize<32>, VariableKeyLength<32, 32, 64> +{ + static const char* StaticAlgorithmName() + { + // Format is Cipher-Blocksize(Keylength) + return "Kalyna-256"; + } +}; + +/// \brief Kalyna-512 block cipher information +/// \since Crypto++ 6.0 +struct CRYPTOPP_NO_VTABLE Kalyna512_Info : public FixedBlockSize<64>, FixedKeyLength<64> +{ + static const char* StaticAlgorithmName() + { + // Format is Cipher-Blocksize(Keylength) + return "Kalyna-512"; + } +}; + +/// \brief Kalyna block cipher base class +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Kalyna_Base +{ +public: + virtual ~Kalyna_Base() {} + +protected: + typedef SecBlock > AlignedSecBlock64; + mutable AlignedSecBlock64 m_wspace; // work space + AlignedSecBlock64 m_mkey; // master key + AlignedSecBlock64 m_rkeys; // round keys + unsigned int m_kl, m_nb, m_nk; // number 64-bit blocks and keys +}; + +/// \brief Kalyna 128-bit block cipher +/// \details Kalyna128 provides 128-bit block size. The valid key sizes are 128-bit and 256-bit. +/// \since Crypto++ 6.0 +class Kalyna128 : public Kalyna128_Info, public BlockCipherDocumentation +{ +public: + class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl + { + public: + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details If the object is unkeyed, then the generic name "Kalyna" is returned + /// to the caller. If the algorithm is keyed, then a two or three part name is + /// returned to the caller. The name follows DSTU 7624:2014, where block size is + /// provided first and then key length. The library uses a dash to identify block size + /// and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna + /// with a 128-bit block size and a 256-bit key length. If a mode is associated + /// with the object, then it follows as expected. For example, Kalyna-128(256)/ECB. + /// DSTU is a little more complex with more parameters, dashes, underscores, but the + /// library does not use the delimiters or full convention. + std::string AlgorithmName() const { + return std::string("Kalyna-128") + "(" + IntToString(m_kl*8) + ")"; + } + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const { + return GetAlignmentOf(); + } + + protected: + void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + void SetKey_22(const word64 key[2]); + void SetKey_24(const word64 key[4]); + void ProcessBlock_22(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + void ProcessBlock_24(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief Kalyna 256-bit block cipher +/// \details Kalyna256 provides 256-bit block size. The valid key sizes are 256-bit and 512-bit. +/// \since Crypto++ 6.0 +class Kalyna256 : public Kalyna256_Info, public BlockCipherDocumentation +{ +public: + class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl + { + public: + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details If the object is unkeyed, then the generic name "Kalyna" is returned + /// to the caller. If the algorithm is keyed, then a two or three part name is + /// returned to the caller. The name follows DSTU 7624:2014, where block size is + /// provided first and then key length. The library uses a dash to identify block size + /// and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna + /// with a 128-bit block size and a 256-bit key length. If a mode is associated + /// with the object, then it follows as expected. For example, Kalyna-128(256)/ECB. + /// DSTU is a little more complex with more parameters, dashes, underscores, but the + /// library does not use the delimiters or full convention. + std::string AlgorithmName() const { + return std::string("Kalyna-256") + "(" + IntToString(m_kl*8) + ")"; + } + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const { + return GetAlignmentOf(); + } + + protected: + void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + void SetKey_44(const word64 key[4]); + void SetKey_48(const word64 key[8]); + void ProcessBlock_44(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + void ProcessBlock_48(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief Kalyna 512-bit block cipher +/// \details Kalyna512 provides 512-bit block size. The valid key size is 512-bit. +/// \since Crypto++ 6.0 +class Kalyna512 : public Kalyna512_Info, public BlockCipherDocumentation +{ +public: + class CRYPTOPP_NO_VTABLE Base : public Kalyna_Base, public BlockCipherImpl + { + public: + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details If the object is unkeyed, then the generic name "Kalyna" is returned + /// to the caller. If the algorithm is keyed, then a two or three part name is + /// returned to the caller. The name follows DSTU 7624:2014, where block size is + /// provided first and then key length. The library uses a dash to identify block size + /// and parenthesis to identify key length. For example, Kalyna-128(256) is Kalyna + /// with a 128-bit block size and a 256-bit key length. If a mode is associated + /// with the object, then it follows as expected. For example, Kalyna-128(256)/ECB. + /// DSTU is a little more complex with more parameters, dashes, underscores, but the + /// library does not use the delimiters or full convention. + std::string AlgorithmName() const { + return std::string("Kalyna-512") + "(" + IntToString(m_kl*8) + ")"; + } + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const { + return GetAlignmentOf(); + } + + protected: + void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + void SetKey_88(const word64 key[8]); + void ProcessBlock_88(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Kalyna128::Encryption Kalyna128Encryption; +typedef Kalyna128::Decryption Kalyna128Decryption; + +typedef Kalyna256::Encryption Kalyna256Encryption; +typedef Kalyna256::Decryption Kalyna256Decryption; + +typedef Kalyna512::Encryption Kalyna512Encryption; +typedef Kalyna512::Decryption Kalyna512Decryption; + +NAMESPACE_END + +#endif // CRYPTOPP_KALYNA_H diff --git a/external/ours/library/crypto/src/shared/original/kalynatab.cpp b/external/ours/library/crypto/src/shared/original/kalynatab.cpp new file mode 100755 index 000000000..d4ad171cd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/kalynatab.cpp @@ -0,0 +1,1232 @@ +// kalynatab.cpp - written and placed in the public domain by Jeffrey Walton + +#include "pch.h" +#include "config.h" +#include "kalyna.h" + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(KalynaTab) + +extern const word64 T[8][256]; // Columns +extern const word64 IT[8][256]; // Inverse +extern const byte S[4][256]; // Substitution +extern const byte IS[4][256]; // Inverse + +const word64 T[8][256] = +{ + { + W64LIT(0xa832a829d77f9aa8), W64LIT(0x4352432297d41143), W64LIT(0x5f3e5fc2df80615f), W64LIT(0x061e063014121806), + W64LIT(0x6bda6b7f670cb16b), W64LIT(0x75bc758f2356c975), W64LIT(0x6cc16c477519ad6c), W64LIT(0x592059f2cb927959), + W64LIT(0x71a871af3b4ad971), W64LIT(0xdf84dfb6f8275bdf), W64LIT(0x87a1874c35b22687), W64LIT(0x95fb95dc59cc6e95), + W64LIT(0x174b17b872655c17), W64LIT(0xf017f0d31aeae7f0), W64LIT(0xd89fd88eea3247d8), W64LIT(0x092d0948363f2409), + W64LIT(0x6dc46d4f731ea96d), W64LIT(0xf318f3cb10e3ebf3), W64LIT(0x1d691de84e53741d), W64LIT(0xcbc0cb16804b0bcb), + W64LIT(0xc9cac9068c4503c9), W64LIT(0x4d644d52b3fe294d), W64LIT(0x2c9c2c7de8c4b02c), W64LIT(0xaf29af11c56a86af), + W64LIT(0x798079ef0b72f979), W64LIT(0xe047e0537a9aa7e0), W64LIT(0x97f197cc55c26697), W64LIT(0xfd2efdbb34c9d3fd), + W64LIT(0x6fce6f5f7f10a16f), W64LIT(0x4b7a4b62a7ec314b), W64LIT(0x454c451283c60945), W64LIT(0x39dd39d596afe439), + W64LIT(0x3ec63eed84baf83e), W64LIT(0xdd8edda6f42953dd), W64LIT(0xa315a371ed4eb6a3), W64LIT(0x4f6e4f42bff0214f), + W64LIT(0xb45eb4c99f2beab4), W64LIT(0xb654b6d99325e2b6), W64LIT(0x9ac89aa47be1529a), W64LIT(0x0e360e70242a380e), + W64LIT(0x1f631ff8425d7c1f), W64LIT(0xbf79bf91a51ac6bf), W64LIT(0x154115a87e6b5415), W64LIT(0xe142e15b7c9da3e1), + W64LIT(0x49704972abe23949), W64LIT(0xd2bdd2ded6046fd2), W64LIT(0x93e593ec4dde7693), W64LIT(0xc6f9c67eae683fc6), + W64LIT(0x92e092e44bd97292), W64LIT(0x72a772b73143d572), W64LIT(0x9edc9e8463fd429e), W64LIT(0x61f8612f5b3a9961), + W64LIT(0xd1b2d1c6dc0d63d1), W64LIT(0x63f2633f57349163), W64LIT(0xfa35fa8326dccffa), W64LIT(0xee71ee235eb09fee), + W64LIT(0xf403f4f302f6f7f4), W64LIT(0x197d19c8564f6419), W64LIT(0xd5a6d5e6c41173d5), W64LIT(0xad23ad01c9648ead), + W64LIT(0x582558facd957d58), W64LIT(0xa40ea449ff5baaa4), W64LIT(0xbb6dbbb1bd06d6bb), W64LIT(0xa11fa161e140bea1), + W64LIT(0xdc8bdcaef22e57dc), W64LIT(0xf21df2c316e4eff2), W64LIT(0x83b5836c2dae3683), W64LIT(0x37eb37a5b285dc37), + W64LIT(0x4257422a91d31542), W64LIT(0xe453e4736286b7e4), W64LIT(0x7a8f7af7017bf57a), W64LIT(0x32fa328dac9ec832), + W64LIT(0x9cd69c946ff34a9c), W64LIT(0xccdbcc2e925e17cc), W64LIT(0xab3dab31dd7696ab), W64LIT(0x4a7f4a6aa1eb354a), + W64LIT(0x8f898f0c058a068f), W64LIT(0x6ecb6e577917a56e), W64LIT(0x04140420181c1004), W64LIT(0x27bb2725d2f59c27), + W64LIT(0x2e962e6de4cab82e), W64LIT(0xe75ce76b688fbbe7), W64LIT(0xe24de2437694afe2), W64LIT(0x5a2f5aeac19b755a), + W64LIT(0x96f496c453c56296), W64LIT(0x164e16b074625816), W64LIT(0x23af2305cae98c23), W64LIT(0x2b872b45fad1ac2b), + W64LIT(0xc2edc25eb6742fc2), W64LIT(0x65ec650f43268965), W64LIT(0x66e36617492f8566), W64LIT(0x0f330f78222d3c0f), + W64LIT(0xbc76bc89af13cabc), W64LIT(0xa937a921d1789ea9), W64LIT(0x474647028fc80147), W64LIT(0x415841329bda1941), + W64LIT(0x34e434bdb88cd034), W64LIT(0x4875487aade53d48), W64LIT(0xfc2bfcb332ced7fc), W64LIT(0xb751b7d19522e6b7), + W64LIT(0x6adf6a77610bb56a), W64LIT(0x88928834179f1a88), W64LIT(0xa50ba541f95caea5), W64LIT(0x530253a2f7a45153), + W64LIT(0x86a4864433b52286), W64LIT(0xf93af99b2cd5c3f9), W64LIT(0x5b2a5be2c79c715b), W64LIT(0xdb90db96e03b4bdb), + W64LIT(0x38d838dd90a8e038), W64LIT(0x7b8a7bff077cf17b), W64LIT(0xc3e8c356b0732bc3), W64LIT(0x1e661ef0445a781e), + W64LIT(0x22aa220dccee8822), W64LIT(0x33ff3385aa99cc33), W64LIT(0x24b4243dd8fc9024), W64LIT(0x2888285df0d8a028), + W64LIT(0x36ee36adb482d836), W64LIT(0xc7fcc776a86f3bc7), W64LIT(0xb240b2f98b39f2b2), W64LIT(0x3bd73bc59aa1ec3b), + W64LIT(0x8e8c8e04038d028e), W64LIT(0x77b6779f2f58c177), W64LIT(0xba68bab9bb01d2ba), W64LIT(0xf506f5fb04f1f3f5), + W64LIT(0x144414a0786c5014), W64LIT(0x9fd99f8c65fa469f), W64LIT(0x0828084030382008), W64LIT(0x551c5592e3b64955), + W64LIT(0x9bcd9bac7de6569b), W64LIT(0x4c614c5ab5f92d4c), W64LIT(0xfe21fea33ec0dffe), W64LIT(0x60fd60275d3d9d60), + W64LIT(0x5c315cdad5896d5c), W64LIT(0xda95da9ee63c4fda), W64LIT(0x187818c050486018), W64LIT(0x4643460a89cf0546), + W64LIT(0xcddecd26945913cd), W64LIT(0x7d947dcf136ee97d), W64LIT(0x21a52115c6e78421), W64LIT(0xb04ab0e98737fab0), + W64LIT(0x3fc33fe582bdfc3f), W64LIT(0x1b771bd85a416c1b), W64LIT(0x8997893c11981e89), W64LIT(0xff24ffab38c7dbff), + W64LIT(0xeb60eb0b40ab8beb), W64LIT(0x84ae84543fbb2a84), W64LIT(0x69d0696f6b02b969), W64LIT(0x3ad23acd9ca6e83a), + W64LIT(0x9dd39d9c69f44e9d), W64LIT(0xd7acd7f6c81f7bd7), W64LIT(0xd3b8d3d6d0036bd3), W64LIT(0x70ad70a73d4ddd70), + W64LIT(0x67e6671f4f288167), W64LIT(0x405d403a9ddd1d40), W64LIT(0xb55bb5c1992ceeb5), W64LIT(0xde81debefe205fde), + W64LIT(0x5d345dd2d38e695d), W64LIT(0x30f0309da090c030), W64LIT(0x91ef91fc41d07e91), W64LIT(0xb14fb1e18130feb1), + W64LIT(0x788578e70d75fd78), W64LIT(0x1155118866774411), W64LIT(0x0105010806070401), W64LIT(0xe556e57b6481b3e5), + W64LIT(0x0000000000000000), W64LIT(0x68d568676d05bd68), W64LIT(0x98c298b477ef5a98), W64LIT(0xa01aa069e747baa0), + W64LIT(0xc5f6c566a46133c5), W64LIT(0x020a02100c0e0802), W64LIT(0xa604a659f355a2a6), W64LIT(0x74b974872551cd74), + W64LIT(0x2d992d75eec3b42d), W64LIT(0x0b270b583a312c0b), W64LIT(0xa210a279eb49b2a2), W64LIT(0x76b37697295fc576), + W64LIT(0xb345b3f18d3ef6b3), W64LIT(0xbe7cbe99a31dc2be), W64LIT(0xced1ce3e9e501fce), W64LIT(0xbd73bd81a914cebd), + W64LIT(0xae2cae19c36d82ae), W64LIT(0xe96ae91b4ca583e9), W64LIT(0x8a988a241b91128a), W64LIT(0x31f53195a697c431), + W64LIT(0x1c6c1ce04854701c), W64LIT(0xec7bec3352be97ec), W64LIT(0xf112f1db1cede3f1), W64LIT(0x99c799bc71e85e99), + W64LIT(0x94fe94d45fcb6a94), W64LIT(0xaa38aa39db7192aa), W64LIT(0xf609f6e30ef8fff6), W64LIT(0x26be262dd4f29826), + W64LIT(0x2f932f65e2cdbc2f), W64LIT(0xef74ef2b58b79bef), W64LIT(0xe86fe8134aa287e8), W64LIT(0x8c868c140f830a8c), + W64LIT(0x35e135b5be8bd435), W64LIT(0x030f03180a090c03), W64LIT(0xd4a3d4eec21677d4), W64LIT(0x7f9e7fdf1f60e17f), + W64LIT(0xfb30fb8b20dbcbfb), W64LIT(0x051105281e1b1405), W64LIT(0xc1e2c146bc7d23c1), W64LIT(0x5e3b5ecad987655e), + W64LIT(0x90ea90f447d77a90), W64LIT(0x20a0201dc0e08020), W64LIT(0x3dc93df58eb3f43d), W64LIT(0x82b082642ba93282), + W64LIT(0xf70cf7eb08fffbf7), W64LIT(0xea65ea0346ac8fea), W64LIT(0x0a220a503c36280a), W64LIT(0x0d390d682e23340d), + W64LIT(0x7e9b7ed71967e57e), W64LIT(0xf83ff8932ad2c7f8), W64LIT(0x500d50bafdad5d50), W64LIT(0x1a721ad05c46681a), + W64LIT(0xc4f3c46ea26637c4), W64LIT(0x071b073812151c07), W64LIT(0x57165782efb84157), W64LIT(0xb862b8a9b70fdab8), + W64LIT(0x3ccc3cfd88b4f03c), W64LIT(0x62f7623751339562), W64LIT(0xe348e34b7093abe3), W64LIT(0xc8cfc80e8a4207c8), + W64LIT(0xac26ac09cf638aac), W64LIT(0x520752aaf1a35552), W64LIT(0x64e9640745218d64), W64LIT(0x1050108060704010), + W64LIT(0xd0b7d0ceda0a67d0), W64LIT(0xd99ad986ec3543d9), W64LIT(0x135f13986a794c13), W64LIT(0x0c3c0c602824300c), + W64LIT(0x125a12906c7e4812), W64LIT(0x298d2955f6dfa429), W64LIT(0x510851b2fbaa5951), W64LIT(0xb967b9a1b108deb9), + W64LIT(0xcfd4cf3698571bcf), W64LIT(0xd6a9d6fece187fd6), W64LIT(0x73a273bf3744d173), W64LIT(0x8d838d1c09840e8d), + W64LIT(0x81bf817c21a03e81), W64LIT(0x5419549ae5b14d54), W64LIT(0xc0e7c04eba7a27c0), W64LIT(0xed7eed3b54b993ed), + W64LIT(0x4e6b4e4ab9f7254e), W64LIT(0x4449441a85c10d44), W64LIT(0xa701a751f552a6a7), W64LIT(0x2a822a4dfcd6a82a), + W64LIT(0x85ab855c39bc2e85), W64LIT(0x25b12535defb9425), W64LIT(0xe659e6636e88bfe6), W64LIT(0xcac5ca1e864c0fca), + W64LIT(0x7c917cc71569ed7c), W64LIT(0x8b9d8b2c1d96168b), W64LIT(0x5613568ae9bf4556), W64LIT(0x80ba807427a73a80) + }, + { + W64LIT(0xd1ce3e9e501fcece), W64LIT(0x6dbbb1bd06d6bbbb), W64LIT(0x60eb0b40ab8bebeb), W64LIT(0xe092e44bd9729292), + W64LIT(0x65ea0346ac8feaea), W64LIT(0xc0cb16804b0bcbcb), W64LIT(0x5f13986a794c1313), W64LIT(0xe2c146bc7d23c1c1), + W64LIT(0x6ae91b4ca583e9e9), W64LIT(0xd23acd9ca6e83a3a), W64LIT(0xa9d6fece187fd6d6), W64LIT(0x40b2f98b39f2b2b2), + W64LIT(0xbdd2ded6046fd2d2), W64LIT(0xea90f447d77a9090), W64LIT(0x4b17b872655c1717), W64LIT(0x3ff8932ad2c7f8f8), + W64LIT(0x57422a91d3154242), W64LIT(0x4115a87e6b541515), W64LIT(0x13568ae9bf455656), W64LIT(0x5eb4c99f2beab4b4), + W64LIT(0xec650f4326896565), W64LIT(0x6c1ce04854701c1c), W64LIT(0x928834179f1a8888), W64LIT(0x52432297d4114343), + W64LIT(0xf6c566a46133c5c5), W64LIT(0x315cdad5896d5c5c), W64LIT(0xee36adb482d83636), W64LIT(0x68bab9bb01d2baba), + W64LIT(0x06f5fb04f1f3f5f5), W64LIT(0x165782efb8415757), W64LIT(0xe6671f4f28816767), W64LIT(0x838d1c09840e8d8d), + W64LIT(0xf53195a697c43131), W64LIT(0x09f6e30ef8fff6f6), W64LIT(0xe9640745218d6464), W64LIT(0x2558facd957d5858), + W64LIT(0xdc9e8463fd429e9e), W64LIT(0x03f4f302f6f7f4f4), W64LIT(0xaa220dccee882222), W64LIT(0x38aa39db7192aaaa), + W64LIT(0xbc758f2356c97575), W64LIT(0x330f78222d3c0f0f), W64LIT(0x0a02100c0e080202), W64LIT(0x4fb1e18130feb1b1), + W64LIT(0x84dfb6f8275bdfdf), W64LIT(0xc46d4f731ea96d6d), W64LIT(0xa273bf3744d17373), W64LIT(0x644d52b3fe294d4d), + W64LIT(0x917cc71569ed7c7c), W64LIT(0xbe262dd4f2982626), W64LIT(0x962e6de4cab82e2e), W64LIT(0x0cf7eb08fffbf7f7), + W64LIT(0x2808403038200808), W64LIT(0x345dd2d38e695d5d), W64LIT(0x49441a85c10d4444), W64LIT(0xc63eed84baf83e3e), + W64LIT(0xd99f8c65fa469f9f), W64LIT(0x4414a0786c501414), W64LIT(0xcfc80e8a4207c8c8), W64LIT(0x2cae19c36d82aeae), + W64LIT(0x19549ae5b14d5454), W64LIT(0x5010806070401010), W64LIT(0x9fd88eea3247d8d8), W64LIT(0x76bc89af13cabcbc), + W64LIT(0x721ad05c46681a1a), W64LIT(0xda6b7f670cb16b6b), W64LIT(0xd0696f6b02b96969), W64LIT(0x18f3cb10e3ebf3f3), + W64LIT(0x73bd81a914cebdbd), W64LIT(0xff3385aa99cc3333), W64LIT(0x3dab31dd7696abab), W64LIT(0x35fa8326dccffafa), + W64LIT(0xb2d1c6dc0d63d1d1), W64LIT(0xcd9bac7de6569b9b), W64LIT(0xd568676d05bd6868), W64LIT(0x6b4e4ab9f7254e4e), + W64LIT(0x4e16b07462581616), W64LIT(0xfb95dc59cc6e9595), W64LIT(0xef91fc41d07e9191), W64LIT(0x71ee235eb09feeee), + W64LIT(0x614c5ab5f92d4c4c), W64LIT(0xf2633f5734916363), W64LIT(0x8c8e04038d028e8e), W64LIT(0x2a5be2c79c715b5b), + W64LIT(0xdbcc2e925e17cccc), W64LIT(0xcc3cfd88b4f03c3c), W64LIT(0x7d19c8564f641919), W64LIT(0x1fa161e140bea1a1), + W64LIT(0xbf817c21a03e8181), W64LIT(0x704972abe2394949), W64LIT(0x8a7bff077cf17b7b), W64LIT(0x9ad986ec3543d9d9), + W64LIT(0xce6f5f7f10a16f6f), W64LIT(0xeb37a5b285dc3737), W64LIT(0xfd60275d3d9d6060), W64LIT(0xc5ca1e864c0fcaca), + W64LIT(0x5ce76b688fbbe7e7), W64LIT(0x872b45fad1ac2b2b), W64LIT(0x75487aade53d4848), W64LIT(0x2efdbb34c9d3fdfd), + W64LIT(0xf496c453c5629696), W64LIT(0x4c451283c6094545), W64LIT(0x2bfcb332ced7fcfc), W64LIT(0x5841329bda194141), + W64LIT(0x5a12906c7e481212), W64LIT(0x390d682e23340d0d), W64LIT(0x8079ef0b72f97979), W64LIT(0x56e57b6481b3e5e5), + W64LIT(0x97893c11981e8989), W64LIT(0x868c140f830a8c8c), W64LIT(0x48e34b7093abe3e3), W64LIT(0xa0201dc0e0802020), + W64LIT(0xf0309da090c03030), W64LIT(0x8bdcaef22e57dcdc), W64LIT(0x51b7d19522e6b7b7), W64LIT(0xc16c477519ad6c6c), + W64LIT(0x7f4a6aa1eb354a4a), W64LIT(0x5bb5c1992ceeb5b5), W64LIT(0xc33fe582bdfc3f3f), W64LIT(0xf197cc55c2669797), + W64LIT(0xa3d4eec21677d4d4), W64LIT(0xf762375133956262), W64LIT(0x992d75eec3b42d2d), W64LIT(0x1e06301412180606), + W64LIT(0x0ea449ff5baaa4a4), W64LIT(0x0ba541f95caea5a5), W64LIT(0xb5836c2dae368383), W64LIT(0x3e5fc2df80615f5f), + W64LIT(0x822a4dfcd6a82a2a), W64LIT(0x95da9ee63c4fdada), W64LIT(0xcac9068c4503c9c9), W64LIT(0x0000000000000000), + W64LIT(0x9b7ed71967e57e7e), W64LIT(0x10a279eb49b2a2a2), W64LIT(0x1c5592e3b6495555), W64LIT(0x79bf91a51ac6bfbf), + W64LIT(0x5511886677441111), W64LIT(0xa6d5e6c41173d5d5), W64LIT(0xd69c946ff34a9c9c), W64LIT(0xd4cf3698571bcfcf), + W64LIT(0x360e70242a380e0e), W64LIT(0x220a503c36280a0a), W64LIT(0xc93df58eb3f43d3d), W64LIT(0x0851b2fbaa595151), + W64LIT(0x947dcf136ee97d7d), W64LIT(0xe593ec4dde769393), W64LIT(0x771bd85a416c1b1b), W64LIT(0x21fea33ec0dffefe), + W64LIT(0xf3c46ea26637c4c4), W64LIT(0x4647028fc8014747), W64LIT(0x2d0948363f240909), W64LIT(0xa4864433b5228686), + W64LIT(0x270b583a312c0b0b), W64LIT(0x898f0c058a068f8f), W64LIT(0xd39d9c69f44e9d9d), W64LIT(0xdf6a77610bb56a6a), + W64LIT(0x1b073812151c0707), W64LIT(0x67b9a1b108deb9b9), W64LIT(0x4ab0e98737fab0b0), W64LIT(0xc298b477ef5a9898), + W64LIT(0x7818c05048601818), W64LIT(0xfa328dac9ec83232), W64LIT(0xa871af3b4ad97171), W64LIT(0x7a4b62a7ec314b4b), + W64LIT(0x74ef2b58b79befef), W64LIT(0xd73bc59aa1ec3b3b), W64LIT(0xad70a73d4ddd7070), W64LIT(0x1aa069e747baa0a0), + W64LIT(0x53e4736286b7e4e4), W64LIT(0x5d403a9ddd1d4040), W64LIT(0x24ffab38c7dbffff), W64LIT(0xe8c356b0732bc3c3), + W64LIT(0x37a921d1789ea9a9), W64LIT(0x59e6636e88bfe6e6), W64LIT(0x8578e70d75fd7878), W64LIT(0x3af99b2cd5c3f9f9), + W64LIT(0x9d8b2c1d96168b8b), W64LIT(0x43460a89cf054646), W64LIT(0xba807427a73a8080), W64LIT(0x661ef0445a781e1e), + W64LIT(0xd838dd90a8e03838), W64LIT(0x42e15b7c9da3e1e1), W64LIT(0x62b8a9b70fdab8b8), W64LIT(0x32a829d77f9aa8a8), + W64LIT(0x47e0537a9aa7e0e0), W64LIT(0x3c0c602824300c0c), W64LIT(0xaf2305cae98c2323), W64LIT(0xb37697295fc57676), + W64LIT(0x691de84e53741d1d), W64LIT(0xb12535defb942525), W64LIT(0xb4243dd8fc902424), W64LIT(0x1105281e1b140505), + W64LIT(0x12f1db1cede3f1f1), W64LIT(0xcb6e577917a56e6e), W64LIT(0xfe94d45fcb6a9494), W64LIT(0x88285df0d8a02828), + W64LIT(0xc89aa47be1529a9a), W64LIT(0xae84543fbb2a8484), W64LIT(0x6fe8134aa287e8e8), W64LIT(0x15a371ed4eb6a3a3), + W64LIT(0x6e4f42bff0214f4f), W64LIT(0xb6779f2f58c17777), W64LIT(0xb8d3d6d0036bd3d3), W64LIT(0xab855c39bc2e8585), + W64LIT(0x4de2437694afe2e2), W64LIT(0x0752aaf1a3555252), W64LIT(0x1df2c316e4eff2f2), W64LIT(0xb082642ba9328282), + W64LIT(0x0d50bafdad5d5050), W64LIT(0x8f7af7017bf57a7a), W64LIT(0x932f65e2cdbc2f2f), W64LIT(0xb974872551cd7474), + W64LIT(0x0253a2f7a4515353), W64LIT(0x45b3f18d3ef6b3b3), W64LIT(0xf8612f5b3a996161), W64LIT(0x29af11c56a86afaf), + W64LIT(0xdd39d596afe43939), W64LIT(0xe135b5be8bd43535), W64LIT(0x81debefe205fdede), W64LIT(0xdecd26945913cdcd), + W64LIT(0x631ff8425d7c1f1f), W64LIT(0xc799bc71e85e9999), W64LIT(0x26ac09cf638aacac), W64LIT(0x23ad01c9648eadad), + W64LIT(0xa772b73143d57272), W64LIT(0x9c2c7de8c4b02c2c), W64LIT(0x8edda6f42953dddd), W64LIT(0xb7d0ceda0a67d0d0), + W64LIT(0xa1874c35b2268787), W64LIT(0x7cbe99a31dc2bebe), W64LIT(0x3b5ecad987655e5e), W64LIT(0x04a659f355a2a6a6), + W64LIT(0x7bec3352be97ecec), W64LIT(0x140420181c100404), W64LIT(0xf9c67eae683fc6c6), W64LIT(0x0f03180a090c0303), + W64LIT(0xe434bdb88cd03434), W64LIT(0x30fb8b20dbcbfbfb), W64LIT(0x90db96e03b4bdbdb), W64LIT(0x2059f2cb92795959), + W64LIT(0x54b6d99325e2b6b6), W64LIT(0xedc25eb6742fc2c2), W64LIT(0x0501080607040101), W64LIT(0x17f0d31aeae7f0f0), + W64LIT(0x2f5aeac19b755a5a), W64LIT(0x7eed3b54b993eded), W64LIT(0x01a751f552a6a7a7), W64LIT(0xe36617492f856666), + W64LIT(0xa52115c6e7842121), W64LIT(0x9e7fdf1f60e17f7f), W64LIT(0x988a241b91128a8a), W64LIT(0xbb2725d2f59c2727), + W64LIT(0xfcc776a86f3bc7c7), W64LIT(0xe7c04eba7a27c0c0), W64LIT(0x8d2955f6dfa42929), W64LIT(0xacd7f6c81f7bd7d7) + }, + { + W64LIT(0x93ec4dde769393e5), W64LIT(0xd986ec3543d9d99a), W64LIT(0x9aa47be1529a9ac8), W64LIT(0xb5c1992ceeb5b55b), + W64LIT(0x98b477ef5a9898c2), W64LIT(0x220dccee882222aa), W64LIT(0x451283c60945454c), W64LIT(0xfcb332ced7fcfc2b), + W64LIT(0xbab9bb01d2baba68), W64LIT(0x6a77610bb56a6adf), W64LIT(0xdfb6f8275bdfdf84), W64LIT(0x02100c0e0802020a), + W64LIT(0x9f8c65fa469f9fd9), W64LIT(0xdcaef22e57dcdc8b), W64LIT(0x51b2fbaa59515108), W64LIT(0x59f2cb9279595920), + W64LIT(0x4a6aa1eb354a4a7f), W64LIT(0x17b872655c17174b), W64LIT(0x2b45fad1ac2b2b87), W64LIT(0xc25eb6742fc2c2ed), + W64LIT(0x94d45fcb6a9494fe), W64LIT(0xf4f302f6f7f4f403), W64LIT(0xbbb1bd06d6bbbb6d), W64LIT(0xa371ed4eb6a3a315), + W64LIT(0x62375133956262f7), W64LIT(0xe4736286b7e4e453), W64LIT(0x71af3b4ad97171a8), W64LIT(0xd4eec21677d4d4a3), + W64LIT(0xcd26945913cdcdde), W64LIT(0x70a73d4ddd7070ad), W64LIT(0x16b074625816164e), W64LIT(0xe15b7c9da3e1e142), + W64LIT(0x4972abe239494970), W64LIT(0x3cfd88b4f03c3ccc), W64LIT(0xc04eba7a27c0c0e7), W64LIT(0xd88eea3247d8d89f), + W64LIT(0x5cdad5896d5c5c31), W64LIT(0x9bac7de6569b9bcd), W64LIT(0xad01c9648eadad23), W64LIT(0x855c39bc2e8585ab), + W64LIT(0x53a2f7a451535302), W64LIT(0xa161e140bea1a11f), W64LIT(0x7af7017bf57a7a8f), W64LIT(0xc80e8a4207c8c8cf), + W64LIT(0x2d75eec3b42d2d99), W64LIT(0xe0537a9aa7e0e047), W64LIT(0xd1c6dc0d63d1d1b2), W64LIT(0x72b73143d57272a7), + W64LIT(0xa659f355a2a6a604), W64LIT(0x2c7de8c4b02c2c9c), W64LIT(0xc46ea26637c4c4f3), W64LIT(0xe34b7093abe3e348), + W64LIT(0x7697295fc57676b3), W64LIT(0x78e70d75fd787885), W64LIT(0xb7d19522e6b7b751), W64LIT(0xb4c99f2beab4b45e), + W64LIT(0x0948363f2409092d), W64LIT(0x3bc59aa1ec3b3bd7), W64LIT(0x0e70242a380e0e36), W64LIT(0x41329bda19414158), + W64LIT(0x4c5ab5f92d4c4c61), W64LIT(0xdebefe205fdede81), W64LIT(0xb2f98b39f2b2b240), W64LIT(0x90f447d77a9090ea), + W64LIT(0x2535defb942525b1), W64LIT(0xa541f95caea5a50b), W64LIT(0xd7f6c81f7bd7d7ac), W64LIT(0x03180a090c03030f), + W64LIT(0x1188667744111155), W64LIT(0x0000000000000000), W64LIT(0xc356b0732bc3c3e8), W64LIT(0x2e6de4cab82e2e96), + W64LIT(0x92e44bd9729292e0), W64LIT(0xef2b58b79befef74), W64LIT(0x4e4ab9f7254e4e6b), W64LIT(0x12906c7e4812125a), + W64LIT(0x9d9c69f44e9d9dd3), W64LIT(0x7dcf136ee97d7d94), W64LIT(0xcb16804b0bcbcbc0), W64LIT(0x35b5be8bd43535e1), + W64LIT(0x1080607040101050), W64LIT(0xd5e6c41173d5d5a6), W64LIT(0x4f42bff0214f4f6e), W64LIT(0x9e8463fd429e9edc), + W64LIT(0x4d52b3fe294d4d64), W64LIT(0xa921d1789ea9a937), W64LIT(0x5592e3b64955551c), W64LIT(0xc67eae683fc6c6f9), + W64LIT(0xd0ceda0a67d0d0b7), W64LIT(0x7bff077cf17b7b8a), W64LIT(0x18c0504860181878), W64LIT(0x97cc55c2669797f1), + W64LIT(0xd3d6d0036bd3d3b8), W64LIT(0x36adb482d83636ee), W64LIT(0xe6636e88bfe6e659), W64LIT(0x487aade53d484875), + W64LIT(0x568ae9bf45565613), W64LIT(0x817c21a03e8181bf), W64LIT(0x8f0c058a068f8f89), W64LIT(0x779f2f58c17777b6), + W64LIT(0xcc2e925e17ccccdb), W64LIT(0x9c946ff34a9c9cd6), W64LIT(0xb9a1b108deb9b967), W64LIT(0xe2437694afe2e24d), + W64LIT(0xac09cf638aacac26), W64LIT(0xb8a9b70fdab8b862), W64LIT(0x2f65e2cdbc2f2f93), W64LIT(0x15a87e6b54151541), + W64LIT(0xa449ff5baaa4a40e), W64LIT(0x7cc71569ed7c7c91), W64LIT(0xda9ee63c4fdada95), W64LIT(0x38dd90a8e03838d8), + W64LIT(0x1ef0445a781e1e66), W64LIT(0x0b583a312c0b0b27), W64LIT(0x05281e1b14050511), W64LIT(0xd6fece187fd6d6a9), + W64LIT(0x14a0786c50141444), W64LIT(0x6e577917a56e6ecb), W64LIT(0x6c477519ad6c6cc1), W64LIT(0x7ed71967e57e7e9b), + W64LIT(0x6617492f856666e3), W64LIT(0xfdbb34c9d3fdfd2e), W64LIT(0xb1e18130feb1b14f), W64LIT(0xe57b6481b3e5e556), + W64LIT(0x60275d3d9d6060fd), W64LIT(0xaf11c56a86afaf29), W64LIT(0x5ecad987655e5e3b), W64LIT(0x3385aa99cc3333ff), + W64LIT(0x874c35b2268787a1), W64LIT(0xc9068c4503c9c9ca), W64LIT(0xf0d31aeae7f0f017), W64LIT(0x5dd2d38e695d5d34), + W64LIT(0x6d4f731ea96d6dc4), W64LIT(0x3fe582bdfc3f3fc3), W64LIT(0x8834179f1a888892), W64LIT(0x8d1c09840e8d8d83), + W64LIT(0xc776a86f3bc7c7fc), W64LIT(0xf7eb08fffbf7f70c), W64LIT(0x1de84e53741d1d69), W64LIT(0xe91b4ca583e9e96a), + W64LIT(0xec3352be97ecec7b), W64LIT(0xed3b54b993eded7e), W64LIT(0x807427a73a8080ba), W64LIT(0x2955f6dfa429298d), + W64LIT(0x2725d2f59c2727bb), W64LIT(0xcf3698571bcfcfd4), W64LIT(0x99bc71e85e9999c7), W64LIT(0xa829d77f9aa8a832), + W64LIT(0x50bafdad5d50500d), W64LIT(0x0f78222d3c0f0f33), W64LIT(0x37a5b285dc3737eb), W64LIT(0x243dd8fc902424b4), + W64LIT(0x285df0d8a0282888), W64LIT(0x309da090c03030f0), W64LIT(0x95dc59cc6e9595fb), W64LIT(0xd2ded6046fd2d2bd), + W64LIT(0x3eed84baf83e3ec6), W64LIT(0x5be2c79c715b5b2a), W64LIT(0x403a9ddd1d40405d), W64LIT(0x836c2dae368383b5), + W64LIT(0xb3f18d3ef6b3b345), W64LIT(0x696f6b02b96969d0), W64LIT(0x5782efb841575716), W64LIT(0x1ff8425d7c1f1f63), + W64LIT(0x073812151c07071b), W64LIT(0x1ce04854701c1c6c), W64LIT(0x8a241b91128a8a98), W64LIT(0xbc89af13cabcbc76), + W64LIT(0x201dc0e0802020a0), W64LIT(0xeb0b40ab8bebeb60), W64LIT(0xce3e9e501fceced1), W64LIT(0x8e04038d028e8e8c), + W64LIT(0xab31dd7696abab3d), W64LIT(0xee235eb09feeee71), W64LIT(0x3195a697c43131f5), W64LIT(0xa279eb49b2a2a210), + W64LIT(0x73bf3744d17373a2), W64LIT(0xf99b2cd5c3f9f93a), W64LIT(0xca1e864c0fcacac5), W64LIT(0x3acd9ca6e83a3ad2), + W64LIT(0x1ad05c46681a1a72), W64LIT(0xfb8b20dbcbfbfb30), W64LIT(0x0d682e23340d0d39), W64LIT(0xc146bc7d23c1c1e2), + W64LIT(0xfea33ec0dffefe21), W64LIT(0xfa8326dccffafa35), W64LIT(0xf2c316e4eff2f21d), W64LIT(0x6f5f7f10a16f6fce), + W64LIT(0xbd81a914cebdbd73), W64LIT(0x96c453c5629696f4), W64LIT(0xdda6f42953dddd8e), W64LIT(0x432297d411434352), + W64LIT(0x52aaf1a355525207), W64LIT(0xb6d99325e2b6b654), W64LIT(0x0840303820080828), W64LIT(0xf3cb10e3ebf3f318), + W64LIT(0xae19c36d82aeae2c), W64LIT(0xbe99a31dc2bebe7c), W64LIT(0x19c8564f6419197d), W64LIT(0x893c11981e898997), + W64LIT(0x328dac9ec83232fa), W64LIT(0x262dd4f2982626be), W64LIT(0xb0e98737fab0b04a), W64LIT(0xea0346ac8feaea65), + W64LIT(0x4b62a7ec314b4b7a), W64LIT(0x640745218d6464e9), W64LIT(0x84543fbb2a8484ae), W64LIT(0x82642ba9328282b0), + W64LIT(0x6b7f670cb16b6bda), W64LIT(0xf5fb04f1f3f5f506), W64LIT(0x79ef0b72f9797980), W64LIT(0xbf91a51ac6bfbf79), + W64LIT(0x0108060704010105), W64LIT(0x5fc2df80615f5f3e), W64LIT(0x758f2356c97575bc), W64LIT(0x633f5734916363f2), + W64LIT(0x1bd85a416c1b1b77), W64LIT(0x2305cae98c2323af), W64LIT(0x3df58eb3f43d3dc9), W64LIT(0x68676d05bd6868d5), + W64LIT(0x2a4dfcd6a82a2a82), W64LIT(0x650f4326896565ec), W64LIT(0xe8134aa287e8e86f), W64LIT(0x91fc41d07e9191ef), + W64LIT(0xf6e30ef8fff6f609), W64LIT(0xffab38c7dbffff24), W64LIT(0x13986a794c13135f), W64LIT(0x58facd957d585825), + W64LIT(0xf1db1cede3f1f112), W64LIT(0x47028fc801474746), W64LIT(0x0a503c36280a0a22), W64LIT(0x7fdf1f60e17f7f9e), + W64LIT(0xc566a46133c5c5f6), W64LIT(0xa751f552a6a7a701), W64LIT(0xe76b688fbbe7e75c), W64LIT(0x612f5b3a996161f8), + W64LIT(0x5aeac19b755a5a2f), W64LIT(0x063014121806061e), W64LIT(0x460a89cf05464643), W64LIT(0x441a85c10d444449), + W64LIT(0x422a91d315424257), W64LIT(0x0420181c10040414), W64LIT(0xa069e747baa0a01a), W64LIT(0xdb96e03b4bdbdb90), + W64LIT(0x39d596afe43939dd), W64LIT(0x864433b5228686a4), W64LIT(0x549ae5b14d545419), W64LIT(0xaa39db7192aaaa38), + W64LIT(0x8c140f830a8c8c86), W64LIT(0x34bdb88cd03434e4), W64LIT(0x2115c6e7842121a5), W64LIT(0x8b2c1d96168b8b9d), + W64LIT(0xf8932ad2c7f8f83f), W64LIT(0x0c602824300c0c3c), W64LIT(0x74872551cd7474b9), W64LIT(0x671f4f28816767e6) + }, + { + W64LIT(0x676d05bd6868d568), W64LIT(0x1c09840e8d8d838d), W64LIT(0x1e864c0fcacac5ca), W64LIT(0x52b3fe294d4d644d), + W64LIT(0xbf3744d17373a273), W64LIT(0x62a7ec314b4b7a4b), W64LIT(0x4ab9f7254e4e6b4e), W64LIT(0x4dfcd6a82a2a822a), + W64LIT(0xeec21677d4d4a3d4), W64LIT(0xaaf1a35552520752), W64LIT(0x2dd4f2982626be26), W64LIT(0xf18d3ef6b3b345b3), + W64LIT(0x9ae5b14d54541954), W64LIT(0xf0445a781e1e661e), W64LIT(0xc8564f6419197d19), W64LIT(0xf8425d7c1f1f631f), + W64LIT(0x0dccee882222aa22), W64LIT(0x180a090c03030f03), W64LIT(0x0a89cf0546464346), W64LIT(0xf58eb3f43d3dc93d), + W64LIT(0x75eec3b42d2d992d), W64LIT(0x6aa1eb354a4a7f4a), W64LIT(0xa2f7a45153530253), W64LIT(0x6c2dae368383b583), + W64LIT(0x986a794c13135f13), W64LIT(0x241b91128a8a988a), W64LIT(0xd19522e6b7b751b7), W64LIT(0xe6c41173d5d5a6d5), + W64LIT(0x35defb942525b125), W64LIT(0xef0b72f979798079), W64LIT(0xfb04f1f3f5f506f5), W64LIT(0x81a914cebdbd73bd), + W64LIT(0xfacd957d58582558), W64LIT(0x65e2cdbc2f2f932f), W64LIT(0x682e23340d0d390d), W64LIT(0x100c0e0802020a02), + W64LIT(0x3b54b993eded7eed), W64LIT(0xb2fbaa5951510851), W64LIT(0x8463fd429e9edc9e), W64LIT(0x8866774411115511), + W64LIT(0xc316e4eff2f21df2), W64LIT(0xed84baf83e3ec63e), W64LIT(0x92e3b64955551c55), W64LIT(0xcad987655e5e3b5e), + W64LIT(0xc6dc0d63d1d1b2d1), W64LIT(0xb074625816164e16), W64LIT(0xfd88b4f03c3ccc3c), W64LIT(0x17492f856666e366), + W64LIT(0xa73d4ddd7070ad70), W64LIT(0xd2d38e695d5d345d), W64LIT(0xcb10e3ebf3f318f3), W64LIT(0x1283c60945454c45), + W64LIT(0x3a9ddd1d40405d40), W64LIT(0x2e925e17ccccdbcc), W64LIT(0x134aa287e8e86fe8), W64LIT(0xd45fcb6a9494fe94), + W64LIT(0x8ae9bf4556561356), W64LIT(0x4030382008082808), W64LIT(0x3e9e501fceced1ce), W64LIT(0xd05c46681a1a721a), + W64LIT(0xcd9ca6e83a3ad23a), W64LIT(0xded6046fd2d2bdd2), W64LIT(0x5b7c9da3e1e142e1), W64LIT(0xb6f8275bdfdf84df), + W64LIT(0xc1992ceeb5b55bb5), W64LIT(0xdd90a8e03838d838), W64LIT(0x577917a56e6ecb6e), W64LIT(0x70242a380e0e360e), + W64LIT(0x7b6481b3e5e556e5), W64LIT(0xf302f6f7f4f403f4), W64LIT(0x9b2cd5c3f9f93af9), W64LIT(0x4433b5228686a486), + W64LIT(0x1b4ca583e9e96ae9), W64LIT(0x42bff0214f4f6e4f), W64LIT(0xfece187fd6d6a9d6), W64LIT(0x5c39bc2e8585ab85), + W64LIT(0x05cae98c2323af23), W64LIT(0x3698571bcfcfd4cf), W64LIT(0x8dac9ec83232fa32), W64LIT(0xbc71e85e9999c799), + W64LIT(0x95a697c43131f531), W64LIT(0xa0786c5014144414), W64LIT(0x19c36d82aeae2cae), W64LIT(0x235eb09feeee71ee), + W64LIT(0x0e8a4207c8c8cfc8), W64LIT(0x7aade53d48487548), W64LIT(0xd6d0036bd3d3b8d3), W64LIT(0x9da090c03030f030), + W64LIT(0x61e140bea1a11fa1), W64LIT(0xe44bd9729292e092), W64LIT(0x329bda1941415841), W64LIT(0xe18130feb1b14fb1), + W64LIT(0xc050486018187818), W64LIT(0x6ea26637c4c4f3c4), W64LIT(0x7de8c4b02c2c9c2c), W64LIT(0xaf3b4ad97171a871), + W64LIT(0xb73143d57272a772), W64LIT(0x1a85c10d44444944), W64LIT(0xa87e6b5415154115), W64LIT(0xbb34c9d3fdfd2efd), + W64LIT(0xa5b285dc3737eb37), W64LIT(0x99a31dc2bebe7cbe), W64LIT(0xc2df80615f5f3e5f), W64LIT(0x39db7192aaaa38aa), + W64LIT(0xac7de6569b9bcd9b), W64LIT(0x34179f1a88889288), W64LIT(0x8eea3247d8d89fd8), W64LIT(0x31dd7696abab3dab), + W64LIT(0x3c11981e89899789), W64LIT(0x946ff34a9c9cd69c), W64LIT(0x8326dccffafa35fa), W64LIT(0x275d3d9d6060fd60), + W64LIT(0x0346ac8feaea65ea), W64LIT(0x89af13cabcbc76bc), W64LIT(0x375133956262f762), W64LIT(0x602824300c0c3c0c), + W64LIT(0x3dd8fc902424b424), W64LIT(0x59f355a2a6a604a6), W64LIT(0x29d77f9aa8a832a8), W64LIT(0x3352be97ecec7bec), + W64LIT(0x1f4f28816767e667), W64LIT(0x1dc0e0802020a020), W64LIT(0x96e03b4bdbdb90db), W64LIT(0xc71569ed7c7c917c), + W64LIT(0x5df0d8a028288828), W64LIT(0xa6f42953dddd8edd), W64LIT(0x09cf638aacac26ac), W64LIT(0xe2c79c715b5b2a5b), + W64LIT(0xbdb88cd03434e434), W64LIT(0xd71967e57e7e9b7e), W64LIT(0x8060704010105010), W64LIT(0xdb1cede3f1f112f1), + W64LIT(0xff077cf17b7b8a7b), W64LIT(0x0c058a068f8f898f), W64LIT(0x3f5734916363f263), W64LIT(0x69e747baa0a01aa0), + W64LIT(0x281e1b1405051105), W64LIT(0xa47be1529a9ac89a), W64LIT(0x2297d41143435243), W64LIT(0x9f2f58c17777b677), + W64LIT(0x15c6e7842121a521), W64LIT(0x91a51ac6bfbf79bf), W64LIT(0x25d2f59c2727bb27), W64LIT(0x48363f2409092d09), + W64LIT(0x56b0732bc3c3e8c3), W64LIT(0x8c65fa469f9fd99f), W64LIT(0xd99325e2b6b654b6), W64LIT(0xf6c81f7bd7d7acd7), + W64LIT(0x55f6dfa429298d29), W64LIT(0x5eb6742fc2c2edc2), W64LIT(0x0b40ab8bebeb60eb), W64LIT(0x4eba7a27c0c0e7c0), + W64LIT(0x49ff5baaa4a40ea4), W64LIT(0x2c1d96168b8b9d8b), W64LIT(0x140f830a8c8c868c), W64LIT(0xe84e53741d1d691d), + W64LIT(0x8b20dbcbfbfb30fb), W64LIT(0xab38c7dbffff24ff), W64LIT(0x46bc7d23c1c1e2c1), W64LIT(0xf98b39f2b2b240b2), + W64LIT(0xcc55c2669797f197), W64LIT(0x6de4cab82e2e962e), W64LIT(0x932ad2c7f8f83ff8), W64LIT(0x0f4326896565ec65), + W64LIT(0xe30ef8fff6f609f6), W64LIT(0x8f2356c97575bc75), W64LIT(0x3812151c07071b07), W64LIT(0x20181c1004041404), + W64LIT(0x72abe23949497049), W64LIT(0x85aa99cc3333ff33), W64LIT(0x736286b7e4e453e4), W64LIT(0x86ec3543d9d99ad9), + W64LIT(0xa1b108deb9b967b9), W64LIT(0xceda0a67d0d0b7d0), W64LIT(0x2a91d31542425742), W64LIT(0x76a86f3bc7c7fcc7), + W64LIT(0x477519ad6c6cc16c), W64LIT(0xf447d77a9090ea90), W64LIT(0x0000000000000000), W64LIT(0x04038d028e8e8c8e), + W64LIT(0x5f7f10a16f6fce6f), W64LIT(0xbafdad5d50500d50), W64LIT(0x0806070401010501), W64LIT(0x66a46133c5c5f6c5), + W64LIT(0x9ee63c4fdada95da), W64LIT(0x028fc80147474647), W64LIT(0xe582bdfc3f3fc33f), W64LIT(0x26945913cdcddecd), + W64LIT(0x6f6b02b96969d069), W64LIT(0x79eb49b2a2a210a2), W64LIT(0x437694afe2e24de2), W64LIT(0xf7017bf57a7a8f7a), + W64LIT(0x51f552a6a7a701a7), W64LIT(0x7eae683fc6c6f9c6), W64LIT(0xec4dde769393e593), W64LIT(0x78222d3c0f0f330f), + W64LIT(0x503c36280a0a220a), W64LIT(0x3014121806061e06), W64LIT(0x636e88bfe6e659e6), W64LIT(0x45fad1ac2b2b872b), + W64LIT(0xc453c5629696f496), W64LIT(0x71ed4eb6a3a315a3), W64LIT(0xe04854701c1c6c1c), W64LIT(0x11c56a86afaf29af), + W64LIT(0x77610bb56a6adf6a), W64LIT(0x906c7e4812125a12), W64LIT(0x543fbb2a8484ae84), W64LIT(0xd596afe43939dd39), + W64LIT(0x6b688fbbe7e75ce7), W64LIT(0xe98737fab0b04ab0), W64LIT(0x642ba9328282b082), W64LIT(0xeb08fffbf7f70cf7), + W64LIT(0xa33ec0dffefe21fe), W64LIT(0x9c69f44e9d9dd39d), W64LIT(0x4c35b2268787a187), W64LIT(0xdad5896d5c5c315c), + W64LIT(0x7c21a03e8181bf81), W64LIT(0xb5be8bd43535e135), W64LIT(0xbefe205fdede81de), W64LIT(0xc99f2beab4b45eb4), + W64LIT(0x41f95caea5a50ba5), W64LIT(0xb332ced7fcfc2bfc), W64LIT(0x7427a73a8080ba80), W64LIT(0x2b58b79befef74ef), + W64LIT(0x16804b0bcbcbc0cb), W64LIT(0xb1bd06d6bbbb6dbb), W64LIT(0x7f670cb16b6bda6b), W64LIT(0x97295fc57676b376), + W64LIT(0xb9bb01d2baba68ba), W64LIT(0xeac19b755a5a2f5a), W64LIT(0xcf136ee97d7d947d), W64LIT(0xe70d75fd78788578), + W64LIT(0x583a312c0b0b270b), W64LIT(0xdc59cc6e9595fb95), W64LIT(0x4b7093abe3e348e3), W64LIT(0x01c9648eadad23ad), + W64LIT(0x872551cd7474b974), W64LIT(0xb477ef5a9898c298), W64LIT(0xc59aa1ec3b3bd73b), W64LIT(0xadb482d83636ee36), + W64LIT(0x0745218d6464e964), W64LIT(0x4f731ea96d6dc46d), W64LIT(0xaef22e57dcdc8bdc), W64LIT(0xd31aeae7f0f017f0), + W64LIT(0xf2cb927959592059), W64LIT(0x21d1789ea9a937a9), W64LIT(0x5ab5f92d4c4c614c), W64LIT(0xb872655c17174b17), + W64LIT(0xdf1f60e17f7f9e7f), W64LIT(0xfc41d07e9191ef91), W64LIT(0xa9b70fdab8b862b8), W64LIT(0x068c4503c9c9cac9), + W64LIT(0x82efb84157571657), W64LIT(0xd85a416c1b1b771b), W64LIT(0x537a9aa7e0e047e0), W64LIT(0x2f5b3a996161f861) + }, + { + W64LIT(0xd77f9aa8a832a829), W64LIT(0x97d4114343524322), W64LIT(0xdf80615f5f3e5fc2), W64LIT(0x14121806061e0630), + W64LIT(0x670cb16b6bda6b7f), W64LIT(0x2356c97575bc758f), W64LIT(0x7519ad6c6cc16c47), W64LIT(0xcb927959592059f2), + W64LIT(0x3b4ad97171a871af), W64LIT(0xf8275bdfdf84dfb6), W64LIT(0x35b2268787a1874c), W64LIT(0x59cc6e9595fb95dc), + W64LIT(0x72655c17174b17b8), W64LIT(0x1aeae7f0f017f0d3), W64LIT(0xea3247d8d89fd88e), W64LIT(0x363f2409092d0948), + W64LIT(0x731ea96d6dc46d4f), W64LIT(0x10e3ebf3f318f3cb), W64LIT(0x4e53741d1d691de8), W64LIT(0x804b0bcbcbc0cb16), + W64LIT(0x8c4503c9c9cac906), W64LIT(0xb3fe294d4d644d52), W64LIT(0xe8c4b02c2c9c2c7d), W64LIT(0xc56a86afaf29af11), + W64LIT(0x0b72f979798079ef), W64LIT(0x7a9aa7e0e047e053), W64LIT(0x55c2669797f197cc), W64LIT(0x34c9d3fdfd2efdbb), + W64LIT(0x7f10a16f6fce6f5f), W64LIT(0xa7ec314b4b7a4b62), W64LIT(0x83c60945454c4512), W64LIT(0x96afe43939dd39d5), + W64LIT(0x84baf83e3ec63eed), W64LIT(0xf42953dddd8edda6), W64LIT(0xed4eb6a3a315a371), W64LIT(0xbff0214f4f6e4f42), + W64LIT(0x9f2beab4b45eb4c9), W64LIT(0x9325e2b6b654b6d9), W64LIT(0x7be1529a9ac89aa4), W64LIT(0x242a380e0e360e70), + W64LIT(0x425d7c1f1f631ff8), W64LIT(0xa51ac6bfbf79bf91), W64LIT(0x7e6b5415154115a8), W64LIT(0x7c9da3e1e142e15b), + W64LIT(0xabe2394949704972), W64LIT(0xd6046fd2d2bdd2de), W64LIT(0x4dde769393e593ec), W64LIT(0xae683fc6c6f9c67e), + W64LIT(0x4bd9729292e092e4), W64LIT(0x3143d57272a772b7), W64LIT(0x63fd429e9edc9e84), W64LIT(0x5b3a996161f8612f), + W64LIT(0xdc0d63d1d1b2d1c6), W64LIT(0x5734916363f2633f), W64LIT(0x26dccffafa35fa83), W64LIT(0x5eb09feeee71ee23), + W64LIT(0x02f6f7f4f403f4f3), W64LIT(0x564f6419197d19c8), W64LIT(0xc41173d5d5a6d5e6), W64LIT(0xc9648eadad23ad01), + W64LIT(0xcd957d58582558fa), W64LIT(0xff5baaa4a40ea449), W64LIT(0xbd06d6bbbb6dbbb1), W64LIT(0xe140bea1a11fa161), + W64LIT(0xf22e57dcdc8bdcae), W64LIT(0x16e4eff2f21df2c3), W64LIT(0x2dae368383b5836c), W64LIT(0xb285dc3737eb37a5), + W64LIT(0x91d315424257422a), W64LIT(0x6286b7e4e453e473), W64LIT(0x017bf57a7a8f7af7), W64LIT(0xac9ec83232fa328d), + W64LIT(0x6ff34a9c9cd69c94), W64LIT(0x925e17ccccdbcc2e), W64LIT(0xdd7696abab3dab31), W64LIT(0xa1eb354a4a7f4a6a), + W64LIT(0x058a068f8f898f0c), W64LIT(0x7917a56e6ecb6e57), W64LIT(0x181c100404140420), W64LIT(0xd2f59c2727bb2725), + W64LIT(0xe4cab82e2e962e6d), W64LIT(0x688fbbe7e75ce76b), W64LIT(0x7694afe2e24de243), W64LIT(0xc19b755a5a2f5aea), + W64LIT(0x53c5629696f496c4), W64LIT(0x74625816164e16b0), W64LIT(0xcae98c2323af2305), W64LIT(0xfad1ac2b2b872b45), + W64LIT(0xb6742fc2c2edc25e), W64LIT(0x4326896565ec650f), W64LIT(0x492f856666e36617), W64LIT(0x222d3c0f0f330f78), + W64LIT(0xaf13cabcbc76bc89), W64LIT(0xd1789ea9a937a921), W64LIT(0x8fc8014747464702), W64LIT(0x9bda194141584132), + W64LIT(0xb88cd03434e434bd), W64LIT(0xade53d484875487a), W64LIT(0x32ced7fcfc2bfcb3), W64LIT(0x9522e6b7b751b7d1), + W64LIT(0x610bb56a6adf6a77), W64LIT(0x179f1a8888928834), W64LIT(0xf95caea5a50ba541), W64LIT(0xf7a45153530253a2), + W64LIT(0x33b5228686a48644), W64LIT(0x2cd5c3f9f93af99b), W64LIT(0xc79c715b5b2a5be2), W64LIT(0xe03b4bdbdb90db96), + W64LIT(0x90a8e03838d838dd), W64LIT(0x077cf17b7b8a7bff), W64LIT(0xb0732bc3c3e8c356), W64LIT(0x445a781e1e661ef0), + W64LIT(0xccee882222aa220d), W64LIT(0xaa99cc3333ff3385), W64LIT(0xd8fc902424b4243d), W64LIT(0xf0d8a0282888285d), + W64LIT(0xb482d83636ee36ad), W64LIT(0xa86f3bc7c7fcc776), W64LIT(0x8b39f2b2b240b2f9), W64LIT(0x9aa1ec3b3bd73bc5), + W64LIT(0x038d028e8e8c8e04), W64LIT(0x2f58c17777b6779f), W64LIT(0xbb01d2baba68bab9), W64LIT(0x04f1f3f5f506f5fb), + W64LIT(0x786c5014144414a0), W64LIT(0x65fa469f9fd99f8c), W64LIT(0x3038200808280840), W64LIT(0xe3b64955551c5592), + W64LIT(0x7de6569b9bcd9bac), W64LIT(0xb5f92d4c4c614c5a), W64LIT(0x3ec0dffefe21fea3), W64LIT(0x5d3d9d6060fd6027), + W64LIT(0xd5896d5c5c315cda), W64LIT(0xe63c4fdada95da9e), W64LIT(0x50486018187818c0), W64LIT(0x89cf05464643460a), + W64LIT(0x945913cdcddecd26), W64LIT(0x136ee97d7d947dcf), W64LIT(0xc6e7842121a52115), W64LIT(0x8737fab0b04ab0e9), + W64LIT(0x82bdfc3f3fc33fe5), W64LIT(0x5a416c1b1b771bd8), W64LIT(0x11981e898997893c), W64LIT(0x38c7dbffff24ffab), + W64LIT(0x40ab8bebeb60eb0b), W64LIT(0x3fbb2a8484ae8454), W64LIT(0x6b02b96969d0696f), W64LIT(0x9ca6e83a3ad23acd), + W64LIT(0x69f44e9d9dd39d9c), W64LIT(0xc81f7bd7d7acd7f6), W64LIT(0xd0036bd3d3b8d3d6), W64LIT(0x3d4ddd7070ad70a7), + W64LIT(0x4f28816767e6671f), W64LIT(0x9ddd1d40405d403a), W64LIT(0x992ceeb5b55bb5c1), W64LIT(0xfe205fdede81debe), + W64LIT(0xd38e695d5d345dd2), W64LIT(0xa090c03030f0309d), W64LIT(0x41d07e9191ef91fc), W64LIT(0x8130feb1b14fb1e1), + W64LIT(0x0d75fd78788578e7), W64LIT(0x6677441111551188), W64LIT(0x0607040101050108), W64LIT(0x6481b3e5e556e57b), + W64LIT(0x0000000000000000), W64LIT(0x6d05bd6868d56867), W64LIT(0x77ef5a9898c298b4), W64LIT(0xe747baa0a01aa069), + W64LIT(0xa46133c5c5f6c566), W64LIT(0x0c0e0802020a0210), W64LIT(0xf355a2a6a604a659), W64LIT(0x2551cd7474b97487), + W64LIT(0xeec3b42d2d992d75), W64LIT(0x3a312c0b0b270b58), W64LIT(0xeb49b2a2a210a279), W64LIT(0x295fc57676b37697), + W64LIT(0x8d3ef6b3b345b3f1), W64LIT(0xa31dc2bebe7cbe99), W64LIT(0x9e501fceced1ce3e), W64LIT(0xa914cebdbd73bd81), + W64LIT(0xc36d82aeae2cae19), W64LIT(0x4ca583e9e96ae91b), W64LIT(0x1b91128a8a988a24), W64LIT(0xa697c43131f53195), + W64LIT(0x4854701c1c6c1ce0), W64LIT(0x52be97ecec7bec33), W64LIT(0x1cede3f1f112f1db), W64LIT(0x71e85e9999c799bc), + W64LIT(0x5fcb6a9494fe94d4), W64LIT(0xdb7192aaaa38aa39), W64LIT(0x0ef8fff6f609f6e3), W64LIT(0xd4f2982626be262d), + W64LIT(0xe2cdbc2f2f932f65), W64LIT(0x58b79befef74ef2b), W64LIT(0x4aa287e8e86fe813), W64LIT(0x0f830a8c8c868c14), + W64LIT(0xbe8bd43535e135b5), W64LIT(0x0a090c03030f0318), W64LIT(0xc21677d4d4a3d4ee), W64LIT(0x1f60e17f7f9e7fdf), + W64LIT(0x20dbcbfbfb30fb8b), W64LIT(0x1e1b140505110528), W64LIT(0xbc7d23c1c1e2c146), W64LIT(0xd987655e5e3b5eca), + W64LIT(0x47d77a9090ea90f4), W64LIT(0xc0e0802020a0201d), W64LIT(0x8eb3f43d3dc93df5), W64LIT(0x2ba9328282b08264), + W64LIT(0x08fffbf7f70cf7eb), W64LIT(0x46ac8feaea65ea03), W64LIT(0x3c36280a0a220a50), W64LIT(0x2e23340d0d390d68), + W64LIT(0x1967e57e7e9b7ed7), W64LIT(0x2ad2c7f8f83ff893), W64LIT(0xfdad5d50500d50ba), W64LIT(0x5c46681a1a721ad0), + W64LIT(0xa26637c4c4f3c46e), W64LIT(0x12151c07071b0738), W64LIT(0xefb8415757165782), W64LIT(0xb70fdab8b862b8a9), + W64LIT(0x88b4f03c3ccc3cfd), W64LIT(0x5133956262f76237), W64LIT(0x7093abe3e348e34b), W64LIT(0x8a4207c8c8cfc80e), + W64LIT(0xcf638aacac26ac09), W64LIT(0xf1a35552520752aa), W64LIT(0x45218d6464e96407), W64LIT(0x6070401010501080), + W64LIT(0xda0a67d0d0b7d0ce), W64LIT(0xec3543d9d99ad986), W64LIT(0x6a794c13135f1398), W64LIT(0x2824300c0c3c0c60), + W64LIT(0x6c7e4812125a1290), W64LIT(0xf6dfa429298d2955), W64LIT(0xfbaa5951510851b2), W64LIT(0xb108deb9b967b9a1), + W64LIT(0x98571bcfcfd4cf36), W64LIT(0xce187fd6d6a9d6fe), W64LIT(0x3744d17373a273bf), W64LIT(0x09840e8d8d838d1c), + W64LIT(0x21a03e8181bf817c), W64LIT(0xe5b14d545419549a), W64LIT(0xba7a27c0c0e7c04e), W64LIT(0x54b993eded7eed3b), + W64LIT(0xb9f7254e4e6b4e4a), W64LIT(0x85c10d444449441a), W64LIT(0xf552a6a7a701a751), W64LIT(0xfcd6a82a2a822a4d), + W64LIT(0x39bc2e8585ab855c), W64LIT(0xdefb942525b12535), W64LIT(0x6e88bfe6e659e663), W64LIT(0x864c0fcacac5ca1e), + W64LIT(0x1569ed7c7c917cc7), W64LIT(0x1d96168b8b9d8b2c), W64LIT(0xe9bf45565613568a), W64LIT(0x27a73a8080ba8074) + }, + { + W64LIT(0x501fceced1ce3e9e), W64LIT(0x06d6bbbb6dbbb1bd), W64LIT(0xab8bebeb60eb0b40), W64LIT(0xd9729292e092e44b), + W64LIT(0xac8feaea65ea0346), W64LIT(0x4b0bcbcbc0cb1680), W64LIT(0x794c13135f13986a), W64LIT(0x7d23c1c1e2c146bc), + W64LIT(0xa583e9e96ae91b4c), W64LIT(0xa6e83a3ad23acd9c), W64LIT(0x187fd6d6a9d6fece), W64LIT(0x39f2b2b240b2f98b), + W64LIT(0x046fd2d2bdd2ded6), W64LIT(0xd77a9090ea90f447), W64LIT(0x655c17174b17b872), W64LIT(0xd2c7f8f83ff8932a), + W64LIT(0xd315424257422a91), W64LIT(0x6b5415154115a87e), W64LIT(0xbf45565613568ae9), W64LIT(0x2beab4b45eb4c99f), + W64LIT(0x26896565ec650f43), W64LIT(0x54701c1c6c1ce048), W64LIT(0x9f1a888892883417), W64LIT(0xd411434352432297), + W64LIT(0x6133c5c5f6c566a4), W64LIT(0x896d5c5c315cdad5), W64LIT(0x82d83636ee36adb4), W64LIT(0x01d2baba68bab9bb), + W64LIT(0xf1f3f5f506f5fb04), W64LIT(0xb8415757165782ef), W64LIT(0x28816767e6671f4f), W64LIT(0x840e8d8d838d1c09), + W64LIT(0x97c43131f53195a6), W64LIT(0xf8fff6f609f6e30e), W64LIT(0x218d6464e9640745), W64LIT(0x957d58582558facd), + W64LIT(0xfd429e9edc9e8463), W64LIT(0xf6f7f4f403f4f302), W64LIT(0xee882222aa220dcc), W64LIT(0x7192aaaa38aa39db), + W64LIT(0x56c97575bc758f23), W64LIT(0x2d3c0f0f330f7822), W64LIT(0x0e0802020a02100c), W64LIT(0x30feb1b14fb1e181), + W64LIT(0x275bdfdf84dfb6f8), W64LIT(0x1ea96d6dc46d4f73), W64LIT(0x44d17373a273bf37), W64LIT(0xfe294d4d644d52b3), + W64LIT(0x69ed7c7c917cc715), W64LIT(0xf2982626be262dd4), W64LIT(0xcab82e2e962e6de4), W64LIT(0xfffbf7f70cf7eb08), + W64LIT(0x3820080828084030), W64LIT(0x8e695d5d345dd2d3), W64LIT(0xc10d444449441a85), W64LIT(0xbaf83e3ec63eed84), + W64LIT(0xfa469f9fd99f8c65), W64LIT(0x6c5014144414a078), W64LIT(0x4207c8c8cfc80e8a), W64LIT(0x6d82aeae2cae19c3), + W64LIT(0xb14d545419549ae5), W64LIT(0x7040101050108060), W64LIT(0x3247d8d89fd88eea), W64LIT(0x13cabcbc76bc89af), + W64LIT(0x46681a1a721ad05c), W64LIT(0x0cb16b6bda6b7f67), W64LIT(0x02b96969d0696f6b), W64LIT(0xe3ebf3f318f3cb10), + W64LIT(0x14cebdbd73bd81a9), W64LIT(0x99cc3333ff3385aa), W64LIT(0x7696abab3dab31dd), W64LIT(0xdccffafa35fa8326), + W64LIT(0x0d63d1d1b2d1c6dc), W64LIT(0xe6569b9bcd9bac7d), W64LIT(0x05bd6868d568676d), W64LIT(0xf7254e4e6b4e4ab9), + W64LIT(0x625816164e16b074), W64LIT(0xcc6e9595fb95dc59), W64LIT(0xd07e9191ef91fc41), W64LIT(0xb09feeee71ee235e), + W64LIT(0xf92d4c4c614c5ab5), W64LIT(0x34916363f2633f57), W64LIT(0x8d028e8e8c8e0403), W64LIT(0x9c715b5b2a5be2c7), + W64LIT(0x5e17ccccdbcc2e92), W64LIT(0xb4f03c3ccc3cfd88), W64LIT(0x4f6419197d19c856), W64LIT(0x40bea1a11fa161e1), + W64LIT(0xa03e8181bf817c21), W64LIT(0xe2394949704972ab), W64LIT(0x7cf17b7b8a7bff07), W64LIT(0x3543d9d99ad986ec), + W64LIT(0x10a16f6fce6f5f7f), W64LIT(0x85dc3737eb37a5b2), W64LIT(0x3d9d6060fd60275d), W64LIT(0x4c0fcacac5ca1e86), + W64LIT(0x8fbbe7e75ce76b68), W64LIT(0xd1ac2b2b872b45fa), W64LIT(0xe53d484875487aad), W64LIT(0xc9d3fdfd2efdbb34), + W64LIT(0xc5629696f496c453), W64LIT(0xc60945454c451283), W64LIT(0xced7fcfc2bfcb332), W64LIT(0xda1941415841329b), + W64LIT(0x7e4812125a12906c), W64LIT(0x23340d0d390d682e), W64LIT(0x72f979798079ef0b), W64LIT(0x81b3e5e556e57b64), + W64LIT(0x981e898997893c11), W64LIT(0x830a8c8c868c140f), W64LIT(0x93abe3e348e34b70), W64LIT(0xe0802020a0201dc0), + W64LIT(0x90c03030f0309da0), W64LIT(0x2e57dcdc8bdcaef2), W64LIT(0x22e6b7b751b7d195), W64LIT(0x19ad6c6cc16c4775), + W64LIT(0xeb354a4a7f4a6aa1), W64LIT(0x2ceeb5b55bb5c199), W64LIT(0xbdfc3f3fc33fe582), W64LIT(0xc2669797f197cc55), + W64LIT(0x1677d4d4a3d4eec2), W64LIT(0x33956262f7623751), W64LIT(0xc3b42d2d992d75ee), W64LIT(0x121806061e063014), + W64LIT(0x5baaa4a40ea449ff), W64LIT(0x5caea5a50ba541f9), W64LIT(0xae368383b5836c2d), W64LIT(0x80615f5f3e5fc2df), + W64LIT(0xd6a82a2a822a4dfc), W64LIT(0x3c4fdada95da9ee6), W64LIT(0x4503c9c9cac9068c), W64LIT(0x0000000000000000), + W64LIT(0x67e57e7e9b7ed719), W64LIT(0x49b2a2a210a279eb), W64LIT(0xb64955551c5592e3), W64LIT(0x1ac6bfbf79bf91a5), + W64LIT(0x7744111155118866), W64LIT(0x1173d5d5a6d5e6c4), W64LIT(0xf34a9c9cd69c946f), W64LIT(0x571bcfcfd4cf3698), + W64LIT(0x2a380e0e360e7024), W64LIT(0x36280a0a220a503c), W64LIT(0xb3f43d3dc93df58e), W64LIT(0xaa5951510851b2fb), + W64LIT(0x6ee97d7d947dcf13), W64LIT(0xde769393e593ec4d), W64LIT(0x416c1b1b771bd85a), W64LIT(0xc0dffefe21fea33e), + W64LIT(0x6637c4c4f3c46ea2), W64LIT(0xc80147474647028f), W64LIT(0x3f2409092d094836), W64LIT(0xb5228686a4864433), + W64LIT(0x312c0b0b270b583a), W64LIT(0x8a068f8f898f0c05), W64LIT(0xf44e9d9dd39d9c69), W64LIT(0x0bb56a6adf6a7761), + W64LIT(0x151c07071b073812), W64LIT(0x08deb9b967b9a1b1), W64LIT(0x37fab0b04ab0e987), W64LIT(0xef5a9898c298b477), + W64LIT(0x486018187818c050), W64LIT(0x9ec83232fa328dac), W64LIT(0x4ad97171a871af3b), W64LIT(0xec314b4b7a4b62a7), + W64LIT(0xb79befef74ef2b58), W64LIT(0xa1ec3b3bd73bc59a), W64LIT(0x4ddd7070ad70a73d), W64LIT(0x47baa0a01aa069e7), + W64LIT(0x86b7e4e453e47362), W64LIT(0xdd1d40405d403a9d), W64LIT(0xc7dbffff24ffab38), W64LIT(0x732bc3c3e8c356b0), + W64LIT(0x789ea9a937a921d1), W64LIT(0x88bfe6e659e6636e), W64LIT(0x75fd78788578e70d), W64LIT(0xd5c3f9f93af99b2c), + W64LIT(0x96168b8b9d8b2c1d), W64LIT(0xcf05464643460a89), W64LIT(0xa73a8080ba807427), W64LIT(0x5a781e1e661ef044), + W64LIT(0xa8e03838d838dd90), W64LIT(0x9da3e1e142e15b7c), W64LIT(0x0fdab8b862b8a9b7), W64LIT(0x7f9aa8a832a829d7), + W64LIT(0x9aa7e0e047e0537a), W64LIT(0x24300c0c3c0c6028), W64LIT(0xe98c2323af2305ca), W64LIT(0x5fc57676b3769729), + W64LIT(0x53741d1d691de84e), W64LIT(0xfb942525b12535de), W64LIT(0xfc902424b4243dd8), W64LIT(0x1b1405051105281e), + W64LIT(0xede3f1f112f1db1c), W64LIT(0x17a56e6ecb6e5779), W64LIT(0xcb6a9494fe94d45f), W64LIT(0xd8a0282888285df0), + W64LIT(0xe1529a9ac89aa47b), W64LIT(0xbb2a8484ae84543f), W64LIT(0xa287e8e86fe8134a), W64LIT(0x4eb6a3a315a371ed), + W64LIT(0xf0214f4f6e4f42bf), W64LIT(0x58c17777b6779f2f), W64LIT(0x036bd3d3b8d3d6d0), W64LIT(0xbc2e8585ab855c39), + W64LIT(0x94afe2e24de24376), W64LIT(0xa35552520752aaf1), W64LIT(0xe4eff2f21df2c316), W64LIT(0xa9328282b082642b), + W64LIT(0xad5d50500d50bafd), W64LIT(0x7bf57a7a8f7af701), W64LIT(0xcdbc2f2f932f65e2), W64LIT(0x51cd7474b9748725), + W64LIT(0xa45153530253a2f7), W64LIT(0x3ef6b3b345b3f18d), W64LIT(0x3a996161f8612f5b), W64LIT(0x6a86afaf29af11c5), + W64LIT(0xafe43939dd39d596), W64LIT(0x8bd43535e135b5be), W64LIT(0x205fdede81debefe), W64LIT(0x5913cdcddecd2694), + W64LIT(0x5d7c1f1f631ff842), W64LIT(0xe85e9999c799bc71), W64LIT(0x638aacac26ac09cf), W64LIT(0x648eadad23ad01c9), + W64LIT(0x43d57272a772b731), W64LIT(0xc4b02c2c9c2c7de8), W64LIT(0x2953dddd8edda6f4), W64LIT(0x0a67d0d0b7d0ceda), + W64LIT(0xb2268787a1874c35), W64LIT(0x1dc2bebe7cbe99a3), W64LIT(0x87655e5e3b5ecad9), W64LIT(0x55a2a6a604a659f3), + W64LIT(0xbe97ecec7bec3352), W64LIT(0x1c10040414042018), W64LIT(0x683fc6c6f9c67eae), W64LIT(0x090c03030f03180a), + W64LIT(0x8cd03434e434bdb8), W64LIT(0xdbcbfbfb30fb8b20), W64LIT(0x3b4bdbdb90db96e0), W64LIT(0x927959592059f2cb), + W64LIT(0x25e2b6b654b6d993), W64LIT(0x742fc2c2edc25eb6), W64LIT(0x0704010105010806), W64LIT(0xeae7f0f017f0d31a), + W64LIT(0x9b755a5a2f5aeac1), W64LIT(0xb993eded7eed3b54), W64LIT(0x52a6a7a701a751f5), W64LIT(0x2f856666e3661749), + W64LIT(0xe7842121a52115c6), W64LIT(0x60e17f7f9e7fdf1f), W64LIT(0x91128a8a988a241b), W64LIT(0xf59c2727bb2725d2), + W64LIT(0x6f3bc7c7fcc776a8), W64LIT(0x7a27c0c0e7c04eba), W64LIT(0xdfa429298d2955f6), W64LIT(0x1f7bd7d7acd7f6c8) + }, + { + W64LIT(0x769393e593ec4dde), W64LIT(0x43d9d99ad986ec35), W64LIT(0x529a9ac89aa47be1), W64LIT(0xeeb5b55bb5c1992c), + W64LIT(0x5a9898c298b477ef), W64LIT(0x882222aa220dccee), W64LIT(0x0945454c451283c6), W64LIT(0xd7fcfc2bfcb332ce), + W64LIT(0xd2baba68bab9bb01), W64LIT(0xb56a6adf6a77610b), W64LIT(0x5bdfdf84dfb6f827), W64LIT(0x0802020a02100c0e), + W64LIT(0x469f9fd99f8c65fa), W64LIT(0x57dcdc8bdcaef22e), W64LIT(0x5951510851b2fbaa), W64LIT(0x7959592059f2cb92), + W64LIT(0x354a4a7f4a6aa1eb), W64LIT(0x5c17174b17b87265), W64LIT(0xac2b2b872b45fad1), W64LIT(0x2fc2c2edc25eb674), + W64LIT(0x6a9494fe94d45fcb), W64LIT(0xf7f4f403f4f302f6), W64LIT(0xd6bbbb6dbbb1bd06), W64LIT(0xb6a3a315a371ed4e), + W64LIT(0x956262f762375133), W64LIT(0xb7e4e453e4736286), W64LIT(0xd97171a871af3b4a), W64LIT(0x77d4d4a3d4eec216), + W64LIT(0x13cdcddecd269459), W64LIT(0xdd7070ad70a73d4d), W64LIT(0x5816164e16b07462), W64LIT(0xa3e1e142e15b7c9d), + W64LIT(0x394949704972abe2), W64LIT(0xf03c3ccc3cfd88b4), W64LIT(0x27c0c0e7c04eba7a), W64LIT(0x47d8d89fd88eea32), + W64LIT(0x6d5c5c315cdad589), W64LIT(0x569b9bcd9bac7de6), W64LIT(0x8eadad23ad01c964), W64LIT(0x2e8585ab855c39bc), + W64LIT(0x5153530253a2f7a4), W64LIT(0xbea1a11fa161e140), W64LIT(0xf57a7a8f7af7017b), W64LIT(0x07c8c8cfc80e8a42), + W64LIT(0xb42d2d992d75eec3), W64LIT(0xa7e0e047e0537a9a), W64LIT(0x63d1d1b2d1c6dc0d), W64LIT(0xd57272a772b73143), + W64LIT(0xa2a6a604a659f355), W64LIT(0xb02c2c9c2c7de8c4), W64LIT(0x37c4c4f3c46ea266), W64LIT(0xabe3e348e34b7093), + W64LIT(0xc57676b37697295f), W64LIT(0xfd78788578e70d75), W64LIT(0xe6b7b751b7d19522), W64LIT(0xeab4b45eb4c99f2b), + W64LIT(0x2409092d0948363f), W64LIT(0xec3b3bd73bc59aa1), W64LIT(0x380e0e360e70242a), W64LIT(0x1941415841329bda), + W64LIT(0x2d4c4c614c5ab5f9), W64LIT(0x5fdede81debefe20), W64LIT(0xf2b2b240b2f98b39), W64LIT(0x7a9090ea90f447d7), + W64LIT(0x942525b12535defb), W64LIT(0xaea5a50ba541f95c), W64LIT(0x7bd7d7acd7f6c81f), W64LIT(0x0c03030f03180a09), + W64LIT(0x4411115511886677), W64LIT(0x0000000000000000), W64LIT(0x2bc3c3e8c356b073), W64LIT(0xb82e2e962e6de4ca), + W64LIT(0x729292e092e44bd9), W64LIT(0x9befef74ef2b58b7), W64LIT(0x254e4e6b4e4ab9f7), W64LIT(0x4812125a12906c7e), + W64LIT(0x4e9d9dd39d9c69f4), W64LIT(0xe97d7d947dcf136e), W64LIT(0x0bcbcbc0cb16804b), W64LIT(0xd43535e135b5be8b), + W64LIT(0x4010105010806070), W64LIT(0x73d5d5a6d5e6c411), W64LIT(0x214f4f6e4f42bff0), W64LIT(0x429e9edc9e8463fd), + W64LIT(0x294d4d644d52b3fe), W64LIT(0x9ea9a937a921d178), W64LIT(0x4955551c5592e3b6), W64LIT(0x3fc6c6f9c67eae68), + W64LIT(0x67d0d0b7d0ceda0a), W64LIT(0xf17b7b8a7bff077c), W64LIT(0x6018187818c05048), W64LIT(0x669797f197cc55c2), + W64LIT(0x6bd3d3b8d3d6d003), W64LIT(0xd83636ee36adb482), W64LIT(0xbfe6e659e6636e88), W64LIT(0x3d484875487aade5), + W64LIT(0x45565613568ae9bf), W64LIT(0x3e8181bf817c21a0), W64LIT(0x068f8f898f0c058a), W64LIT(0xc17777b6779f2f58), + W64LIT(0x17ccccdbcc2e925e), W64LIT(0x4a9c9cd69c946ff3), W64LIT(0xdeb9b967b9a1b108), W64LIT(0xafe2e24de2437694), + W64LIT(0x8aacac26ac09cf63), W64LIT(0xdab8b862b8a9b70f), W64LIT(0xbc2f2f932f65e2cd), W64LIT(0x5415154115a87e6b), + W64LIT(0xaaa4a40ea449ff5b), W64LIT(0xed7c7c917cc71569), W64LIT(0x4fdada95da9ee63c), W64LIT(0xe03838d838dd90a8), + W64LIT(0x781e1e661ef0445a), W64LIT(0x2c0b0b270b583a31), W64LIT(0x1405051105281e1b), W64LIT(0x7fd6d6a9d6fece18), + W64LIT(0x5014144414a0786c), W64LIT(0xa56e6ecb6e577917), W64LIT(0xad6c6cc16c477519), W64LIT(0xe57e7e9b7ed71967), + W64LIT(0x856666e36617492f), W64LIT(0xd3fdfd2efdbb34c9), W64LIT(0xfeb1b14fb1e18130), W64LIT(0xb3e5e556e57b6481), + W64LIT(0x9d6060fd60275d3d), W64LIT(0x86afaf29af11c56a), W64LIT(0x655e5e3b5ecad987), W64LIT(0xcc3333ff3385aa99), + W64LIT(0x268787a1874c35b2), W64LIT(0x03c9c9cac9068c45), W64LIT(0xe7f0f017f0d31aea), W64LIT(0x695d5d345dd2d38e), + W64LIT(0xa96d6dc46d4f731e), W64LIT(0xfc3f3fc33fe582bd), W64LIT(0x1a8888928834179f), W64LIT(0x0e8d8d838d1c0984), + W64LIT(0x3bc7c7fcc776a86f), W64LIT(0xfbf7f70cf7eb08ff), W64LIT(0x741d1d691de84e53), W64LIT(0x83e9e96ae91b4ca5), + W64LIT(0x97ecec7bec3352be), W64LIT(0x93eded7eed3b54b9), W64LIT(0x3a8080ba807427a7), W64LIT(0xa429298d2955f6df), + W64LIT(0x9c2727bb2725d2f5), W64LIT(0x1bcfcfd4cf369857), W64LIT(0x5e9999c799bc71e8), W64LIT(0x9aa8a832a829d77f), + W64LIT(0x5d50500d50bafdad), W64LIT(0x3c0f0f330f78222d), W64LIT(0xdc3737eb37a5b285), W64LIT(0x902424b4243dd8fc), + W64LIT(0xa0282888285df0d8), W64LIT(0xc03030f0309da090), W64LIT(0x6e9595fb95dc59cc), W64LIT(0x6fd2d2bdd2ded604), + W64LIT(0xf83e3ec63eed84ba), W64LIT(0x715b5b2a5be2c79c), W64LIT(0x1d40405d403a9ddd), W64LIT(0x368383b5836c2dae), + W64LIT(0xf6b3b345b3f18d3e), W64LIT(0xb96969d0696f6b02), W64LIT(0x415757165782efb8), W64LIT(0x7c1f1f631ff8425d), + W64LIT(0x1c07071b07381215), W64LIT(0x701c1c6c1ce04854), W64LIT(0x128a8a988a241b91), W64LIT(0xcabcbc76bc89af13), + W64LIT(0x802020a0201dc0e0), W64LIT(0x8bebeb60eb0b40ab), W64LIT(0x1fceced1ce3e9e50), W64LIT(0x028e8e8c8e04038d), + W64LIT(0x96abab3dab31dd76), W64LIT(0x9feeee71ee235eb0), W64LIT(0xc43131f53195a697), W64LIT(0xb2a2a210a279eb49), + W64LIT(0xd17373a273bf3744), W64LIT(0xc3f9f93af99b2cd5), W64LIT(0x0fcacac5ca1e864c), W64LIT(0xe83a3ad23acd9ca6), + W64LIT(0x681a1a721ad05c46), W64LIT(0xcbfbfb30fb8b20db), W64LIT(0x340d0d390d682e23), W64LIT(0x23c1c1e2c146bc7d), + W64LIT(0xdffefe21fea33ec0), W64LIT(0xcffafa35fa8326dc), W64LIT(0xeff2f21df2c316e4), W64LIT(0xa16f6fce6f5f7f10), + W64LIT(0xcebdbd73bd81a914), W64LIT(0x629696f496c453c5), W64LIT(0x53dddd8edda6f429), W64LIT(0x11434352432297d4), + W64LIT(0x5552520752aaf1a3), W64LIT(0xe2b6b654b6d99325), W64LIT(0x2008082808403038), W64LIT(0xebf3f318f3cb10e3), + W64LIT(0x82aeae2cae19c36d), W64LIT(0xc2bebe7cbe99a31d), W64LIT(0x6419197d19c8564f), W64LIT(0x1e898997893c1198), + W64LIT(0xc83232fa328dac9e), W64LIT(0x982626be262dd4f2), W64LIT(0xfab0b04ab0e98737), W64LIT(0x8feaea65ea0346ac), + W64LIT(0x314b4b7a4b62a7ec), W64LIT(0x8d6464e964074521), W64LIT(0x2a8484ae84543fbb), W64LIT(0x328282b082642ba9), + W64LIT(0xb16b6bda6b7f670c), W64LIT(0xf3f5f506f5fb04f1), W64LIT(0xf979798079ef0b72), W64LIT(0xc6bfbf79bf91a51a), + W64LIT(0x0401010501080607), W64LIT(0x615f5f3e5fc2df80), W64LIT(0xc97575bc758f2356), W64LIT(0x916363f2633f5734), + W64LIT(0x6c1b1b771bd85a41), W64LIT(0x8c2323af2305cae9), W64LIT(0xf43d3dc93df58eb3), W64LIT(0xbd6868d568676d05), + W64LIT(0xa82a2a822a4dfcd6), W64LIT(0x896565ec650f4326), W64LIT(0x87e8e86fe8134aa2), W64LIT(0x7e9191ef91fc41d0), + W64LIT(0xfff6f609f6e30ef8), W64LIT(0xdbffff24ffab38c7), W64LIT(0x4c13135f13986a79), W64LIT(0x7d58582558facd95), + W64LIT(0xe3f1f112f1db1ced), W64LIT(0x0147474647028fc8), W64LIT(0x280a0a220a503c36), W64LIT(0xe17f7f9e7fdf1f60), + W64LIT(0x33c5c5f6c566a461), W64LIT(0xa6a7a701a751f552), W64LIT(0xbbe7e75ce76b688f), W64LIT(0x996161f8612f5b3a), + W64LIT(0x755a5a2f5aeac19b), W64LIT(0x1806061e06301412), W64LIT(0x05464643460a89cf), W64LIT(0x0d444449441a85c1), + W64LIT(0x15424257422a91d3), W64LIT(0x100404140420181c), W64LIT(0xbaa0a01aa069e747), W64LIT(0x4bdbdb90db96e03b), + W64LIT(0xe43939dd39d596af), W64LIT(0x228686a4864433b5), W64LIT(0x4d545419549ae5b1), W64LIT(0x92aaaa38aa39db71), + W64LIT(0x0a8c8c868c140f83), W64LIT(0xd03434e434bdb88c), W64LIT(0x842121a52115c6e7), W64LIT(0x168b8b9d8b2c1d96), + W64LIT(0xc7f8f83ff8932ad2), W64LIT(0x300c0c3c0c602824), W64LIT(0xcd7474b974872551), W64LIT(0x816767e6671f4f28) + }, + { + W64LIT(0x6868d568676d05bd), W64LIT(0x8d8d838d1c09840e), W64LIT(0xcacac5ca1e864c0f), W64LIT(0x4d4d644d52b3fe29), + W64LIT(0x7373a273bf3744d1), W64LIT(0x4b4b7a4b62a7ec31), W64LIT(0x4e4e6b4e4ab9f725), W64LIT(0x2a2a822a4dfcd6a8), + W64LIT(0xd4d4a3d4eec21677), W64LIT(0x52520752aaf1a355), W64LIT(0x2626be262dd4f298), W64LIT(0xb3b345b3f18d3ef6), + W64LIT(0x545419549ae5b14d), W64LIT(0x1e1e661ef0445a78), W64LIT(0x19197d19c8564f64), W64LIT(0x1f1f631ff8425d7c), + W64LIT(0x2222aa220dccee88), W64LIT(0x03030f03180a090c), W64LIT(0x464643460a89cf05), W64LIT(0x3d3dc93df58eb3f4), + W64LIT(0x2d2d992d75eec3b4), W64LIT(0x4a4a7f4a6aa1eb35), W64LIT(0x53530253a2f7a451), W64LIT(0x8383b5836c2dae36), + W64LIT(0x13135f13986a794c), W64LIT(0x8a8a988a241b9112), W64LIT(0xb7b751b7d19522e6), W64LIT(0xd5d5a6d5e6c41173), + W64LIT(0x2525b12535defb94), W64LIT(0x79798079ef0b72f9), W64LIT(0xf5f506f5fb04f1f3), W64LIT(0xbdbd73bd81a914ce), + W64LIT(0x58582558facd957d), W64LIT(0x2f2f932f65e2cdbc), W64LIT(0x0d0d390d682e2334), W64LIT(0x02020a02100c0e08), + W64LIT(0xeded7eed3b54b993), W64LIT(0x51510851b2fbaa59), W64LIT(0x9e9edc9e8463fd42), W64LIT(0x1111551188667744), + W64LIT(0xf2f21df2c316e4ef), W64LIT(0x3e3ec63eed84baf8), W64LIT(0x55551c5592e3b649), W64LIT(0x5e5e3b5ecad98765), + W64LIT(0xd1d1b2d1c6dc0d63), W64LIT(0x16164e16b0746258), W64LIT(0x3c3ccc3cfd88b4f0), W64LIT(0x6666e36617492f85), + W64LIT(0x7070ad70a73d4ddd), W64LIT(0x5d5d345dd2d38e69), W64LIT(0xf3f318f3cb10e3eb), W64LIT(0x45454c451283c609), + W64LIT(0x40405d403a9ddd1d), W64LIT(0xccccdbcc2e925e17), W64LIT(0xe8e86fe8134aa287), W64LIT(0x9494fe94d45fcb6a), + W64LIT(0x565613568ae9bf45), W64LIT(0x0808280840303820), W64LIT(0xceced1ce3e9e501f), W64LIT(0x1a1a721ad05c4668), + W64LIT(0x3a3ad23acd9ca6e8), W64LIT(0xd2d2bdd2ded6046f), W64LIT(0xe1e142e15b7c9da3), W64LIT(0xdfdf84dfb6f8275b), + W64LIT(0xb5b55bb5c1992cee), W64LIT(0x3838d838dd90a8e0), W64LIT(0x6e6ecb6e577917a5), W64LIT(0x0e0e360e70242a38), + W64LIT(0xe5e556e57b6481b3), W64LIT(0xf4f403f4f302f6f7), W64LIT(0xf9f93af99b2cd5c3), W64LIT(0x8686a4864433b522), + W64LIT(0xe9e96ae91b4ca583), W64LIT(0x4f4f6e4f42bff021), W64LIT(0xd6d6a9d6fece187f), W64LIT(0x8585ab855c39bc2e), + W64LIT(0x2323af2305cae98c), W64LIT(0xcfcfd4cf3698571b), W64LIT(0x3232fa328dac9ec8), W64LIT(0x9999c799bc71e85e), + W64LIT(0x3131f53195a697c4), W64LIT(0x14144414a0786c50), W64LIT(0xaeae2cae19c36d82), W64LIT(0xeeee71ee235eb09f), + W64LIT(0xc8c8cfc80e8a4207), W64LIT(0x484875487aade53d), W64LIT(0xd3d3b8d3d6d0036b), W64LIT(0x3030f0309da090c0), + W64LIT(0xa1a11fa161e140be), W64LIT(0x9292e092e44bd972), W64LIT(0x41415841329bda19), W64LIT(0xb1b14fb1e18130fe), + W64LIT(0x18187818c0504860), W64LIT(0xc4c4f3c46ea26637), W64LIT(0x2c2c9c2c7de8c4b0), W64LIT(0x7171a871af3b4ad9), + W64LIT(0x7272a772b73143d5), W64LIT(0x444449441a85c10d), W64LIT(0x15154115a87e6b54), W64LIT(0xfdfd2efdbb34c9d3), + W64LIT(0x3737eb37a5b285dc), W64LIT(0xbebe7cbe99a31dc2), W64LIT(0x5f5f3e5fc2df8061), W64LIT(0xaaaa38aa39db7192), + W64LIT(0x9b9bcd9bac7de656), W64LIT(0x8888928834179f1a), W64LIT(0xd8d89fd88eea3247), W64LIT(0xabab3dab31dd7696), + W64LIT(0x898997893c11981e), W64LIT(0x9c9cd69c946ff34a), W64LIT(0xfafa35fa8326dccf), W64LIT(0x6060fd60275d3d9d), + W64LIT(0xeaea65ea0346ac8f), W64LIT(0xbcbc76bc89af13ca), W64LIT(0x6262f76237513395), W64LIT(0x0c0c3c0c60282430), + W64LIT(0x2424b4243dd8fc90), W64LIT(0xa6a604a659f355a2), W64LIT(0xa8a832a829d77f9a), W64LIT(0xecec7bec3352be97), + W64LIT(0x6767e6671f4f2881), W64LIT(0x2020a0201dc0e080), W64LIT(0xdbdb90db96e03b4b), W64LIT(0x7c7c917cc71569ed), + W64LIT(0x282888285df0d8a0), W64LIT(0xdddd8edda6f42953), W64LIT(0xacac26ac09cf638a), W64LIT(0x5b5b2a5be2c79c71), + W64LIT(0x3434e434bdb88cd0), W64LIT(0x7e7e9b7ed71967e5), W64LIT(0x1010501080607040), W64LIT(0xf1f112f1db1cede3), + W64LIT(0x7b7b8a7bff077cf1), W64LIT(0x8f8f898f0c058a06), W64LIT(0x6363f2633f573491), W64LIT(0xa0a01aa069e747ba), + W64LIT(0x05051105281e1b14), W64LIT(0x9a9ac89aa47be152), W64LIT(0x434352432297d411), W64LIT(0x7777b6779f2f58c1), + W64LIT(0x2121a52115c6e784), W64LIT(0xbfbf79bf91a51ac6), W64LIT(0x2727bb2725d2f59c), W64LIT(0x09092d0948363f24), + W64LIT(0xc3c3e8c356b0732b), W64LIT(0x9f9fd99f8c65fa46), W64LIT(0xb6b654b6d99325e2), W64LIT(0xd7d7acd7f6c81f7b), + W64LIT(0x29298d2955f6dfa4), W64LIT(0xc2c2edc25eb6742f), W64LIT(0xebeb60eb0b40ab8b), W64LIT(0xc0c0e7c04eba7a27), + W64LIT(0xa4a40ea449ff5baa), W64LIT(0x8b8b9d8b2c1d9616), W64LIT(0x8c8c868c140f830a), W64LIT(0x1d1d691de84e5374), + W64LIT(0xfbfb30fb8b20dbcb), W64LIT(0xffff24ffab38c7db), W64LIT(0xc1c1e2c146bc7d23), W64LIT(0xb2b240b2f98b39f2), + W64LIT(0x9797f197cc55c266), W64LIT(0x2e2e962e6de4cab8), W64LIT(0xf8f83ff8932ad2c7), W64LIT(0x6565ec650f432689), + W64LIT(0xf6f609f6e30ef8ff), W64LIT(0x7575bc758f2356c9), W64LIT(0x07071b073812151c), W64LIT(0x0404140420181c10), + W64LIT(0x4949704972abe239), W64LIT(0x3333ff3385aa99cc), W64LIT(0xe4e453e4736286b7), W64LIT(0xd9d99ad986ec3543), + W64LIT(0xb9b967b9a1b108de), W64LIT(0xd0d0b7d0ceda0a67), W64LIT(0x424257422a91d315), W64LIT(0xc7c7fcc776a86f3b), + W64LIT(0x6c6cc16c477519ad), W64LIT(0x9090ea90f447d77a), W64LIT(0x0000000000000000), W64LIT(0x8e8e8c8e04038d02), + W64LIT(0x6f6fce6f5f7f10a1), W64LIT(0x50500d50bafdad5d), W64LIT(0x0101050108060704), W64LIT(0xc5c5f6c566a46133), + W64LIT(0xdada95da9ee63c4f), W64LIT(0x47474647028fc801), W64LIT(0x3f3fc33fe582bdfc), W64LIT(0xcdcddecd26945913), + W64LIT(0x6969d0696f6b02b9), W64LIT(0xa2a210a279eb49b2), W64LIT(0xe2e24de2437694af), W64LIT(0x7a7a8f7af7017bf5), + W64LIT(0xa7a701a751f552a6), W64LIT(0xc6c6f9c67eae683f), W64LIT(0x9393e593ec4dde76), W64LIT(0x0f0f330f78222d3c), + W64LIT(0x0a0a220a503c3628), W64LIT(0x06061e0630141218), W64LIT(0xe6e659e6636e88bf), W64LIT(0x2b2b872b45fad1ac), + W64LIT(0x9696f496c453c562), W64LIT(0xa3a315a371ed4eb6), W64LIT(0x1c1c6c1ce0485470), W64LIT(0xafaf29af11c56a86), + W64LIT(0x6a6adf6a77610bb5), W64LIT(0x12125a12906c7e48), W64LIT(0x8484ae84543fbb2a), W64LIT(0x3939dd39d596afe4), + W64LIT(0xe7e75ce76b688fbb), W64LIT(0xb0b04ab0e98737fa), W64LIT(0x8282b082642ba932), W64LIT(0xf7f70cf7eb08fffb), + W64LIT(0xfefe21fea33ec0df), W64LIT(0x9d9dd39d9c69f44e), W64LIT(0x8787a1874c35b226), W64LIT(0x5c5c315cdad5896d), + W64LIT(0x8181bf817c21a03e), W64LIT(0x3535e135b5be8bd4), W64LIT(0xdede81debefe205f), W64LIT(0xb4b45eb4c99f2bea), + W64LIT(0xa5a50ba541f95cae), W64LIT(0xfcfc2bfcb332ced7), W64LIT(0x8080ba807427a73a), W64LIT(0xefef74ef2b58b79b), + W64LIT(0xcbcbc0cb16804b0b), W64LIT(0xbbbb6dbbb1bd06d6), W64LIT(0x6b6bda6b7f670cb1), W64LIT(0x7676b37697295fc5), + W64LIT(0xbaba68bab9bb01d2), W64LIT(0x5a5a2f5aeac19b75), W64LIT(0x7d7d947dcf136ee9), W64LIT(0x78788578e70d75fd), + W64LIT(0x0b0b270b583a312c), W64LIT(0x9595fb95dc59cc6e), W64LIT(0xe3e348e34b7093ab), W64LIT(0xadad23ad01c9648e), + W64LIT(0x7474b974872551cd), W64LIT(0x9898c298b477ef5a), W64LIT(0x3b3bd73bc59aa1ec), W64LIT(0x3636ee36adb482d8), + W64LIT(0x6464e9640745218d), W64LIT(0x6d6dc46d4f731ea9), W64LIT(0xdcdc8bdcaef22e57), W64LIT(0xf0f017f0d31aeae7), + W64LIT(0x59592059f2cb9279), W64LIT(0xa9a937a921d1789e), W64LIT(0x4c4c614c5ab5f92d), W64LIT(0x17174b17b872655c), + W64LIT(0x7f7f9e7fdf1f60e1), W64LIT(0x9191ef91fc41d07e), W64LIT(0xb8b862b8a9b70fda), W64LIT(0xc9c9cac9068c4503), + W64LIT(0x5757165782efb841), W64LIT(0x1b1b771bd85a416c), W64LIT(0xe0e047e0537a9aa7), W64LIT(0x6161f8612f5b3a99) + } +}; + +const word64 IT[8][256] = +{ + { + W64LIT(0x7826942b9f5f8a9a), W64LIT(0x210f43c934970c53), W64LIT(0x5f028fdd9d0551b8), W64LIT(0x14facd82b494c83b), + W64LIT(0x2b72ab886edd68c0), W64LIT(0xa6a87e5bff19d9b4), W64LIT(0xa29ae571db6443ea), W64LIT(0x039b2c911be8e5b6), + W64LIT(0xd9275dcb5fd32cc6), W64LIT(0x10c856a890e95265), W64LIT(0x7d96e085b27ab85d), W64LIT(0x31c71561a47e5e36), + W64LIT(0x74702455f3d83978), W64LIT(0xe8e048aafbad72f0), W64LIT(0x9b39db4437e03460), W64LIT(0x75f2cbd1fa8091e1), + W64LIT(0x1ab5bee9caa336f6), W64LIT(0x8395a6b8eff34fb9), W64LIT(0x64b872fd63316b1d), W64LIT(0xe1068c7aba0ff3d5), + W64LIT(0xeecb1095cd60a581), W64LIT(0xbc1dc0b235baef42), W64LIT(0xf04c355623be0929), W64LIT(0xb252b3d94b8d118f), + W64LIT(0x18ac7dfcd8137bd9), W64LIT(0xbbb477090a2f90aa), W64LIT(0x8625d216c2d67d7e), W64LIT(0x66a1b1e871812632), + W64LIT(0x6f4775383023a717), W64LIT(0x92df1f947642b545), W64LIT(0xe962a72ef2f5da69), W64LIT(0x8bf18deca7096605), + W64LIT(0xc86de4e7c662d63a), W64LIT(0xaafece25939e6a56), W64LIT(0x5c99a34c86edb40e), W64LIT(0x52d6d027f8da4ac3), + W64LIT(0x6b75ee12145e3d49), W64LIT(0x54fd8818ce179db2), W64LIT(0xa3180af5d23ceb73), W64LIT(0xbe0403a7270aa26d), + W64LIT(0xfe03463d5d89f7e4), W64LIT(0xf1cedad22ae6a1b0), W64LIT(0xd143769f1729057a), W64LIT(0xc7a07808b10d806e), + W64LIT(0xfc1a85284f39bacb), W64LIT(0xa4b1bd4eeda9949b), W64LIT(0x0bff07c55312cc0a), W64LIT(0xef49ff11c4380d18), + W64LIT(0xc392e32295701a30), W64LIT(0x7f8f2390a0caf572), W64LIT(0x62932ac255fcbc6c), W64LIT(0xc9ef0b63cf3a7ea3), + W64LIT(0xf9aaf186621c880c), W64LIT(0x818c65adfd430296), W64LIT(0x325c39f0bf96bb80), W64LIT(0x0c56b07e6c87b3e2), + W64LIT(0x4bf8425f29919983), W64LIT(0xb5fb046274186e67), W64LIT(0x462c1da54c4e82f8), W64LIT(0x90c6dc8164f2f86a), + W64LIT(0xf8281e026b442095), W64LIT(0x6af701961d0695d0), W64LIT(0x5766a489d5ff7804), W64LIT(0xf3d719c73856ec9f), + W64LIT(0xad57799eac0b15be), W64LIT(0x1b37516dc3fb9e6f), W64LIT(0xc009cfb38e98ff86), W64LIT(0x9576a82f49d7caad), + W64LIT(0xe6af3bc1859a8c3d), W64LIT(0x208dac4d3dcfa4ca), W64LIT(0x8ddad5d391c4b174), W64LIT(0x8e41f9428a2c54c2), + W64LIT(0x6cdc59a92bcb42a1), W64LIT(0xe53417509e72698b), W64LIT(0xd0c1991b1e71ade3), W64LIT(0x8217493ce6abe720), + W64LIT(0xd4f302313a0c37bd), W64LIT(0x5e806059945df921), W64LIT(0x73d993eecc4d4690), W64LIT(0xf5fc41f80e9b3bee), + W64LIT(0x13537a398b01b7d3), W64LIT(0x53543fa3f182e25a), W64LIT(0x2d59f3b75810bfb1), W64LIT(0x35f58e4b8003c468), + W64LIT(0x886aa17dbce183b3), W64LIT(0x4c51f5e41604e66b), W64LIT(0x98a2f7d52c08d1d6), W64LIT(0xa101c9e0c08ca65c), + W64LIT(0x4007459a7a835589), W64LIT(0xcc5f7fcde21f4c64), W64LIT(0xa965e2b488768fe0), W64LIT(0x12d195bd82591f4a), + W64LIT(0x2f4030a24aa0f29e), W64LIT(0x56e44b0ddca7d09d), W64LIT(0x914433056daa50f3), W64LIT(0x37ec4d5e92b38947), + W64LIT(0xe31f4f6fa8bfbefa), W64LIT(0x50cf1332ea6a07ec), W64LIT(0x6d5eb62d2293ea38), W64LIT(0x09e6c4d041a28125), + W64LIT(0x8fc316c68374fc5b), W64LIT(0x421e868f683318a6), W64LIT(0xe08463feb3575b4c), W64LIT(0x3821d1b1e5dcdf13), + W64LIT(0xed503c04d6884037), W64LIT(0xd35ab58a05994855), W64LIT(0x976f6b3a5b678782), W64LIT(0x6ec59abc397b0f8e), + W64LIT(0x5929d7e2abc886c9), W64LIT(0xa53352cae4f13c02), W64LIT(0x89e84ef9b5b92b2a), W64LIT(0x1761e113af7c2d8d), + W64LIT(0x28e9871975358d76), W64LIT(0xdc97296572f61e01), W64LIT(0x67235e6c78d98eab), W64LIT(0x3d91a51fc8f9edd4), + W64LIT(0x68eec2830fb6d8ff), W64LIT(0xfbb3329370acc523), W64LIT(0x062b583f36cdd771), W64LIT(0x15782206bdcc60a2), + W64LIT(0x16e30e97a6248514), W64LIT(0x79a47baf96072203), W64LIT(0xf7e582ed1c2b76c1), W64LIT(0xde8eea706046532e), + W64LIT(0xaf4eba8bbebb5891), W64LIT(0x08642b5448fa29bc), W64LIT(0x24bf376719b23e94), W64LIT(0x231680dc2627417c), + W64LIT(0x0dd45ffa65df1b7b), W64LIT(0x1d1c0952f536491e), W64LIT(0xff81a9b954d15f7d), W64LIT(0x992018512550794f), + W64LIT(0x71c050fbdefd0bbf), W64LIT(0xc18b203787c0571f), W64LIT(0x253dd8e310ea960d), W64LIT(0xeb7b643be0459746), + W64LIT(0x0219c31512b04d2f), W64LIT(0xc43b5499aae565d8), W64LIT(0xeaf98bbfe91d3fdf), W64LIT(0x3a3812a4f76c923c), + W64LIT(0x4dd31a601f5c4ef2), W64LIT(0xa8e70d30812e2779), W64LIT(0x800e8a29f41baa0f), W64LIT(0x1c9ee6d6fc6ee187), + W64LIT(0x5d1b4cc88fb51c97), W64LIT(0x610806534e1459da), W64LIT(0xf255f643310e4406), W64LIT(0xd2d85a0e0cc1e0cc), + W64LIT(0x0182ef840958a899), W64LIT(0x7e0dcc14a9925deb), W64LIT(0x653a9d796a69c384), W64LIT(0x4e4836f104b4ab44), + W64LIT(0x4fcad9750dec03dd), W64LIT(0xcddd9049eb47e4fd), W64LIT(0x0e4f736b7e37fecd), W64LIT(0x4185aa1e73dbfd10), + W64LIT(0x725b7c6ac515ee09), W64LIT(0x8a736268ae51ce9c), W64LIT(0xc5b9bb1da3bdcd41), W64LIT(0x7bbdb8ba84b76f2c), + W64LIT(0xdabc715a443bc970), W64LIT(0xe29da0eba1e71663), W64LIT(0x935df0107f1a1ddc), W64LIT(0x608ae9d7474cf143), + W64LIT(0xd571edb533549f24), W64LIT(0xa0832664c9d40ec5), W64LIT(0xfd986aac46611252), W64LIT(0x4435deb05efecfd7), + W64LIT(0x0000000000000000), W64LIT(0x2cdb1c3351481728), W64LIT(0x94f447ab408f6234), W64LIT(0x45b7313457a6674e), + W64LIT(0xb82f5b9811c7751c), W64LIT(0x8c583a57989c19ed), W64LIT(0xdd15c6e17baeb698), W64LIT(0x696c2d0706ee7066), + W64LIT(0x3f88660ada49a0fb), W64LIT(0xf47eae7c07c39377), W64LIT(0x05b074ae2d2532c7), W64LIT(0xb3d05c5d42d5b916), + W64LIT(0x39a33e35ec84778a), W64LIT(0x0fcd9cef776f5654), W64LIT(0xacd5961aa553bd27), W64LIT(0x5b3014f7b978cbe6), + W64LIT(0x347761cf895b6cf1), W64LIT(0xc622978cb85528f7), W64LIT(0xb7e2c77766a82348), W64LIT(0x77eb08c4e830dcce), + W64LIT(0xb9adb41c189fdd85), W64LIT(0x114ab92c99b1fafc), W64LIT(0x26a6f4720b0273bb), W64LIT(0x1e8725c3eedeaca8), + W64LIT(0x2af0440c6785c059), W64LIT(0x04329b2a247d9a5e), W64LIT(0xd7682ea021e4d20b), W64LIT(0x7c140f01bb2210c4), + W64LIT(0x96ed84be523f2f1b), W64LIT(0xca7427f2d4d29b15), W64LIT(0x47aef22145162a61), W64LIT(0xa72a91dff641712d), + W64LIT(0x5ab2fb73b020637f), W64LIT(0xcbf6c876dd8a338c), W64LIT(0x6311c5465ca414f5), W64LIT(0x07a9b7bb3f957fe8), + W64LIT(0xe72dd4458cc224a4), W64LIT(0x9d12837b012de311), W64LIT(0x843c1103d0663051), W64LIT(0x0a7de8415a4a6493), + W64LIT(0xd6eac12428bc7a92), W64LIT(0x9c906cff08754b88), W64LIT(0x7042bf7fd7a5a326), W64LIT(0xbd9f2f363ce247db), + W64LIT(0xb66028f36ff08bd1), W64LIT(0x192e9278d14bd340), W64LIT(0x9f0b406e139dae3e), W64LIT(0x1f05ca47e7860431), + W64LIT(0x85befe87d93e98c8), W64LIT(0x439c690b616bb03f), W64LIT(0xba36988d03773833), W64LIT(0x87a73d92cb8ed5e7), + W64LIT(0xaecc550fb7e3f008), W64LIT(0xc2100ca69c28b2a9), W64LIT(0x9abb34c03eb89cf9), W64LIT(0x49e1814a3b21d4ac), + W64LIT(0xecd2d380dfd0e8ae), W64LIT(0x296b689d7c6d25ef), W64LIT(0x3c134a9bc1a1454d), W64LIT(0xcfc4535cf9f7a9d2), + W64LIT(0x557f679cc74f352b), W64LIT(0xb479ebe67d40c6fe), W64LIT(0xf6676d691573de58), W64LIT(0x9e89afea1ac506a7), + W64LIT(0xd8a5b24f568b845f), W64LIT(0x48636ece32797c35), W64LIT(0xdf0c05f4691efbb7), W64LIT(0xe4b6f8d4972ac112), + W64LIT(0xfa31dd1779f46dba), W64LIT(0xbf86ec232e520af4), W64LIT(0x3e0a898ed3110862), W64LIT(0x7a3f573e8defc7b5), + W64LIT(0x27241bf6025adb22), W64LIT(0x58ab3866a2902e50), W64LIT(0x3bbafd20fe343aa5), W64LIT(0x3045fae5ad26f6af), + W64LIT(0x2ec2df2643f85a07), W64LIT(0x22946f582f7fe9e5), W64LIT(0x366ea2da9beb21de), W64LIT(0x4a7aaddb20c9311a), + W64LIT(0xb1c99f485065f439), W64LIT(0xb04b70cc593d5ca0), W64LIT(0xab7c21a19ac6c2cf), W64LIT(0x33ded674b6ce1319), + W64LIT(0xce46bcd8f0af014b), W64LIT(0xdb3e9ede4d6361e9), W64LIT(0x7669e740e1687457), W64LIT(0x514dfcb6e332af75) + }, + { + W64LIT(0x1f4f6fa8bfbefae3), W64LIT(0xf0440c6785c0592a), W64LIT(0x1dc0b235baef42bc), W64LIT(0x22978cb85528f7c6), + W64LIT(0xcedad22ae6a1b0f1), W64LIT(0x180af5d23ceb73a3), W64LIT(0x946f582f7fe9e522), W64LIT(0xe44b0ddca7d09d56), + W64LIT(0x906cff08754b889c), W64LIT(0x9f2f363ce247dbbd), W64LIT(0xa1b1e87181263266), W64LIT(0x21d1b1e5dcdf1338), + W64LIT(0x31dd1779f46dbafa), W64LIT(0x4b70cc593d5ca0b0), W64LIT(0xd719c73856ec9ff3), W64LIT(0x8725c3eedeaca81e), + W64LIT(0x71edb533549f24d5), W64LIT(0x12837b012de3119d), W64LIT(0x3dd8e310ea960d25), W64LIT(0x29d7e2abc886c959), + W64LIT(0xb477090a2f90aabb), W64LIT(0x45fae5ad26f6af30), W64LIT(0x9ee6d6fc6ee1871c), W64LIT(0xbefe87d93e98c885), + W64LIT(0xe30e97a624851416), W64LIT(0xd6d027f8da4ac352), W64LIT(0xcc550fb7e3f008ae), W64LIT(0x5ab58a05994855d3), + W64LIT(0x806059945df9215e), W64LIT(0x82ef840958a89901), W64LIT(0x4ab92c99b1fafc11), W64LIT(0x281e026b442095f8), + W64LIT(0x62a72ef2f5da69e9), W64LIT(0x8b203787c0571fc1), W64LIT(0x4f736b7e37fecd0e), W64LIT(0xab3866a2902e5058), + W64LIT(0x6ea2da9beb21de36), W64LIT(0xf447ab408f623494), W64LIT(0x235e6c78d98eab67), W64LIT(0x11c5465ca414f563), + W64LIT(0xd31a601f5c4ef24d), W64LIT(0xa2f7d52c08d1d698), W64LIT(0x85aa1e73dbfd1041), W64LIT(0xdc59a92bcb42a16c), + W64LIT(0x59f3b75810bfb12d), W64LIT(0xe2c77766a82348b7), W64LIT(0xb9bb1da3bdcd41c5), W64LIT(0x96e085b27ab85d7d), + W64LIT(0x99a34c86edb40e5c), W64LIT(0x66a489d5ff780457), W64LIT(0x95a6b8eff34fb983), W64LIT(0x7f679cc74f352b55), + W64LIT(0x7de8415a4a64930a), W64LIT(0x9b2c911be8e5b603), W64LIT(0x4836f104b4ab444e), W64LIT(0xdb1c33514817282c), + W64LIT(0x15c6e17baeb698dd), W64LIT(0xed84be523f2f1b96), W64LIT(0xe1814a3b21d4ac49), W64LIT(0x503c04d6884037ed), + W64LIT(0x4c355623be0929f0), W64LIT(0x3b5499aae565d8c4), W64LIT(0x0a898ed31108623e), W64LIT(0xb074ae2d2532c705), + W64LIT(0x028fdd9d0551b85f), W64LIT(0xf58e4b8003c46835), W64LIT(0x3352cae4f13c02a5), W64LIT(0x6c2d0706ee706669), + W64LIT(0x7c21a19ac6c2cfab), W64LIT(0x19c31512b04d2f02), W64LIT(0xa6f4720b0273bb26), W64LIT(0x05ca47e78604311f), + W64LIT(0x46bcd8f0af014bce), W64LIT(0x1e868f683318a642), W64LIT(0x5c39f0bf96bb8032), W64LIT(0x79ebe67d40c6feb4), + W64LIT(0xff07c55312cc0a0b), W64LIT(0xaef22145162a6147), W64LIT(0xc1991b1e71ade3d0), W64LIT(0xded674b6ce131933), + W64LIT(0x7aaddb20c9311a4a), W64LIT(0x4dfcb6e332af7551), W64LIT(0x6de4e7c662d63ac8), W64LIT(0xbf376719b23e9424), + W64LIT(0x07459a7a83558940), W64LIT(0xac7dfcd8137bd918), W64LIT(0xdf1f947642b54592), W64LIT(0x17493ce6abe72082), + W64LIT(0xfc41f80e9b3beef5), W64LIT(0xe70d30812e2779a8), W64LIT(0xd993eecc4d469073), W64LIT(0x65e2b488768fe0a9), + W64LIT(0xd2d380dfd0e8aeec), W64LIT(0xe6c4d041a2812509), W64LIT(0x068c7aba0ff3d5e1), W64LIT(0x51f5e41604e66b4c), + W64LIT(0x41f9428a2c54c28e), W64LIT(0x537a398b01b7d313), W64LIT(0x782206bdcc60a215), W64LIT(0x89afea1ac506a79e), + W64LIT(0x8ae9d7474cf14360), W64LIT(0xf6c876dd8a338ccb), W64LIT(0x43769f1729057ad1), W64LIT(0x8dac4d3dcfa4ca20), + W64LIT(0xb7313457a6674e45), W64LIT(0x2018512550794f99), W64LIT(0xbb34c03eb89cf99a), W64LIT(0xbafd20fe343aa53b), + W64LIT(0x03463d5d89f7e4fe), W64LIT(0x42bf7fd7a5a32670), W64LIT(0x3f573e8defc7b57a), W64LIT(0xadb41c189fdd85b9), + W64LIT(0xcad9750dec03dd4f), W64LIT(0x0f43c934970c5321), W64LIT(0x2f5b9811c7751cb8), W64LIT(0xd85a0e0cc1e0ccd2), + W64LIT(0xe048aafbad72f0e8), W64LIT(0xf18deca70966058b), W64LIT(0xdd9049eb47e4fdcd), W64LIT(0xa87e5bff19d9b4a6), + W64LIT(0x5df0107f1a1ddc93), W64LIT(0xd195bd82591f4a12), W64LIT(0x0c05f4691efbb7df), W64LIT(0x8463feb3575b4ce0), + W64LIT(0x55f643310e4406f2), W64LIT(0xb6f8d4972ac112e4), W64LIT(0x4030a24aa0f29e2f), W64LIT(0xfd8818ce179db254), + W64LIT(0x3c1103d066305184), W64LIT(0x682ea021e4d20bd7), W64LIT(0x81a9b954d15f7dff), W64LIT(0x275dcb5fd32cc6d9), + W64LIT(0xfacd82b494c83b14), W64LIT(0x4433056daa50f391), W64LIT(0xe9871975358d7628), W64LIT(0xeac12428bc7a92d6), + W64LIT(0x1a85284f39bacbfc), W64LIT(0xf8425f299199834b), W64LIT(0x676d691573de58f6), W64LIT(0xd05c5d42d5b916b3), + W64LIT(0x8eea706046532ede), W64LIT(0xfb046274186e67b5), W64LIT(0x134a9bc1a1454d3c), W64LIT(0x57799eac0b15bead), + W64LIT(0x241bf6025adb2227), W64LIT(0x72ab886edd68c02b), W64LIT(0x9ae571db6443eaa2), W64LIT(0xc050fbdefd0bbf71), + W64LIT(0xa5b24f568b845fd8), W64LIT(0xe84ef9b5b92b2a89), W64LIT(0x6f6b3a5b67878297), W64LIT(0xc6dc8164f2f86a90), + W64LIT(0x7eae7c07c39377f4), W64LIT(0x5eb62d2293ea386d), W64LIT(0x8c65adfd43029681), W64LIT(0x2dd4458cc224a4e7), + W64LIT(0xfece25939e6a56aa), W64LIT(0xcd9cef776f56540f), W64LIT(0xa33e35ec84778a39), W64LIT(0xc2df2643f85a072e), + W64LIT(0xbc715a443bc970da), W64LIT(0xa07808b10d806ec7), W64LIT(0x36988d03773833ba), W64LIT(0x1680dc2627417c23), + W64LIT(0xcb1095cd60a581ee), W64LIT(0xbdb8ba84b76f2c7b), W64LIT(0x702455f3d8397874), W64LIT(0x35deb05efecfd744), + W64LIT(0x8f2390a0caf5727f), W64LIT(0xb1bd4eeda9949ba4), W64LIT(0x39db4437e034609b), W64LIT(0xe582ed1c2b76c1f7), + W64LIT(0xc4535cf9f7a9d2cf), W64LIT(0xb2fb73b020637f5a), W64LIT(0x583a57989c19ed8c), W64LIT(0x25d216c2d67d7e86), + W64LIT(0x0806534e1459da61), W64LIT(0x6b689d7c6d25ef29), W64LIT(0x0dcc14a9925deb7e), W64LIT(0xc99f485065f439b1), + W64LIT(0xa9b7bb3f957fe807), W64LIT(0x2a91dff641712da7), W64LIT(0x1c0952f536491e1d), W64LIT(0x75ee12145e3d496b), + W64LIT(0xf98bbfe91d3fdfea), W64LIT(0x92e32295701a30c3), W64LIT(0x3e9ede4d6361e9db), W64LIT(0x76a82f49d7caad95), + W64LIT(0x9da0eba1e71663e2), W64LIT(0x09cfb38e98ff86c0), W64LIT(0x9c690b616bb03f43), W64LIT(0xdad5d391c4b1748d), + W64LIT(0x3812a4f76c923c3a), W64LIT(0x5f7fcde21f4c64cc), W64LIT(0x6aa17dbce183b388), W64LIT(0xeec2830fb6d8ff68), + W64LIT(0x736268ae51ce9c8a), W64LIT(0xa47baf9607220379), W64LIT(0x543fa3f182e25a53), W64LIT(0x4eba8bbebb5891af), + W64LIT(0x2e9278d14bd34019), W64LIT(0x69e740e168745776), W64LIT(0x37516dc3fb9e6f1b), W64LIT(0xb3329370acc523fb), + W64LIT(0x3a9d796a69c38465), W64LIT(0x7761cf895b6cf134), W64LIT(0x0000000000000000), W64LIT(0x88660ada49a0fb3f), + W64LIT(0xb5bee9caa336f61a), W64LIT(0x5b7c6ac515ee0972), W64LIT(0x52b3d94b8d118fb2), W64LIT(0x329b2a247d9a5e04), + W64LIT(0x0e8a29f41baa0f80), W64LIT(0x642b5448fa29bc08), W64LIT(0x7b643be0459746eb), W64LIT(0xd45ffa65df1b7b0d), + W64LIT(0xeb08c4e830dcce77), W64LIT(0xf2cbd1fa8091e175), W64LIT(0xf302313a0c37bdd4), W64LIT(0x91a51fc8f9edd43d), + W64LIT(0xef0b63cf3a7ea3c9), W64LIT(0xc316c68374fc5b8f), W64LIT(0x01c9e0c08ca65ca1), W64LIT(0x3417509e72698be5), + W64LIT(0x4775383023a7176f), W64LIT(0x636ece32797c3548), W64LIT(0x1b4cc88fb51c975d), W64LIT(0x140f01bb2210c47c), + W64LIT(0x7427f2d4d29b15ca), W64LIT(0xa73d92cb8ed5e787), W64LIT(0xc71561a47e5e3631), W64LIT(0xaaf186621c880cf9), + W64LIT(0x6028f36ff08bd1b6), W64LIT(0x97296572f61e01dc), W64LIT(0xc59abc397b0f8e6e), W64LIT(0xec4d5e92b3894737), + W64LIT(0xb872fd63316b1d64), W64LIT(0xaf3bc1859a8c3de6), W64LIT(0x0403a7270aa26dbe), W64LIT(0x26942b9f5f8a9a78), + W64LIT(0x86ec232e520af4bf), W64LIT(0x49ff11c4380d18ef), W64LIT(0xf701961d0695d06a), W64LIT(0x56b07e6c87b3e20c), + W64LIT(0xd5961aa553bd27ac), W64LIT(0x61e113af7c2d8d17), W64LIT(0x100ca69c28b2a9c2), W64LIT(0xcf1332ea6a07ec50), + W64LIT(0xc856a890e9526510), W64LIT(0x2b583f36cdd77106), W64LIT(0x932ac255fcbc6c62), W64LIT(0x0b406e139dae3e9f), + W64LIT(0x832664c9d40ec5a0), W64LIT(0x3014f7b978cbe65b), W64LIT(0x2c1da54c4e82f846), W64LIT(0x986aac46611252fd) + }, + { + W64LIT(0x679cc74f352b557f), W64LIT(0x376719b23e9424bf), W64LIT(0xcc14a9925deb7e0d), W64LIT(0xb07e6c87b3e20c56), + W64LIT(0xa17dbce183b3886a), W64LIT(0xee12145e3d496b75), W64LIT(0x406e139dae3e9f0b), W64LIT(0x942b9f5f8a9a7826), + W64LIT(0xb24f568b845fd8a5), W64LIT(0xdf2643f85a072ec2), W64LIT(0x8c7aba0ff3d5e106), W64LIT(0x0b63cf3a7ea3c9ef), + W64LIT(0x12a4f76c923c3a38), W64LIT(0x8bbfe91d3fdfeaf9), W64LIT(0x9278d14bd340192e), W64LIT(0xca47e78604311f05), + W64LIT(0x07c55312cc0a0bff), W64LIT(0xcfb38e98ff86c009), W64LIT(0x991b1e71ade3d0c1), W64LIT(0x16c68374fc5b8fc3), + W64LIT(0x39f0bf96bb80325c), W64LIT(0x3d92cb8ed5e787a7), W64LIT(0xac4d3dcfa4ca208d), W64LIT(0xfae5ad26f6af3045), + W64LIT(0x63feb3575b4ce084), W64LIT(0x28f36ff08bd1b660), W64LIT(0xc6e17baeb698dd15), W64LIT(0x84be523f2f1b96ed), + W64LIT(0x3c04d6884037ed50), W64LIT(0xce25939e6a56aafe), W64LIT(0xa34c86edb40e5c99), W64LIT(0xebe67d40c6feb479), + W64LIT(0x27f2d4d29b15ca74), W64LIT(0x6d691573de58f667), W64LIT(0x329370acc523fbb3), W64LIT(0x2c911be8e5b6039b), + W64LIT(0x871975358d7628e9), W64LIT(0x550fb7e3f008aecc), W64LIT(0x7e5bff19d9b4a6a8), W64LIT(0xf8d4972ac112e4b6), + W64LIT(0xd1b1e5dcdf133821), W64LIT(0xfcb6e332af75514d), W64LIT(0x1e026b442095f828), W64LIT(0x1f947642b54592df), + W64LIT(0x5e6c78d98eab6723), W64LIT(0x17509e72698be534), W64LIT(0x2ac255fcbc6c6293), W64LIT(0x95bd82591f4a12d1), + W64LIT(0x799eac0b15bead57), W64LIT(0xf0107f1a1ddc935d), W64LIT(0xd674b6ce131933de), W64LIT(0xf5e41604e66b4c51), + W64LIT(0x8818ce179db254fd), W64LIT(0x03a7270aa26dbe04), W64LIT(0x1c33514817282cdb), W64LIT(0x2f363ce247dbbd9f), + W64LIT(0xa72ef2f5da69e962), W64LIT(0x93eecc4d469073d9), W64LIT(0xb92c99b1fafc114a), W64LIT(0x77090a2f90aabbb4), + W64LIT(0x0ca69c28b2a9c210), W64LIT(0xc9e0c08ca65ca101), W64LIT(0x4b0ddca7d09d56e4), W64LIT(0x988d03773833ba36), + W64LIT(0x06534e1459da6108), W64LIT(0x3a57989c19ed8c58), W64LIT(0x0952f536491e1d1c), W64LIT(0x0af5d23ceb73a318), + W64LIT(0x0d30812e2779a8e7), W64LIT(0xd7e2abc886c95929), W64LIT(0xa51fc8f9edd43d91), W64LIT(0x690b616bb03f439c), + W64LIT(0x516dc3fb9e6f1b37), W64LIT(0xa489d5ff78045766), W64LIT(0x52cae4f13c02a533), W64LIT(0x4cc88fb51c975d1b), + W64LIT(0x459a7a8355894007), W64LIT(0x9d796a69c384653a), W64LIT(0x313457a6674e45b7), W64LIT(0x4a9bc1a1454d3c13), + W64LIT(0x6268ae51ce9c8a73), W64LIT(0xfe87d93e98c885be), W64LIT(0xff11c4380d18ef49), W64LIT(0x8deca70966058bf1), + W64LIT(0xdeb05efecfd74435), W64LIT(0xd027f8da4ac352d6), W64LIT(0xf186621c880cf9aa), W64LIT(0x43c934970c53210f), + W64LIT(0xbee9caa336f61ab5), W64LIT(0x56a890e9526510c8), W64LIT(0xe8415a4a64930a7d), W64LIT(0xe32295701a30c392), + W64LIT(0x3e35ec84778a39a3), W64LIT(0x4f6fa8bfbefae31f), W64LIT(0x5dcb5fd32cc6d927), W64LIT(0x9f485065f439b1c9), + W64LIT(0x1095cd60a581eecb), W64LIT(0x978cb85528f7c622), W64LIT(0x7baf9607220379a4), W64LIT(0xd216c2d67d7e8625), + W64LIT(0xe4e7c662d63ac86d), W64LIT(0xb62d2293ea386d5e), W64LIT(0x8a29f41baa0f800e), W64LIT(0x5ffa65df1b7b0dd4), + W64LIT(0x61cf895b6cf13477), W64LIT(0xa6b8eff34fb98395), W64LIT(0x814a3b21d4ac49e1), W64LIT(0xaddb20c9311a4a7a), + W64LIT(0x74ae2d2532c705b0), W64LIT(0x30a24aa0f29e2f40), W64LIT(0x91dff641712da72a), W64LIT(0x9049eb47e4fdcddd), + W64LIT(0x493ce6abe7208217), W64LIT(0x36f104b4ab444e48), W64LIT(0xf22145162a6147ae), W64LIT(0x5c5d42d5b916b3d0), + W64LIT(0xf7d52c08d1d698a2), W64LIT(0x7a398b01b7d31353), W64LIT(0x6cff08754b889c90), W64LIT(0x14f7b978cbe65b30), + W64LIT(0xc4d041a2812509e6), W64LIT(0xe085b27ab85d7d96), W64LIT(0xc0b235baef42bc1d), W64LIT(0x868f683318a6421e), + W64LIT(0xea706046532ede8e), W64LIT(0x4ef9b5b92b2a89e8), W64LIT(0xdc8164f2f86a90c6), W64LIT(0x2455f3d839787470), + W64LIT(0x5499aae565d8c43b), W64LIT(0x59a92bcb42a16cdc), W64LIT(0xa9b954d15f7dff81), W64LIT(0xae7c07c39377f47e), + W64LIT(0x01961d0695d06af7), W64LIT(0xdb4437e034609b39), W64LIT(0x3bc1859a8c3de6af), W64LIT(0xaa1e73dbfd104185), + W64LIT(0x7dfcd8137bd918ac), W64LIT(0x80dc2627417c2316), W64LIT(0xd9750dec03dd4fca), W64LIT(0xc5465ca414f56311), + W64LIT(0x203787c0571fc18b), W64LIT(0xd5d391c4b1748dda), W64LIT(0xc2830fb6d8ff68ee), W64LIT(0xbcd8f0af014bce46), + W64LIT(0xa0eba1e71663e29d), W64LIT(0xfb73b020637f5ab2), W64LIT(0x7c6ac515ee09725b), W64LIT(0x0000000000000000), + W64LIT(0xc876dd8a338ccbf6), W64LIT(0x9cef776f56540fcd), W64LIT(0x47ab408f623494f4), W64LIT(0xcbd1fa8091e175f2), + W64LIT(0x9abc397b0f8e6ec5), W64LIT(0xb58a05994855d35a), W64LIT(0x4d5e92b3894737ec), W64LIT(0x961aa553bd27acd5), + W64LIT(0xc31512b04d2f0219), W64LIT(0xe6d6fc6ee1871c9e), W64LIT(0xe2b488768fe0a965), W64LIT(0xb3d94b8d118fb252), + W64LIT(0x440c6785c0592af0), W64LIT(0x25c3eedeaca81e87), W64LIT(0x583f36cdd771062b), W64LIT(0x2d0706ee7066696c), + W64LIT(0x425f299199834bf8), W64LIT(0xfd20fe343aa53bba), W64LIT(0xf643310e4406f255), W64LIT(0xdad22ae6a1b0f1ce), + W64LIT(0x1da54c4e82f8462c), W64LIT(0x355623be0929f04c), W64LIT(0x769f1729057ad143), W64LIT(0xbd4eeda9949ba4b1), + W64LIT(0xd8e310ea960d253d), W64LIT(0x736b7e37fecd0e4f), W64LIT(0x65adfd430296818c), W64LIT(0xb8ba84b76f2c7bbd), + W64LIT(0x9b2a247d9a5e0432), W64LIT(0xc77766a82348b7e2), W64LIT(0x08c4e830dcce77eb), W64LIT(0x0e97a624851416e3), + W64LIT(0x898ed31108623e0a), W64LIT(0xe571db6443eaa29a), W64LIT(0x573e8defc7b57a3f), W64LIT(0x21a19ac6c2cfab7c), + W64LIT(0x70cc593d5ca0b04b), W64LIT(0x2664c9d40ec5a083), W64LIT(0x296572f61e01dc97), W64LIT(0x85284f39bacbfc1a), + W64LIT(0x715a443bc970dabc), W64LIT(0xef840958a8990182), W64LIT(0xcd82b494c83b14fa), W64LIT(0x48aafbad72f0e8e0), + W64LIT(0xe9d7474cf143608a), W64LIT(0x2390a0caf5727f8f), W64LIT(0xb7bb3f957fe807a9), W64LIT(0x82ed1c2b76c1f7e5), + W64LIT(0xbb1da3bdcd41c5b9), W64LIT(0x72fd63316b1d64b8), W64LIT(0x7808b10d806ec7a0), W64LIT(0x837b012de3119d12), + W64LIT(0x689d7c6d25ef296b), W64LIT(0x02313a0c37bdd4f3), W64LIT(0x1103d0663051843c), W64LIT(0xab886edd68c02b72), + W64LIT(0x6b3a5b678782976f), W64LIT(0xe113af7c2d8d1761), W64LIT(0x6aac46611252fd98), W64LIT(0x50fbdefd0bbf71c0), + W64LIT(0x2ea021e4d20bd768), W64LIT(0x5a0e0cc1e0ccd2d8), W64LIT(0x34c03eb89cf99abb), W64LIT(0xb41c189fdd85b9ad), + W64LIT(0x9ede4d6361e9db3e), W64LIT(0xafea1ac506a79e89), W64LIT(0x463d5d89f7e4fe03), W64LIT(0x18512550794f9920), + W64LIT(0x41f80e9b3beef5fc), W64LIT(0xa82f49d7caad9576), W64LIT(0x0f01bb2210c47c14), W64LIT(0xec232e520af4bf86), + W64LIT(0x1bf6025adb222724), W64LIT(0xa2da9beb21de366e), W64LIT(0xedb533549f24d571), W64LIT(0x643be0459746eb7b), + W64LIT(0xbf7fd7a5a3267042), W64LIT(0x046274186e67b5fb), W64LIT(0x8e4b8003c46835f5), W64LIT(0x1332ea6a07ec50cf), + W64LIT(0xd380dfd0e8aeecd2), W64LIT(0x6f582f7fe9e52294), W64LIT(0xf9428a2c54c28e41), W64LIT(0x3fa3f182e25a5354), + W64LIT(0x535cf9f7a9d2cfc4), W64LIT(0x660ada49a0fb3f88), W64LIT(0x33056daa50f39144), W64LIT(0x8fdd9d0551b85f02), + W64LIT(0x19c73856ec9ff3d7), W64LIT(0xb1e87181263266a1), W64LIT(0x1561a47e5e3631c7), W64LIT(0xd4458cc224a4e72d), + W64LIT(0xe740e16874577669), W64LIT(0xc12428bc7a92d6ea), W64LIT(0x3866a2902e5058ab), W64LIT(0x1a601f5c4ef24dd3), + W64LIT(0x6059945df9215e80), W64LIT(0x05f4691efbb7df0c), W64LIT(0x5b9811c7751cb82f), W64LIT(0x2b5448fa29bc0864), + W64LIT(0xba8bbebb5891af4e), W64LIT(0xf4720b0273bb26a6), W64LIT(0xdd1779f46dbafa31), W64LIT(0x6ece32797c354863), + W64LIT(0x7fcde21f4c64cc5f), W64LIT(0x2206bdcc60a21578), W64LIT(0x75383023a7176f47), W64LIT(0xf3b75810bfb12d59) + }, + { + W64LIT(0x03d0663051843c11), W64LIT(0xbfe91d3fdfeaf98b), W64LIT(0xf80e9b3beef5fc41), W64LIT(0xe5ad26f6af3045fa), + W64LIT(0x5a443bc970dabc71), W64LIT(0x7b012de3119d1283), W64LIT(0x82b494c83b14facd), W64LIT(0x750dec03dd4fcad9), + W64LIT(0x090a2f90aabbb477), W64LIT(0xb6e332af75514dfc), W64LIT(0xadfd430296818c65), W64LIT(0xfd63316b1d64b872), + W64LIT(0x3d5d89f7e4fe0346), W64LIT(0xd7474cf143608ae9), W64LIT(0x7e6c87b3e20c56b0), W64LIT(0x601f5c4ef24dd31a), + W64LIT(0x40e16874577669e7), W64LIT(0x4437e034609b39db), W64LIT(0xe7c662d63ac86de4), W64LIT(0xaf9607220379a47b), + W64LIT(0xea1ac506a79e89af), W64LIT(0xd8f0af014bce46bc), W64LIT(0x7fd7a5a3267042bf), W64LIT(0x9f1729057ad14376), + W64LIT(0x1c189fdd85b9adb4), W64LIT(0x87d93e98c885befe), W64LIT(0x57989c19ed8c583a), W64LIT(0xa4f76c923c3a3812), + W64LIT(0x2a247d9a5e04329b), W64LIT(0xc03eb89cf99abb34), W64LIT(0xf6025adb2227241b), W64LIT(0xa890e9526510c856), + W64LIT(0x06bdcc60a2157822), W64LIT(0xc73856ec9ff3d719), W64LIT(0xcae4f13c02a53352), W64LIT(0xd6fc6ee1871c9ee6), + W64LIT(0xf0bf96bb80325c39), W64LIT(0x13af7c2d8d1761e1), W64LIT(0x3be0459746eb7b64), W64LIT(0x99aae565d8c43b54), + W64LIT(0x95cd60a581eecb10), W64LIT(0x68ae51ce9c8a7362), W64LIT(0xcde21f4c64cc5f7f), W64LIT(0xdc2627417c231680), + W64LIT(0x428a2c54c28e41f9), W64LIT(0x76dd8a338ccbf6c8), W64LIT(0xb8eff34fb98395a6), W64LIT(0xa69c28b2a9c2100c), + W64LIT(0x08b10d806ec7a078), W64LIT(0xc55312cc0a0bff07), W64LIT(0x886edd68c02b72ab), W64LIT(0xdd9d0551b85f028f), + W64LIT(0x1e73dbfd104185aa), W64LIT(0x911be8e5b6039b2c), W64LIT(0x30812e2779a8e70d), W64LIT(0x3a5b678782976f6b), + W64LIT(0x20fe343aa53bbafd), W64LIT(0xb954d15f7dff81a9), W64LIT(0x9a7a835589400745), W64LIT(0x1fc8f9edd43d91a5), + W64LIT(0x0e0cc1e0ccd2d85a), W64LIT(0xbb3f957fe807a9b7), W64LIT(0xc3eedeaca81e8725), W64LIT(0x66a2902e5058ab38), + W64LIT(0xff08754b889c906c), W64LIT(0xfeb3575b4ce08463), W64LIT(0x107f1a1ddc935df0), W64LIT(0x25939e6a56aafece), + W64LIT(0xa92bcb42a16cdc59), W64LIT(0x32ea6a07ec50cf13), W64LIT(0x947642b54592df1f), W64LIT(0x1779f46dbafa31dd), + W64LIT(0x5623be0929f04c35), W64LIT(0xf2d4d29b15ca7427), W64LIT(0x59945df9215e8060), W64LIT(0x9370acc523fbb332), + W64LIT(0xb05efecfd74435de), W64LIT(0x71db6443eaa29ae5), W64LIT(0xe2abc886c95929d7), W64LIT(0x458cc224a4e72dd4), + W64LIT(0xce32797c3548636e), W64LIT(0x1aa553bd27acd596), W64LIT(0x4a3b21d4ac49e181), W64LIT(0x284f39bacbfc1a85), + W64LIT(0xd94b8d118fb252b3), W64LIT(0xb235baef42bc1dc0), W64LIT(0x2643f85a072ec2df), W64LIT(0x8bbebb5891af4eba), + W64LIT(0x89d5ff78045766a4), W64LIT(0xeecc4d469073d993), W64LIT(0x0b616bb03f439c69), W64LIT(0xe41604e66b4c51f5), + W64LIT(0x16c2d67d7e8625d2), W64LIT(0x6c78d98eab67235e), W64LIT(0x9d7c6d25ef296b68), W64LIT(0x64c9d40ec5a08326), + W64LIT(0x2ef2f5da69e962a7), W64LIT(0xfa65df1b7b0dd45f), W64LIT(0x12145e3d496b75ee), W64LIT(0xfcd8137bd918ac7d), + W64LIT(0x52f536491e1d1c09), W64LIT(0xe67d40c6feb479eb), W64LIT(0x2145162a6147aef2), W64LIT(0x29f41baa0f800e8a), + W64LIT(0x0000000000000000), W64LIT(0x840958a8990182ef), W64LIT(0xc88fb51c975d1b4c), W64LIT(0xc68374fc5b8fc316), + W64LIT(0x5d42d5b916b3d05c), W64LIT(0x7dbce183b3886aa1), W64LIT(0x512550794f992018), W64LIT(0xe17baeb698dd15c6), + W64LIT(0x43310e4406f255f6), W64LIT(0x6dc3fb9e6f1b3751), W64LIT(0x86621c880cf9aaf1), W64LIT(0xbc397b0f8e6ec59a), + W64LIT(0x415a4a64930a7de8), W64LIT(0x04d6884037ed503c), W64LIT(0xe9caa336f61ab5be), W64LIT(0x0ada49a0fb3f8866), + W64LIT(0x55f3d83978747024), W64LIT(0x3ce6abe720821749), W64LIT(0xf5d23ceb73a3180a), W64LIT(0xa24aa0f29e2f4030), + W64LIT(0x582f7fe9e522946f), W64LIT(0x7aba0ff3d5e1068c), W64LIT(0x313a0c37bdd4f302), W64LIT(0x3787c0571fc18b20), + W64LIT(0x5cf9f7a9d2cfc453), W64LIT(0xbe523f2f1b96ed84), W64LIT(0x85b27ab85d7d96e0), W64LIT(0x0706ee7066696c2d), + W64LIT(0x961d0695d06af701), W64LIT(0x1b1e71ade3d0c199), W64LIT(0xc255fcbc6c62932a), W64LIT(0x398b01b7d313537a), + W64LIT(0xcc593d5ca0b04b70), W64LIT(0x5f299199834bf842), W64LIT(0x80dfd0e8aeecd2d3), W64LIT(0x9eac0b15bead5779), + W64LIT(0xef776f56540fcd9c), W64LIT(0x2f49d7caad9576a8), W64LIT(0x2c99b1fafc114ab9), W64LIT(0x8d03773833ba3698), + W64LIT(0x720b0273bb26a6f4), W64LIT(0x18ce179db254fd88), W64LIT(0x8f683318a6421e86), W64LIT(0x4f568b845fd8a5b2), + W64LIT(0x8ed31108623e0a89), W64LIT(0xd22ae6a1b0f1ceda), W64LIT(0x74b6ce131933ded6), W64LIT(0x97a624851416e30e), + W64LIT(0x6e139dae3e9f0b40), W64LIT(0xa7270aa26dbe0403), W64LIT(0x5448fa29bc08642b), W64LIT(0xe310ea960d253dd8), + W64LIT(0x706046532ede8eea), W64LIT(0x485065f439b1c99f), W64LIT(0x6b7e37fecd0e4f73), W64LIT(0xfbdefd0bbf71c050), + W64LIT(0xd391c4b1748ddad5), W64LIT(0xa021e4d20bd7682e), W64LIT(0xab408f623494f447), W64LIT(0x5bff19d9b4a6a87e), + W64LIT(0xb1e5dcdf133821d1), W64LIT(0x026b442095f8281e), W64LIT(0xdff641712da72a91), W64LIT(0x11c4380d18ef49ff), + W64LIT(0xae2d2532c705b074), W64LIT(0xc1859a8c3de6af3b), W64LIT(0x4b8003c46835f58e), W64LIT(0x92cb8ed5e787a73d), + W64LIT(0xcb5fd32cc6d9275d), W64LIT(0x8cb85528f7c62297), W64LIT(0x9bc1a1454d3c134a), W64LIT(0x056daa50f3914433), + W64LIT(0xf4691efbb7df0c05), W64LIT(0xd1fa8091e175f2cb), W64LIT(0x7c07c39377f47eae), W64LIT(0x14a9925deb7e0dcc), + W64LIT(0xcf895b6cf1347761), W64LIT(0x0fb7e3f008aecc55), W64LIT(0x8a05994855d35ab5), W64LIT(0xf104b4ab444e4836), + W64LIT(0x691573de58f6676d), W64LIT(0x4eeda9949ba4b1bd), W64LIT(0x2428bc7a92d6eac1), W64LIT(0xb75810bfb12d59f3), + W64LIT(0x63cf3a7ea3c9ef0b), W64LIT(0x6274186e67b5fb04), W64LIT(0x1512b04d2f0219c3), W64LIT(0xe87181263266a1b1), + W64LIT(0x1975358d7628e987), W64LIT(0x534e1459da610806), W64LIT(0x47e78604311f05ca), W64LIT(0xd4972ac112e4b6f8), + W64LIT(0x33514817282cdb1c), W64LIT(0x90a0caf5727f8f23), W64LIT(0x3e8defc7b57a3f57), W64LIT(0x3f36cdd771062b58), + W64LIT(0x796a69c384653a9d), W64LIT(0x465ca414f56311c5), W64LIT(0x5e92b3894737ec4d), W64LIT(0x9811c7751cb82f5b), + W64LIT(0xd041a2812509e6c4), W64LIT(0x49eb47e4fdcddd90), W64LIT(0x78d14bd340192e92), W64LIT(0xf9b5b92b2a89e84e), + W64LIT(0x61a47e5e3631c715), W64LIT(0x509e72698be53417), W64LIT(0xb533549f24d571ed), W64LIT(0x27f8da4ac352d6d0), + W64LIT(0x6572f61e01dc9729), W64LIT(0xde4d6361e9db3e9e), W64LIT(0x3457a6674e45b731), W64LIT(0xa54c4e82f8462c1d), + W64LIT(0xbd82591f4a12d195), W64LIT(0x830fb6d8ff68eec2), W64LIT(0x383023a7176f4775), W64LIT(0x7766a82348b7e2c7), + W64LIT(0x0c6785c0592af044), W64LIT(0xba84b76f2c7bbdb8), W64LIT(0xe0c08ca65ca101c9), W64LIT(0xeba1e71663e29da0), + W64LIT(0xd52c08d1d698a2f7), W64LIT(0xc4e830dcce77eb08), W64LIT(0xda9beb21de366ea2), W64LIT(0xa3f182e25a53543f), + W64LIT(0xac46611252fd986a), W64LIT(0xb38e98ff86c009cf), W64LIT(0xf36ff08bd1b66028), W64LIT(0xdb20c9311a4a7aad), + W64LIT(0xa19ac6c2cfab7c21), W64LIT(0x6ac515ee09725b7c), W64LIT(0x4c86edb40e5c99a3), W64LIT(0x363ce247dbbd9f2f), + W64LIT(0x8164f2f86a90c6dc), W64LIT(0x35ec84778a39a33e), W64LIT(0xb488768fe0a965e2), W64LIT(0x73b020637f5ab2fb), + W64LIT(0x232e520af4bf86ec), W64LIT(0x6fa8bfbefae31f4f), W64LIT(0xeca70966058bf18d), W64LIT(0x1da3bdcd41c5b9bb), + W64LIT(0x9cc74f352b557f67), W64LIT(0x4d3dcfa4ca208dac), W64LIT(0x2b9f5f8a9a782694), W64LIT(0xaafbad72f0e8e048), + W64LIT(0xc934970c53210f43), W64LIT(0xed1c2b76c1f7e582), W64LIT(0x01bb2210c47c140f), W64LIT(0x0ddca7d09d56e44b), + W64LIT(0x2d2293ea386d5eb6), W64LIT(0xf7b978cbe65b3014), W64LIT(0x6719b23e9424bf37), W64LIT(0x2295701a30c392e3) + }, + { + W64LIT(0x9f5f8a9a7826942b), W64LIT(0x34970c53210f43c9), W64LIT(0x9d0551b85f028fdd), W64LIT(0xb494c83b14facd82), + W64LIT(0x6edd68c02b72ab88), W64LIT(0xff19d9b4a6a87e5b), W64LIT(0xdb6443eaa29ae571), W64LIT(0x1be8e5b6039b2c91), + W64LIT(0x5fd32cc6d9275dcb), W64LIT(0x90e9526510c856a8), W64LIT(0xb27ab85d7d96e085), W64LIT(0xa47e5e3631c71561), + W64LIT(0xf3d8397874702455), W64LIT(0xfbad72f0e8e048aa), W64LIT(0x37e034609b39db44), W64LIT(0xfa8091e175f2cbd1), + W64LIT(0xcaa336f61ab5bee9), W64LIT(0xeff34fb98395a6b8), W64LIT(0x63316b1d64b872fd), W64LIT(0xba0ff3d5e1068c7a), + W64LIT(0xcd60a581eecb1095), W64LIT(0x35baef42bc1dc0b2), W64LIT(0x23be0929f04c3556), W64LIT(0x4b8d118fb252b3d9), + W64LIT(0xd8137bd918ac7dfc), W64LIT(0x0a2f90aabbb47709), W64LIT(0xc2d67d7e8625d216), W64LIT(0x7181263266a1b1e8), + W64LIT(0x3023a7176f477538), W64LIT(0x7642b54592df1f94), W64LIT(0xf2f5da69e962a72e), W64LIT(0xa70966058bf18dec), + W64LIT(0xc662d63ac86de4e7), W64LIT(0x939e6a56aafece25), W64LIT(0x86edb40e5c99a34c), W64LIT(0xf8da4ac352d6d027), + W64LIT(0x145e3d496b75ee12), W64LIT(0xce179db254fd8818), W64LIT(0xd23ceb73a3180af5), W64LIT(0x270aa26dbe0403a7), + W64LIT(0x5d89f7e4fe03463d), W64LIT(0x2ae6a1b0f1cedad2), W64LIT(0x1729057ad143769f), W64LIT(0xb10d806ec7a07808), + W64LIT(0x4f39bacbfc1a8528), W64LIT(0xeda9949ba4b1bd4e), W64LIT(0x5312cc0a0bff07c5), W64LIT(0xc4380d18ef49ff11), + W64LIT(0x95701a30c392e322), W64LIT(0xa0caf5727f8f2390), W64LIT(0x55fcbc6c62932ac2), W64LIT(0xcf3a7ea3c9ef0b63), + W64LIT(0x621c880cf9aaf186), W64LIT(0xfd430296818c65ad), W64LIT(0xbf96bb80325c39f0), W64LIT(0x6c87b3e20c56b07e), + W64LIT(0x299199834bf8425f), W64LIT(0x74186e67b5fb0462), W64LIT(0x4c4e82f8462c1da5), W64LIT(0x64f2f86a90c6dc81), + W64LIT(0x6b442095f8281e02), W64LIT(0x1d0695d06af70196), W64LIT(0xd5ff78045766a489), W64LIT(0x3856ec9ff3d719c7), + W64LIT(0xac0b15bead57799e), W64LIT(0xc3fb9e6f1b37516d), W64LIT(0x8e98ff86c009cfb3), W64LIT(0x49d7caad9576a82f), + W64LIT(0x859a8c3de6af3bc1), W64LIT(0x3dcfa4ca208dac4d), W64LIT(0x91c4b1748ddad5d3), W64LIT(0x8a2c54c28e41f942), + W64LIT(0x2bcb42a16cdc59a9), W64LIT(0x9e72698be5341750), W64LIT(0x1e71ade3d0c1991b), W64LIT(0xe6abe7208217493c), + W64LIT(0x3a0c37bdd4f30231), W64LIT(0x945df9215e806059), W64LIT(0xcc4d469073d993ee), W64LIT(0x0e9b3beef5fc41f8), + W64LIT(0x8b01b7d313537a39), W64LIT(0xf182e25a53543fa3), W64LIT(0x5810bfb12d59f3b7), W64LIT(0x8003c46835f58e4b), + W64LIT(0xbce183b3886aa17d), W64LIT(0x1604e66b4c51f5e4), W64LIT(0x2c08d1d698a2f7d5), W64LIT(0xc08ca65ca101c9e0), + W64LIT(0x7a8355894007459a), W64LIT(0xe21f4c64cc5f7fcd), W64LIT(0x88768fe0a965e2b4), W64LIT(0x82591f4a12d195bd), + W64LIT(0x4aa0f29e2f4030a2), W64LIT(0xdca7d09d56e44b0d), W64LIT(0x6daa50f391443305), W64LIT(0x92b3894737ec4d5e), + W64LIT(0xa8bfbefae31f4f6f), W64LIT(0xea6a07ec50cf1332), W64LIT(0x2293ea386d5eb62d), W64LIT(0x41a2812509e6c4d0), + W64LIT(0x8374fc5b8fc316c6), W64LIT(0x683318a6421e868f), W64LIT(0xb3575b4ce08463fe), W64LIT(0xe5dcdf133821d1b1), + W64LIT(0xd6884037ed503c04), W64LIT(0x05994855d35ab58a), W64LIT(0x5b678782976f6b3a), W64LIT(0x397b0f8e6ec59abc), + W64LIT(0xabc886c95929d7e2), W64LIT(0xe4f13c02a53352ca), W64LIT(0xb5b92b2a89e84ef9), W64LIT(0xaf7c2d8d1761e113), + W64LIT(0x75358d7628e98719), W64LIT(0x72f61e01dc972965), W64LIT(0x78d98eab67235e6c), W64LIT(0xc8f9edd43d91a51f), + W64LIT(0x0fb6d8ff68eec283), W64LIT(0x70acc523fbb33293), W64LIT(0x36cdd771062b583f), W64LIT(0xbdcc60a215782206), + W64LIT(0xa624851416e30e97), W64LIT(0x9607220379a47baf), W64LIT(0x1c2b76c1f7e582ed), W64LIT(0x6046532ede8eea70), + W64LIT(0xbebb5891af4eba8b), W64LIT(0x48fa29bc08642b54), W64LIT(0x19b23e9424bf3767), W64LIT(0x2627417c231680dc), + W64LIT(0x65df1b7b0dd45ffa), W64LIT(0xf536491e1d1c0952), W64LIT(0x54d15f7dff81a9b9), W64LIT(0x2550794f99201851), + W64LIT(0xdefd0bbf71c050fb), W64LIT(0x87c0571fc18b2037), W64LIT(0x10ea960d253dd8e3), W64LIT(0xe0459746eb7b643b), + W64LIT(0x12b04d2f0219c315), W64LIT(0xaae565d8c43b5499), W64LIT(0xe91d3fdfeaf98bbf), W64LIT(0xf76c923c3a3812a4), + W64LIT(0x1f5c4ef24dd31a60), W64LIT(0x812e2779a8e70d30), W64LIT(0xf41baa0f800e8a29), W64LIT(0xfc6ee1871c9ee6d6), + W64LIT(0x8fb51c975d1b4cc8), W64LIT(0x4e1459da61080653), W64LIT(0x310e4406f255f643), W64LIT(0x0cc1e0ccd2d85a0e), + W64LIT(0x0958a8990182ef84), W64LIT(0xa9925deb7e0dcc14), W64LIT(0x6a69c384653a9d79), W64LIT(0x04b4ab444e4836f1), + W64LIT(0x0dec03dd4fcad975), W64LIT(0xeb47e4fdcddd9049), W64LIT(0x7e37fecd0e4f736b), W64LIT(0x73dbfd104185aa1e), + W64LIT(0xc515ee09725b7c6a), W64LIT(0xae51ce9c8a736268), W64LIT(0xa3bdcd41c5b9bb1d), W64LIT(0x84b76f2c7bbdb8ba), + W64LIT(0x443bc970dabc715a), W64LIT(0xa1e71663e29da0eb), W64LIT(0x7f1a1ddc935df010), W64LIT(0x474cf143608ae9d7), + W64LIT(0x33549f24d571edb5), W64LIT(0xc9d40ec5a0832664), W64LIT(0x46611252fd986aac), W64LIT(0x5efecfd74435deb0), + W64LIT(0x0000000000000000), W64LIT(0x514817282cdb1c33), W64LIT(0x408f623494f447ab), W64LIT(0x57a6674e45b73134), + W64LIT(0x11c7751cb82f5b98), W64LIT(0x989c19ed8c583a57), W64LIT(0x7baeb698dd15c6e1), W64LIT(0x06ee7066696c2d07), + W64LIT(0xda49a0fb3f88660a), W64LIT(0x07c39377f47eae7c), W64LIT(0x2d2532c705b074ae), W64LIT(0x42d5b916b3d05c5d), + W64LIT(0xec84778a39a33e35), W64LIT(0x776f56540fcd9cef), W64LIT(0xa553bd27acd5961a), W64LIT(0xb978cbe65b3014f7), + W64LIT(0x895b6cf1347761cf), W64LIT(0xb85528f7c622978c), W64LIT(0x66a82348b7e2c777), W64LIT(0xe830dcce77eb08c4), + W64LIT(0x189fdd85b9adb41c), W64LIT(0x99b1fafc114ab92c), W64LIT(0x0b0273bb26a6f472), W64LIT(0xeedeaca81e8725c3), + W64LIT(0x6785c0592af0440c), W64LIT(0x247d9a5e04329b2a), W64LIT(0x21e4d20bd7682ea0), W64LIT(0xbb2210c47c140f01), + W64LIT(0x523f2f1b96ed84be), W64LIT(0xd4d29b15ca7427f2), W64LIT(0x45162a6147aef221), W64LIT(0xf641712da72a91df), + W64LIT(0xb020637f5ab2fb73), W64LIT(0xdd8a338ccbf6c876), W64LIT(0x5ca414f56311c546), W64LIT(0x3f957fe807a9b7bb), + W64LIT(0x8cc224a4e72dd445), W64LIT(0x012de3119d12837b), W64LIT(0xd0663051843c1103), W64LIT(0x5a4a64930a7de841), + W64LIT(0x28bc7a92d6eac124), W64LIT(0x08754b889c906cff), W64LIT(0xd7a5a3267042bf7f), W64LIT(0x3ce247dbbd9f2f36), + W64LIT(0x6ff08bd1b66028f3), W64LIT(0xd14bd340192e9278), W64LIT(0x139dae3e9f0b406e), W64LIT(0xe78604311f05ca47), + W64LIT(0xd93e98c885befe87), W64LIT(0x616bb03f439c690b), W64LIT(0x03773833ba36988d), W64LIT(0xcb8ed5e787a73d92), + W64LIT(0xb7e3f008aecc550f), W64LIT(0x9c28b2a9c2100ca6), W64LIT(0x3eb89cf99abb34c0), W64LIT(0x3b21d4ac49e1814a), + W64LIT(0xdfd0e8aeecd2d380), W64LIT(0x7c6d25ef296b689d), W64LIT(0xc1a1454d3c134a9b), W64LIT(0xf9f7a9d2cfc4535c), + W64LIT(0xc74f352b557f679c), W64LIT(0x7d40c6feb479ebe6), W64LIT(0x1573de58f6676d69), W64LIT(0x1ac506a79e89afea), + W64LIT(0x568b845fd8a5b24f), W64LIT(0x32797c3548636ece), W64LIT(0x691efbb7df0c05f4), W64LIT(0x972ac112e4b6f8d4), + W64LIT(0x79f46dbafa31dd17), W64LIT(0x2e520af4bf86ec23), W64LIT(0xd31108623e0a898e), W64LIT(0x8defc7b57a3f573e), + W64LIT(0x025adb2227241bf6), W64LIT(0xa2902e5058ab3866), W64LIT(0xfe343aa53bbafd20), W64LIT(0xad26f6af3045fae5), + W64LIT(0x43f85a072ec2df26), W64LIT(0x2f7fe9e522946f58), W64LIT(0x9beb21de366ea2da), W64LIT(0x20c9311a4a7aaddb), + W64LIT(0x5065f439b1c99f48), W64LIT(0x593d5ca0b04b70cc), W64LIT(0x9ac6c2cfab7c21a1), W64LIT(0xb6ce131933ded674), + W64LIT(0xf0af014bce46bcd8), W64LIT(0x4d6361e9db3e9ede), W64LIT(0xe16874577669e740), W64LIT(0xe332af75514dfcb6) + }, + { + W64LIT(0xbfbefae31f4f6fa8), W64LIT(0x85c0592af0440c67), W64LIT(0xbaef42bc1dc0b235), W64LIT(0x5528f7c622978cb8), + W64LIT(0xe6a1b0f1cedad22a), W64LIT(0x3ceb73a3180af5d2), W64LIT(0x7fe9e522946f582f), W64LIT(0xa7d09d56e44b0ddc), + W64LIT(0x754b889c906cff08), W64LIT(0xe247dbbd9f2f363c), W64LIT(0x81263266a1b1e871), W64LIT(0xdcdf133821d1b1e5), + W64LIT(0xf46dbafa31dd1779), W64LIT(0x3d5ca0b04b70cc59), W64LIT(0x56ec9ff3d719c738), W64LIT(0xdeaca81e8725c3ee), + W64LIT(0x549f24d571edb533), W64LIT(0x2de3119d12837b01), W64LIT(0xea960d253dd8e310), W64LIT(0xc886c95929d7e2ab), + W64LIT(0x2f90aabbb477090a), W64LIT(0x26f6af3045fae5ad), W64LIT(0x6ee1871c9ee6d6fc), W64LIT(0x3e98c885befe87d9), + W64LIT(0x24851416e30e97a6), W64LIT(0xda4ac352d6d027f8), W64LIT(0xe3f008aecc550fb7), W64LIT(0x994855d35ab58a05), + W64LIT(0x5df9215e80605994), W64LIT(0x58a8990182ef8409), W64LIT(0xb1fafc114ab92c99), W64LIT(0x442095f8281e026b), + W64LIT(0xf5da69e962a72ef2), W64LIT(0xc0571fc18b203787), W64LIT(0x37fecd0e4f736b7e), W64LIT(0x902e5058ab3866a2), + W64LIT(0xeb21de366ea2da9b), W64LIT(0x8f623494f447ab40), W64LIT(0xd98eab67235e6c78), W64LIT(0xa414f56311c5465c), + W64LIT(0x5c4ef24dd31a601f), W64LIT(0x08d1d698a2f7d52c), W64LIT(0xdbfd104185aa1e73), W64LIT(0xcb42a16cdc59a92b), + W64LIT(0x10bfb12d59f3b758), W64LIT(0xa82348b7e2c77766), W64LIT(0xbdcd41c5b9bb1da3), W64LIT(0x7ab85d7d96e085b2), + W64LIT(0xedb40e5c99a34c86), W64LIT(0xff78045766a489d5), W64LIT(0xf34fb98395a6b8ef), W64LIT(0x4f352b557f679cc7), + W64LIT(0x4a64930a7de8415a), W64LIT(0xe8e5b6039b2c911b), W64LIT(0xb4ab444e4836f104), W64LIT(0x4817282cdb1c3351), + W64LIT(0xaeb698dd15c6e17b), W64LIT(0x3f2f1b96ed84be52), W64LIT(0x21d4ac49e1814a3b), W64LIT(0x884037ed503c04d6), + W64LIT(0xbe0929f04c355623), W64LIT(0xe565d8c43b5499aa), W64LIT(0x1108623e0a898ed3), W64LIT(0x2532c705b074ae2d), + W64LIT(0x0551b85f028fdd9d), W64LIT(0x03c46835f58e4b80), W64LIT(0xf13c02a53352cae4), W64LIT(0xee7066696c2d0706), + W64LIT(0xc6c2cfab7c21a19a), W64LIT(0xb04d2f0219c31512), W64LIT(0x0273bb26a6f4720b), W64LIT(0x8604311f05ca47e7), + W64LIT(0xaf014bce46bcd8f0), W64LIT(0x3318a6421e868f68), W64LIT(0x96bb80325c39f0bf), W64LIT(0x40c6feb479ebe67d), + W64LIT(0x12cc0a0bff07c553), W64LIT(0x162a6147aef22145), W64LIT(0x71ade3d0c1991b1e), W64LIT(0xce131933ded674b6), + W64LIT(0xc9311a4a7aaddb20), W64LIT(0x32af75514dfcb6e3), W64LIT(0x62d63ac86de4e7c6), W64LIT(0xb23e9424bf376719), + W64LIT(0x8355894007459a7a), W64LIT(0x137bd918ac7dfcd8), W64LIT(0x42b54592df1f9476), W64LIT(0xabe7208217493ce6), + W64LIT(0x9b3beef5fc41f80e), W64LIT(0x2e2779a8e70d3081), W64LIT(0x4d469073d993eecc), W64LIT(0x768fe0a965e2b488), + W64LIT(0xd0e8aeecd2d380df), W64LIT(0xa2812509e6c4d041), W64LIT(0x0ff3d5e1068c7aba), W64LIT(0x04e66b4c51f5e416), + W64LIT(0x2c54c28e41f9428a), W64LIT(0x01b7d313537a398b), W64LIT(0xcc60a215782206bd), W64LIT(0xc506a79e89afea1a), + W64LIT(0x4cf143608ae9d747), W64LIT(0x8a338ccbf6c876dd), W64LIT(0x29057ad143769f17), W64LIT(0xcfa4ca208dac4d3d), + W64LIT(0xa6674e45b7313457), W64LIT(0x50794f9920185125), W64LIT(0xb89cf99abb34c03e), W64LIT(0x343aa53bbafd20fe), + W64LIT(0x89f7e4fe03463d5d), W64LIT(0xa5a3267042bf7fd7), W64LIT(0xefc7b57a3f573e8d), W64LIT(0x9fdd85b9adb41c18), + W64LIT(0xec03dd4fcad9750d), W64LIT(0x970c53210f43c934), W64LIT(0xc7751cb82f5b9811), W64LIT(0xc1e0ccd2d85a0e0c), + W64LIT(0xad72f0e8e048aafb), W64LIT(0x0966058bf18deca7), W64LIT(0x47e4fdcddd9049eb), W64LIT(0x19d9b4a6a87e5bff), + W64LIT(0x1a1ddc935df0107f), W64LIT(0x591f4a12d195bd82), W64LIT(0x1efbb7df0c05f469), W64LIT(0x575b4ce08463feb3), + W64LIT(0x0e4406f255f64331), W64LIT(0x2ac112e4b6f8d497), W64LIT(0xa0f29e2f4030a24a), W64LIT(0x179db254fd8818ce), + W64LIT(0x663051843c1103d0), W64LIT(0xe4d20bd7682ea021), W64LIT(0xd15f7dff81a9b954), W64LIT(0xd32cc6d9275dcb5f), + W64LIT(0x94c83b14facd82b4), W64LIT(0xaa50f3914433056d), W64LIT(0x358d7628e9871975), W64LIT(0xbc7a92d6eac12428), + W64LIT(0x39bacbfc1a85284f), W64LIT(0x9199834bf8425f29), W64LIT(0x73de58f6676d6915), W64LIT(0xd5b916b3d05c5d42), + W64LIT(0x46532ede8eea7060), W64LIT(0x186e67b5fb046274), W64LIT(0xa1454d3c134a9bc1), W64LIT(0x0b15bead57799eac), + W64LIT(0x5adb2227241bf602), W64LIT(0xdd68c02b72ab886e), W64LIT(0x6443eaa29ae571db), W64LIT(0xfd0bbf71c050fbde), + W64LIT(0x8b845fd8a5b24f56), W64LIT(0xb92b2a89e84ef9b5), W64LIT(0x678782976f6b3a5b), W64LIT(0xf2f86a90c6dc8164), + W64LIT(0xc39377f47eae7c07), W64LIT(0x93ea386d5eb62d22), W64LIT(0x430296818c65adfd), W64LIT(0xc224a4e72dd4458c), + W64LIT(0x9e6a56aafece2593), W64LIT(0x6f56540fcd9cef77), W64LIT(0x84778a39a33e35ec), W64LIT(0xf85a072ec2df2643), + W64LIT(0x3bc970dabc715a44), W64LIT(0x0d806ec7a07808b1), W64LIT(0x773833ba36988d03), W64LIT(0x27417c231680dc26), + W64LIT(0x60a581eecb1095cd), W64LIT(0xb76f2c7bbdb8ba84), W64LIT(0xd8397874702455f3), W64LIT(0xfecfd74435deb05e), + W64LIT(0xcaf5727f8f2390a0), W64LIT(0xa9949ba4b1bd4eed), W64LIT(0xe034609b39db4437), W64LIT(0x2b76c1f7e582ed1c), + W64LIT(0xf7a9d2cfc4535cf9), W64LIT(0x20637f5ab2fb73b0), W64LIT(0x9c19ed8c583a5798), W64LIT(0xd67d7e8625d216c2), + W64LIT(0x1459da610806534e), W64LIT(0x6d25ef296b689d7c), W64LIT(0x925deb7e0dcc14a9), W64LIT(0x65f439b1c99f4850), + W64LIT(0x957fe807a9b7bb3f), W64LIT(0x41712da72a91dff6), W64LIT(0x36491e1d1c0952f5), W64LIT(0x5e3d496b75ee1214), + W64LIT(0x1d3fdfeaf98bbfe9), W64LIT(0x701a30c392e32295), W64LIT(0x6361e9db3e9ede4d), W64LIT(0xd7caad9576a82f49), + W64LIT(0xe71663e29da0eba1), W64LIT(0x98ff86c009cfb38e), W64LIT(0x6bb03f439c690b61), W64LIT(0xc4b1748ddad5d391), + W64LIT(0x6c923c3a3812a4f7), W64LIT(0x1f4c64cc5f7fcde2), W64LIT(0xe183b3886aa17dbc), W64LIT(0xb6d8ff68eec2830f), + W64LIT(0x51ce9c8a736268ae), W64LIT(0x07220379a47baf96), W64LIT(0x82e25a53543fa3f1), W64LIT(0xbb5891af4eba8bbe), + W64LIT(0x4bd340192e9278d1), W64LIT(0x6874577669e740e1), W64LIT(0xfb9e6f1b37516dc3), W64LIT(0xacc523fbb3329370), + W64LIT(0x69c384653a9d796a), W64LIT(0x5b6cf1347761cf89), W64LIT(0x0000000000000000), W64LIT(0x49a0fb3f88660ada), + W64LIT(0xa336f61ab5bee9ca), W64LIT(0x15ee09725b7c6ac5), W64LIT(0x8d118fb252b3d94b), W64LIT(0x7d9a5e04329b2a24), + W64LIT(0x1baa0f800e8a29f4), W64LIT(0xfa29bc08642b5448), W64LIT(0x459746eb7b643be0), W64LIT(0xdf1b7b0dd45ffa65), + W64LIT(0x30dcce77eb08c4e8), W64LIT(0x8091e175f2cbd1fa), W64LIT(0x0c37bdd4f302313a), W64LIT(0xf9edd43d91a51fc8), + W64LIT(0x3a7ea3c9ef0b63cf), W64LIT(0x74fc5b8fc316c683), W64LIT(0x8ca65ca101c9e0c0), W64LIT(0x72698be53417509e), + W64LIT(0x23a7176f47753830), W64LIT(0x797c3548636ece32), W64LIT(0xb51c975d1b4cc88f), W64LIT(0x2210c47c140f01bb), + W64LIT(0xd29b15ca7427f2d4), W64LIT(0x8ed5e787a73d92cb), W64LIT(0x7e5e3631c71561a4), W64LIT(0x1c880cf9aaf18662), + W64LIT(0xf08bd1b66028f36f), W64LIT(0xf61e01dc97296572), W64LIT(0x7b0f8e6ec59abc39), W64LIT(0xb3894737ec4d5e92), + W64LIT(0x316b1d64b872fd63), W64LIT(0x9a8c3de6af3bc185), W64LIT(0x0aa26dbe0403a727), W64LIT(0x5f8a9a7826942b9f), + W64LIT(0x520af4bf86ec232e), W64LIT(0x380d18ef49ff11c4), W64LIT(0x0695d06af701961d), W64LIT(0x87b3e20c56b07e6c), + W64LIT(0x53bd27acd5961aa5), W64LIT(0x7c2d8d1761e113af), W64LIT(0x28b2a9c2100ca69c), W64LIT(0x6a07ec50cf1332ea), + W64LIT(0xe9526510c856a890), W64LIT(0xcdd771062b583f36), W64LIT(0xfcbc6c62932ac255), W64LIT(0x9dae3e9f0b406e13), + W64LIT(0xd40ec5a0832664c9), W64LIT(0x78cbe65b3014f7b9), W64LIT(0x4e82f8462c1da54c), W64LIT(0x611252fd986aac46) + }, + { + W64LIT(0x352b557f679cc74f), W64LIT(0x3e9424bf376719b2), W64LIT(0x5deb7e0dcc14a992), W64LIT(0xb3e20c56b07e6c87), + W64LIT(0x83b3886aa17dbce1), W64LIT(0x3d496b75ee12145e), W64LIT(0xae3e9f0b406e139d), W64LIT(0x8a9a7826942b9f5f), + W64LIT(0x845fd8a5b24f568b), W64LIT(0x5a072ec2df2643f8), W64LIT(0xf3d5e1068c7aba0f), W64LIT(0x7ea3c9ef0b63cf3a), + W64LIT(0x923c3a3812a4f76c), W64LIT(0x3fdfeaf98bbfe91d), W64LIT(0xd340192e9278d14b), W64LIT(0x04311f05ca47e786), + W64LIT(0xcc0a0bff07c55312), W64LIT(0xff86c009cfb38e98), W64LIT(0xade3d0c1991b1e71), W64LIT(0xfc5b8fc316c68374), + W64LIT(0xbb80325c39f0bf96), W64LIT(0xd5e787a73d92cb8e), W64LIT(0xa4ca208dac4d3dcf), W64LIT(0xf6af3045fae5ad26), + W64LIT(0x5b4ce08463feb357), W64LIT(0x8bd1b66028f36ff0), W64LIT(0xb698dd15c6e17bae), W64LIT(0x2f1b96ed84be523f), + W64LIT(0x4037ed503c04d688), W64LIT(0x6a56aafece25939e), W64LIT(0xb40e5c99a34c86ed), W64LIT(0xc6feb479ebe67d40), + W64LIT(0x9b15ca7427f2d4d2), W64LIT(0xde58f6676d691573), W64LIT(0xc523fbb3329370ac), W64LIT(0xe5b6039b2c911be8), + W64LIT(0x8d7628e987197535), W64LIT(0xf008aecc550fb7e3), W64LIT(0xd9b4a6a87e5bff19), W64LIT(0xc112e4b6f8d4972a), + W64LIT(0xdf133821d1b1e5dc), W64LIT(0xaf75514dfcb6e332), W64LIT(0x2095f8281e026b44), W64LIT(0xb54592df1f947642), + W64LIT(0x8eab67235e6c78d9), W64LIT(0x698be53417509e72), W64LIT(0xbc6c62932ac255fc), W64LIT(0x1f4a12d195bd8259), + W64LIT(0x15bead57799eac0b), W64LIT(0x1ddc935df0107f1a), W64LIT(0x131933ded674b6ce), W64LIT(0xe66b4c51f5e41604), + W64LIT(0x9db254fd8818ce17), W64LIT(0xa26dbe0403a7270a), W64LIT(0x17282cdb1c335148), W64LIT(0x47dbbd9f2f363ce2), + W64LIT(0xda69e962a72ef2f5), W64LIT(0x469073d993eecc4d), W64LIT(0xfafc114ab92c99b1), W64LIT(0x90aabbb477090a2f), + W64LIT(0xb2a9c2100ca69c28), W64LIT(0xa65ca101c9e0c08c), W64LIT(0xd09d56e44b0ddca7), W64LIT(0x3833ba36988d0377), + W64LIT(0x59da610806534e14), W64LIT(0x19ed8c583a57989c), W64LIT(0x491e1d1c0952f536), W64LIT(0xeb73a3180af5d23c), + W64LIT(0x2779a8e70d30812e), W64LIT(0x86c95929d7e2abc8), W64LIT(0xedd43d91a51fc8f9), W64LIT(0xb03f439c690b616b), + W64LIT(0x9e6f1b37516dc3fb), W64LIT(0x78045766a489d5ff), W64LIT(0x3c02a53352cae4f1), W64LIT(0x1c975d1b4cc88fb5), + W64LIT(0x55894007459a7a83), W64LIT(0xc384653a9d796a69), W64LIT(0x674e45b7313457a6), W64LIT(0x454d3c134a9bc1a1), + W64LIT(0xce9c8a736268ae51), W64LIT(0x98c885befe87d93e), W64LIT(0x0d18ef49ff11c438), W64LIT(0x66058bf18deca709), + W64LIT(0xcfd74435deb05efe), W64LIT(0x4ac352d6d027f8da), W64LIT(0x880cf9aaf186621c), W64LIT(0x0c53210f43c93497), + W64LIT(0x36f61ab5bee9caa3), W64LIT(0x526510c856a890e9), W64LIT(0x64930a7de8415a4a), W64LIT(0x1a30c392e3229570), + W64LIT(0x778a39a33e35ec84), W64LIT(0xbefae31f4f6fa8bf), W64LIT(0x2cc6d9275dcb5fd3), W64LIT(0xf439b1c99f485065), + W64LIT(0xa581eecb1095cd60), W64LIT(0x28f7c622978cb855), W64LIT(0x220379a47baf9607), W64LIT(0x7d7e8625d216c2d6), + W64LIT(0xd63ac86de4e7c662), W64LIT(0xea386d5eb62d2293), W64LIT(0xaa0f800e8a29f41b), W64LIT(0x1b7b0dd45ffa65df), + W64LIT(0x6cf1347761cf895b), W64LIT(0x4fb98395a6b8eff3), W64LIT(0xd4ac49e1814a3b21), W64LIT(0x311a4a7aaddb20c9), + W64LIT(0x32c705b074ae2d25), W64LIT(0xf29e2f4030a24aa0), W64LIT(0x712da72a91dff641), W64LIT(0xe4fdcddd9049eb47), + W64LIT(0xe7208217493ce6ab), W64LIT(0xab444e4836f104b4), W64LIT(0x2a6147aef2214516), W64LIT(0xb916b3d05c5d42d5), + W64LIT(0xd1d698a2f7d52c08), W64LIT(0xb7d313537a398b01), W64LIT(0x4b889c906cff0875), W64LIT(0xcbe65b3014f7b978), + W64LIT(0x812509e6c4d041a2), W64LIT(0xb85d7d96e085b27a), W64LIT(0xef42bc1dc0b235ba), W64LIT(0x18a6421e868f6833), + W64LIT(0x532ede8eea706046), W64LIT(0x2b2a89e84ef9b5b9), W64LIT(0xf86a90c6dc8164f2), W64LIT(0x397874702455f3d8), + W64LIT(0x65d8c43b5499aae5), W64LIT(0x42a16cdc59a92bcb), W64LIT(0x5f7dff81a9b954d1), W64LIT(0x9377f47eae7c07c3), + W64LIT(0x95d06af701961d06), W64LIT(0x34609b39db4437e0), W64LIT(0x8c3de6af3bc1859a), W64LIT(0xfd104185aa1e73db), + W64LIT(0x7bd918ac7dfcd813), W64LIT(0x417c231680dc2627), W64LIT(0x03dd4fcad9750dec), W64LIT(0x14f56311c5465ca4), + W64LIT(0x571fc18b203787c0), W64LIT(0xb1748ddad5d391c4), W64LIT(0xd8ff68eec2830fb6), W64LIT(0x014bce46bcd8f0af), + W64LIT(0x1663e29da0eba1e7), W64LIT(0x637f5ab2fb73b020), W64LIT(0xee09725b7c6ac515), W64LIT(0x0000000000000000), + W64LIT(0x338ccbf6c876dd8a), W64LIT(0x56540fcd9cef776f), W64LIT(0x623494f447ab408f), W64LIT(0x91e175f2cbd1fa80), + W64LIT(0x0f8e6ec59abc397b), W64LIT(0x4855d35ab58a0599), W64LIT(0x894737ec4d5e92b3), W64LIT(0xbd27acd5961aa553), + W64LIT(0x4d2f0219c31512b0), W64LIT(0xe1871c9ee6d6fc6e), W64LIT(0x8fe0a965e2b48876), W64LIT(0x118fb252b3d94b8d), + W64LIT(0xc0592af0440c6785), W64LIT(0xaca81e8725c3eede), W64LIT(0xd771062b583f36cd), W64LIT(0x7066696c2d0706ee), + W64LIT(0x99834bf8425f2991), W64LIT(0x3aa53bbafd20fe34), W64LIT(0x4406f255f643310e), W64LIT(0xa1b0f1cedad22ae6), + W64LIT(0x82f8462c1da54c4e), W64LIT(0x0929f04c355623be), W64LIT(0x057ad143769f1729), W64LIT(0x949ba4b1bd4eeda9), + W64LIT(0x960d253dd8e310ea), W64LIT(0xfecd0e4f736b7e37), W64LIT(0x0296818c65adfd43), W64LIT(0x6f2c7bbdb8ba84b7), + W64LIT(0x9a5e04329b2a247d), W64LIT(0x2348b7e2c77766a8), W64LIT(0xdcce77eb08c4e830), W64LIT(0x851416e30e97a624), + W64LIT(0x08623e0a898ed311), W64LIT(0x43eaa29ae571db64), W64LIT(0xc7b57a3f573e8def), W64LIT(0xc2cfab7c21a19ac6), + W64LIT(0x5ca0b04b70cc593d), W64LIT(0x0ec5a0832664c9d4), W64LIT(0x1e01dc97296572f6), W64LIT(0xbacbfc1a85284f39), + W64LIT(0xc970dabc715a443b), W64LIT(0xa8990182ef840958), W64LIT(0xc83b14facd82b494), W64LIT(0x72f0e8e048aafbad), + W64LIT(0xf143608ae9d7474c), W64LIT(0xf5727f8f2390a0ca), W64LIT(0x7fe807a9b7bb3f95), W64LIT(0x76c1f7e582ed1c2b), + W64LIT(0xcd41c5b9bb1da3bd), W64LIT(0x6b1d64b872fd6331), W64LIT(0x806ec7a07808b10d), W64LIT(0xe3119d12837b012d), + W64LIT(0x25ef296b689d7c6d), W64LIT(0x37bdd4f302313a0c), W64LIT(0x3051843c1103d066), W64LIT(0x68c02b72ab886edd), + W64LIT(0x8782976f6b3a5b67), W64LIT(0x2d8d1761e113af7c), W64LIT(0x1252fd986aac4661), W64LIT(0x0bbf71c050fbdefd), + W64LIT(0xd20bd7682ea021e4), W64LIT(0xe0ccd2d85a0e0cc1), W64LIT(0x9cf99abb34c03eb8), W64LIT(0xdd85b9adb41c189f), + W64LIT(0x61e9db3e9ede4d63), W64LIT(0x06a79e89afea1ac5), W64LIT(0xf7e4fe03463d5d89), W64LIT(0x794f992018512550), + W64LIT(0x3beef5fc41f80e9b), W64LIT(0xcaad9576a82f49d7), W64LIT(0x10c47c140f01bb22), W64LIT(0x0af4bf86ec232e52), + W64LIT(0xdb2227241bf6025a), W64LIT(0x21de366ea2da9beb), W64LIT(0x9f24d571edb53354), W64LIT(0x9746eb7b643be045), + W64LIT(0xa3267042bf7fd7a5), W64LIT(0x6e67b5fb04627418), W64LIT(0xc46835f58e4b8003), W64LIT(0x07ec50cf1332ea6a), + W64LIT(0xe8aeecd2d380dfd0), W64LIT(0xe9e522946f582f7f), W64LIT(0x54c28e41f9428a2c), W64LIT(0xe25a53543fa3f182), + W64LIT(0xa9d2cfc4535cf9f7), W64LIT(0xa0fb3f88660ada49), W64LIT(0x50f3914433056daa), W64LIT(0x51b85f028fdd9d05), + W64LIT(0xec9ff3d719c73856), W64LIT(0x263266a1b1e87181), W64LIT(0x5e3631c71561a47e), W64LIT(0x24a4e72dd4458cc2), + W64LIT(0x74577669e740e168), W64LIT(0x7a92d6eac12428bc), W64LIT(0x2e5058ab3866a290), W64LIT(0x4ef24dd31a601f5c), + W64LIT(0xf9215e806059945d), W64LIT(0xfbb7df0c05f4691e), W64LIT(0x751cb82f5b9811c7), W64LIT(0x29bc08642b5448fa), + W64LIT(0x5891af4eba8bbebb), W64LIT(0x73bb26a6f4720b02), W64LIT(0x6dbafa31dd1779f4), W64LIT(0x7c3548636ece3279), + W64LIT(0x4c64cc5f7fcde21f), W64LIT(0x60a215782206bdcc), W64LIT(0xa7176f4775383023), W64LIT(0xbfb12d59f3b75810) + }, + { + W64LIT(0x51843c1103d06630), W64LIT(0xdfeaf98bbfe91d3f), W64LIT(0xeef5fc41f80e9b3b), W64LIT(0xaf3045fae5ad26f6), + W64LIT(0x70dabc715a443bc9), W64LIT(0x119d12837b012de3), W64LIT(0x3b14facd82b494c8), W64LIT(0xdd4fcad9750dec03), + W64LIT(0xaabbb477090a2f90), W64LIT(0x75514dfcb6e332af), W64LIT(0x96818c65adfd4302), W64LIT(0x1d64b872fd63316b), + W64LIT(0xe4fe03463d5d89f7), W64LIT(0x43608ae9d7474cf1), W64LIT(0xe20c56b07e6c87b3), W64LIT(0xf24dd31a601f5c4e), + W64LIT(0x577669e740e16874), W64LIT(0x609b39db4437e034), W64LIT(0x3ac86de4e7c662d6), W64LIT(0x0379a47baf960722), + W64LIT(0xa79e89afea1ac506), W64LIT(0x4bce46bcd8f0af01), W64LIT(0x267042bf7fd7a5a3), W64LIT(0x7ad143769f172905), + W64LIT(0x85b9adb41c189fdd), W64LIT(0xc885befe87d93e98), W64LIT(0xed8c583a57989c19), W64LIT(0x3c3a3812a4f76c92), + W64LIT(0x5e04329b2a247d9a), W64LIT(0xf99abb34c03eb89c), W64LIT(0x2227241bf6025adb), W64LIT(0x6510c856a890e952), + W64LIT(0xa215782206bdcc60), W64LIT(0x9ff3d719c73856ec), W64LIT(0x02a53352cae4f13c), W64LIT(0x871c9ee6d6fc6ee1), + W64LIT(0x80325c39f0bf96bb), W64LIT(0x8d1761e113af7c2d), W64LIT(0x46eb7b643be04597), W64LIT(0xd8c43b5499aae565), + W64LIT(0x81eecb1095cd60a5), W64LIT(0x9c8a736268ae51ce), W64LIT(0x64cc5f7fcde21f4c), W64LIT(0x7c231680dc262741), + W64LIT(0xc28e41f9428a2c54), W64LIT(0x8ccbf6c876dd8a33), W64LIT(0xb98395a6b8eff34f), W64LIT(0xa9c2100ca69c28b2), + W64LIT(0x6ec7a07808b10d80), W64LIT(0x0a0bff07c55312cc), W64LIT(0xc02b72ab886edd68), W64LIT(0xb85f028fdd9d0551), + W64LIT(0x104185aa1e73dbfd), W64LIT(0xb6039b2c911be8e5), W64LIT(0x79a8e70d30812e27), W64LIT(0x82976f6b3a5b6787), + W64LIT(0xa53bbafd20fe343a), W64LIT(0x7dff81a9b954d15f), W64LIT(0x894007459a7a8355), W64LIT(0xd43d91a51fc8f9ed), + W64LIT(0xccd2d85a0e0cc1e0), W64LIT(0xe807a9b7bb3f957f), W64LIT(0xa81e8725c3eedeac), W64LIT(0x5058ab3866a2902e), + W64LIT(0x889c906cff08754b), W64LIT(0x4ce08463feb3575b), W64LIT(0xdc935df0107f1a1d), W64LIT(0x56aafece25939e6a), + W64LIT(0xa16cdc59a92bcb42), W64LIT(0xec50cf1332ea6a07), W64LIT(0x4592df1f947642b5), W64LIT(0xbafa31dd1779f46d), + W64LIT(0x29f04c355623be09), W64LIT(0x15ca7427f2d4d29b), W64LIT(0x215e806059945df9), W64LIT(0x23fbb3329370acc5), + W64LIT(0xd74435deb05efecf), W64LIT(0xeaa29ae571db6443), W64LIT(0xc95929d7e2abc886), W64LIT(0xa4e72dd4458cc224), + W64LIT(0x3548636ece32797c), W64LIT(0x27acd5961aa553bd), W64LIT(0xac49e1814a3b21d4), W64LIT(0xcbfc1a85284f39ba), + W64LIT(0x8fb252b3d94b8d11), W64LIT(0x42bc1dc0b235baef), W64LIT(0x072ec2df2643f85a), W64LIT(0x91af4eba8bbebb58), + W64LIT(0x045766a489d5ff78), W64LIT(0x9073d993eecc4d46), W64LIT(0x3f439c690b616bb0), W64LIT(0x6b4c51f5e41604e6), + W64LIT(0x7e8625d216c2d67d), W64LIT(0xab67235e6c78d98e), W64LIT(0xef296b689d7c6d25), W64LIT(0xc5a0832664c9d40e), + W64LIT(0x69e962a72ef2f5da), W64LIT(0x7b0dd45ffa65df1b), W64LIT(0x496b75ee12145e3d), W64LIT(0xd918ac7dfcd8137b), + W64LIT(0x1e1d1c0952f53649), W64LIT(0xfeb479ebe67d40c6), W64LIT(0x6147aef22145162a), W64LIT(0x0f800e8a29f41baa), + W64LIT(0x0000000000000000), W64LIT(0x990182ef840958a8), W64LIT(0x975d1b4cc88fb51c), W64LIT(0x5b8fc316c68374fc), + W64LIT(0x16b3d05c5d42d5b9), W64LIT(0xb3886aa17dbce183), W64LIT(0x4f99201851255079), W64LIT(0x98dd15c6e17baeb6), + W64LIT(0x06f255f643310e44), W64LIT(0x6f1b37516dc3fb9e), W64LIT(0x0cf9aaf186621c88), W64LIT(0x8e6ec59abc397b0f), + W64LIT(0x930a7de8415a4a64), W64LIT(0x37ed503c04d68840), W64LIT(0xf61ab5bee9caa336), W64LIT(0xfb3f88660ada49a0), + W64LIT(0x7874702455f3d839), W64LIT(0x208217493ce6abe7), W64LIT(0x73a3180af5d23ceb), W64LIT(0x9e2f4030a24aa0f2), + W64LIT(0xe522946f582f7fe9), W64LIT(0xd5e1068c7aba0ff3), W64LIT(0xbdd4f302313a0c37), W64LIT(0x1fc18b203787c057), + W64LIT(0xd2cfc4535cf9f7a9), W64LIT(0x1b96ed84be523f2f), W64LIT(0x5d7d96e085b27ab8), W64LIT(0x66696c2d0706ee70), + W64LIT(0xd06af701961d0695), W64LIT(0xe3d0c1991b1e71ad), W64LIT(0x6c62932ac255fcbc), W64LIT(0xd313537a398b01b7), + W64LIT(0xa0b04b70cc593d5c), W64LIT(0x834bf8425f299199), W64LIT(0xaeecd2d380dfd0e8), W64LIT(0xbead57799eac0b15), + W64LIT(0x540fcd9cef776f56), W64LIT(0xad9576a82f49d7ca), W64LIT(0xfc114ab92c99b1fa), W64LIT(0x33ba36988d037738), + W64LIT(0xbb26a6f4720b0273), W64LIT(0xb254fd8818ce179d), W64LIT(0xa6421e868f683318), W64LIT(0x5fd8a5b24f568b84), + W64LIT(0x623e0a898ed31108), W64LIT(0xb0f1cedad22ae6a1), W64LIT(0x1933ded674b6ce13), W64LIT(0x1416e30e97a62485), + W64LIT(0x3e9f0b406e139dae), W64LIT(0x6dbe0403a7270aa2), W64LIT(0xbc08642b5448fa29), W64LIT(0x0d253dd8e310ea96), + W64LIT(0x2ede8eea70604653), W64LIT(0x39b1c99f485065f4), W64LIT(0xcd0e4f736b7e37fe), W64LIT(0xbf71c050fbdefd0b), + W64LIT(0x748ddad5d391c4b1), W64LIT(0x0bd7682ea021e4d2), W64LIT(0x3494f447ab408f62), W64LIT(0xb4a6a87e5bff19d9), + W64LIT(0x133821d1b1e5dcdf), W64LIT(0x95f8281e026b4420), W64LIT(0x2da72a91dff64171), W64LIT(0x18ef49ff11c4380d), + W64LIT(0xc705b074ae2d2532), W64LIT(0x3de6af3bc1859a8c), W64LIT(0x6835f58e4b8003c4), W64LIT(0xe787a73d92cb8ed5), + W64LIT(0xc6d9275dcb5fd32c), W64LIT(0xf7c622978cb85528), W64LIT(0x4d3c134a9bc1a145), W64LIT(0xf3914433056daa50), + W64LIT(0xb7df0c05f4691efb), W64LIT(0xe175f2cbd1fa8091), W64LIT(0x77f47eae7c07c393), W64LIT(0xeb7e0dcc14a9925d), + W64LIT(0xf1347761cf895b6c), W64LIT(0x08aecc550fb7e3f0), W64LIT(0x55d35ab58a059948), W64LIT(0x444e4836f104b4ab), + W64LIT(0x58f6676d691573de), W64LIT(0x9ba4b1bd4eeda994), W64LIT(0x92d6eac12428bc7a), W64LIT(0xb12d59f3b75810bf), + W64LIT(0xa3c9ef0b63cf3a7e), W64LIT(0x67b5fb046274186e), W64LIT(0x2f0219c31512b04d), W64LIT(0x3266a1b1e8718126), + W64LIT(0x7628e9871975358d), W64LIT(0xda610806534e1459), W64LIT(0x311f05ca47e78604), W64LIT(0x12e4b6f8d4972ac1), + W64LIT(0x282cdb1c33514817), W64LIT(0x727f8f2390a0caf5), W64LIT(0xb57a3f573e8defc7), W64LIT(0x71062b583f36cdd7), + W64LIT(0x84653a9d796a69c3), W64LIT(0xf56311c5465ca414), W64LIT(0x4737ec4d5e92b389), W64LIT(0x1cb82f5b9811c775), + W64LIT(0x2509e6c4d041a281), W64LIT(0xfdcddd9049eb47e4), W64LIT(0x40192e9278d14bd3), W64LIT(0x2a89e84ef9b5b92b), + W64LIT(0x3631c71561a47e5e), W64LIT(0x8be53417509e7269), W64LIT(0x24d571edb533549f), W64LIT(0xc352d6d027f8da4a), + W64LIT(0x01dc97296572f61e), W64LIT(0xe9db3e9ede4d6361), W64LIT(0x4e45b7313457a667), W64LIT(0xf8462c1da54c4e82), + W64LIT(0x4a12d195bd82591f), W64LIT(0xff68eec2830fb6d8), W64LIT(0x176f4775383023a7), W64LIT(0x48b7e2c77766a823), + W64LIT(0x592af0440c6785c0), W64LIT(0x2c7bbdb8ba84b76f), W64LIT(0x5ca101c9e0c08ca6), W64LIT(0x63e29da0eba1e716), + W64LIT(0xd698a2f7d52c08d1), W64LIT(0xce77eb08c4e830dc), W64LIT(0xde366ea2da9beb21), W64LIT(0x5a53543fa3f182e2), + W64LIT(0x52fd986aac466112), W64LIT(0x86c009cfb38e98ff), W64LIT(0xd1b66028f36ff08b), W64LIT(0x1a4a7aaddb20c931), + W64LIT(0xcfab7c21a19ac6c2), W64LIT(0x09725b7c6ac515ee), W64LIT(0x0e5c99a34c86edb4), W64LIT(0xdbbd9f2f363ce247), + W64LIT(0x6a90c6dc8164f2f8), W64LIT(0x8a39a33e35ec8477), W64LIT(0xe0a965e2b488768f), W64LIT(0x7f5ab2fb73b02063), + W64LIT(0xf4bf86ec232e520a), W64LIT(0xfae31f4f6fa8bfbe), W64LIT(0x058bf18deca70966), W64LIT(0x41c5b9bb1da3bdcd), + W64LIT(0x2b557f679cc74f35), W64LIT(0xca208dac4d3dcfa4), W64LIT(0x9a7826942b9f5f8a), W64LIT(0xf0e8e048aafbad72), + W64LIT(0x53210f43c934970c), W64LIT(0xc1f7e582ed1c2b76), W64LIT(0xc47c140f01bb2210), W64LIT(0x9d56e44b0ddca7d0), + W64LIT(0x386d5eb62d2293ea), W64LIT(0xe65b3014f7b978cb), W64LIT(0x9424bf376719b23e), W64LIT(0x30c392e32295701a) + } +}; + +const byte S[4][256] = +{ + { + 0xA8, 0x43, 0x5F, 0x06, 0x6B, 0x75, 0x6C, 0x59, 0x71, 0xDF, 0x87, 0x95, 0x17, 0xF0, 0xD8, 0x09, + 0x6D, 0xF3, 0x1D, 0xCB, 0xC9, 0x4D, 0x2C, 0xAF, 0x79, 0xE0, 0x97, 0xFD, 0x6F, 0x4B, 0x45, 0x39, + 0x3E, 0xDD, 0xA3, 0x4F, 0xB4, 0xB6, 0x9A, 0x0E, 0x1F, 0xBF, 0x15, 0xE1, 0x49, 0xD2, 0x93, 0xC6, + 0x92, 0x72, 0x9E, 0x61, 0xD1, 0x63, 0xFA, 0xEE, 0xF4, 0x19, 0xD5, 0xAD, 0x58, 0xA4, 0xBB, 0xA1, + 0xDC, 0xF2, 0x83, 0x37, 0x42, 0xE4, 0x7A, 0x32, 0x9C, 0xCC, 0xAB, 0x4A, 0x8F, 0x6E, 0x04, 0x27, + 0x2E, 0xE7, 0xE2, 0x5A, 0x96, 0x16, 0x23, 0x2B, 0xC2, 0x65, 0x66, 0x0F, 0xBC, 0xA9, 0x47, 0x41, + 0x34, 0x48, 0xFC, 0xB7, 0x6A, 0x88, 0xA5, 0x53, 0x86, 0xF9, 0x5B, 0xDB, 0x38, 0x7B, 0xC3, 0x1E, + 0x22, 0x33, 0x24, 0x28, 0x36, 0xC7, 0xB2, 0x3B, 0x8E, 0x77, 0xBA, 0xF5, 0x14, 0x9F, 0x08, 0x55, + 0x9B, 0x4C, 0xFE, 0x60, 0x5C, 0xDA, 0x18, 0x46, 0xCD, 0x7D, 0x21, 0xB0, 0x3F, 0x1B, 0x89, 0xFF, + 0xEB, 0x84, 0x69, 0x3A, 0x9D, 0xD7, 0xD3, 0x70, 0x67, 0x40, 0xB5, 0xDE, 0x5D, 0x30, 0x91, 0xB1, + 0x78, 0x11, 0x01, 0xE5, 0x00, 0x68, 0x98, 0xA0, 0xC5, 0x02, 0xA6, 0x74, 0x2D, 0x0B, 0xA2, 0x76, + 0xB3, 0xBE, 0xCE, 0xBD, 0xAE, 0xE9, 0x8A, 0x31, 0x1C, 0xEC, 0xF1, 0x99, 0x94, 0xAA, 0xF6, 0x26, + 0x2F, 0xEF, 0xE8, 0x8C, 0x35, 0x03, 0xD4, 0x7F, 0xFB, 0x05, 0xC1, 0x5E, 0x90, 0x20, 0x3D, 0x82, + 0xF7, 0xEA, 0x0A, 0x0D, 0x7E, 0xF8, 0x50, 0x1A, 0xC4, 0x07, 0x57, 0xB8, 0x3C, 0x62, 0xE3, 0xC8, + 0xAC, 0x52, 0x64, 0x10, 0xD0, 0xD9, 0x13, 0x0C, 0x12, 0x29, 0x51, 0xB9, 0xCF, 0xD6, 0x73, 0x8D, + 0x81, 0x54, 0xC0, 0xED, 0x4E, 0x44, 0xA7, 0x2A, 0x85, 0x25, 0xE6, 0xCA, 0x7C, 0x8B, 0x56, 0x80 + }, + { + 0xCE, 0xBB, 0xEB, 0x92, 0xEA, 0xCB, 0x13, 0xC1, 0xE9, 0x3A, 0xD6, 0xB2, 0xD2, 0x90, 0x17, 0xF8, + 0x42, 0x15, 0x56, 0xB4, 0x65, 0x1C, 0x88, 0x43, 0xC5, 0x5C, 0x36, 0xBA, 0xF5, 0x57, 0x67, 0x8D, + 0x31, 0xF6, 0x64, 0x58, 0x9E, 0xF4, 0x22, 0xAA, 0x75, 0x0F, 0x02, 0xB1, 0xDF, 0x6D, 0x73, 0x4D, + 0x7C, 0x26, 0x2E, 0xF7, 0x08, 0x5D, 0x44, 0x3E, 0x9F, 0x14, 0xC8, 0xAE, 0x54, 0x10, 0xD8, 0xBC, + 0x1A, 0x6B, 0x69, 0xF3, 0xBD, 0x33, 0xAB, 0xFA, 0xD1, 0x9B, 0x68, 0x4E, 0x16, 0x95, 0x91, 0xEE, + 0x4C, 0x63, 0x8E, 0x5B, 0xCC, 0x3C, 0x19, 0xA1, 0x81, 0x49, 0x7B, 0xD9, 0x6F, 0x37, 0x60, 0xCA, + 0xE7, 0x2B, 0x48, 0xFD, 0x96, 0x45, 0xFC, 0x41, 0x12, 0x0D, 0x79, 0xE5, 0x89, 0x8C, 0xE3, 0x20, + 0x30, 0xDC, 0xB7, 0x6C, 0x4A, 0xB5, 0x3F, 0x97, 0xD4, 0x62, 0x2D, 0x06, 0xA4, 0xA5, 0x83, 0x5F, + 0x2A, 0xDA, 0xC9, 0x00, 0x7E, 0xA2, 0x55, 0xBF, 0x11, 0xD5, 0x9C, 0xCF, 0x0E, 0x0A, 0x3D, 0x51, + 0x7D, 0x93, 0x1B, 0xFE, 0xC4, 0x47, 0x09, 0x86, 0x0B, 0x8F, 0x9D, 0x6A, 0x07, 0xB9, 0xB0, 0x98, + 0x18, 0x32, 0x71, 0x4B, 0xEF, 0x3B, 0x70, 0xA0, 0xE4, 0x40, 0xFF, 0xC3, 0xA9, 0xE6, 0x78, 0xF9, + 0x8B, 0x46, 0x80, 0x1E, 0x38, 0xE1, 0xB8, 0xA8, 0xE0, 0x0C, 0x23, 0x76, 0x1D, 0x25, 0x24, 0x05, + 0xF1, 0x6E, 0x94, 0x28, 0x9A, 0x84, 0xE8, 0xA3, 0x4F, 0x77, 0xD3, 0x85, 0xE2, 0x52, 0xF2, 0x82, + 0x50, 0x7A, 0x2F, 0x74, 0x53, 0xB3, 0x61, 0xAF, 0x39, 0x35, 0xDE, 0xCD, 0x1F, 0x99, 0xAC, 0xAD, + 0x72, 0x2C, 0xDD, 0xD0, 0x87, 0xBE, 0x5E, 0xA6, 0xEC, 0x04, 0xC6, 0x03, 0x34, 0xFB, 0xDB, 0x59, + 0xB6, 0xC2, 0x01, 0xF0, 0x5A, 0xED, 0xA7, 0x66, 0x21, 0x7F, 0x8A, 0x27, 0xC7, 0xC0, 0x29, 0xD7 + }, + { + 0x93, 0xD9, 0x9A, 0xB5, 0x98, 0x22, 0x45, 0xFC, 0xBA, 0x6A, 0xDF, 0x02, 0x9F, 0xDC, 0x51, 0x59, + 0x4A, 0x17, 0x2B, 0xC2, 0x94, 0xF4, 0xBB, 0xA3, 0x62, 0xE4, 0x71, 0xD4, 0xCD, 0x70, 0x16, 0xE1, + 0x49, 0x3C, 0xC0, 0xD8, 0x5C, 0x9B, 0xAD, 0x85, 0x53, 0xA1, 0x7A, 0xC8, 0x2D, 0xE0, 0xD1, 0x72, + 0xA6, 0x2C, 0xC4, 0xE3, 0x76, 0x78, 0xB7, 0xB4, 0x09, 0x3B, 0x0E, 0x41, 0x4C, 0xDE, 0xB2, 0x90, + 0x25, 0xA5, 0xD7, 0x03, 0x11, 0x00, 0xC3, 0x2E, 0x92, 0xEF, 0x4E, 0x12, 0x9D, 0x7D, 0xCB, 0x35, + 0x10, 0xD5, 0x4F, 0x9E, 0x4D, 0xA9, 0x55, 0xC6, 0xD0, 0x7B, 0x18, 0x97, 0xD3, 0x36, 0xE6, 0x48, + 0x56, 0x81, 0x8F, 0x77, 0xCC, 0x9C, 0xB9, 0xE2, 0xAC, 0xB8, 0x2F, 0x15, 0xA4, 0x7C, 0xDA, 0x38, + 0x1E, 0x0B, 0x05, 0xD6, 0x14, 0x6E, 0x6C, 0x7E, 0x66, 0xFD, 0xB1, 0xE5, 0x60, 0xAF, 0x5E, 0x33, + 0x87, 0xC9, 0xF0, 0x5D, 0x6D, 0x3F, 0x88, 0x8D, 0xC7, 0xF7, 0x1D, 0xE9, 0xEC, 0xED, 0x80, 0x29, + 0x27, 0xCF, 0x99, 0xA8, 0x50, 0x0F, 0x37, 0x24, 0x28, 0x30, 0x95, 0xD2, 0x3E, 0x5B, 0x40, 0x83, + 0xB3, 0x69, 0x57, 0x1F, 0x07, 0x1C, 0x8A, 0xBC, 0x20, 0xEB, 0xCE, 0x8E, 0xAB, 0xEE, 0x31, 0xA2, + 0x73, 0xF9, 0xCA, 0x3A, 0x1A, 0xFB, 0x0D, 0xC1, 0xFE, 0xFA, 0xF2, 0x6F, 0xBD, 0x96, 0xDD, 0x43, + 0x52, 0xB6, 0x08, 0xF3, 0xAE, 0xBE, 0x19, 0x89, 0x32, 0x26, 0xB0, 0xEA, 0x4B, 0x64, 0x84, 0x82, + 0x6B, 0xF5, 0x79, 0xBF, 0x01, 0x5F, 0x75, 0x63, 0x1B, 0x23, 0x3D, 0x68, 0x2A, 0x65, 0xE8, 0x91, + 0xF6, 0xFF, 0x13, 0x58, 0xF1, 0x47, 0x0A, 0x7F, 0xC5, 0xA7, 0xE7, 0x61, 0x5A, 0x06, 0x46, 0x44, + 0x42, 0x04, 0xA0, 0xDB, 0x39, 0x86, 0x54, 0xAA, 0x8C, 0x34, 0x21, 0x8B, 0xF8, 0x0C, 0x74, 0x67 + }, + { + 0x68, 0x8D, 0xCA, 0x4D, 0x73, 0x4B, 0x4E, 0x2A, 0xD4, 0x52, 0x26, 0xB3, 0x54, 0x1E, 0x19, 0x1F, + 0x22, 0x03, 0x46, 0x3D, 0x2D, 0x4A, 0x53, 0x83, 0x13, 0x8A, 0xB7, 0xD5, 0x25, 0x79, 0xF5, 0xBD, + 0x58, 0x2F, 0x0D, 0x02, 0xED, 0x51, 0x9E, 0x11, 0xF2, 0x3E, 0x55, 0x5E, 0xD1, 0x16, 0x3C, 0x66, + 0x70, 0x5D, 0xF3, 0x45, 0x40, 0xCC, 0xE8, 0x94, 0x56, 0x08, 0xCE, 0x1A, 0x3A, 0xD2, 0xE1, 0xDF, + 0xB5, 0x38, 0x6E, 0x0E, 0xE5, 0xF4, 0xF9, 0x86, 0xE9, 0x4F, 0xD6, 0x85, 0x23, 0xCF, 0x32, 0x99, + 0x31, 0x14, 0xAE, 0xEE, 0xC8, 0x48, 0xD3, 0x30, 0xA1, 0x92, 0x41, 0xB1, 0x18, 0xC4, 0x2C, 0x71, + 0x72, 0x44, 0x15, 0xFD, 0x37, 0xBE, 0x5F, 0xAA, 0x9B, 0x88, 0xD8, 0xAB, 0x89, 0x9C, 0xFA, 0x60, + 0xEA, 0xBC, 0x62, 0x0C, 0x24, 0xA6, 0xA8, 0xEC, 0x67, 0x20, 0xDB, 0x7C, 0x28, 0xDD, 0xAC, 0x5B, + 0x34, 0x7E, 0x10, 0xF1, 0x7B, 0x8F, 0x63, 0xA0, 0x05, 0x9A, 0x43, 0x77, 0x21, 0xBF, 0x27, 0x09, + 0xC3, 0x9F, 0xB6, 0xD7, 0x29, 0xC2, 0xEB, 0xC0, 0xA4, 0x8B, 0x8C, 0x1D, 0xFB, 0xFF, 0xC1, 0xB2, + 0x97, 0x2E, 0xF8, 0x65, 0xF6, 0x75, 0x07, 0x04, 0x49, 0x33, 0xE4, 0xD9, 0xB9, 0xD0, 0x42, 0xC7, + 0x6C, 0x90, 0x00, 0x8E, 0x6F, 0x50, 0x01, 0xC5, 0xDA, 0x47, 0x3F, 0xCD, 0x69, 0xA2, 0xE2, 0x7A, + 0xA7, 0xC6, 0x93, 0x0F, 0x0A, 0x06, 0xE6, 0x2B, 0x96, 0xA3, 0x1C, 0xAF, 0x6A, 0x12, 0x84, 0x39, + 0xE7, 0xB0, 0x82, 0xF7, 0xFE, 0x9D, 0x87, 0x5C, 0x81, 0x35, 0xDE, 0xB4, 0xA5, 0xFC, 0x80, 0xEF, + 0xCB, 0xBB, 0x6B, 0x76, 0xBA, 0x5A, 0x7D, 0x78, 0x0B, 0x95, 0xE3, 0xAD, 0x74, 0x98, 0x3B, 0x36, + 0x64, 0x6D, 0xDC, 0xF0, 0x59, 0xA9, 0x4C, 0x17, 0x7F, 0x91, 0xB8, 0xC9, 0x57, 0x1B, 0xE0, 0x61 + } +}; + +const byte IS[4][256] = +{ + { + 0xA4, 0xA2, 0xA9, 0xC5, 0x4E, 0xC9, 0x03, 0xD9, 0x7E, 0x0F, 0xD2, 0xAD, 0xE7, 0xD3, 0x27, 0x5B, + 0xE3, 0xA1, 0xE8, 0xE6, 0x7C, 0x2A, 0x55, 0x0C, 0x86, 0x39, 0xD7, 0x8D, 0xB8, 0x12, 0x6F, 0x28, + 0xCD, 0x8A, 0x70, 0x56, 0x72, 0xF9, 0xBF, 0x4F, 0x73, 0xE9, 0xF7, 0x57, 0x16, 0xAC, 0x50, 0xC0, + 0x9D, 0xB7, 0x47, 0x71, 0x60, 0xC4, 0x74, 0x43, 0x6C, 0x1F, 0x93, 0x77, 0xDC, 0xCE, 0x20, 0x8C, + 0x99, 0x5F, 0x44, 0x01, 0xF5, 0x1E, 0x87, 0x5E, 0x61, 0x2C, 0x4B, 0x1D, 0x81, 0x15, 0xF4, 0x23, + 0xD6, 0xEA, 0xE1, 0x67, 0xF1, 0x7F, 0xFE, 0xDA, 0x3C, 0x07, 0x53, 0x6A, 0x84, 0x9C, 0xCB, 0x02, + 0x83, 0x33, 0xDD, 0x35, 0xE2, 0x59, 0x5A, 0x98, 0xA5, 0x92, 0x64, 0x04, 0x06, 0x10, 0x4D, 0x1C, + 0x97, 0x08, 0x31, 0xEE, 0xAB, 0x05, 0xAF, 0x79, 0xA0, 0x18, 0x46, 0x6D, 0xFC, 0x89, 0xD4, 0xC7, + 0xFF, 0xF0, 0xCF, 0x42, 0x91, 0xF8, 0x68, 0x0A, 0x65, 0x8E, 0xB6, 0xFD, 0xC3, 0xEF, 0x78, 0x4C, + 0xCC, 0x9E, 0x30, 0x2E, 0xBC, 0x0B, 0x54, 0x1A, 0xA6, 0xBB, 0x26, 0x80, 0x48, 0x94, 0x32, 0x7D, + 0xA7, 0x3F, 0xAE, 0x22, 0x3D, 0x66, 0xAA, 0xF6, 0x00, 0x5D, 0xBD, 0x4A, 0xE0, 0x3B, 0xB4, 0x17, + 0x8B, 0x9F, 0x76, 0xB0, 0x24, 0x9A, 0x25, 0x63, 0xDB, 0xEB, 0x7A, 0x3E, 0x5C, 0xB3, 0xB1, 0x29, + 0xF2, 0xCA, 0x58, 0x6E, 0xD8, 0xA8, 0x2F, 0x75, 0xDF, 0x14, 0xFB, 0x13, 0x49, 0x88, 0xB2, 0xEC, + 0xE4, 0x34, 0x2D, 0x96, 0xC6, 0x3A, 0xED, 0x95, 0x0E, 0xE5, 0x85, 0x6B, 0x40, 0x21, 0x9B, 0x09, + 0x19, 0x2B, 0x52, 0xDE, 0x45, 0xA3, 0xFA, 0x51, 0xC2, 0xB5, 0xD1, 0x90, 0xB9, 0xF3, 0x37, 0xC1, + 0x0D, 0xBA, 0x41, 0x11, 0x38, 0x7B, 0xBE, 0xD0, 0xD5, 0x69, 0x36, 0xC8, 0x62, 0x1B, 0x82, 0x8F + }, + { + 0x83, 0xF2, 0x2A, 0xEB, 0xE9, 0xBF, 0x7B, 0x9C, 0x34, 0x96, 0x8D, 0x98, 0xB9, 0x69, 0x8C, 0x29, + 0x3D, 0x88, 0x68, 0x06, 0x39, 0x11, 0x4C, 0x0E, 0xA0, 0x56, 0x40, 0x92, 0x15, 0xBC, 0xB3, 0xDC, + 0x6F, 0xF8, 0x26, 0xBA, 0xBE, 0xBD, 0x31, 0xFB, 0xC3, 0xFE, 0x80, 0x61, 0xE1, 0x7A, 0x32, 0xD2, + 0x70, 0x20, 0xA1, 0x45, 0xEC, 0xD9, 0x1A, 0x5D, 0xB4, 0xD8, 0x09, 0xA5, 0x55, 0x8E, 0x37, 0x76, + 0xA9, 0x67, 0x10, 0x17, 0x36, 0x65, 0xB1, 0x95, 0x62, 0x59, 0x74, 0xA3, 0x50, 0x2F, 0x4B, 0xC8, + 0xD0, 0x8F, 0xCD, 0xD4, 0x3C, 0x86, 0x12, 0x1D, 0x23, 0xEF, 0xF4, 0x53, 0x19, 0x35, 0xE6, 0x7F, + 0x5E, 0xD6, 0x79, 0x51, 0x22, 0x14, 0xF7, 0x1E, 0x4A, 0x42, 0x9B, 0x41, 0x73, 0x2D, 0xC1, 0x5C, + 0xA6, 0xA2, 0xE0, 0x2E, 0xD3, 0x28, 0xBB, 0xC9, 0xAE, 0x6A, 0xD1, 0x5A, 0x30, 0x90, 0x84, 0xF9, + 0xB2, 0x58, 0xCF, 0x7E, 0xC5, 0xCB, 0x97, 0xE4, 0x16, 0x6C, 0xFA, 0xB0, 0x6D, 0x1F, 0x52, 0x99, + 0x0D, 0x4E, 0x03, 0x91, 0xC2, 0x4D, 0x64, 0x77, 0x9F, 0xDD, 0xC4, 0x49, 0x8A, 0x9A, 0x24, 0x38, + 0xA7, 0x57, 0x85, 0xC7, 0x7C, 0x7D, 0xE7, 0xF6, 0xB7, 0xAC, 0x27, 0x46, 0xDE, 0xDF, 0x3B, 0xD7, + 0x9E, 0x2B, 0x0B, 0xD5, 0x13, 0x75, 0xF0, 0x72, 0xB6, 0x9D, 0x1B, 0x01, 0x3F, 0x44, 0xE5, 0x87, + 0xFD, 0x07, 0xF1, 0xAB, 0x94, 0x18, 0xEA, 0xFC, 0x3A, 0x82, 0x5F, 0x05, 0x54, 0xDB, 0x00, 0x8B, + 0xE3, 0x48, 0x0C, 0xCA, 0x78, 0x89, 0x0A, 0xFF, 0x3E, 0x5B, 0x81, 0xEE, 0x71, 0xE2, 0xDA, 0x2C, + 0xB8, 0xB5, 0xCC, 0x6E, 0xA8, 0x6B, 0xAD, 0x60, 0xC6, 0x08, 0x04, 0x02, 0xE8, 0xF5, 0x4F, 0xA4, + 0xF3, 0xC0, 0xCE, 0x43, 0x25, 0x1C, 0x21, 0x33, 0x0F, 0xAF, 0x47, 0xED, 0x66, 0x63, 0x93, 0xAA + }, + { + 0x45, 0xD4, 0x0B, 0x43, 0xF1, 0x72, 0xED, 0xA4, 0xC2, 0x38, 0xE6, 0x71, 0xFD, 0xB6, 0x3A, 0x95, + 0x50, 0x44, 0x4B, 0xE2, 0x74, 0x6B, 0x1E, 0x11, 0x5A, 0xC6, 0xB4, 0xD8, 0xA5, 0x8A, 0x70, 0xA3, + 0xA8, 0xFA, 0x05, 0xD9, 0x97, 0x40, 0xC9, 0x90, 0x98, 0x8F, 0xDC, 0x12, 0x31, 0x2C, 0x47, 0x6A, + 0x99, 0xAE, 0xC8, 0x7F, 0xF9, 0x4F, 0x5D, 0x96, 0x6F, 0xF4, 0xB3, 0x39, 0x21, 0xDA, 0x9C, 0x85, + 0x9E, 0x3B, 0xF0, 0xBF, 0xEF, 0x06, 0xEE, 0xE5, 0x5F, 0x20, 0x10, 0xCC, 0x3C, 0x54, 0x4A, 0x52, + 0x94, 0x0E, 0xC0, 0x28, 0xF6, 0x56, 0x60, 0xA2, 0xE3, 0x0F, 0xEC, 0x9D, 0x24, 0x83, 0x7E, 0xD5, + 0x7C, 0xEB, 0x18, 0xD7, 0xCD, 0xDD, 0x78, 0xFF, 0xDB, 0xA1, 0x09, 0xD0, 0x76, 0x84, 0x75, 0xBB, + 0x1D, 0x1A, 0x2F, 0xB0, 0xFE, 0xD6, 0x34, 0x63, 0x35, 0xD2, 0x2A, 0x59, 0x6D, 0x4D, 0x77, 0xE7, + 0x8E, 0x61, 0xCF, 0x9F, 0xCE, 0x27, 0xF5, 0x80, 0x86, 0xC7, 0xA6, 0xFB, 0xF8, 0x87, 0xAB, 0x62, + 0x3F, 0xDF, 0x48, 0x00, 0x14, 0x9A, 0xBD, 0x5B, 0x04, 0x92, 0x02, 0x25, 0x65, 0x4C, 0x53, 0x0C, + 0xF2, 0x29, 0xAF, 0x17, 0x6C, 0x41, 0x30, 0xE9, 0x93, 0x55, 0xF7, 0xAC, 0x68, 0x26, 0xC4, 0x7D, + 0xCA, 0x7A, 0x3E, 0xA0, 0x37, 0x03, 0xC1, 0x36, 0x69, 0x66, 0x08, 0x16, 0xA7, 0xBC, 0xC5, 0xD3, + 0x22, 0xB7, 0x13, 0x46, 0x32, 0xE8, 0x57, 0x88, 0x2B, 0x81, 0xB2, 0x4E, 0x64, 0x1C, 0xAA, 0x91, + 0x58, 0x2E, 0x9B, 0x5C, 0x1B, 0x51, 0x73, 0x42, 0x23, 0x01, 0x6E, 0xF3, 0x0D, 0xBE, 0x3D, 0x0A, + 0x2D, 0x1F, 0x67, 0x33, 0x19, 0x7B, 0x5E, 0xEA, 0xDE, 0x8B, 0xCB, 0xA9, 0x8C, 0x8D, 0xAD, 0x49, + 0x82, 0xE4, 0xBA, 0xC3, 0x15, 0xD1, 0xE0, 0x89, 0xFC, 0xB1, 0xB9, 0xB5, 0x07, 0x79, 0xB8, 0xE1 + }, + { + 0xB2, 0xB6, 0x23, 0x11, 0xA7, 0x88, 0xC5, 0xA6, 0x39, 0x8F, 0xC4, 0xE8, 0x73, 0x22, 0x43, 0xC3, + 0x82, 0x27, 0xCD, 0x18, 0x51, 0x62, 0x2D, 0xF7, 0x5C, 0x0E, 0x3B, 0xFD, 0xCA, 0x9B, 0x0D, 0x0F, + 0x79, 0x8C, 0x10, 0x4C, 0x74, 0x1C, 0x0A, 0x8E, 0x7C, 0x94, 0x07, 0xC7, 0x5E, 0x14, 0xA1, 0x21, + 0x57, 0x50, 0x4E, 0xA9, 0x80, 0xD9, 0xEF, 0x64, 0x41, 0xCF, 0x3C, 0xEE, 0x2E, 0x13, 0x29, 0xBA, + 0x34, 0x5A, 0xAE, 0x8A, 0x61, 0x33, 0x12, 0xB9, 0x55, 0xA8, 0x15, 0x05, 0xF6, 0x03, 0x06, 0x49, + 0xB5, 0x25, 0x09, 0x16, 0x0C, 0x2A, 0x38, 0xFC, 0x20, 0xF4, 0xE5, 0x7F, 0xD7, 0x31, 0x2B, 0x66, + 0x6F, 0xFF, 0x72, 0x86, 0xF0, 0xA3, 0x2F, 0x78, 0x00, 0xBC, 0xCC, 0xE2, 0xB0, 0xF1, 0x42, 0xB4, + 0x30, 0x5F, 0x60, 0x04, 0xEC, 0xA5, 0xE3, 0x8B, 0xE7, 0x1D, 0xBF, 0x84, 0x7B, 0xE6, 0x81, 0xF8, + 0xDE, 0xD8, 0xD2, 0x17, 0xCE, 0x4B, 0x47, 0xD6, 0x69, 0x6C, 0x19, 0x99, 0x9A, 0x01, 0xB3, 0x85, + 0xB1, 0xF9, 0x59, 0xC2, 0x37, 0xE9, 0xC8, 0xA0, 0xED, 0x4F, 0x89, 0x68, 0x6D, 0xD5, 0x26, 0x91, + 0x87, 0x58, 0xBD, 0xC9, 0x98, 0xDC, 0x75, 0xC0, 0x76, 0xF5, 0x67, 0x6B, 0x7E, 0xEB, 0x52, 0xCB, + 0xD1, 0x5B, 0x9F, 0x0B, 0xDB, 0x40, 0x92, 0x1A, 0xFA, 0xAC, 0xE4, 0xE1, 0x71, 0x1F, 0x65, 0x8D, + 0x97, 0x9E, 0x95, 0x90, 0x5D, 0xB7, 0xC1, 0xAF, 0x54, 0xFB, 0x02, 0xE0, 0x35, 0xBB, 0x3A, 0x4D, + 0xAD, 0x2C, 0x3D, 0x56, 0x08, 0x1B, 0x4A, 0x93, 0x6A, 0xAB, 0xB8, 0x7A, 0xF2, 0x7D, 0xDA, 0x3F, + 0xFE, 0x3E, 0xBE, 0xEA, 0xAA, 0x44, 0xC6, 0xD0, 0x36, 0x48, 0x70, 0x96, 0x77, 0x24, 0x53, 0xDF, + 0xF3, 0x83, 0x28, 0x32, 0x45, 0x1E, 0xA4, 0xD3, 0xA2, 0x46, 0x6E, 0x9C, 0xDD, 0x63, 0xD4, 0x9D + } +}; + +NAMESPACE_END +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/keccak.cpp b/external/ours/library/crypto/src/shared/original/keccak.cpp new file mode 100755 index 000000000..ed69590e6 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/keccak.cpp @@ -0,0 +1,67 @@ +// keccak.cpp - modified by Wei Dai from Ronny Van Keer's public domain +// sha3-simple.c. All modifications here are placed in the +// public domain by Wei Dai. +// Keccack core function moved to keccakc.cpp in AUG 2018 +// by Jeffrey Walton. Separating the core file allows both +// SHA3 and Keccack to share the core implementation. + +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michael Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "pch.h" +#include "keccak.h" + +NAMESPACE_BEGIN(CryptoPP) + +// The Keccak core function +extern void KeccakF1600(word64 *state); + +void Keccak::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); + if (length == 0) { return; } + + size_t spaceLeft; + while (length >= (spaceLeft = r() - m_counter)) + { + if (spaceLeft) + xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft); + KeccakF1600(m_state); + input += spaceLeft; + length -= spaceLeft; + m_counter = 0; + } + + if (length) + xorbuf(m_state.BytePtr() + m_counter, input, length); + m_counter += (unsigned int)length; +} + +void Keccak::Restart() +{ + memset(m_state, 0, m_state.SizeInBytes()); + m_counter = 0; +} + +void Keccak::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + ThrowIfInvalidTruncatedSize(size); + + m_state.BytePtr()[m_counter] ^= 0x01; + m_state.BytePtr()[r()-1] ^= 0x80; + KeccakF1600(m_state); + std::memcpy(hash, m_state, size); + Restart(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/keccak.h b/external/ours/library/crypto/src/shared/original/keccak.h new file mode 100755 index 000000000..f40cec5e2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/keccak.h @@ -0,0 +1,118 @@ +// keccak.h - originally written and placed in the public domain by Wei Dai + +/// \file keccak.h +/// \brief Classes for Keccak message digests +/// \details The Crypto++ Keccak implementation uses F1600 with XOF d=0x01. +/// FIPS 202 conformance (XOF d=0x06) is available in SHA3 classes. +/// \details Keccak will likely change in the future to accommodate extensibility of the +/// round function and the XOF functions. +/// \sa Keccak +/// \since Crypto++ 5.6.4 + +#ifndef CRYPTOPP_KECCAK_H +#define CRYPTOPP_KECCAK_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Keccak message digest base class +/// \details The Crypto++ Keccak implementation uses F1600 with XOF d=0x01. +/// FIPS 202 conformance (XOF d=0x06) is available in SHA3 classes. +/// \details Keccak is the base class for Keccak_224, Keccak_256, Keccak_384 and Keccak_512. +/// Library users should instantiate a derived class, and only use Keccak +/// as a base class reference or pointer. +/// \details Keccak will likely change in the future to accommodate extensibility of the +/// round function and the XOF functions. +/// \details Perform the following to specify a different digest size. The class will use F1600, +/// XOF d=0x01, and a new vaue for r() (which will be 200-2*24 = 152). +///
  Keccack_192 : public Keccack
+///   {
+///     public:
+///       CRYPTOPP_CONSTANT(DIGESTSIZE = 24);
+///       Keccack_192() : Keccack(DIGESTSIZE) {}
+///   };
+///   
+/// +/// \sa SHA3, Keccak_224, Keccak_256, Keccak_384 and Keccak_512. +/// \since Crypto++ 5.6.4 +class Keccak : public HashTransformation +{ +protected: + /// \brief Construct a Keccak + /// \param digestSize the digest size, in bytes + /// \details Keccak is the base class for Keccak_224, Keccak_256, Keccak_384 and Keccak_512. + /// Library users should instantiate a derived class, and only use Keccak + /// as a base class reference or pointer. + /// \details This constructor was moved to protected at Crypto++ 8.1 + /// because users were attempting to create Keccak objects with it. + /// \since Crypto++ 5.6.4 + Keccak(unsigned int digestSize) : m_digestSize(digestSize) {Restart();} + +public: + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + void Update(const byte *input, size_t length); + void Restart(); + void TruncatedFinal(byte *hash, size_t size); + +protected: + inline unsigned int r() const {return BlockSize();} + + FixedSizeSecBlock m_state; + unsigned int m_digestSize, m_counter; +}; + +/// \brief Keccak message digest template +/// \tparam T_DigestSize the size of the digest, in bytes +/// \since Crypto++ 6.0 +template +class Keccak_Final : public Keccak +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize); + CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * DIGESTSIZE); + static std::string StaticAlgorithmName() + { return "Keccak-" + IntToString(DIGESTSIZE * 8); } + + /// \brief Construct a Keccak-X message digest + Keccak_Final() : Keccak(DIGESTSIZE) {} + + /// \brief Provides the block size of the compression function + /// \return block size of the compression function, in bytes + /// \details BlockSize() will return 0 if the hash is not block based + /// or does not have an equivalent block size. For example, Keccak + /// and SHA-3 do not have a block size, but they do have an equivalent + /// block size called rate expressed as r. + unsigned int BlockSize() const { return BLOCKSIZE; } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } + +private: +#if !defined(__BORLANDC__) + // ensure there was no underflow in the math + CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); +#endif +}; + +/// \brief Keccak-224 message digest +/// \since Crypto++ 5.6.4 +DOCUMENTED_TYPEDEF(Keccak_Final<28>, Keccak_224); + +/// \brief Keccak-256 message digest +/// \since Crypto++ 5.6.4 +DOCUMENTED_TYPEDEF(Keccak_Final<32>, Keccak_256); + +/// \brief Keccak-384 message digest +/// \since Crypto++ 5.6.4 +DOCUMENTED_TYPEDEF(Keccak_Final<48>, Keccak_384); + +/// \brief Keccak-512 message digest +/// \since Crypto++ 5.6.4 +DOCUMENTED_TYPEDEF(Keccak_Final<64>, Keccak_512); + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/keccak_core.cpp b/external/ours/library/crypto/src/shared/original/keccak_core.cpp new file mode 100755 index 000000000..6a8a91bf4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/keccak_core.cpp @@ -0,0 +1,261 @@ +// keccakc.cpp - Keccak core functions shared between SHA3 and Keccak. +// written and placed in the public domain by JW. + +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michael Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "pch.h" +#include "keccak.h" + +NAMESPACE_BEGIN(CryptoPP) + +// The Keccak core function +extern void KeccakF1600(word64 *state); +// The F1600 round constants +extern const word64 KeccakF1600Constants[24]; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_ALIGN_DATA(8) +const word64 KeccakF1600Constants[24] = +{ + W64LIT(0x0000000000000001), W64LIT(0x0000000000008082), + W64LIT(0x800000000000808a), W64LIT(0x8000000080008000), + W64LIT(0x000000000000808b), W64LIT(0x0000000080000001), + W64LIT(0x8000000080008081), W64LIT(0x8000000000008009), + W64LIT(0x000000000000008a), W64LIT(0x0000000000000088), + W64LIT(0x0000000080008009), W64LIT(0x000000008000000a), + W64LIT(0x000000008000808b), W64LIT(0x800000000000008b), + W64LIT(0x8000000000008089), W64LIT(0x8000000000008003), + W64LIT(0x8000000000008002), W64LIT(0x8000000000000080), + W64LIT(0x000000000000800a), W64LIT(0x800000008000000a), + W64LIT(0x8000000080008081), W64LIT(0x8000000000008080), + W64LIT(0x0000000080000001), W64LIT(0x8000000080008008) +}; + +void KeccakF1600(word64 *state) +{ + word64 Aba, Abe, Abi, Abo, Abu; + word64 Aga, Age, Agi, Ago, Agu; + word64 Aka, Ake, Aki, Ako, Aku; + word64 Ama, Ame, Ami, Amo, Amu; + word64 Asa, Ase, Asi, Aso, Asu; + word64 BCa, BCe, BCi, BCo, BCu; + word64 Da, De, Di, Do, Du; + word64 Eba, Ebe, Ebi, Ebo, Ebu; + word64 Ega, Ege, Egi, Ego, Egu; + word64 Eka, Eke, Eki, Eko, Eku; + word64 Ema, Eme, Emi, Emo, Emu; + word64 Esa, Ese, Esi, Eso, Esu; + + typedef BlockGetAndPut Block; + Block::Get(state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu); + + for( unsigned int round = 0; round < 24; round += 2 ) + { + // prepareTheta + BCa = Aba^Aga^Aka^Ama^Asa; + BCe = Abe^Age^Ake^Ame^Ase; + BCi = Abi^Agi^Aki^Ami^Asi; + BCo = Abo^Ago^Ako^Amo^Aso; + BCu = Abu^Agu^Aku^Amu^Asu; + + //thetaRhoPiChiIotaPrepareTheta(round , A, E) + Da = BCu^rotlConstant<1>(BCe); + De = BCa^rotlConstant<1>(BCi); + Di = BCe^rotlConstant<1>(BCo); + Do = BCi^rotlConstant<1>(BCu); + Du = BCo^rotlConstant<1>(BCa); + + Aba ^= Da; + BCa = Aba; + Age ^= De; + BCe = rotlConstant<44>(Age); + Aki ^= Di; + BCi = rotlConstant<43>(Aki); + Amo ^= Do; + BCo = rotlConstant<21>(Amo); + Asu ^= Du; + BCu = rotlConstant<14>(Asu); + Eba = BCa ^((~BCe)& BCi ); + Eba ^= KeccakF1600Constants[round]; + Ebe = BCe ^((~BCi)& BCo ); + Ebi = BCi ^((~BCo)& BCu ); + Ebo = BCo ^((~BCu)& BCa ); + Ebu = BCu ^((~BCa)& BCe ); + + Abo ^= Do; + BCa = rotlConstant<28>(Abo); + Agu ^= Du; + BCe = rotlConstant<20>(Agu); + Aka ^= Da; + BCi = rotlConstant<3>(Aka); + Ame ^= De; + BCo = rotlConstant<45>(Ame); + Asi ^= Di; + BCu = rotlConstant<61>(Asi); + Ega = BCa ^((~BCe)& BCi ); + Ege = BCe ^((~BCi)& BCo ); + Egi = BCi ^((~BCo)& BCu ); + Ego = BCo ^((~BCu)& BCa ); + Egu = BCu ^((~BCa)& BCe ); + + Abe ^= De; + BCa = rotlConstant<1>(Abe); + Agi ^= Di; + BCe = rotlConstant<6>(Agi); + Ako ^= Do; + BCi = rotlConstant<25>(Ako); + Amu ^= Du; + BCo = rotlConstant<8>(Amu); + Asa ^= Da; + BCu = rotlConstant<18>(Asa); + Eka = BCa ^((~BCe)& BCi ); + Eke = BCe ^((~BCi)& BCo ); + Eki = BCi ^((~BCo)& BCu ); + Eko = BCo ^((~BCu)& BCa ); + Eku = BCu ^((~BCa)& BCe ); + + Abu ^= Du; + BCa = rotlConstant<27>(Abu); + Aga ^= Da; + BCe = rotlConstant<36>(Aga); + Ake ^= De; + BCi = rotlConstant<10>(Ake); + Ami ^= Di; + BCo = rotlConstant<15>(Ami); + Aso ^= Do; + BCu = rotlConstant<56>(Aso); + Ema = BCa ^((~BCe)& BCi ); + Eme = BCe ^((~BCi)& BCo ); + Emi = BCi ^((~BCo)& BCu ); + Emo = BCo ^((~BCu)& BCa ); + Emu = BCu ^((~BCa)& BCe ); + + Abi ^= Di; + BCa = rotlConstant<62>(Abi); + Ago ^= Do; + BCe = rotlConstant<55>(Ago); + Aku ^= Du; + BCi = rotlConstant<39>(Aku); + Ama ^= Da; + BCo = rotlConstant<41>(Ama); + Ase ^= De; + BCu = rotlConstant<2>(Ase); + Esa = BCa ^((~BCe)& BCi ); + Ese = BCe ^((~BCi)& BCo ); + Esi = BCi ^((~BCo)& BCu ); + Eso = BCo ^((~BCu)& BCa ); + Esu = BCu ^((~BCa)& BCe ); + + // prepareTheta + BCa = Eba^Ega^Eka^Ema^Esa; + BCe = Ebe^Ege^Eke^Eme^Ese; + BCi = Ebi^Egi^Eki^Emi^Esi; + BCo = Ebo^Ego^Eko^Emo^Eso; + BCu = Ebu^Egu^Eku^Emu^Esu; + + //thetaRhoPiChiIotaPrepareTheta(round+1, E, A) + Da = BCu^rotlConstant<1>(BCe); + De = BCa^rotlConstant<1>(BCi); + Di = BCe^rotlConstant<1>(BCo); + Do = BCi^rotlConstant<1>(BCu); + Du = BCo^rotlConstant<1>(BCa); + + Eba ^= Da; + BCa = Eba; + Ege ^= De; + BCe = rotlConstant<44>(Ege); + Eki ^= Di; + BCi = rotlConstant<43>(Eki); + Emo ^= Do; + BCo = rotlConstant<21>(Emo); + Esu ^= Du; + BCu = rotlConstant<14>(Esu); + Aba = BCa ^((~BCe)& BCi ); + Aba ^= KeccakF1600Constants[round+1]; + Abe = BCe ^((~BCi)& BCo ); + Abi = BCi ^((~BCo)& BCu ); + Abo = BCo ^((~BCu)& BCa ); + Abu = BCu ^((~BCa)& BCe ); + + Ebo ^= Do; + BCa = rotlConstant<28>(Ebo); + Egu ^= Du; + BCe = rotlConstant<20>(Egu); + Eka ^= Da; + BCi = rotlConstant<3>(Eka); + Eme ^= De; + BCo = rotlConstant<45>(Eme); + Esi ^= Di; + BCu = rotlConstant<61>(Esi); + Aga = BCa ^((~BCe)& BCi ); + Age = BCe ^((~BCi)& BCo ); + Agi = BCi ^((~BCo)& BCu ); + Ago = BCo ^((~BCu)& BCa ); + Agu = BCu ^((~BCa)& BCe ); + + Ebe ^= De; + BCa = rotlConstant<1>(Ebe); + Egi ^= Di; + BCe = rotlConstant<6>(Egi); + Eko ^= Do; + BCi = rotlConstant<25>(Eko); + Emu ^= Du; + BCo = rotlConstant<8>(Emu); + Esa ^= Da; + BCu = rotlConstant<18>(Esa); + Aka = BCa ^((~BCe)& BCi ); + Ake = BCe ^((~BCi)& BCo ); + Aki = BCi ^((~BCo)& BCu ); + Ako = BCo ^((~BCu)& BCa ); + Aku = BCu ^((~BCa)& BCe ); + + Ebu ^= Du; + BCa = rotlConstant<27>(Ebu); + Ega ^= Da; + BCe = rotlConstant<36>(Ega); + Eke ^= De; + BCi = rotlConstant<10>(Eke); + Emi ^= Di; + BCo = rotlConstant<15>(Emi); + Eso ^= Do; + BCu = rotlConstant<56>(Eso); + Ama = BCa ^((~BCe)& BCi ); + Ame = BCe ^((~BCi)& BCo ); + Ami = BCi ^((~BCo)& BCu ); + Amo = BCo ^((~BCu)& BCa ); + Amu = BCu ^((~BCa)& BCe ); + + Ebi ^= Di; + BCa = rotlConstant<62>(Ebi); + Ego ^= Do; + BCe = rotlConstant<55>(Ego); + Eku ^= Du; + BCi = rotlConstant<39>(Eku); + Ema ^= Da; + BCo = rotlConstant<41>(Ema); + Ese ^= De; + BCu = rotlConstant<2>(Ese); + Asa = BCa ^((~BCe)& BCi ); + Ase = BCe ^((~BCi)& BCo ); + Asi = BCi ^((~BCo)& BCu ); + Aso = BCo ^((~BCu)& BCa ); + Asu = BCu ^((~BCa)& BCe ); + } + + Block::Put(NULLPTR, state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/keccak_simd.cpp b/external/ours/library/crypto/src/shared/original/keccak_simd.cpp new file mode 100755 index 000000000..5a534a99b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/keccak_simd.cpp @@ -0,0 +1,2681 @@ +// keccak_simd.cpp - written and placed in the public domain by Jeffrey Walton. +// +// This source file uses intrinsics to gain access to SSE and +// NEON instructions. A separate source file is needed because +// additional CXXFLAGS are required to enable the appropriate +// instructions sets in some build configurations. + +// The XKCP package is provided by Guido Bertoni, Joan Daemen, Seth Hoffert, +// Michael Peeters, Gilles Van Assche, and Ronny Van Keer. The code was +// placed public domain by the authors. + +// KeccakF1600x2_SSE is ParallelHash128. The SSE2 ParallelHash128 +// implementation was extracted from XKCP using the following command. +// +// gcc -I lib/common -I lib/low/KeccakP-1600/Optimized +// -I lib/low/KeccakP-1600-times2/SIMD128/SSE2ufull +// lib/low/KeccakP-1600-times2/SIMD128/KeccakP-1600-times2-SIMD128.c -E + +#include "pch.h" +#include "config.h" +#include "keccak.h" +#include "misc.h" + +#if (CRYPTOPP_SSSE3_AVAILABLE) +# include +# include +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char KECCAK_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_SSSE3_AVAILABLE) + +// The Keccak ParallelHash128 core function +extern void KeccakF1600x2_SSE(word64 *state); + +// The F1600 round constants +extern const word64 KeccakF1600Constants[24]; + +CRYPTOPP_ALIGN_DATA(16) +const word64 +rho8[2] = {W64LIT(0x0605040302010007), W64LIT(0x0E0D0C0B0A09080F)}; + +CRYPTOPP_ALIGN_DATA(16) +const word64 +rho56[2] = {W64LIT(0x0007060504030201), W64LIT(0x080F0E0D0C0B0A09)}; + +#if defined(__XOP__) +# define ROL64in128(a, o) _mm_roti_epi64((a), (o)) +# define ROL64in128_8(a) ROL64in128((a), 8) +# define ROL64in128_56(a) ROL64in128((a), 56) +#else +# define ROL64in128(a, o) _mm_or_si128(_mm_slli_epi64((a), (o)), _mm_srli_epi64(a, 64-(o))) +# define ROL64in128_8(a) _mm_shuffle_epi8((a), _mm_load_si128(CONST_M128_CAST(rho8))) +# define ROL64in128_56(a) _mm_shuffle_epi8((a), _mm_load_si128(CONST_M128_CAST(rho56))) +#endif + +// Damn Visual Studio is missing too many intrinsics... +inline __m128i SPLAT64(const word64 a) +{ +#if defined(_MSC_VER) + double x; std::memcpy(&x, &a, 8); + return _mm_castpd_si128(_mm_loaddup_pd(&x)); +#else + return _mm_set1_epi64x(a); +#endif +} + +// The Keccak ParallelHash128 core function +void KeccakF1600x2_SSE(word64 *state) +{ + __m128i Aba, Abe, Abi, Abo, Abu; + __m128i Aga, Age, Agi, Ago, Agu; + __m128i Aka, Ake, Aki, Ako, Aku; + __m128i Ama, Ame, Ami, Amo, Amu; + __m128i Asa, Ase, Asi, Aso, Asu; + __m128i Bba, Bbe, Bbi, Bbo, Bbu; + __m128i Bga, Bge, Bgi, Bgo, Bgu; + __m128i Bka, Bke, Bki, Bko, Bku; + __m128i Bma, Bme, Bmi, Bmo, Bmu; + __m128i Bsa, Bse, Bsi, Bso, Bsu; + __m128i Ca, Ce, Ci, Co, Cu; + __m128i Da, De, Di, Do, Du; + __m128i Eba, Ebe, Ebi, Ebo, Ebu; + __m128i Ega, Ege, Egi, Ego, Egu; + __m128i Eka, Eke, Eki, Eko, Eku; + __m128i Ema, Eme, Emi, Emo, Emu; + __m128i Esa, Ese, Esi, Eso, Esu; + + __m128i* lanes = reinterpret_cast<__m128i*>(state); + Aba = _mm_loadu_si128(CONST_M128_CAST(lanes+ 0)); + Abe = _mm_loadu_si128(CONST_M128_CAST(lanes+ 1)); + Abi = _mm_loadu_si128(CONST_M128_CAST(lanes+ 2)); + Abo = _mm_loadu_si128(CONST_M128_CAST(lanes+ 3)); + Abu = _mm_loadu_si128(CONST_M128_CAST(lanes+ 4)); + Aga = _mm_loadu_si128(CONST_M128_CAST(lanes+ 5)); + Age = _mm_loadu_si128(CONST_M128_CAST(lanes+ 6)); + Agi = _mm_loadu_si128(CONST_M128_CAST(lanes+ 7)); + Ago = _mm_loadu_si128(CONST_M128_CAST(lanes+ 8)); + Agu = _mm_loadu_si128(CONST_M128_CAST(lanes+ 9)); + Aka = _mm_loadu_si128(CONST_M128_CAST(lanes+10)); + Ake = _mm_loadu_si128(CONST_M128_CAST(lanes+11)); + Aki = _mm_loadu_si128(CONST_M128_CAST(lanes+12)); + Ako = _mm_loadu_si128(CONST_M128_CAST(lanes+13)); + Aku = _mm_loadu_si128(CONST_M128_CAST(lanes+14)); + Ama = _mm_loadu_si128(CONST_M128_CAST(lanes+15)); + Ame = _mm_loadu_si128(CONST_M128_CAST(lanes+16)); + Ami = _mm_loadu_si128(CONST_M128_CAST(lanes+17)); + Amo = _mm_loadu_si128(CONST_M128_CAST(lanes+18)); + Amu = _mm_loadu_si128(CONST_M128_CAST(lanes+19)); + Asa = _mm_loadu_si128(CONST_M128_CAST(lanes+20)); + Ase = _mm_loadu_si128(CONST_M128_CAST(lanes+21)); + Asi = _mm_loadu_si128(CONST_M128_CAST(lanes+22)); + Aso = _mm_loadu_si128(CONST_M128_CAST(lanes+23)); + Asu = _mm_loadu_si128(CONST_M128_CAST(lanes+24)); + + Ca = _mm_xor_si128(Aba, _mm_xor_si128(Aga, _mm_xor_si128(Aka, _mm_xor_si128(Ama, Asa)))); + Ce = _mm_xor_si128(Abe, _mm_xor_si128(Age, _mm_xor_si128(Ake, _mm_xor_si128(Ame, Ase)))); + Ci = _mm_xor_si128(Abi, _mm_xor_si128(Agi, _mm_xor_si128(Aki, _mm_xor_si128(Ami, Asi)))); + Co = _mm_xor_si128(Abo, _mm_xor_si128(Ago, _mm_xor_si128(Ako, _mm_xor_si128(Amo, Aso)))); + Cu = _mm_xor_si128(Abu, _mm_xor_si128(Agu, _mm_xor_si128(Aku, _mm_xor_si128(Amu, Asu)))); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[0])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[1])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[2])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[3])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[4])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[5])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[6])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[7])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[8])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[9])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[10])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[11])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[12])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[13])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[14])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[15])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[16])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[17])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[18])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[19])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[20])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[21])); + Ca = Aba; + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Abe; + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Abi; + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Abo; + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Abu; + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Aga); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Age); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Agi); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ago); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Agu); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Aka); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Ake); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Aki); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Ako); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Aku); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ama); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Ame); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Ami); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Amo); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Amu); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Asa); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ase); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Asi); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Aso); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Asu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Aba = _mm_xor_si128(Aba, Da); + Bba = Aba; + Age = _mm_xor_si128(Age, De); + Bbe = ROL64in128(Age, 44); + Aki = _mm_xor_si128(Aki, Di); + Bbi = ROL64in128(Aki, 43); + Eba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Eba = _mm_xor_si128(Eba, SPLAT64(KeccakF1600Constants[22])); + Ca = Eba; + Amo = _mm_xor_si128(Amo, Do); + Bbo = ROL64in128(Amo, 21); + Ebe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Ce = Ebe; + Asu = _mm_xor_si128(Asu, Du); + Bbu = ROL64in128(Asu, 14); + Ebi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Ci = Ebi; + Ebo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Co = Ebo; + Ebu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Cu = Ebu; + Abo = _mm_xor_si128(Abo, Do); + Bga = ROL64in128(Abo, 28); + Agu = _mm_xor_si128(Agu, Du); + Bge = ROL64in128(Agu, 20); + Aka = _mm_xor_si128(Aka, Da); + Bgi = ROL64in128(Aka, 3); + Ega = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Ca = _mm_xor_si128(Ca, Ega); + Ame = _mm_xor_si128(Ame, De); + Bgo = ROL64in128(Ame, 45); + Ege = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Ce = _mm_xor_si128(Ce, Ege); + Asi = _mm_xor_si128(Asi, Di); + Bgu = ROL64in128(Asi, 61); + Egi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ci = _mm_xor_si128(Ci, Egi); + Ego = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Co = _mm_xor_si128(Co, Ego); + Egu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Cu = _mm_xor_si128(Cu, Egu); + Abe = _mm_xor_si128(Abe, De); + Bka = ROL64in128(Abe, 1); + Agi = _mm_xor_si128(Agi, Di); + Bke = ROL64in128(Agi, 6); + Ako = _mm_xor_si128(Ako, Do); + Bki = ROL64in128(Ako, 25); + Eka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Ca = _mm_xor_si128(Ca, Eka); + Amu = _mm_xor_si128(Amu, Du); + Bko = ROL64in128_8(Amu); + Eke = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Ce = _mm_xor_si128(Ce, Eke); + Asa = _mm_xor_si128(Asa, Da); + Bku = ROL64in128(Asa, 18); + Eki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ci = _mm_xor_si128(Ci, Eki); + Eko = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Co = _mm_xor_si128(Co, Eko); + Eku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Cu = _mm_xor_si128(Cu, Eku); + Abu = _mm_xor_si128(Abu, Du); + Bma = ROL64in128(Abu, 27); + Aga = _mm_xor_si128(Aga, Da); + Bme = ROL64in128(Aga, 36); + Ake = _mm_xor_si128(Ake, De); + Bmi = ROL64in128(Ake, 10); + Ema = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Ca = _mm_xor_si128(Ca, Ema); + Ami = _mm_xor_si128(Ami, Di); + Bmo = ROL64in128(Ami, 15); + Eme = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Ce = _mm_xor_si128(Ce, Eme); + Aso = _mm_xor_si128(Aso, Do); + Bmu = ROL64in128_56(Aso); + Emi = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Ci = _mm_xor_si128(Ci, Emi); + Emo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Co = _mm_xor_si128(Co, Emo); + Emu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Cu = _mm_xor_si128(Cu, Emu); + Abi = _mm_xor_si128(Abi, Di); + Bsa = ROL64in128(Abi, 62); + Ago = _mm_xor_si128(Ago, Do); + Bse = ROL64in128(Ago, 55); + Aku = _mm_xor_si128(Aku, Du); + Bsi = ROL64in128(Aku, 39); + Esa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ca = _mm_xor_si128(Ca, Esa); + Ama = _mm_xor_si128(Ama, Da); + Bso = ROL64in128(Ama, 41); + Ese = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ce = _mm_xor_si128(Ce, Ese); + Ase = _mm_xor_si128(Ase, De); + Bsu = ROL64in128(Ase, 2); + Esi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Ci = _mm_xor_si128(Ci, Esi); + Eso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Co = _mm_xor_si128(Co, Eso); + Esu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + Cu = _mm_xor_si128(Cu, Esu); + Da = _mm_xor_si128(Cu, ROL64in128(Ce, 1)); + De = _mm_xor_si128(Ca, ROL64in128(Ci, 1)); + Di = _mm_xor_si128(Ce, ROL64in128(Co, 1)); + Do = _mm_xor_si128(Ci, ROL64in128(Cu, 1)); + Du = _mm_xor_si128(Co, ROL64in128(Ca, 1)); + Eba = _mm_xor_si128(Eba, Da); + Bba = Eba; + Ege = _mm_xor_si128(Ege, De); + Bbe = ROL64in128(Ege, 44); + Eki = _mm_xor_si128(Eki, Di); + Bbi = ROL64in128(Eki, 43); + Aba = _mm_xor_si128(Bba, _mm_andnot_si128(Bbe, Bbi)); + Aba = _mm_xor_si128(Aba, SPLAT64(KeccakF1600Constants[23])); + Emo = _mm_xor_si128(Emo, Do); + Bbo = ROL64in128(Emo, 21); + Abe = _mm_xor_si128(Bbe, _mm_andnot_si128(Bbi, Bbo)); + Esu = _mm_xor_si128(Esu, Du); + Bbu = ROL64in128(Esu, 14); + Abi = _mm_xor_si128(Bbi, _mm_andnot_si128(Bbo, Bbu)); + Abo = _mm_xor_si128(Bbo, _mm_andnot_si128(Bbu, Bba)); + Abu = _mm_xor_si128(Bbu, _mm_andnot_si128(Bba, Bbe)); + Ebo = _mm_xor_si128(Ebo, Do); + Bga = ROL64in128(Ebo, 28); + Egu = _mm_xor_si128(Egu, Du); + Bge = ROL64in128(Egu, 20); + Eka = _mm_xor_si128(Eka, Da); + Bgi = ROL64in128(Eka, 3); + Aga = _mm_xor_si128(Bga, _mm_andnot_si128(Bge, Bgi)); + Eme = _mm_xor_si128(Eme, De); + Bgo = ROL64in128(Eme, 45); + Age = _mm_xor_si128(Bge, _mm_andnot_si128(Bgi, Bgo)); + Esi = _mm_xor_si128(Esi, Di); + Bgu = ROL64in128(Esi, 61); + Agi = _mm_xor_si128(Bgi, _mm_andnot_si128(Bgo, Bgu)); + Ago = _mm_xor_si128(Bgo, _mm_andnot_si128(Bgu, Bga)); + Agu = _mm_xor_si128(Bgu, _mm_andnot_si128(Bga, Bge)); + Ebe = _mm_xor_si128(Ebe, De); + Bka = ROL64in128(Ebe, 1); + Egi = _mm_xor_si128(Egi, Di); + Bke = ROL64in128(Egi, 6); + Eko = _mm_xor_si128(Eko, Do); + Bki = ROL64in128(Eko, 25); + Aka = _mm_xor_si128(Bka, _mm_andnot_si128(Bke, Bki)); + Emu = _mm_xor_si128(Emu, Du); + Bko = ROL64in128_8(Emu); + Ake = _mm_xor_si128(Bke, _mm_andnot_si128(Bki, Bko)); + Esa = _mm_xor_si128(Esa, Da); + Bku = ROL64in128(Esa, 18); + Aki = _mm_xor_si128(Bki, _mm_andnot_si128(Bko, Bku)); + Ako = _mm_xor_si128(Bko, _mm_andnot_si128(Bku, Bka)); + Aku = _mm_xor_si128(Bku, _mm_andnot_si128(Bka, Bke)); + Ebu = _mm_xor_si128(Ebu, Du); + Bma = ROL64in128(Ebu, 27); + Ega = _mm_xor_si128(Ega, Da); + Bme = ROL64in128(Ega, 36); + Eke = _mm_xor_si128(Eke, De); + Bmi = ROL64in128(Eke, 10); + Ama = _mm_xor_si128(Bma, _mm_andnot_si128(Bme, Bmi)); + Emi = _mm_xor_si128(Emi, Di); + Bmo = ROL64in128(Emi, 15); + Ame = _mm_xor_si128(Bme, _mm_andnot_si128(Bmi, Bmo)); + Eso = _mm_xor_si128(Eso, Do); + Bmu = ROL64in128_56(Eso); + Ami = _mm_xor_si128(Bmi, _mm_andnot_si128(Bmo, Bmu)); + Amo = _mm_xor_si128(Bmo, _mm_andnot_si128(Bmu, Bma)); + Amu = _mm_xor_si128(Bmu, _mm_andnot_si128(Bma, Bme)); + Ebi = _mm_xor_si128(Ebi, Di); + Bsa = ROL64in128(Ebi, 62); + Ego = _mm_xor_si128(Ego, Do); + Bse = ROL64in128(Ego, 55); + Eku = _mm_xor_si128(Eku, Du); + Bsi = ROL64in128(Eku, 39); + Asa = _mm_xor_si128(Bsa, _mm_andnot_si128(Bse, Bsi)); + Ema = _mm_xor_si128(Ema, Da); + Bso = ROL64in128(Ema, 41); + Ase = _mm_xor_si128(Bse, _mm_andnot_si128(Bsi, Bso)); + Ese = _mm_xor_si128(Ese, De); + Bsu = ROL64in128(Ese, 2); + Asi = _mm_xor_si128(Bsi, _mm_andnot_si128(Bso, Bsu)); + Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); + Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); + + _mm_storeu_si128(M128_CAST(lanes+ 0), Aba); + _mm_storeu_si128(M128_CAST(lanes+ 1), Abe); + _mm_storeu_si128(M128_CAST(lanes+ 2), Abi); + _mm_storeu_si128(M128_CAST(lanes+ 3), Abo); + _mm_storeu_si128(M128_CAST(lanes+ 4), Abu); + _mm_storeu_si128(M128_CAST(lanes+ 5), Aga); + _mm_storeu_si128(M128_CAST(lanes+ 6), Age); + _mm_storeu_si128(M128_CAST(lanes+ 7), Agi); + _mm_storeu_si128(M128_CAST(lanes+ 8), Ago); + _mm_storeu_si128(M128_CAST(lanes+ 9), Agu); + _mm_storeu_si128(M128_CAST(lanes+10), Aka); + _mm_storeu_si128(M128_CAST(lanes+11), Ake); + _mm_storeu_si128(M128_CAST(lanes+12), Aki); + _mm_storeu_si128(M128_CAST(lanes+13), Ako); + _mm_storeu_si128(M128_CAST(lanes+14), Aku); + _mm_storeu_si128(M128_CAST(lanes+15), Ama); + _mm_storeu_si128(M128_CAST(lanes+16), Ame); + _mm_storeu_si128(M128_CAST(lanes+17), Ami); + _mm_storeu_si128(M128_CAST(lanes+18), Amo); + _mm_storeu_si128(M128_CAST(lanes+19), Amu); + _mm_storeu_si128(M128_CAST(lanes+20), Asa); + _mm_storeu_si128(M128_CAST(lanes+21), Ase); + _mm_storeu_si128(M128_CAST(lanes+22), Asi); + _mm_storeu_si128(M128_CAST(lanes+23), Aso); + _mm_storeu_si128(M128_CAST(lanes+24), Asu); +} + +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/lea.cpp b/external/ours/library/crypto/src/shared/original/lea.cpp new file mode 100755 index 000000000..4361d5139 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lea.cpp @@ -0,0 +1,899 @@ +// lea.cpp - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "LEA: A 128-Bit Block Cipher for Fast Encryption on Common +// Processors" by Deukjo Hong, Jung-Keun Lee, Dong-Chan Kim, Daesung Kwon, +// Kwon Ho Ryu, and Dong-Geon Lee. +// +// This implementation is based on source files found in a zip file at the +// Korea Internet and Security Agency (https://www.kisa.or.kr/eng/main.jsp). +// The zip files was downloaded from the Korean language area of the site so we +// don't have a url or english zip filename to cite. The source filename from +// the zip is lea_core.c. +// +// The LEA team appears to have applied optimizations to functions in lea_core.c. +// The implementation does not exactly follow the aglorithmic description from +// the LEA paper. + +#include "pch.h" +#include "config.h" + +#include "lea.h" +#include "misc.h" +#include "cpu.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::rotlConstant; + +ANONYMOUS_NAMESPACE_END + +const word32 delta[8][36] = { + {0xc3efe9db, 0x87dfd3b7, 0x0fbfa76f, 0x1f7f4ede, 0x3efe9dbc, 0x7dfd3b78, 0xfbfa76f0, 0xf7f4ede1, + 0xefe9dbc3, 0xdfd3b787, 0xbfa76f0f, 0x7f4ede1f, 0xfe9dbc3e, 0xfd3b787d, 0xfa76f0fb, 0xf4ede1f7, + 0xe9dbc3ef, 0xd3b787df, 0xa76f0fbf, 0x4ede1f7f, 0x9dbc3efe, 0x3b787dfd, 0x76f0fbfa, 0xede1f7f4, + 0xdbc3efe9, 0xb787dfd3, 0x6f0fbfa7, 0xde1f7f4e, 0xbc3efe9d, 0x787dfd3b, 0xf0fbfa76, 0xe1f7f4eD, + 0xc3efe9db, 0x87dfd3b7, 0x0fbfa76f, 0x1f7f4ede}, + {0x44626b02, 0x88c4d604, 0x1189ac09, 0x23135812, 0x4626b024, 0x8c4d6048, 0x189ac091, 0x31358122, + 0x626b0244, 0xc4d60488, 0x89ac0911, 0x13581223, 0x26b02446, 0x4d60488c, 0x9ac09118, 0x35812231, + 0x6b024462, 0xd60488c4, 0xac091189, 0x58122313, 0xb0244626, 0x60488c4d, 0xc091189a, 0x81223135, + 0x0244626b, 0x0488c4d6, 0x091189ac, 0x12231358, 0x244626b0, 0x488c4d60, 0x91189ac0, 0x22313581, + 0x44626b02, 0x88c4d604, 0x1189ac09, 0x23135812}, + {0x79e27c8a, 0xf3c4f914, 0xe789f229, 0xcf13e453, 0x9e27c8a7, 0x3c4f914f, 0x789f229e, 0xf13e453c, + 0xe27c8a79, 0xc4f914f3, 0x89f229e7, 0x13e453cf, 0x27c8a79e, 0x4f914f3c, 0x9f229e78, 0x3e453cf1, + 0x7c8a79e2, 0xf914f3c4, 0xf229e789, 0xe453cf13, 0xc8a79e27, 0x914f3c4f, 0x229e789f, 0x453cf13e, + 0x8a79e27c, 0x14f3c4f9, 0x29e789f2, 0x53cf13e4, 0xa79e27c8, 0x4f3c4f91, 0x9e789f22, 0x3cf13e45, + 0x79e27c8a, 0xf3c4f914, 0xe789f229, 0xcf13e453}, + {0x78df30ec, 0xf1be61d8, 0xe37cc3b1, 0xc6f98763, 0x8df30ec7, 0x1be61d8f, 0x37cc3b1e, 0x6f98763c, + 0xdf30ec78, 0xbe61d8f1, 0x7cc3b1e3, 0xf98763c6, 0xf30ec78d, 0xe61d8f1b, 0xcc3b1e37, 0x98763c6f, + 0x30ec78df, 0x61d8f1be, 0xc3b1e37c, 0x8763c6f9, 0x0ec78df3, 0x1d8f1be6, 0x3b1e37cc, 0x763c6f98, + 0xec78df30, 0xd8f1be61, 0xb1e37cc3, 0x63c6f987, 0xc78df30e, 0x8f1be61d, 0x1e37cc3b, 0x3c6f9876, + 0x78df30ec, 0xf1be61d8, 0xe37cc3b1, 0xc6f98763}, + {0x715ea49e, 0xe2bd493c, 0xc57a9279, 0x8af524f3, 0x15ea49e7, 0x2bd493ce, 0x57a9279c, 0xaf524f38, + 0x5ea49e71, 0xbd493ce2, 0x7a9279c5, 0xf524f38a, 0xea49e715, 0xd493ce2b, 0xa9279c57, 0x524f38af, + 0xa49e715e, 0x493ce2bd, 0x9279c57a, 0x24f38af5, 0x49e715ea, 0x93ce2bd4, 0x279c57a9, 0x4f38af52, + 0x9e715ea4, 0x3ce2bd49, 0x79c57a92, 0xf38af524, 0xe715ea49, 0xce2bd493, 0x9c57a927, 0x38af524f, + 0x715ea49e, 0xe2bd493c, 0xc57a9279, 0x8af524f3}, + {0xc785da0a, 0x8f0bb415, 0x1e17682b, 0x3c2ed056, 0x785da0ac, 0xf0bb4158, 0xe17682b1, 0xc2ed0563, + 0x85da0ac7, 0x0bb4158f, 0x17682b1e, 0x2ed0563c, 0x5da0ac78, 0xbb4158f0, 0x7682b1e1, 0xed0563c2, + 0xda0ac785, 0xb4158f0b, 0x682b1e17, 0xd0563c2e, 0xa0ac785d, 0x4158f0bb, 0x82b1e176, 0x0563c2ed, + 0x0ac785da, 0x158f0bb4, 0x2b1e1768, 0x563c2ed0, 0xac785da0, 0x58f0bb41, 0xb1e17682, 0x63c2ed05, + 0xc785da0a, 0x8f0bb415, 0x1e17682b, 0x3c2ed056}, + {0xe04ef22a, 0xc09de455, 0x813bc8ab, 0x02779157, 0x04ef22ae, 0x09de455c, 0x13bc8ab8, 0x27791570, + 0x4ef22ae0, 0x9de455c0, 0x3bc8ab81, 0x77915702, 0xef22ae04, 0xde455c09, 0xbc8ab813, 0x79157027, + 0xf22ae04e, 0xe455c09d, 0xc8ab813b, 0x91570277, 0x22ae04ef, 0x455c09de, 0x8ab813bc, 0x15702779, + 0x2ae04ef2, 0x55c09de4, 0xab813bc8, 0x57027791, 0xae04ef22, 0x5c09de45, 0xb813bc8a, 0x70277915, + 0xe04ef22a, 0xc09de455, 0x813bc8ab, 0x02779157}, + {0xe5c40957, 0xcb8812af, 0x9710255f, 0x2e204abf, 0x5c40957e, 0xb8812afc, 0x710255f9, 0xe204abf2, + 0xc40957e5, 0x8812afcb, 0x10255f97, 0x204abf2e, 0x40957e5c, 0x812afcb8, 0x0255f971, 0x04abf2e2, + 0x0957e5c4, 0x12afcb88, 0x255f9710, 0x4abf2e20, 0x957e5c40, 0x2afcb881, 0x55f97102, 0xabf2e204, + 0x57e5c409, 0xafcb8812, 0x5f971025, 0xbf2e204a, 0x7e5c4095, 0xfcb8812a, 0xf9710255, 0xf2e204ab, + 0xe5c40957, 0xcb8812af, 0x9710255f, 0x2e204abf} +}; + +inline void SetKey128(word32 rkey[144], const word32 key[4]) +{ + rkey[ 0] = rotlConstant<1>( key[ 0] + delta[0][ 0]); + rkey[ 6] = rotlConstant<1>(rkey[ 0] + delta[1][ 1]); + rkey[ 12] = rotlConstant<1>(rkey[ 6] + delta[2][ 2]); + rkey[ 18] = rotlConstant<1>(rkey[ 12] + delta[3][ 3]); + rkey[ 24] = rotlConstant<1>(rkey[ 18] + delta[0][ 4]); + rkey[ 30] = rotlConstant<1>(rkey[ 24] + delta[1][ 5]); + rkey[ 36] = rotlConstant<1>(rkey[ 30] + delta[2][ 6]); + rkey[ 42] = rotlConstant<1>(rkey[ 36] + delta[3][ 7]); + rkey[ 48] = rotlConstant<1>(rkey[ 42] + delta[0][ 8]); + rkey[ 54] = rotlConstant<1>(rkey[ 48] + delta[1][ 9]); + rkey[ 60] = rotlConstant<1>(rkey[ 54] + delta[2][10]); + rkey[ 66] = rotlConstant<1>(rkey[ 60] + delta[3][11]); + rkey[ 72] = rotlConstant<1>(rkey[ 66] + delta[0][12]); + rkey[ 78] = rotlConstant<1>(rkey[ 72] + delta[1][13]); + rkey[ 84] = rotlConstant<1>(rkey[ 78] + delta[2][14]); + rkey[ 90] = rotlConstant<1>(rkey[ 84] + delta[3][15]); + rkey[ 96] = rotlConstant<1>(rkey[ 90] + delta[0][16]); + rkey[102] = rotlConstant<1>(rkey[ 96] + delta[1][17]); + rkey[108] = rotlConstant<1>(rkey[102] + delta[2][18]); + rkey[114] = rotlConstant<1>(rkey[108] + delta[3][19]); + rkey[120] = rotlConstant<1>(rkey[114] + delta[0][20]); + rkey[126] = rotlConstant<1>(rkey[120] + delta[1][21]); + rkey[132] = rotlConstant<1>(rkey[126] + delta[2][22]); + rkey[138] = rotlConstant<1>(rkey[132] + delta[3][23]); + + rkey[ 1] = rkey[ 3] = rkey[ 5] = rotlConstant<3>( key[ 1] + delta[0][ 1]); + rkey[ 7] = rkey[ 9] = rkey[ 11] = rotlConstant<3>(rkey[ 1] + delta[1][ 2]); + rkey[ 13] = rkey[ 15] = rkey[ 17] = rotlConstant<3>(rkey[ 7] + delta[2][ 3]); + rkey[ 19] = rkey[ 21] = rkey[ 23] = rotlConstant<3>(rkey[ 13] + delta[3][ 4]); + rkey[ 25] = rkey[ 27] = rkey[ 29] = rotlConstant<3>(rkey[ 19] + delta[0][ 5]); + rkey[ 31] = rkey[ 33] = rkey[ 35] = rotlConstant<3>(rkey[ 25] + delta[1][ 6]); + rkey[ 37] = rkey[ 39] = rkey[ 41] = rotlConstant<3>(rkey[ 31] + delta[2][ 7]); + rkey[ 43] = rkey[ 45] = rkey[ 47] = rotlConstant<3>(rkey[ 37] + delta[3][ 8]); + rkey[ 49] = rkey[ 51] = rkey[ 53] = rotlConstant<3>(rkey[ 43] + delta[0][ 9]); + rkey[ 55] = rkey[ 57] = rkey[ 59] = rotlConstant<3>(rkey[ 49] + delta[1][10]); + rkey[ 61] = rkey[ 63] = rkey[ 65] = rotlConstant<3>(rkey[ 55] + delta[2][11]); + rkey[ 67] = rkey[ 69] = rkey[ 71] = rotlConstant<3>(rkey[ 61] + delta[3][12]); + rkey[ 73] = rkey[ 75] = rkey[ 77] = rotlConstant<3>(rkey[ 67] + delta[0][13]); + rkey[ 79] = rkey[ 81] = rkey[ 83] = rotlConstant<3>(rkey[ 73] + delta[1][14]); + rkey[ 85] = rkey[ 87] = rkey[ 89] = rotlConstant<3>(rkey[ 79] + delta[2][15]); + rkey[ 91] = rkey[ 93] = rkey[ 95] = rotlConstant<3>(rkey[ 85] + delta[3][16]); + rkey[ 97] = rkey[ 99] = rkey[101] = rotlConstant<3>(rkey[ 91] + delta[0][17]); + rkey[103] = rkey[105] = rkey[107] = rotlConstant<3>(rkey[ 97] + delta[1][18]); + rkey[109] = rkey[111] = rkey[113] = rotlConstant<3>(rkey[103] + delta[2][19]); + rkey[115] = rkey[117] = rkey[119] = rotlConstant<3>(rkey[109] + delta[3][20]); + rkey[121] = rkey[123] = rkey[125] = rotlConstant<3>(rkey[115] + delta[0][21]); + rkey[127] = rkey[129] = rkey[131] = rotlConstant<3>(rkey[121] + delta[1][22]); + rkey[133] = rkey[135] = rkey[137] = rotlConstant<3>(rkey[127] + delta[2][23]); + rkey[139] = rkey[141] = rkey[143] = rotlConstant<3>(rkey[133] + delta[3][24]); + + rkey[ 2] = rotlConstant<6>( key[ 2] + delta[0][ 2]); + rkey[ 8] = rotlConstant<6>(rkey[ 2] + delta[1][ 3]); + rkey[ 14] = rotlConstant<6>(rkey[ 8] + delta[2][ 4]); + rkey[ 20] = rotlConstant<6>(rkey[ 14] + delta[3][ 5]); + rkey[ 26] = rotlConstant<6>(rkey[ 20] + delta[0][ 6]); + rkey[ 32] = rotlConstant<6>(rkey[ 26] + delta[1][ 7]); + rkey[ 38] = rotlConstant<6>(rkey[ 32] + delta[2][ 8]); + rkey[ 44] = rotlConstant<6>(rkey[ 38] + delta[3][ 9]); + rkey[ 50] = rotlConstant<6>(rkey[ 44] + delta[0][10]); + rkey[ 56] = rotlConstant<6>(rkey[ 50] + delta[1][11]); + rkey[ 62] = rotlConstant<6>(rkey[ 56] + delta[2][12]); + rkey[ 68] = rotlConstant<6>(rkey[ 62] + delta[3][13]); + rkey[ 74] = rotlConstant<6>(rkey[ 68] + delta[0][14]); + rkey[ 80] = rotlConstant<6>(rkey[ 74] + delta[1][15]); + rkey[ 86] = rotlConstant<6>(rkey[ 80] + delta[2][16]); + rkey[ 92] = rotlConstant<6>(rkey[ 86] + delta[3][17]); + rkey[ 98] = rotlConstant<6>(rkey[ 92] + delta[0][18]); + rkey[104] = rotlConstant<6>(rkey[ 98] + delta[1][19]); + rkey[110] = rotlConstant<6>(rkey[104] + delta[2][20]); + rkey[116] = rotlConstant<6>(rkey[110] + delta[3][21]); + rkey[122] = rotlConstant<6>(rkey[116] + delta[0][22]); + rkey[128] = rotlConstant<6>(rkey[122] + delta[1][23]); + rkey[134] = rotlConstant<6>(rkey[128] + delta[2][24]); + rkey[140] = rotlConstant<6>(rkey[134] + delta[3][25]); + + rkey[ 4] = rotlConstant<11>( key[ 3] + delta[0][ 3]); + rkey[ 10] = rotlConstant<11>(rkey[ 4] + delta[1][ 4]); + rkey[ 16] = rotlConstant<11>(rkey[ 10] + delta[2][ 5]); + rkey[ 22] = rotlConstant<11>(rkey[ 16] + delta[3][ 6]); + rkey[ 28] = rotlConstant<11>(rkey[ 22] + delta[0][ 7]); + rkey[ 34] = rotlConstant<11>(rkey[ 28] + delta[1][ 8]); + rkey[ 40] = rotlConstant<11>(rkey[ 34] + delta[2][ 9]); + rkey[ 46] = rotlConstant<11>(rkey[ 40] + delta[3][10]); + rkey[ 52] = rotlConstant<11>(rkey[ 46] + delta[0][11]); + rkey[ 58] = rotlConstant<11>(rkey[ 52] + delta[1][12]); + rkey[ 64] = rotlConstant<11>(rkey[ 58] + delta[2][13]); + rkey[ 70] = rotlConstant<11>(rkey[ 64] + delta[3][14]); + rkey[ 76] = rotlConstant<11>(rkey[ 70] + delta[0][15]); + rkey[ 82] = rotlConstant<11>(rkey[ 76] + delta[1][16]); + rkey[ 88] = rotlConstant<11>(rkey[ 82] + delta[2][17]); + rkey[ 94] = rotlConstant<11>(rkey[ 88] + delta[3][18]); + rkey[100] = rotlConstant<11>(rkey[ 94] + delta[0][19]); + rkey[106] = rotlConstant<11>(rkey[100] + delta[1][20]); + rkey[112] = rotlConstant<11>(rkey[106] + delta[2][21]); + rkey[118] = rotlConstant<11>(rkey[112] + delta[3][22]); + rkey[124] = rotlConstant<11>(rkey[118] + delta[0][23]); + rkey[130] = rotlConstant<11>(rkey[124] + delta[1][24]); + rkey[136] = rotlConstant<11>(rkey[130] + delta[2][25]); + rkey[142] = rotlConstant<11>(rkey[136] + delta[3][26]); +} + +inline void SetKey192(word32 rkey[168], const word32 key[6]) +{ + rkey[ 0] = rotlConstant<1>( key[ 0] + delta[0][ 0]); + rkey[ 6] = rotlConstant<1>(rkey[ 0] + delta[1][ 1]); + rkey[ 12] = rotlConstant<1>(rkey[ 6] + delta[2][ 2]); + rkey[ 18] = rotlConstant<1>(rkey[ 12] + delta[3][ 3]); + rkey[ 24] = rotlConstant<1>(rkey[ 18] + delta[4][ 4]); + rkey[ 30] = rotlConstant<1>(rkey[ 24] + delta[5][ 5]); + rkey[ 36] = rotlConstant<1>(rkey[ 30] + delta[0][ 6]); + rkey[ 42] = rotlConstant<1>(rkey[ 36] + delta[1][ 7]); + rkey[ 48] = rotlConstant<1>(rkey[ 42] + delta[2][ 8]); + rkey[ 54] = rotlConstant<1>(rkey[ 48] + delta[3][ 9]); + rkey[ 60] = rotlConstant<1>(rkey[ 54] + delta[4][10]); + rkey[ 66] = rotlConstant<1>(rkey[ 60] + delta[5][11]); + rkey[ 72] = rotlConstant<1>(rkey[ 66] + delta[0][12]); + rkey[ 78] = rotlConstant<1>(rkey[ 72] + delta[1][13]); + rkey[ 84] = rotlConstant<1>(rkey[ 78] + delta[2][14]); + rkey[ 90] = rotlConstant<1>(rkey[ 84] + delta[3][15]); + rkey[ 96] = rotlConstant<1>(rkey[ 90] + delta[4][16]); + rkey[102] = rotlConstant<1>(rkey[ 96] + delta[5][17]); + rkey[108] = rotlConstant<1>(rkey[102] + delta[0][18]); + rkey[114] = rotlConstant<1>(rkey[108] + delta[1][19]); + rkey[120] = rotlConstant<1>(rkey[114] + delta[2][20]); + rkey[126] = rotlConstant<1>(rkey[120] + delta[3][21]); + rkey[132] = rotlConstant<1>(rkey[126] + delta[4][22]); + rkey[138] = rotlConstant<1>(rkey[132] + delta[5][23]); + rkey[144] = rotlConstant<1>(rkey[138] + delta[0][24]); + rkey[150] = rotlConstant<1>(rkey[144] + delta[1][25]); + rkey[156] = rotlConstant<1>(rkey[150] + delta[2][26]); + rkey[162] = rotlConstant<1>(rkey[156] + delta[3][27]); + + rkey[ 1] = rotlConstant<3>( key[ 1] + delta[0][ 1]); + rkey[ 7] = rotlConstant<3>(rkey[ 1] + delta[1][ 2]); + rkey[ 13] = rotlConstant<3>(rkey[ 7] + delta[2][ 3]); + rkey[ 19] = rotlConstant<3>(rkey[ 13] + delta[3][ 4]); + rkey[ 25] = rotlConstant<3>(rkey[ 19] + delta[4][ 5]); + rkey[ 31] = rotlConstant<3>(rkey[ 25] + delta[5][ 6]); + rkey[ 37] = rotlConstant<3>(rkey[ 31] + delta[0][ 7]); + rkey[ 43] = rotlConstant<3>(rkey[ 37] + delta[1][ 8]); + rkey[ 49] = rotlConstant<3>(rkey[ 43] + delta[2][ 9]); + rkey[ 55] = rotlConstant<3>(rkey[ 49] + delta[3][10]); + rkey[ 61] = rotlConstant<3>(rkey[ 55] + delta[4][11]); + rkey[ 67] = rotlConstant<3>(rkey[ 61] + delta[5][12]); + rkey[ 73] = rotlConstant<3>(rkey[ 67] + delta[0][13]); + rkey[ 79] = rotlConstant<3>(rkey[ 73] + delta[1][14]); + rkey[ 85] = rotlConstant<3>(rkey[ 79] + delta[2][15]); + rkey[ 91] = rotlConstant<3>(rkey[ 85] + delta[3][16]); + rkey[ 97] = rotlConstant<3>(rkey[ 91] + delta[4][17]); + rkey[103] = rotlConstant<3>(rkey[ 97] + delta[5][18]); + rkey[109] = rotlConstant<3>(rkey[103] + delta[0][19]); + rkey[115] = rotlConstant<3>(rkey[109] + delta[1][20]); + rkey[121] = rotlConstant<3>(rkey[115] + delta[2][21]); + rkey[127] = rotlConstant<3>(rkey[121] + delta[3][22]); + rkey[133] = rotlConstant<3>(rkey[127] + delta[4][23]); + rkey[139] = rotlConstant<3>(rkey[133] + delta[5][24]); + rkey[145] = rotlConstant<3>(rkey[139] + delta[0][25]); + rkey[151] = rotlConstant<3>(rkey[145] + delta[1][26]); + rkey[157] = rotlConstant<3>(rkey[151] + delta[2][27]); + rkey[163] = rotlConstant<3>(rkey[157] + delta[3][28]); + + rkey[ 2] = rotlConstant<6>( key[ 2] + delta[0][ 2]); + rkey[ 8] = rotlConstant<6>(rkey[ 2] + delta[1][ 3]); + rkey[ 14] = rotlConstant<6>(rkey[ 8] + delta[2][ 4]); + rkey[ 20] = rotlConstant<6>(rkey[ 14] + delta[3][ 5]); + rkey[ 26] = rotlConstant<6>(rkey[ 20] + delta[4][ 6]); + rkey[ 32] = rotlConstant<6>(rkey[ 26] + delta[5][ 7]); + rkey[ 38] = rotlConstant<6>(rkey[ 32] + delta[0][ 8]); + rkey[ 44] = rotlConstant<6>(rkey[ 38] + delta[1][ 9]); + rkey[ 50] = rotlConstant<6>(rkey[ 44] + delta[2][10]); + rkey[ 56] = rotlConstant<6>(rkey[ 50] + delta[3][11]); + rkey[ 62] = rotlConstant<6>(rkey[ 56] + delta[4][12]); + rkey[ 68] = rotlConstant<6>(rkey[ 62] + delta[5][13]); + rkey[ 74] = rotlConstant<6>(rkey[ 68] + delta[0][14]); + rkey[ 80] = rotlConstant<6>(rkey[ 74] + delta[1][15]); + rkey[ 86] = rotlConstant<6>(rkey[ 80] + delta[2][16]); + rkey[ 92] = rotlConstant<6>(rkey[ 86] + delta[3][17]); + rkey[ 98] = rotlConstant<6>(rkey[ 92] + delta[4][18]); + rkey[104] = rotlConstant<6>(rkey[ 98] + delta[5][19]); + rkey[110] = rotlConstant<6>(rkey[104] + delta[0][20]); + rkey[116] = rotlConstant<6>(rkey[110] + delta[1][21]); + rkey[122] = rotlConstant<6>(rkey[116] + delta[2][22]); + rkey[128] = rotlConstant<6>(rkey[122] + delta[3][23]); + rkey[134] = rotlConstant<6>(rkey[128] + delta[4][24]); + rkey[140] = rotlConstant<6>(rkey[134] + delta[5][25]); + rkey[146] = rotlConstant<6>(rkey[140] + delta[0][26]); + rkey[152] = rotlConstant<6>(rkey[146] + delta[1][27]); + rkey[158] = rotlConstant<6>(rkey[152] + delta[2][28]); + rkey[164] = rotlConstant<6>(rkey[158] + delta[3][29]); + + rkey[ 3] = rotlConstant<11>( key[ 3] + delta[0][ 3]); + rkey[ 9] = rotlConstant<11>(rkey[ 3] + delta[1][ 4]); + rkey[ 15] = rotlConstant<11>(rkey[ 9] + delta[2][ 5]); + rkey[ 21] = rotlConstant<11>(rkey[ 15] + delta[3][ 6]); + rkey[ 27] = rotlConstant<11>(rkey[ 21] + delta[4][ 7]); + rkey[ 33] = rotlConstant<11>(rkey[ 27] + delta[5][ 8]); + rkey[ 39] = rotlConstant<11>(rkey[ 33] + delta[0][ 9]); + rkey[ 45] = rotlConstant<11>(rkey[ 39] + delta[1][10]); + rkey[ 51] = rotlConstant<11>(rkey[ 45] + delta[2][11]); + rkey[ 57] = rotlConstant<11>(rkey[ 51] + delta[3][12]); + rkey[ 63] = rotlConstant<11>(rkey[ 57] + delta[4][13]); + rkey[ 69] = rotlConstant<11>(rkey[ 63] + delta[5][14]); + rkey[ 75] = rotlConstant<11>(rkey[ 69] + delta[0][15]); + rkey[ 81] = rotlConstant<11>(rkey[ 75] + delta[1][16]); + rkey[ 87] = rotlConstant<11>(rkey[ 81] + delta[2][17]); + rkey[ 93] = rotlConstant<11>(rkey[ 87] + delta[3][18]); + rkey[ 99] = rotlConstant<11>(rkey[ 93] + delta[4][19]); + rkey[105] = rotlConstant<11>(rkey[ 99] + delta[5][20]); + rkey[111] = rotlConstant<11>(rkey[105] + delta[0][21]); + rkey[117] = rotlConstant<11>(rkey[111] + delta[1][22]); + rkey[123] = rotlConstant<11>(rkey[117] + delta[2][23]); + rkey[129] = rotlConstant<11>(rkey[123] + delta[3][24]); + rkey[135] = rotlConstant<11>(rkey[129] + delta[4][25]); + rkey[141] = rotlConstant<11>(rkey[135] + delta[5][26]); + rkey[147] = rotlConstant<11>(rkey[141] + delta[0][27]); + rkey[153] = rotlConstant<11>(rkey[147] + delta[1][28]); + rkey[159] = rotlConstant<11>(rkey[153] + delta[2][29]); + rkey[165] = rotlConstant<11>(rkey[159] + delta[3][30]); + + rkey[ 4] = rotlConstant<13>( key[ 4] + delta[0][ 4]); + rkey[ 10] = rotlConstant<13>(rkey[ 4] + delta[1][ 5]); + rkey[ 16] = rotlConstant<13>(rkey[ 10] + delta[2][ 6]); + rkey[ 22] = rotlConstant<13>(rkey[ 16] + delta[3][ 7]); + rkey[ 28] = rotlConstant<13>(rkey[ 22] + delta[4][ 8]); + rkey[ 34] = rotlConstant<13>(rkey[ 28] + delta[5][ 9]); + rkey[ 40] = rotlConstant<13>(rkey[ 34] + delta[0][10]); + rkey[ 46] = rotlConstant<13>(rkey[ 40] + delta[1][11]); + rkey[ 52] = rotlConstant<13>(rkey[ 46] + delta[2][12]); + rkey[ 58] = rotlConstant<13>(rkey[ 52] + delta[3][13]); + rkey[ 64] = rotlConstant<13>(rkey[ 58] + delta[4][14]); + rkey[ 70] = rotlConstant<13>(rkey[ 64] + delta[5][15]); + rkey[ 76] = rotlConstant<13>(rkey[ 70] + delta[0][16]); + rkey[ 82] = rotlConstant<13>(rkey[ 76] + delta[1][17]); + rkey[ 88] = rotlConstant<13>(rkey[ 82] + delta[2][18]); + rkey[ 94] = rotlConstant<13>(rkey[ 88] + delta[3][19]); + rkey[100] = rotlConstant<13>(rkey[ 94] + delta[4][20]); + rkey[106] = rotlConstant<13>(rkey[100] + delta[5][21]); + rkey[112] = rotlConstant<13>(rkey[106] + delta[0][22]); + rkey[118] = rotlConstant<13>(rkey[112] + delta[1][23]); + rkey[124] = rotlConstant<13>(rkey[118] + delta[2][24]); + rkey[130] = rotlConstant<13>(rkey[124] + delta[3][25]); + rkey[136] = rotlConstant<13>(rkey[130] + delta[4][26]); + rkey[142] = rotlConstant<13>(rkey[136] + delta[5][27]); + rkey[148] = rotlConstant<13>(rkey[142] + delta[0][28]); + rkey[154] = rotlConstant<13>(rkey[148] + delta[1][29]); + rkey[160] = rotlConstant<13>(rkey[154] + delta[2][30]); + rkey[166] = rotlConstant<13>(rkey[160] + delta[3][31]); + + rkey[ 5] = rotlConstant<17>( key[ 5] + delta[0][ 5]); + rkey[ 11] = rotlConstant<17>(rkey[ 5] + delta[1][ 6]); + rkey[ 17] = rotlConstant<17>(rkey[ 11] + delta[2][ 7]); + rkey[ 23] = rotlConstant<17>(rkey[ 17] + delta[3][ 8]); + rkey[ 29] = rotlConstant<17>(rkey[ 23] + delta[4][ 9]); + rkey[ 35] = rotlConstant<17>(rkey[ 29] + delta[5][10]); + rkey[ 41] = rotlConstant<17>(rkey[ 35] + delta[0][11]); + rkey[ 47] = rotlConstant<17>(rkey[ 41] + delta[1][12]); + rkey[ 53] = rotlConstant<17>(rkey[ 47] + delta[2][13]); + rkey[ 59] = rotlConstant<17>(rkey[ 53] + delta[3][14]); + rkey[ 65] = rotlConstant<17>(rkey[ 59] + delta[4][15]); + rkey[ 71] = rotlConstant<17>(rkey[ 65] + delta[5][16]); + rkey[ 77] = rotlConstant<17>(rkey[ 71] + delta[0][17]); + rkey[ 83] = rotlConstant<17>(rkey[ 77] + delta[1][18]); + rkey[ 89] = rotlConstant<17>(rkey[ 83] + delta[2][19]); + rkey[ 95] = rotlConstant<17>(rkey[ 89] + delta[3][20]); + rkey[101] = rotlConstant<17>(rkey[ 95] + delta[4][21]); + rkey[107] = rotlConstant<17>(rkey[101] + delta[5][22]); + rkey[113] = rotlConstant<17>(rkey[107] + delta[0][23]); + rkey[119] = rotlConstant<17>(rkey[113] + delta[1][24]); + rkey[125] = rotlConstant<17>(rkey[119] + delta[2][25]); + rkey[131] = rotlConstant<17>(rkey[125] + delta[3][26]); + rkey[137] = rotlConstant<17>(rkey[131] + delta[4][27]); + rkey[143] = rotlConstant<17>(rkey[137] + delta[5][28]); + rkey[149] = rotlConstant<17>(rkey[143] + delta[0][29]); + rkey[155] = rotlConstant<17>(rkey[149] + delta[1][30]); + rkey[161] = rotlConstant<17>(rkey[155] + delta[2][31]); + rkey[167] = rotlConstant<17>(rkey[161] + delta[3][ 0]); +} + +inline void SetKey256(word32 rkey[192], const word32 key[8]) +{ + rkey[ 0] = rotlConstant< 1>( key[ 0] + delta[0][ 0]); + rkey[ 8] = rotlConstant< 6>(rkey[ 0] + delta[1][ 3]); + rkey[ 16] = rotlConstant<13>(rkey[ 8] + delta[2][ 6]); + rkey[ 24] = rotlConstant< 1>(rkey[ 16] + delta[4][ 4]); + rkey[ 32] = rotlConstant< 6>(rkey[ 24] + delta[5][ 7]); + rkey[ 40] = rotlConstant<13>(rkey[ 32] + delta[6][10]); + rkey[ 48] = rotlConstant< 1>(rkey[ 40] + delta[0][ 8]); + rkey[ 56] = rotlConstant< 6>(rkey[ 48] + delta[1][11]); + rkey[ 64] = rotlConstant<13>(rkey[ 56] + delta[2][14]); + rkey[ 72] = rotlConstant< 1>(rkey[ 64] + delta[4][12]); + rkey[ 80] = rotlConstant< 6>(rkey[ 72] + delta[5][15]); + rkey[ 88] = rotlConstant<13>(rkey[ 80] + delta[6][18]); + rkey[ 96] = rotlConstant< 1>(rkey[ 88] + delta[0][16]); + rkey[104] = rotlConstant< 6>(rkey[ 96] + delta[1][19]); + rkey[112] = rotlConstant<13>(rkey[104] + delta[2][22]); + rkey[120] = rotlConstant< 1>(rkey[112] + delta[4][20]); + rkey[128] = rotlConstant< 6>(rkey[120] + delta[5][23]); + rkey[136] = rotlConstant<13>(rkey[128] + delta[6][26]); + rkey[144] = rotlConstant< 1>(rkey[136] + delta[0][24]); + rkey[152] = rotlConstant< 6>(rkey[144] + delta[1][27]); + rkey[160] = rotlConstant<13>(rkey[152] + delta[2][30]); + rkey[168] = rotlConstant< 1>(rkey[160] + delta[4][28]); + rkey[176] = rotlConstant< 6>(rkey[168] + delta[5][31]); + rkey[184] = rotlConstant<13>(rkey[176] + delta[6][ 2]); + + rkey[ 1] = rotlConstant< 3>( key[ 1] + delta[0][ 1]); + rkey[ 9] = rotlConstant<11>(rkey[ 1] + delta[1][ 4]); + rkey[ 17] = rotlConstant<17>(rkey[ 9] + delta[2][ 7]); + rkey[ 25] = rotlConstant< 3>(rkey[ 17] + delta[4][ 5]); + rkey[ 33] = rotlConstant<11>(rkey[ 25] + delta[5][ 8]); + rkey[ 41] = rotlConstant<17>(rkey[ 33] + delta[6][11]); + rkey[ 49] = rotlConstant< 3>(rkey[ 41] + delta[0][ 9]); + rkey[ 57] = rotlConstant<11>(rkey[ 49] + delta[1][12]); + rkey[ 65] = rotlConstant<17>(rkey[ 57] + delta[2][15]); + rkey[ 73] = rotlConstant< 3>(rkey[ 65] + delta[4][13]); + rkey[ 81] = rotlConstant<11>(rkey[ 73] + delta[5][16]); + rkey[ 89] = rotlConstant<17>(rkey[ 81] + delta[6][19]); + rkey[ 97] = rotlConstant< 3>(rkey[ 89] + delta[0][17]); + rkey[105] = rotlConstant<11>(rkey[ 97] + delta[1][20]); + rkey[113] = rotlConstant<17>(rkey[105] + delta[2][23]); + rkey[121] = rotlConstant< 3>(rkey[113] + delta[4][21]); + rkey[129] = rotlConstant<11>(rkey[121] + delta[5][24]); + rkey[137] = rotlConstant<17>(rkey[129] + delta[6][27]); + rkey[145] = rotlConstant< 3>(rkey[137] + delta[0][25]); + rkey[153] = rotlConstant<11>(rkey[145] + delta[1][28]); + rkey[161] = rotlConstant<17>(rkey[153] + delta[2][31]); + rkey[169] = rotlConstant< 3>(rkey[161] + delta[4][29]); + rkey[177] = rotlConstant<11>(rkey[169] + delta[5][ 0]); + rkey[185] = rotlConstant<17>(rkey[177] + delta[6][ 3]); + + rkey[ 2] = rotlConstant< 6>( key[ 2] + delta[0][ 2]); + rkey[ 10] = rotlConstant<13>(rkey[ 2] + delta[1][ 5]); + rkey[ 18] = rotlConstant< 1>(rkey[ 10] + delta[3][ 3]); + rkey[ 26] = rotlConstant< 6>(rkey[ 18] + delta[4][ 6]); + rkey[ 34] = rotlConstant<13>(rkey[ 26] + delta[5][ 9]); + rkey[ 42] = rotlConstant< 1>(rkey[ 34] + delta[7][ 7]); + rkey[ 50] = rotlConstant< 6>(rkey[ 42] + delta[0][10]); + rkey[ 58] = rotlConstant<13>(rkey[ 50] + delta[1][13]); + rkey[ 66] = rotlConstant< 1>(rkey[ 58] + delta[3][11]); + rkey[ 74] = rotlConstant< 6>(rkey[ 66] + delta[4][14]); + rkey[ 82] = rotlConstant<13>(rkey[ 74] + delta[5][17]); + rkey[ 90] = rotlConstant< 1>(rkey[ 82] + delta[7][15]); + rkey[ 98] = rotlConstant< 6>(rkey[ 90] + delta[0][18]); + rkey[106] = rotlConstant<13>(rkey[ 98] + delta[1][21]); + rkey[114] = rotlConstant< 1>(rkey[106] + delta[3][19]); + rkey[122] = rotlConstant< 6>(rkey[114] + delta[4][22]); + rkey[130] = rotlConstant<13>(rkey[122] + delta[5][25]); + rkey[138] = rotlConstant< 1>(rkey[130] + delta[7][23]); + rkey[146] = rotlConstant< 6>(rkey[138] + delta[0][26]); + rkey[154] = rotlConstant<13>(rkey[146] + delta[1][29]); + rkey[162] = rotlConstant< 1>(rkey[154] + delta[3][27]); + rkey[170] = rotlConstant< 6>(rkey[162] + delta[4][30]); + rkey[178] = rotlConstant<13>(rkey[170] + delta[5][ 1]); + rkey[186] = rotlConstant< 1>(rkey[178] + delta[7][31]); + + rkey[ 3] = rotlConstant<11>( key[ 3] + delta[0][ 3]); + rkey[ 11] = rotlConstant<17>(rkey[ 3] + delta[1][ 6]); + rkey[ 19] = rotlConstant< 3>(rkey[ 11] + delta[3][ 4]); + rkey[ 27] = rotlConstant<11>(rkey[ 19] + delta[4][ 7]); + rkey[ 35] = rotlConstant<17>(rkey[ 27] + delta[5][10]); + rkey[ 43] = rotlConstant< 3>(rkey[ 35] + delta[7][ 8]); + rkey[ 51] = rotlConstant<11>(rkey[ 43] + delta[0][11]); + rkey[ 59] = rotlConstant<17>(rkey[ 51] + delta[1][14]); + rkey[ 67] = rotlConstant< 3>(rkey[ 59] + delta[3][12]); + rkey[ 75] = rotlConstant<11>(rkey[ 67] + delta[4][15]); + rkey[ 83] = rotlConstant<17>(rkey[ 75] + delta[5][18]); + rkey[ 91] = rotlConstant< 3>(rkey[ 83] + delta[7][16]); + rkey[ 99] = rotlConstant<11>(rkey[ 91] + delta[0][19]); + rkey[107] = rotlConstant<17>(rkey[ 99] + delta[1][22]); + rkey[115] = rotlConstant< 3>(rkey[107] + delta[3][20]); + rkey[123] = rotlConstant<11>(rkey[115] + delta[4][23]); + rkey[131] = rotlConstant<17>(rkey[123] + delta[5][26]); + rkey[139] = rotlConstant< 3>(rkey[131] + delta[7][24]); + rkey[147] = rotlConstant<11>(rkey[139] + delta[0][27]); + rkey[155] = rotlConstant<17>(rkey[147] + delta[1][30]); + rkey[163] = rotlConstant< 3>(rkey[155] + delta[3][28]); + rkey[171] = rotlConstant<11>(rkey[163] + delta[4][31]); + rkey[179] = rotlConstant<17>(rkey[171] + delta[5][ 2]); + rkey[187] = rotlConstant< 3>(rkey[179] + delta[7][ 0]); + + rkey[ 4] = rotlConstant<13>( key[ 4] + delta[0][ 4]); + rkey[ 12] = rotlConstant< 1>(rkey[ 4] + delta[2][ 2]); + rkey[ 20] = rotlConstant< 6>(rkey[ 12] + delta[3][ 5]); + rkey[ 28] = rotlConstant<13>(rkey[ 20] + delta[4][ 8]); + rkey[ 36] = rotlConstant< 1>(rkey[ 28] + delta[6][ 6]); + rkey[ 44] = rotlConstant< 6>(rkey[ 36] + delta[7][ 9]); + rkey[ 52] = rotlConstant<13>(rkey[ 44] + delta[0][12]); + rkey[ 60] = rotlConstant< 1>(rkey[ 52] + delta[2][10]); + rkey[ 68] = rotlConstant< 6>(rkey[ 60] + delta[3][13]); + rkey[ 76] = rotlConstant<13>(rkey[ 68] + delta[4][16]); + rkey[ 84] = rotlConstant< 1>(rkey[ 76] + delta[6][14]); + rkey[ 92] = rotlConstant< 6>(rkey[ 84] + delta[7][17]); + rkey[100] = rotlConstant<13>(rkey[ 92] + delta[0][20]); + rkey[108] = rotlConstant< 1>(rkey[100] + delta[2][18]); + rkey[116] = rotlConstant< 6>(rkey[108] + delta[3][21]); + rkey[124] = rotlConstant<13>(rkey[116] + delta[4][24]); + rkey[132] = rotlConstant< 1>(rkey[124] + delta[6][22]); + rkey[140] = rotlConstant< 6>(rkey[132] + delta[7][25]); + rkey[148] = rotlConstant<13>(rkey[140] + delta[0][28]); + rkey[156] = rotlConstant< 1>(rkey[148] + delta[2][26]); + rkey[164] = rotlConstant< 6>(rkey[156] + delta[3][29]); + rkey[172] = rotlConstant<13>(rkey[164] + delta[4][ 0]); + rkey[180] = rotlConstant< 1>(rkey[172] + delta[6][30]); + rkey[188] = rotlConstant< 6>(rkey[180] + delta[7][ 1]); + + rkey[ 5] = rotlConstant<17>( key[ 5] + delta[0][ 5]); + rkey[ 13] = rotlConstant< 3>(rkey[ 5] + delta[2][ 3]); + rkey[ 21] = rotlConstant<11>(rkey[ 13] + delta[3][ 6]); + rkey[ 29] = rotlConstant<17>(rkey[ 21] + delta[4][ 9]); + rkey[ 37] = rotlConstant< 3>(rkey[ 29] + delta[6][ 7]); + rkey[ 45] = rotlConstant<11>(rkey[ 37] + delta[7][10]); + rkey[ 53] = rotlConstant<17>(rkey[ 45] + delta[0][13]); + rkey[ 61] = rotlConstant< 3>(rkey[ 53] + delta[2][11]); + rkey[ 69] = rotlConstant<11>(rkey[ 61] + delta[3][14]); + rkey[ 77] = rotlConstant<17>(rkey[ 69] + delta[4][17]); + rkey[ 85] = rotlConstant< 3>(rkey[ 77] + delta[6][15]); + rkey[ 93] = rotlConstant<11>(rkey[ 85] + delta[7][18]); + rkey[101] = rotlConstant<17>(rkey[ 93] + delta[0][21]); + rkey[109] = rotlConstant< 3>(rkey[101] + delta[2][19]); + rkey[117] = rotlConstant<11>(rkey[109] + delta[3][22]); + rkey[125] = rotlConstant<17>(rkey[117] + delta[4][25]); + rkey[133] = rotlConstant< 3>(rkey[125] + delta[6][23]); + rkey[141] = rotlConstant<11>(rkey[133] + delta[7][26]); + rkey[149] = rotlConstant<17>(rkey[141] + delta[0][29]); + rkey[157] = rotlConstant< 3>(rkey[149] + delta[2][27]); + rkey[165] = rotlConstant<11>(rkey[157] + delta[3][30]); + rkey[173] = rotlConstant<17>(rkey[165] + delta[4][ 1]); + rkey[181] = rotlConstant< 3>(rkey[173] + delta[6][31]); + rkey[189] = rotlConstant<11>(rkey[181] + delta[7][ 2]); + + rkey[ 6] = rotlConstant< 1>( key[ 6] + delta[1][ 1]); + rkey[ 14] = rotlConstant< 6>(rkey[ 6] + delta[2][ 4]); + rkey[ 22] = rotlConstant<13>(rkey[ 14] + delta[3][ 7]); + rkey[ 30] = rotlConstant< 1>(rkey[ 22] + delta[5][ 5]); + rkey[ 38] = rotlConstant< 6>(rkey[ 30] + delta[6][ 8]); + rkey[ 46] = rotlConstant<13>(rkey[ 38] + delta[7][11]); + rkey[ 54] = rotlConstant< 1>(rkey[ 46] + delta[1][ 9]); + rkey[ 62] = rotlConstant< 6>(rkey[ 54] + delta[2][12]); + rkey[ 70] = rotlConstant<13>(rkey[ 62] + delta[3][15]); + rkey[ 78] = rotlConstant< 1>(rkey[ 70] + delta[5][13]); + rkey[ 86] = rotlConstant< 6>(rkey[ 78] + delta[6][16]); + rkey[ 94] = rotlConstant<13>(rkey[ 86] + delta[7][19]); + rkey[102] = rotlConstant< 1>(rkey[ 94] + delta[1][17]); + rkey[110] = rotlConstant< 6>(rkey[102] + delta[2][20]); + rkey[118] = rotlConstant<13>(rkey[110] + delta[3][23]); + rkey[126] = rotlConstant< 1>(rkey[118] + delta[5][21]); + rkey[134] = rotlConstant< 6>(rkey[126] + delta[6][24]); + rkey[142] = rotlConstant<13>(rkey[134] + delta[7][27]); + rkey[150] = rotlConstant< 1>(rkey[142] + delta[1][25]); + rkey[158] = rotlConstant< 6>(rkey[150] + delta[2][28]); + rkey[166] = rotlConstant<13>(rkey[158] + delta[3][31]); + rkey[174] = rotlConstant< 1>(rkey[166] + delta[5][29]); + rkey[182] = rotlConstant< 6>(rkey[174] + delta[6][ 0]); + rkey[190] = rotlConstant<13>(rkey[182] + delta[7][ 3]); + + rkey[ 7] = rotlConstant< 3>( key[ 7] + delta[1][ 2]); + rkey[ 15] = rotlConstant<11>(rkey[ 7] + delta[2][ 5]); + rkey[ 23] = rotlConstant<17>(rkey[ 15] + delta[3][ 8]); + rkey[ 31] = rotlConstant< 3>(rkey[ 23] + delta[5][ 6]); + rkey[ 39] = rotlConstant<11>(rkey[ 31] + delta[6][ 9]); + rkey[ 47] = rotlConstant<17>(rkey[ 39] + delta[7][12]); + rkey[ 55] = rotlConstant< 3>(rkey[ 47] + delta[1][10]); + rkey[ 63] = rotlConstant<11>(rkey[ 55] + delta[2][13]); + rkey[ 71] = rotlConstant<17>(rkey[ 63] + delta[3][16]); + rkey[ 79] = rotlConstant< 3>(rkey[ 71] + delta[5][14]); + rkey[ 87] = rotlConstant<11>(rkey[ 79] + delta[6][17]); + rkey[ 95] = rotlConstant<17>(rkey[ 87] + delta[7][20]); + rkey[103] = rotlConstant< 3>(rkey[ 95] + delta[1][18]); + rkey[111] = rotlConstant<11>(rkey[103] + delta[2][21]); + rkey[119] = rotlConstant<17>(rkey[111] + delta[3][24]); + rkey[127] = rotlConstant< 3>(rkey[119] + delta[5][22]); + rkey[135] = rotlConstant<11>(rkey[127] + delta[6][25]); + rkey[143] = rotlConstant<17>(rkey[135] + delta[7][28]); + rkey[151] = rotlConstant< 3>(rkey[143] + delta[1][26]); + rkey[159] = rotlConstant<11>(rkey[151] + delta[2][29]); + rkey[167] = rotlConstant<17>(rkey[159] + delta[3][ 0]); + rkey[175] = rotlConstant< 3>(rkey[167] + delta[5][30]); + rkey[183] = rotlConstant<11>(rkey[175] + delta[6][ 1]); + rkey[191] = rotlConstant<17>(rkey[183] + delta[7][ 4]); +} + +NAMESPACE_BEGIN(CryptoPP) + +#if CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS +# if defined(CRYPTOPP_SSSE3_AVAILABLE) +extern size_t LEA_Enc_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t LEA_Dec_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +# endif + +# if (CRYPTOPP_ARM_NEON_AVAILABLE) +extern size_t LEA_Enc_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t LEA_Dec_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +# endif +#endif + +std::string LEA::Base::AlgorithmProvider() const +{ +#if (CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS) +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return "SSSE3"; +# endif +# if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; +# endif +#endif + return "C++"; +} + +void LEA::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + + switch(keyLength) + { + case 16: // 128-bit key + { + m_rkey.New(144); m_temp.New(4); m_rounds = 24; + GetUserKey(LITTLE_ENDIAN_ORDER, m_temp.begin(), 4, userKey, 16); + SetKey128(m_rkey, m_temp); + break; + } + case 24: // 192-bit key + { + m_rkey.New(168); m_temp.New(6); m_rounds = 28; + GetUserKey(LITTLE_ENDIAN_ORDER, m_temp.begin(), 6, userKey, 24); + SetKey192(m_rkey, m_temp); + break; + } + case 32: // 256-bit key + { + m_rkey.New(192); m_temp.New(8); m_rounds = 32; + GetUserKey(LITTLE_ENDIAN_ORDER, m_temp.begin(), 8, userKey, 32); + SetKey256(m_rkey, m_temp); + break; + } + default: + CRYPTOPP_ASSERT(0); + } +} + +void LEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_temp[0])(m_temp[1])(m_temp[2])(m_temp[3]); + + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[ 4]) + (m_temp[3] ^ m_rkey[ 5])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[ 2]) + (m_temp[2] ^ m_rkey[ 3])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[ 0]) + (m_temp[1] ^ m_rkey[ 1])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[ 10]) + (m_temp[0] ^ m_rkey[ 11])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[ 8]) + (m_temp[3] ^ m_rkey[ 9])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[ 6]) + (m_temp[2] ^ m_rkey[ 7])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[ 16]) + (m_temp[1] ^ m_rkey[ 17])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[ 14]) + (m_temp[0] ^ m_rkey[ 15])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[ 12]) + (m_temp[3] ^ m_rkey[ 13])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[ 22]) + (m_temp[2] ^ m_rkey[ 23])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[ 20]) + (m_temp[1] ^ m_rkey[ 21])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[ 18]) + (m_temp[0] ^ m_rkey[ 19])); + + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[ 28]) + (m_temp[3] ^ m_rkey[ 29])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[ 26]) + (m_temp[2] ^ m_rkey[ 27])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[ 24]) + (m_temp[1] ^ m_rkey[ 25])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[ 34]) + (m_temp[0] ^ m_rkey[ 35])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[ 32]) + (m_temp[3] ^ m_rkey[ 33])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[ 30]) + (m_temp[2] ^ m_rkey[ 31])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[ 40]) + (m_temp[1] ^ m_rkey[ 41])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[ 38]) + (m_temp[0] ^ m_rkey[ 39])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[ 36]) + (m_temp[3] ^ m_rkey[ 37])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[ 46]) + (m_temp[2] ^ m_rkey[ 47])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[ 44]) + (m_temp[1] ^ m_rkey[ 45])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[ 42]) + (m_temp[0] ^ m_rkey[ 43])); + + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[ 52]) + (m_temp[3] ^ m_rkey[ 53])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[ 50]) + (m_temp[2] ^ m_rkey[ 51])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[ 48]) + (m_temp[1] ^ m_rkey[ 49])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[ 58]) + (m_temp[0] ^ m_rkey[ 59])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[ 56]) + (m_temp[3] ^ m_rkey[ 57])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[ 54]) + (m_temp[2] ^ m_rkey[ 55])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[ 64]) + (m_temp[1] ^ m_rkey[ 65])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[ 62]) + (m_temp[0] ^ m_rkey[ 63])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[ 60]) + (m_temp[3] ^ m_rkey[ 61])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[ 70]) + (m_temp[2] ^ m_rkey[ 71])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[ 68]) + (m_temp[1] ^ m_rkey[ 69])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[ 66]) + (m_temp[0] ^ m_rkey[ 67])); + + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[ 76]) + (m_temp[3] ^ m_rkey[ 77])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[ 74]) + (m_temp[2] ^ m_rkey[ 75])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[ 72]) + (m_temp[1] ^ m_rkey[ 73])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[ 82]) + (m_temp[0] ^ m_rkey[ 83])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[ 80]) + (m_temp[3] ^ m_rkey[ 81])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[ 78]) + (m_temp[2] ^ m_rkey[ 79])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[ 88]) + (m_temp[1] ^ m_rkey[ 89])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[ 86]) + (m_temp[0] ^ m_rkey[ 87])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[ 84]) + (m_temp[3] ^ m_rkey[ 85])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[ 94]) + (m_temp[2] ^ m_rkey[ 95])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[ 92]) + (m_temp[1] ^ m_rkey[ 93])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[ 90]) + (m_temp[0] ^ m_rkey[ 91])); + + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[100]) + (m_temp[3] ^ m_rkey[101])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[ 98]) + (m_temp[2] ^ m_rkey[ 99])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[ 96]) + (m_temp[1] ^ m_rkey[ 97])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[106]) + (m_temp[0] ^ m_rkey[107])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[104]) + (m_temp[3] ^ m_rkey[105])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[102]) + (m_temp[2] ^ m_rkey[103])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[112]) + (m_temp[1] ^ m_rkey[113])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[110]) + (m_temp[0] ^ m_rkey[111])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[108]) + (m_temp[3] ^ m_rkey[109])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[118]) + (m_temp[2] ^ m_rkey[119])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[116]) + (m_temp[1] ^ m_rkey[117])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[114]) + (m_temp[0] ^ m_rkey[115])); + + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[124]) + (m_temp[3] ^ m_rkey[125])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[122]) + (m_temp[2] ^ m_rkey[123])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[120]) + (m_temp[1] ^ m_rkey[121])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[130]) + (m_temp[0] ^ m_rkey[131])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[128]) + (m_temp[3] ^ m_rkey[129])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[126]) + (m_temp[2] ^ m_rkey[127])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[136]) + (m_temp[1] ^ m_rkey[137])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[134]) + (m_temp[0] ^ m_rkey[135])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[132]) + (m_temp[3] ^ m_rkey[133])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[142]) + (m_temp[2] ^ m_rkey[143])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[140]) + (m_temp[1] ^ m_rkey[141])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[138]) + (m_temp[0] ^ m_rkey[139])); + + if(m_rounds > 24) + { + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[148]) + (m_temp[3] ^ m_rkey[149])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[146]) + (m_temp[2] ^ m_rkey[147])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[144]) + (m_temp[1] ^ m_rkey[145])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[154]) + (m_temp[0] ^ m_rkey[155])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[152]) + (m_temp[3] ^ m_rkey[153])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[150]) + (m_temp[2] ^ m_rkey[151])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[160]) + (m_temp[1] ^ m_rkey[161])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[158]) + (m_temp[0] ^ m_rkey[159])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[156]) + (m_temp[3] ^ m_rkey[157])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[166]) + (m_temp[2] ^ m_rkey[167])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[164]) + (m_temp[1] ^ m_rkey[165])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[162]) + (m_temp[0] ^ m_rkey[163])); + } + + if(m_rounds > 28) + { + m_temp[3] = rotrConstant<3>((m_temp[2] ^ m_rkey[172]) + (m_temp[3] ^ m_rkey[173])); + m_temp[2] = rotrConstant<5>((m_temp[1] ^ m_rkey[170]) + (m_temp[2] ^ m_rkey[171])); + m_temp[1] = rotlConstant<9>((m_temp[0] ^ m_rkey[168]) + (m_temp[1] ^ m_rkey[169])); + m_temp[0] = rotrConstant<3>((m_temp[3] ^ m_rkey[178]) + (m_temp[0] ^ m_rkey[179])); + m_temp[3] = rotrConstant<5>((m_temp[2] ^ m_rkey[176]) + (m_temp[3] ^ m_rkey[177])); + m_temp[2] = rotlConstant<9>((m_temp[1] ^ m_rkey[174]) + (m_temp[2] ^ m_rkey[175])); + m_temp[1] = rotrConstant<3>((m_temp[0] ^ m_rkey[184]) + (m_temp[1] ^ m_rkey[185])); + m_temp[0] = rotrConstant<5>((m_temp[3] ^ m_rkey[182]) + (m_temp[0] ^ m_rkey[183])); + m_temp[3] = rotlConstant<9>((m_temp[2] ^ m_rkey[180]) + (m_temp[3] ^ m_rkey[181])); + m_temp[2] = rotrConstant<3>((m_temp[1] ^ m_rkey[190]) + (m_temp[2] ^ m_rkey[191])); + m_temp[1] = rotrConstant<5>((m_temp[0] ^ m_rkey[188]) + (m_temp[1] ^ m_rkey[189])); + m_temp[0] = rotlConstant<9>((m_temp[3] ^ m_rkey[186]) + (m_temp[0] ^ m_rkey[187])); + } + + PutBlock oblock(xorBlock, outBlock); + oblock(m_temp[0])(m_temp[1])(m_temp[2])(m_temp[3]); +} + +void LEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_temp[0])(m_temp[1])(m_temp[2])(m_temp[3]); + + if(m_rounds > 28) + { + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[186])) ^ m_rkey[187]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[188])) ^ m_rkey[189]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[190])) ^ m_rkey[191]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[180])) ^ m_rkey[181]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[182])) ^ m_rkey[183]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[184])) ^ m_rkey[185]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[174])) ^ m_rkey[175]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[176])) ^ m_rkey[177]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[178])) ^ m_rkey[179]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[168])) ^ m_rkey[169]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[170])) ^ m_rkey[171]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[172])) ^ m_rkey[173]; + } + + if(m_rounds > 24) + { + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[162])) ^ m_rkey[163]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[164])) ^ m_rkey[165]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[166])) ^ m_rkey[167]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[156])) ^ m_rkey[157]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[158])) ^ m_rkey[159]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[160])) ^ m_rkey[161]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[150])) ^ m_rkey[151]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[152])) ^ m_rkey[153]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[154])) ^ m_rkey[155]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[144])) ^ m_rkey[145]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[146])) ^ m_rkey[147]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[148])) ^ m_rkey[149]; + } + + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[138])) ^ m_rkey[139]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[140])) ^ m_rkey[141]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[142])) ^ m_rkey[143]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[132])) ^ m_rkey[133]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[134])) ^ m_rkey[135]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[136])) ^ m_rkey[137]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[126])) ^ m_rkey[127]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[128])) ^ m_rkey[129]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[130])) ^ m_rkey[131]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[120])) ^ m_rkey[121]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[122])) ^ m_rkey[123]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[124])) ^ m_rkey[125]; + + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[114])) ^ m_rkey[115]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[116])) ^ m_rkey[117]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[118])) ^ m_rkey[119]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[108])) ^ m_rkey[109]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[110])) ^ m_rkey[111]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[112])) ^ m_rkey[113]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[102])) ^ m_rkey[103]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[104])) ^ m_rkey[105]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[106])) ^ m_rkey[107]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 96])) ^ m_rkey[ 97]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 98])) ^ m_rkey[ 99]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[100])) ^ m_rkey[101]; + + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 90])) ^ m_rkey[ 91]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 92])) ^ m_rkey[ 93]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 94])) ^ m_rkey[ 95]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 84])) ^ m_rkey[ 85]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 86])) ^ m_rkey[ 87]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 88])) ^ m_rkey[ 89]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 78])) ^ m_rkey[ 79]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 80])) ^ m_rkey[ 81]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 82])) ^ m_rkey[ 83]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 72])) ^ m_rkey[ 73]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 74])) ^ m_rkey[ 75]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 76])) ^ m_rkey[ 77]; + + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 66])) ^ m_rkey[ 67]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 68])) ^ m_rkey[ 69]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 70])) ^ m_rkey[ 71]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 60])) ^ m_rkey[ 61]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 62])) ^ m_rkey[ 63]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 64])) ^ m_rkey[ 65]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 54])) ^ m_rkey[ 55]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 56])) ^ m_rkey[ 57]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 58])) ^ m_rkey[ 59]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 48])) ^ m_rkey[ 49]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 50])) ^ m_rkey[ 51]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 52])) ^ m_rkey[ 53]; + + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 42])) ^ m_rkey[ 43]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 44])) ^ m_rkey[ 45]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 46])) ^ m_rkey[ 47]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 36])) ^ m_rkey[ 37]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 38])) ^ m_rkey[ 39]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 40])) ^ m_rkey[ 41]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 30])) ^ m_rkey[ 31]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 32])) ^ m_rkey[ 33]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 34])) ^ m_rkey[ 35]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 24])) ^ m_rkey[ 25]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 26])) ^ m_rkey[ 27]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 28])) ^ m_rkey[ 29]; + + m_temp[0] = (rotrConstant<9>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 18])) ^ m_rkey[ 19]; + m_temp[1] = (rotlConstant<5>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 20])) ^ m_rkey[ 21]; + m_temp[2] = (rotlConstant<3>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 22])) ^ m_rkey[ 23]; + m_temp[3] = (rotrConstant<9>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 12])) ^ m_rkey[ 13]; + m_temp[0] = (rotlConstant<5>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 14])) ^ m_rkey[ 15]; + m_temp[1] = (rotlConstant<3>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 16])) ^ m_rkey[ 17]; + m_temp[2] = (rotrConstant<9>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 6])) ^ m_rkey[ 7]; + m_temp[3] = (rotlConstant<5>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 8])) ^ m_rkey[ 9]; + m_temp[0] = (rotlConstant<3>(m_temp[0]) - (m_temp[3] ^ m_rkey[ 10])) ^ m_rkey[ 11]; + m_temp[1] = (rotrConstant<9>(m_temp[1]) - (m_temp[0] ^ m_rkey[ 0])) ^ m_rkey[ 1]; + m_temp[2] = (rotlConstant<5>(m_temp[2]) - (m_temp[1] ^ m_rkey[ 2])) ^ m_rkey[ 3]; + m_temp[3] = (rotlConstant<3>(m_temp[3]) - (m_temp[2] ^ m_rkey[ 4])) ^ m_rkey[ 5]; + + PutBlock oblock(xorBlock, outBlock); + oblock(m_temp[0])(m_temp[1])(m_temp[2])(m_temp[3]); +} + +#if CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS +size_t LEA::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if defined(CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) { + return LEA_Enc_AdvancedProcessBlocks_SSSE3(m_rkey, m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); + } +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return LEA_Enc_AdvancedProcessBlocks_NEON(m_rkey, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t LEA::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if defined(CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) { + return LEA_Dec_AdvancedProcessBlocks_SSSE3(m_rkey, m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); + } +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return LEA_Dec_AdvancedProcessBlocks_NEON(m_rkey, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/lea.h b/external/ours/library/crypto/src/shared/original/lea.h new file mode 100755 index 000000000..26650d397 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lea.h @@ -0,0 +1,108 @@ +// lea.h - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "LEA: A 128-Bit Block Cipher for Fast Encryption on Common +// Processors" by Deukjo Hong, Jung-Keun Lee, Dong-Chan Kim, Daesung Kwon, +// Kwon Ho Ryu, and Dong-Geon Lee. + +/// \file lea.h +/// \brief Classes for the LEA block cipher +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_LEA_H +#define CRYPTOPP_LEA_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +#if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) +# ifndef CRYPTOPP_DISABLE_LEA_SIMD +# define CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS 1 +# endif +#endif + +// Yet another SunStudio/SunCC workaround. Failed self tests +// in SSE code paths on i386 for SunStudio 12.3 and below. +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) +# undef CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief LEA block cipher information +/// \since Crypto++ 8.0 +struct LEA_Info : public FixedBlockSize<16>, public VariableKeyLength<16,16,32,8> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "LEA-128"; + } +}; + +/// \brief LEA 128-bit block cipher +/// \details LEA provides 128-bit block size. The valid key size is 128-bits, 192-bits and 256-bits. +/// \note Crypto++ provides a byte oriented implementation +/// \sa LEA, +/// +/// LEA: A 128-Bit Block Cipher for Fast Encryption on Common Processors +/// \since Crypto++ 8.0 +class CRYPTOPP_NO_VTABLE LEA : public LEA_Info, public BlockCipherDocumentation +{ +public: + /// \brief LEA block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + std::string AlgorithmProvider() const; + + SecBlock m_rkey; + mutable SecBlock m_temp; + unsigned int m_rounds; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + +#if CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + +#if CRYPTOPP_LEA_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef LEA::Encryption LEAEncryption; +typedef LEA::Decryption LEADecryption; + +NAMESPACE_END + +#endif // CRYPTOPP_LEA_H diff --git a/external/ours/library/crypto/src/shared/original/lea_simd.cpp b/external/ours/library/crypto/src/shared/original/lea_simd.cpp new file mode 100755 index 000000000..7ea9cfa54 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lea_simd.cpp @@ -0,0 +1,1072 @@ +// lea_simd.cpp - written and placed in the public domain by Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// SSSE3, ARM NEON and ARMv8a, and Power8 Altivec instructions. A separate +// source file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#include "lea.h" +#include "misc.h" + +// Uncomment for benchmarking C++ against SSE or NEON. +// Do so in both simon.cpp and simon_simd.cpp. +// #undef CRYPTOPP_SSSE3_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_SSSE3_AVAILABLE) +# include "adv_simd.h" +# include +# include +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include "adv_simd.h" +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if defined(_M_ARM64) +# include "adv_simd.h" +#endif + +// Do not port this to POWER architecture. Naively we hoped +// for a 2x to 3x speedup. The result was a 5x slow down. +// The table below shows MiB/s and cpb. +// +// C++: +// LEA-128(128)/CTR (128-bit key)C++20715.64 +// LEA-128(192)/CTR (192-bit key)C++18617.48 +// LEA-128(256)/CTR (256-bit key)C++12426.2 +// +// Power8: +// LEA-128(128)/CTR (128-bit key)Power83788.7 +// LEA-128(192)/CTR (192-bit key)Power84082.1 +// LEA-128(256)/CTR (256-bit key)Power828116.0 + +#undef CRYPTOPP_POWER8_AVAILABLE +#if defined(CRYPTOPP_POWER8_AVAILABLE) +# include "adv_simd.h" +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char LEA_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; + +// *************************** ARM NEON ***************************// + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +inline uint32x4_t Xor(const uint32x4_t& a, const uint32x4_t& b) +{ + return veorq_u32(a, b); +} + +inline uint32x4_t Add(const uint32x4_t& a, const uint32x4_t& b) +{ + return vaddq_u32(a, b); +} + +inline uint32x4_t Sub(const uint32x4_t& a, const uint32x4_t& b) +{ + return vsubq_u32(a, b); +} + +template +inline uint32x4_t RotateLeft(const uint32x4_t& val) +{ + const uint32x4_t a(vshlq_n_u32(val, R)); + const uint32x4_t b(vshrq_n_u32(val, 32 - R)); + return vorrq_u32(a, b); +} + +template +inline uint32x4_t RotateRight(const uint32x4_t& val) +{ + const uint32x4_t a(vshlq_n_u32(val, 32 - R)); + const uint32x4_t b(vshrq_n_u32(val, R)); + return vorrq_u32(a, b); +} + +#if defined(__aarch32__) || defined(__aarch64__) +template <> +inline uint32x4_t RotateLeft<8>(const uint32x4_t& val) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8_t maskb[16] = { 14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3 }; + const uint8x16_t mask = vld1q_u8(maskb); +#else + const uint8_t maskb[16] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 }; + const uint8x16_t mask = vld1q_u8(maskb); +#endif + + return vreinterpretq_u32_u8( + vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); +} + +template <> +inline uint32x4_t RotateRight<8>(const uint32x4_t& val) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8_t maskb[16] = { 12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1 }; + const uint8x16_t mask = vld1q_u8(maskb); +#else + const uint8_t maskb[16] = { 1,2,3,0, 5,6,7,4, 9,10,11,8, 13,14,14,12 }; + const uint8x16_t mask = vld1q_u8(maskb); +#endif + + return vreinterpretq_u32_u8( + vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); +} +#endif + +uint32x4_t UnpackLow32(uint32x4_t a, uint32x4_t b) +{ + uint32x2_t a1 = vget_low_u32(a); + uint32x2_t b1 = vget_low_u32(b); + uint32x2x2_t result = vzip_u32(a1, b1); + return vcombine_u32(result.val[0], result.val[1]); +} + +uint32x4_t UnpackHigh32(uint32x4_t a, uint32x4_t b) +{ + uint32x2_t a1 = vget_high_u32(a); + uint32x2_t b1 = vget_high_u32(b); + uint32x2x2_t result = vzip_u32(a1, b1); + return vcombine_u32(result.val[0], result.val[1]); +} + +uint32x4_t UnpackLow64(uint32x4_t a, uint32x4_t b) +{ + uint64x1_t a1 = vget_low_u64((uint64x2_t)a); + uint64x1_t b1 = vget_low_u64((uint64x2_t)b); + return (uint32x4_t)vcombine_u64(a1, b1); +} + +uint32x4_t UnpackHigh64(uint32x4_t a, uint32x4_t b) +{ + uint64x1_t a1 = vget_high_u64((uint64x2_t)a); + uint64x1_t b1 = vget_high_u64((uint64x2_t)b); + return (uint32x4_t)vcombine_u64(a1, b1); +} + +template +inline uint32x4_t LoadKey(const word32 rkey[]) +{ + return vdupq_n_u32(rkey[IDX]); +} + +template +inline uint32x4_t UnpackNEON(const uint32x4_t& a, const uint32x4_t& b, const uint32x4_t& c, const uint32x4_t& d) +{ + // Should not be instantiated + CRYPTOPP_ASSERT(0); + + CRYPTOPP_UNUSED(a); CRYPTOPP_UNUSED(b); + CRYPTOPP_UNUSED(c); CRYPTOPP_UNUSED(d); + return vmovq_n_u32(0); +} + +template <> +inline uint32x4_t UnpackNEON<0>(const uint32x4_t& a, const uint32x4_t& b, const uint32x4_t& c, const uint32x4_t& d) +{ + const uint32x4_t r1 = UnpackLow32(a, b); + const uint32x4_t r2 = UnpackLow32(c, d); + return UnpackLow64(r1, r2); +} + +template <> +inline uint32x4_t UnpackNEON<1>(const uint32x4_t& a, const uint32x4_t& b, const uint32x4_t& c, const uint32x4_t& d) +{ + const uint32x4_t r1 = UnpackLow32(a, b); + const uint32x4_t r2 = UnpackLow32(c, d); + return UnpackHigh64(r1, r2); +} + +template <> +inline uint32x4_t UnpackNEON<2>(const uint32x4_t& a, const uint32x4_t& b, const uint32x4_t& c, const uint32x4_t& d) +{ + const uint32x4_t r1 = UnpackHigh32(a, b); + const uint32x4_t r2 = UnpackHigh32(c, d); + return UnpackLow64(r1, r2); +} + +template <> +inline uint32x4_t UnpackNEON<3>(const uint32x4_t& a, const uint32x4_t& b, const uint32x4_t& c, const uint32x4_t& d) +{ + const uint32x4_t r1 = UnpackHigh32(a, b); + const uint32x4_t r2 = UnpackHigh32(c, d); + return UnpackHigh64(r1, r2); +} + +template +inline uint32x4_t UnpackNEON(const uint32x4_t& v) +{ + // Should not be instantiated + CRYPTOPP_ASSERT(0); + + CRYPTOPP_UNUSED(v); + return vmovq_n_u32(0); +} + +template <> +inline uint32x4_t UnpackNEON<0>(const uint32x4_t& v) +{ + // Splat to all lanes + return vdupq_n_u32(vgetq_lane_u32(v, 0)); +} + +template <> +inline uint32x4_t UnpackNEON<1>(const uint32x4_t& v) +{ + // Splat to all lanes + return vdupq_n_u32(vgetq_lane_u32(v, 1)); +} + +template <> +inline uint32x4_t UnpackNEON<2>(const uint32x4_t& v) +{ + // Splat to all lanes + return vdupq_n_u32(vgetq_lane_u32(v, 2)); +} + +template <> +inline uint32x4_t UnpackNEON<3>(const uint32x4_t& v) +{ + // Splat to all lanes + return vdupq_n_u32(vgetq_lane_u32(v, 3)); +} + +template +inline uint32x4_t RepackNEON(const uint32x4_t& a, const uint32x4_t& b, const uint32x4_t& c, const uint32x4_t& d) +{ + return UnpackNEON(a, b, c, d); +} + +template +inline uint32x4_t RepackNEON(const uint32x4_t& v) +{ + return UnpackNEON(v); +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// *************************** IA-32 ***************************// + +#if (CRYPTOPP_SSSE3_AVAILABLE) + +inline __m128i Xor(const __m128i& a, const __m128i& b) +{ + return _mm_xor_si128(a, b); +} + +inline __m128i Add(const __m128i& a, const __m128i& b) +{ + return _mm_add_epi32(a, b); +} + +inline __m128i Sub(const __m128i& a, const __m128i& b) +{ + return _mm_sub_epi32(a, b); +} + +template +inline __m128i RotateLeft(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, R); +#else + return _mm_or_si128( + _mm_slli_epi32(val, R), _mm_srli_epi32(val, 32-R)); +#endif +} + +template +inline __m128i RotateRight(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 32-R); +#else + return _mm_or_si128( + _mm_slli_epi32(val, 32-R), _mm_srli_epi32(val, R)); +#endif +} + +// Faster than two Shifts and an Or. +template <> +inline __m128i RotateLeft<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 8); +#else + const __m128i mask = _mm_set_epi8(14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3); + return _mm_shuffle_epi8(val, mask); +#endif +} + +// Faster than two Shifts and an Or. +template <> +inline __m128i RotateRight<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi32(val, 32-8); +#else + const __m128i mask = _mm_set_epi8(12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1); + return _mm_shuffle_epi8(val, mask); +#endif +} + +template +inline __m128i LoadKey(const word32 rkey[]) +{ + float rk; std::memcpy(&rk, rkey+IDX, sizeof(rk)); + return _mm_castps_si128(_mm_load_ps1(&rk)); +} + +template +inline __m128i UnpackXMM(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(a); CRYPTOPP_UNUSED(b); + CRYPTOPP_UNUSED(c); CRYPTOPP_UNUSED(d); + CRYPTOPP_ASSERT(0); + return _mm_setzero_si128(); +} + +template <> +inline __m128i UnpackXMM<0>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // LEA is little-endian oriented, so there is no need for a separate shuffle. + const __m128i r1 = _mm_unpacklo_epi32(a, b); + const __m128i r2 = _mm_unpacklo_epi32(c, d); + return _mm_unpacklo_epi64(r1, r2); +} + +template <> +inline __m128i UnpackXMM<1>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // LEA is little-endian oriented, so there is no need for a separate shuffle. + const __m128i r1 = _mm_unpacklo_epi32(a, b); + const __m128i r2 = _mm_unpacklo_epi32(c, d); + return _mm_unpackhi_epi64(r1, r2); +} + +template <> +inline __m128i UnpackXMM<2>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // LEA is little-endian oriented, so there is no need for a separate shuffle. + const __m128i r1 = _mm_unpackhi_epi32(a, b); + const __m128i r2 = _mm_unpackhi_epi32(c, d); + return _mm_unpacklo_epi64(r1, r2); +} + +template <> +inline __m128i UnpackXMM<3>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // LEA is little-endian oriented, so there is no need for a separate shuffle. + const __m128i r1 = _mm_unpackhi_epi32(a, b); + const __m128i r2 = _mm_unpackhi_epi32(c, d); + return _mm_unpackhi_epi64(r1, r2); +} + +template +inline __m128i UnpackXMM(const __m128i& v) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(v); CRYPTOPP_ASSERT(0); + return _mm_setzero_si128(); +} + +template <> +inline __m128i UnpackXMM<0>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); +} + +template <> +inline __m128i UnpackXMM<1>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); +} + +template <> +inline __m128i UnpackXMM<2>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(11,10,9,8, 11,10,9,8, 11,10,9,8, 11,10,9,8)); +} + +template <> +inline __m128i UnpackXMM<3>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(15,14,13,12, 15,14,13,12, 15,14,13,12, 15,14,13,12)); +} + +template +inline __m128i RepackXMM(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + return UnpackXMM(a, b, c, d); +} + +template +inline __m128i RepackXMM(const __m128i& v) +{ + return UnpackXMM(v); +} + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// *************************** Power8 ***************************// + +#if (CRYPTOPP_POWER8_AVAILABLE) + +using CryptoPP::uint8x16_p; +using CryptoPP::uint32x4_p; +using CryptoPP::uint64x2_p; + +inline uint32x4_p Xor(const uint32x4_p& a, const uint32x4_p& b) +{ + return VecXor(a, b); +} + +inline uint32x4_p Add(const uint32x4_p& a, const uint32x4_p& b) +{ + return VecAdd(a, b); +} + +inline uint32x4_p Sub(const uint32x4_p& a, const uint32x4_p& b) +{ + return VecSub(a, b); +} + +template +inline uint32x4_p RotateLeft(const uint32x4_p& val) +{ + const uint32x4_p m = {R, R, R, R}; + return vec_rl(val, m); +} + +template +inline uint32x4_p RotateRight(const uint32x4_p& val) +{ + const uint32x4_p m = {32-R, 32-R, 32-R, 32-R}; + return vec_rl(val, m); +} + +template +inline uint32x4_p LoadKey(const word32 rkey[]) +{ + return vec_splats(rkey[IDX]); +} + +template +inline uint32x4_p UnpackSIMD(const uint32x4_p& a, const uint32x4_p& b, const uint32x4_p& c, const uint32x4_p& d) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(a); CRYPTOPP_UNUSED(b); + CRYPTOPP_UNUSED(c); CRYPTOPP_UNUSED(d); + CRYPTOPP_ASSERT(0); + return VecXor(a, a); +} + +template <> +inline uint32x4_p UnpackSIMD<0>(const uint32x4_p& a, const uint32x4_p& b, const uint32x4_p& c, const uint32x4_p& d) +{ + const uint64x2_p r1 = (uint64x2_p)vec_mergel(a, b); + const uint64x2_p r2 = (uint64x2_p)vec_mergel(c, d); + return (uint32x4_p)vec_mergel(r1, r2); +} + +template <> +inline uint32x4_p UnpackSIMD<1>(const uint32x4_p& a, const uint32x4_p& b, const uint32x4_p& c, const uint32x4_p& d) +{ + const uint64x2_p r1 = (uint64x2_p)vec_mergel(a, b); + const uint64x2_p r2 = (uint64x2_p)vec_mergel(c, d); + return (uint32x4_p)vec_mergeh(r1, r2); +} + +template <> +inline uint32x4_p UnpackSIMD<2>(const uint32x4_p& a, const uint32x4_p& b, const uint32x4_p& c, const uint32x4_p& d) +{ + const uint64x2_p r1 = (uint64x2_p)vec_mergeh(a, b); + const uint64x2_p r2 = (uint64x2_p)vec_mergeh(c, d); + return (uint32x4_p)vec_mergel(r1, r2); +} + +template <> +inline uint32x4_p UnpackSIMD<3>(const uint32x4_p& a, const uint32x4_p& b, const uint32x4_p& c, const uint32x4_p& d) +{ + const uint64x2_p r1 = (uint64x2_p)vec_mergeh(a, b); + const uint64x2_p r2 = (uint64x2_p)vec_mergeh(c, d); + return (uint32x4_p)vec_mergeh(r1, r2); +} + +template +inline uint32x4_p UnpackSIMD(const uint32x4_p& v) +{ + // Should not be instantiated + CRYPTOPP_ASSERT(0); + return VecXor(v, v); +} + +template <> +inline uint32x4_p UnpackSIMD<0>(const uint32x4_p& v) +{ + // Splat to all lanes + const uint8x16_p m = {3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0}; + return (uint32x4_p)VecPermute(v, v, m); +} + +template <> +inline uint32x4_p UnpackSIMD<1>(const uint32x4_p& v) +{ + // Splat to all lanes + const uint8x16_p m = {7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4}; + return (uint32x4_p)VecPermute(v, v, m); +} + +template <> +inline uint32x4_p UnpackSIMD<2>(const uint32x4_p& v) +{ + // Splat to all lanes + const uint8x16_p m = {11,10,9,8, 11,10,9,8, 11,10,9,8, 11,10,9,8}; + return (uint32x4_p)VecPermute(v, v, m); +} + +template <> +inline uint32x4_p UnpackSIMD<3>(const uint32x4_p& v) +{ + // Splat to all lanes + const uint8x16_p m = {15,14,13,12, 15,14,13,12, 15,14,13,12, 15,14,13,12}; + return (uint32x4_p)VecPermute(v, v, m); +} + +template +inline uint32x4_p RepackSIMD(const uint32x4_p& a, const uint32x4_p& b, const uint32x4_p& c, const uint32x4_p& d) +{ + return UnpackSIMD(a, b, c, d); +} + +template +inline uint32x4_p RepackSIMD(const uint32x4_p& v) +{ + return UnpackSIMD(v); +} + +#endif // CRYPTOPP_POWER8_AVAILABLE + +// *************************** LEA Encryption ***************************// + +#if (CRYPTOPP_ARM_NEON_AVAILABLE || CRYPTOPP_SSSE3_AVAILABLE) + +template +inline void LEA_Encryption(W temp[4], const word32 *subkeys, unsigned int rounds) +{ + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<4>(subkeys)), Xor(temp[3], LoadKey<5>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<2>(subkeys)), Xor(temp[2], LoadKey<3>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<0>(subkeys)), Xor(temp[1], LoadKey<1>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<10>(subkeys)), Xor(temp[0], LoadKey<11>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<8>(subkeys)), Xor(temp[3], LoadKey<9>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<6>(subkeys)), Xor(temp[2], LoadKey<7>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<16>(subkeys)), Xor(temp[1], LoadKey<17>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<14>(subkeys)), Xor(temp[0], LoadKey<15>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<12>(subkeys)), Xor(temp[3], LoadKey<13>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<22>(subkeys)), Xor(temp[2], LoadKey<23>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<20>(subkeys)), Xor(temp[1], LoadKey<21>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<18>(subkeys)), Xor(temp[0], LoadKey<19>(subkeys)))); + + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<28>(subkeys)), Xor(temp[3], LoadKey<29>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<26>(subkeys)), Xor(temp[2], LoadKey<27>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<24>(subkeys)), Xor(temp[1], LoadKey<25>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<34>(subkeys)), Xor(temp[0], LoadKey<35>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<32>(subkeys)), Xor(temp[3], LoadKey<33>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<30>(subkeys)), Xor(temp[2], LoadKey<31>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<40>(subkeys)), Xor(temp[1], LoadKey<41>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<38>(subkeys)), Xor(temp[0], LoadKey<39>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<36>(subkeys)), Xor(temp[3], LoadKey<37>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<46>(subkeys)), Xor(temp[2], LoadKey<47>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<44>(subkeys)), Xor(temp[1], LoadKey<45>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<42>(subkeys)), Xor(temp[0], LoadKey<43>(subkeys)))); + + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<52>(subkeys)), Xor(temp[3], LoadKey<53>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<50>(subkeys)), Xor(temp[2], LoadKey<51>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<48>(subkeys)), Xor(temp[1], LoadKey<49>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<58>(subkeys)), Xor(temp[0], LoadKey<59>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<56>(subkeys)), Xor(temp[3], LoadKey<57>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<54>(subkeys)), Xor(temp[2], LoadKey<55>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<64>(subkeys)), Xor(temp[1], LoadKey<65>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<62>(subkeys)), Xor(temp[0], LoadKey<63>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<60>(subkeys)), Xor(temp[3], LoadKey<61>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<70>(subkeys)), Xor(temp[2], LoadKey<71>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<68>(subkeys)), Xor(temp[1], LoadKey<69>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<66>(subkeys)), Xor(temp[0], LoadKey<67>(subkeys)))); + + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<76>(subkeys)), Xor(temp[3], LoadKey<77>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<74>(subkeys)), Xor(temp[2], LoadKey<75>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<72>(subkeys)), Xor(temp[1], LoadKey<73>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<82>(subkeys)), Xor(temp[0], LoadKey<83>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<80>(subkeys)), Xor(temp[3], LoadKey<81>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<78>(subkeys)), Xor(temp[2], LoadKey<79>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<88>(subkeys)), Xor(temp[1], LoadKey<89>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<86>(subkeys)), Xor(temp[0], LoadKey<87>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<84>(subkeys)), Xor(temp[3], LoadKey<85>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<94>(subkeys)), Xor(temp[2], LoadKey<95>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<92>(subkeys)), Xor(temp[1], LoadKey<93>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<90>(subkeys)), Xor(temp[0], LoadKey<91>(subkeys)))); + + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<100>(subkeys)), Xor(temp[3], LoadKey<101>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<98>(subkeys)), Xor(temp[2], LoadKey<99>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<96>(subkeys)), Xor(temp[1], LoadKey<97>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<106>(subkeys)), Xor(temp[0], LoadKey<107>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<104>(subkeys)), Xor(temp[3], LoadKey<105>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<102>(subkeys)), Xor(temp[2], LoadKey<103>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<112>(subkeys)), Xor(temp[1], LoadKey<113>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<110>(subkeys)), Xor(temp[0], LoadKey<111>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<108>(subkeys)), Xor(temp[3], LoadKey<109>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<118>(subkeys)), Xor(temp[2], LoadKey<119>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<116>(subkeys)), Xor(temp[1], LoadKey<117>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<114>(subkeys)), Xor(temp[0], LoadKey<115>(subkeys)))); + + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<124>(subkeys)), Xor(temp[3], LoadKey<125>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<122>(subkeys)), Xor(temp[2], LoadKey<123>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<120>(subkeys)), Xor(temp[1], LoadKey<121>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<130>(subkeys)), Xor(temp[0], LoadKey<131>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<128>(subkeys)), Xor(temp[3], LoadKey<129>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<126>(subkeys)), Xor(temp[2], LoadKey<127>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<136>(subkeys)), Xor(temp[1], LoadKey<137>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<134>(subkeys)), Xor(temp[0], LoadKey<135>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<132>(subkeys)), Xor(temp[3], LoadKey<133>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<142>(subkeys)), Xor(temp[2], LoadKey<143>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<140>(subkeys)), Xor(temp[1], LoadKey<141>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<138>(subkeys)), Xor(temp[0], LoadKey<139>(subkeys)))); + + if(rounds > 24) + { + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<148>(subkeys)), Xor(temp[3], LoadKey<149>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<146>(subkeys)), Xor(temp[2], LoadKey<147>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<144>(subkeys)), Xor(temp[1], LoadKey<145>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<154>(subkeys)), Xor(temp[0], LoadKey<155>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<152>(subkeys)), Xor(temp[3], LoadKey<153>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<150>(subkeys)), Xor(temp[2], LoadKey<151>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<160>(subkeys)), Xor(temp[1], LoadKey<161>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<158>(subkeys)), Xor(temp[0], LoadKey<159>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<156>(subkeys)), Xor(temp[3], LoadKey<157>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<166>(subkeys)), Xor(temp[2], LoadKey<167>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<164>(subkeys)), Xor(temp[1], LoadKey<165>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<162>(subkeys)), Xor(temp[0], LoadKey<163>(subkeys)))); + } + + if(rounds > 28) + { + temp[3] = RotateRight<3>(Add(Xor(temp[2], LoadKey<172>(subkeys)), Xor(temp[3], LoadKey<173>(subkeys)))); + temp[2] = RotateRight<5>(Add(Xor(temp[1], LoadKey<170>(subkeys)), Xor(temp[2], LoadKey<171>(subkeys)))); + temp[1] = RotateLeft<9>(Add(Xor(temp[0], LoadKey<168>(subkeys)), Xor(temp[1], LoadKey<169>(subkeys)))); + temp[0] = RotateRight<3>(Add(Xor(temp[3], LoadKey<178>(subkeys)), Xor(temp[0], LoadKey<179>(subkeys)))); + temp[3] = RotateRight<5>(Add(Xor(temp[2], LoadKey<176>(subkeys)), Xor(temp[3], LoadKey<177>(subkeys)))); + temp[2] = RotateLeft<9>(Add(Xor(temp[1], LoadKey<174>(subkeys)), Xor(temp[2], LoadKey<175>(subkeys)))); + temp[1] = RotateRight<3>(Add(Xor(temp[0], LoadKey<184>(subkeys)), Xor(temp[1], LoadKey<185>(subkeys)))); + temp[0] = RotateRight<5>(Add(Xor(temp[3], LoadKey<182>(subkeys)), Xor(temp[0], LoadKey<183>(subkeys)))); + temp[3] = RotateLeft<9>(Add(Xor(temp[2], LoadKey<180>(subkeys)), Xor(temp[3], LoadKey<181>(subkeys)))); + temp[2] = RotateRight<3>(Add(Xor(temp[1], LoadKey<190>(subkeys)), Xor(temp[2], LoadKey<191>(subkeys)))); + temp[1] = RotateRight<5>(Add(Xor(temp[0], LoadKey<188>(subkeys)), Xor(temp[1], LoadKey<189>(subkeys)))); + temp[0] = RotateLeft<9>(Add(Xor(temp[3], LoadKey<186>(subkeys)), Xor(temp[0], LoadKey<187>(subkeys)))); + } +} + +// *************************** LEA Decryption ***************************// + +template +inline void LEA_Decryption(W temp[4], const word32 *subkeys, unsigned int rounds) +{ + if(rounds > 28) + { + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<186>(subkeys))), LoadKey<187>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<188>(subkeys))), LoadKey<189>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<190>(subkeys))), LoadKey<191>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<180>(subkeys))), LoadKey<181>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<182>(subkeys))), LoadKey<183>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<184>(subkeys))), LoadKey<185>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<174>(subkeys))), LoadKey<175>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<176>(subkeys))), LoadKey<177>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<178>(subkeys))), LoadKey<179>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<168>(subkeys))), LoadKey<169>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<170>(subkeys))), LoadKey<171>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<172>(subkeys))), LoadKey<173>(subkeys)); + } + + if(rounds > 24) + { + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<162>(subkeys))), LoadKey<163>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<164>(subkeys))), LoadKey<165>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<166>(subkeys))), LoadKey<167>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<156>(subkeys))), LoadKey<157>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<158>(subkeys))), LoadKey<159>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<160>(subkeys))), LoadKey<161>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<150>(subkeys))), LoadKey<151>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<152>(subkeys))), LoadKey<153>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<154>(subkeys))), LoadKey<155>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<144>(subkeys))), LoadKey<145>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<146>(subkeys))), LoadKey<147>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<148>(subkeys))), LoadKey<149>(subkeys)); + } + + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<138>(subkeys))), LoadKey<139>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<140>(subkeys))), LoadKey<141>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<142>(subkeys))), LoadKey<143>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<132>(subkeys))), LoadKey<133>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<134>(subkeys))), LoadKey<135>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<136>(subkeys))), LoadKey<137>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<126>(subkeys))), LoadKey<127>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<128>(subkeys))), LoadKey<129>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<130>(subkeys))), LoadKey<131>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<120>(subkeys))), LoadKey<121>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<122>(subkeys))), LoadKey<123>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<124>(subkeys))), LoadKey<125>(subkeys)); + + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<114>(subkeys))), LoadKey<115>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<116>(subkeys))), LoadKey<117>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<118>(subkeys))), LoadKey<119>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<108>(subkeys))), LoadKey<109>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<110>(subkeys))), LoadKey<111>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<112>(subkeys))), LoadKey<113>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<102>(subkeys))), LoadKey<103>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<104>(subkeys))), LoadKey<105>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<106>(subkeys))), LoadKey<107>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<96>(subkeys))), LoadKey<97>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<98>(subkeys))), LoadKey<99>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<100>(subkeys))), LoadKey<101>(subkeys)); + + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<90>(subkeys))), LoadKey<91>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<92>(subkeys))), LoadKey<93>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<94>(subkeys))), LoadKey<95>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<84>(subkeys))), LoadKey<85>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<86>(subkeys))), LoadKey<87>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<88>(subkeys))), LoadKey<89>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<78>(subkeys))), LoadKey<79>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<80>(subkeys))), LoadKey<81>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<82>(subkeys))), LoadKey<83>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<72>(subkeys))), LoadKey<73>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<74>(subkeys))), LoadKey<75>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<76>(subkeys))), LoadKey<77>(subkeys)); + + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<66>(subkeys))), LoadKey<67>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<68>(subkeys))), LoadKey<69>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<70>(subkeys))), LoadKey<71>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<60>(subkeys))), LoadKey<61>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<62>(subkeys))), LoadKey<63>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<64>(subkeys))), LoadKey<65>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<54>(subkeys))), LoadKey<55>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<56>(subkeys))), LoadKey<57>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<58>(subkeys))), LoadKey<59>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<48>(subkeys))), LoadKey<49>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<50>(subkeys))), LoadKey<51>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<52>(subkeys))), LoadKey<53>(subkeys)); + + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<42>(subkeys))), LoadKey<43>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<44>(subkeys))), LoadKey<45>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<46>(subkeys))), LoadKey<47>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<36>(subkeys))), LoadKey<37>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<38>(subkeys))), LoadKey<39>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<40>(subkeys))), LoadKey<41>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<30>(subkeys))), LoadKey<31>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<32>(subkeys))), LoadKey<33>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<34>(subkeys))), LoadKey<35>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<24>(subkeys))), LoadKey<25>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<26>(subkeys))), LoadKey<27>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<28>(subkeys))), LoadKey<29>(subkeys)); + + temp[0] = Xor(Sub(RotateRight<9>(temp[0]), Xor(temp[3], LoadKey<18>(subkeys))), LoadKey<19>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<5>(temp[1]), Xor(temp[0], LoadKey<20>(subkeys))), LoadKey<21>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<3>(temp[2]), Xor(temp[1], LoadKey<22>(subkeys))), LoadKey<23>(subkeys)); + temp[3] = Xor(Sub(RotateRight<9>(temp[3]), Xor(temp[2], LoadKey<12>(subkeys))), LoadKey<13>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<5>(temp[0]), Xor(temp[3], LoadKey<14>(subkeys))), LoadKey<15>(subkeys)); + temp[1] = Xor(Sub(RotateLeft<3>(temp[1]), Xor(temp[0], LoadKey<16>(subkeys))), LoadKey<17>(subkeys)); + temp[2] = Xor(Sub(RotateRight<9>(temp[2]), Xor(temp[1], LoadKey<6>(subkeys))), LoadKey<7>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<5>(temp[3]), Xor(temp[2], LoadKey<8>(subkeys))), LoadKey<9>(subkeys)); + temp[0] = Xor(Sub(RotateLeft<3>(temp[0]), Xor(temp[3], LoadKey<10>(subkeys))), LoadKey<11>(subkeys)); + temp[1] = Xor(Sub(RotateRight<9>(temp[1]), Xor(temp[0], LoadKey<0>(subkeys))), LoadKey<1>(subkeys)); + temp[2] = Xor(Sub(RotateLeft<5>(temp[2]), Xor(temp[1], LoadKey<2>(subkeys))), LoadKey<3>(subkeys)); + temp[3] = Xor(Sub(RotateLeft<3>(temp[3]), Xor(temp[2], LoadKey<4>(subkeys))), LoadKey<5>(subkeys)); +} + +#endif // LEA Encryption and Decryption + +// *************************** ARM NEON ***************************// + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +inline void LEA_Enc_Block(uint32x4_t &block0, + const word32 *subkeys, unsigned int rounds) +{ + uint32x4_t temp[4]; + temp[0] = UnpackNEON<0>(block0); + temp[1] = UnpackNEON<1>(block0); + temp[2] = UnpackNEON<2>(block0); + temp[3] = UnpackNEON<3>(block0); + + LEA_Encryption(temp, subkeys, rounds); + + block0 = RepackNEON<0>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Dec_Block(uint32x4_t &block0, + const word32 *subkeys, unsigned int rounds) +{ + uint32x4_t temp[4]; + temp[0] = UnpackNEON<0>(block0); + temp[1] = UnpackNEON<1>(block0); + temp[2] = UnpackNEON<2>(block0); + temp[3] = UnpackNEON<3>(block0); + + LEA_Decryption(temp, subkeys, rounds); + + block0 = RepackNEON<0>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Enc_4_Blocks(uint32x4_t &block0, uint32x4_t &block1, + uint32x4_t &block2, uint32x4_t &block3, const word32 *subkeys, unsigned int rounds) +{ + uint32x4_t temp[4]; + temp[0] = UnpackNEON<0>(block0, block1, block2, block3); + temp[1] = UnpackNEON<1>(block0, block1, block2, block3); + temp[2] = UnpackNEON<2>(block0, block1, block2, block3); + temp[3] = UnpackNEON<3>(block0, block1, block2, block3); + + LEA_Encryption(temp, subkeys, rounds); + + block0 = RepackNEON<0>(temp[0], temp[1], temp[2], temp[3]); + block1 = RepackNEON<1>(temp[0], temp[1], temp[2], temp[3]); + block2 = RepackNEON<2>(temp[0], temp[1], temp[2], temp[3]); + block3 = RepackNEON<3>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Dec_4_Blocks(uint32x4_t &block0, uint32x4_t &block1, + uint32x4_t &block2, uint32x4_t &block3, const word32 *subkeys, unsigned int rounds) +{ + uint32x4_t temp[4]; + temp[0] = UnpackNEON<0>(block0, block1, block2, block3); + temp[1] = UnpackNEON<1>(block0, block1, block2, block3); + temp[2] = UnpackNEON<2>(block0, block1, block2, block3); + temp[3] = UnpackNEON<3>(block0, block1, block2, block3); + + LEA_Decryption(temp, subkeys, rounds); + + block0 = RepackNEON<0>(temp[0], temp[1], temp[2], temp[3]); + block1 = RepackNEON<1>(temp[0], temp[1], temp[2], temp[3]); + block2 = RepackNEON<2>(temp[0], temp[1], temp[2], temp[3]); + block3 = RepackNEON<3>(temp[0], temp[1], temp[2], temp[3]); +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// *************************** IA-32 ***************************// + +#if (CRYPTOPP_SSSE3_AVAILABLE) + +inline void LEA_Enc_Block(__m128i &block0, + const word32 *subkeys, unsigned int rounds) +{ + __m128i temp[4]; + temp[0] = UnpackXMM<0>(block0); + temp[1] = UnpackXMM<1>(block0); + temp[2] = UnpackXMM<2>(block0); + temp[3] = UnpackXMM<3>(block0); + + LEA_Encryption(temp, subkeys, rounds); + + block0 = RepackXMM<0>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Dec_Block(__m128i &block0, + const word32 *subkeys, unsigned int rounds) +{ + __m128i temp[4]; + temp[0] = UnpackXMM<0>(block0); + temp[1] = UnpackXMM<1>(block0); + temp[2] = UnpackXMM<2>(block0); + temp[3] = UnpackXMM<3>(block0); + + LEA_Decryption(temp, subkeys, rounds); + + block0 = RepackXMM<0>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Enc_4_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys, unsigned int rounds) +{ + __m128i temp[4]; + temp[0] = UnpackXMM<0>(block0, block1, block2, block3); + temp[1] = UnpackXMM<1>(block0, block1, block2, block3); + temp[2] = UnpackXMM<2>(block0, block1, block2, block3); + temp[3] = UnpackXMM<3>(block0, block1, block2, block3); + + LEA_Encryption(temp, subkeys, rounds); + + block0 = RepackXMM<0>(temp[0], temp[1], temp[2], temp[3]); + block1 = RepackXMM<1>(temp[0], temp[1], temp[2], temp[3]); + block2 = RepackXMM<2>(temp[0], temp[1], temp[2], temp[3]); + block3 = RepackXMM<3>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Dec_4_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys, unsigned int rounds) +{ + __m128i temp[4]; + temp[0] = UnpackXMM<0>(block0, block1, block2, block3); + temp[1] = UnpackXMM<1>(block0, block1, block2, block3); + temp[2] = UnpackXMM<2>(block0, block1, block2, block3); + temp[3] = UnpackXMM<3>(block0, block1, block2, block3); + + LEA_Decryption(temp, subkeys, rounds); + + block0 = RepackXMM<0>(temp[0], temp[1], temp[2], temp[3]); + block1 = RepackXMM<1>(temp[0], temp[1], temp[2], temp[3]); + block2 = RepackXMM<2>(temp[0], temp[1], temp[2], temp[3]); + block3 = RepackXMM<3>(temp[0], temp[1], temp[2], temp[3]); +} + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// *************************** Power8 ***************************// + +#if (CRYPTOPP_POWER8_AVAILABLE) + +inline void LEA_Enc_Block(uint32x4_p &block0, + const word32 *subkeys, unsigned int rounds) +{ + uint32x4_p temp[4]; + temp[0] = UnpackSIMD<0>(block0); + temp[1] = UnpackSIMD<1>(block0); + temp[2] = UnpackSIMD<2>(block0); + temp[3] = UnpackSIMD<3>(block0); + + LEA_Encryption(temp, subkeys, rounds); + + block0 = RepackSIMD<0>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Dec_Block(uint32x4_p &block0, + const word32 *subkeys, unsigned int rounds) +{ + uint32x4_p temp[4]; + temp[0] = UnpackSIMD<0>(block0); + temp[1] = UnpackSIMD<1>(block0); + temp[2] = UnpackSIMD<2>(block0); + temp[3] = UnpackSIMD<3>(block0); + + LEA_Decryption(temp, subkeys, rounds); + + block0 = RepackSIMD<0>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Enc_4_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, const word32 *subkeys, unsigned int rounds) +{ + uint32x4_p temp[4]; + temp[0] = UnpackSIMD<0>(block0, block1, block2, block3); + temp[1] = UnpackSIMD<1>(block0, block1, block2, block3); + temp[2] = UnpackSIMD<2>(block0, block1, block2, block3); + temp[3] = UnpackSIMD<3>(block0, block1, block2, block3); + + LEA_Encryption(temp, subkeys, rounds); + + block0 = RepackSIMD<0>(temp[0], temp[1], temp[2], temp[3]); + block1 = RepackSIMD<1>(temp[0], temp[1], temp[2], temp[3]); + block2 = RepackSIMD<2>(temp[0], temp[1], temp[2], temp[3]); + block3 = RepackSIMD<3>(temp[0], temp[1], temp[2], temp[3]); +} + +inline void LEA_Dec_4_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, const word32 *subkeys, unsigned int rounds) +{ + uint32x4_p temp[4]; + temp[0] = UnpackSIMD<0>(block0, block1, block2, block3); + temp[1] = UnpackSIMD<1>(block0, block1, block2, block3); + temp[2] = UnpackSIMD<2>(block0, block1, block2, block3); + temp[3] = UnpackSIMD<3>(block0, block1, block2, block3); + + LEA_Decryption(temp, subkeys, rounds); + + block0 = RepackSIMD<0>(temp[0], temp[1], temp[2], temp[3]); + block1 = RepackSIMD<1>(temp[0], temp[1], temp[2], temp[3]); + block2 = RepackSIMD<2>(temp[0], temp[1], temp[2], temp[3]); + block3 = RepackSIMD<3>(temp[0], temp[1], temp[2], temp[3]); +} + +#endif // CRYPTOPP_POWER8_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +// *************************** SIMD Templates ***************************// + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) +size_t LEA_Enc_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_SSE(LEA_Enc_Block, LEA_Enc_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t LEA_Dec_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_SSE(LEA_Dec_Block, LEA_Dec_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SSSE3_AVAILABLE + +#if defined(CRYPTOPP_ARM_NEON_AVAILABLE) +size_t LEA_Enc_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_NEON(LEA_Enc_Block, LEA_Enc_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t LEA_Dec_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_NEON(LEA_Dec_Block, LEA_Dec_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +#if defined(CRYPTOPP_POWER8_AVAILABLE) +size_t LEA_Enc_AdvancedProcessBlocks_POWER8(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_ALTIVEC(LEA_Enc_Block, LEA_Enc_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t LEA_Dec_AdvancedProcessBlocks_POWER8(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_ALTIVEC(LEA_Dec_Block, LEA_Dec_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_POWER8_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/lsh.h b/external/ours/library/crypto/src/shared/original/lsh.h new file mode 100755 index 000000000..2f9918d82 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh.h @@ -0,0 +1,262 @@ +// lsh.h - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + +/// \file lsh.h +/// \brief Classes for the LSH hash functions +/// \since Crypto++ 8.6 +/// \sa LSH +/// on the Korea Internet & Security Agency (KISA) website. +#ifndef CRYPTOPP_LSH_H +#define CRYPTOPP_LSH_H + +#include "cryptlib.h" +#include "secblock.h" + +// Enable SSE2 and AVX2 for 64-bit machines. +// 32-bit machines slow down with SSE2. +#if (CRYPTOPP_BOOL_X32) || (CRYPTOPP_BOOL_X64) +# define CRYPTOPP_ENABLE_64BIT_SSE 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief LSH-224 and LSH-256 hash base class +/// \details LSH256_Base is the base class for both LSH-224 and LSH-256 +/// \since Crypto++ 8.6 +class LSH256_Base : public HashTransformation +{ +public: + /// \brief Block size, in bytes + /// \details LSH_256 uses LSH256_MSG_BLK_BYTE_LEN for block size, which is 128 + CRYPTOPP_CONSTANT(BLOCKSIZE = 128); + + virtual ~LSH256_Base() {} + + unsigned int BlockSize() const { return BLOCKSIZE; } + unsigned int DigestSize() const { return m_digestSize; } + unsigned int OptimalDataAlignment() const { return GetAlignmentOf(); } + + void Restart(); + void Update(const byte *input, size_t size); + void TruncatedFinal(byte *hash, size_t size); + + std::string AlgorithmProvider() const; + +protected: + LSH256_Base(unsigned int algType, unsigned int digestSize) + : m_digestSize(digestSize) { m_state[80] = algType; } + +protected: + // Working state is: + // * cv_l = 8 32-bit words + // * cv_r = 8 32-bit words + // * submsg_e_l = 8 32-bit words + // * submsg_e_r = 8 32-bit words + // * submsg_o_l = 8 32-bit words + // * submsg_o_r = 8 32-bit words + // * last_block = 32 32-bit words (128 bytes) + // * algType + // * remainingBitLength + FixedSizeSecBlock m_state; + // word32 m_algType, m_remainingBitLength; + word32 m_digestSize; +}; + +/// \brief LSH-224 hash function +/// \sa LSH +/// on the Korea Internet & Security Agency (KISA) website. +/// \since Crypto++ 8.6 +class LSH224 : public LSH256_Base +{ +public: + /// \brief Digest size, in bytes + /// \details LSH_256 uses LSH_GET_HASHBYTE(algType) for digest size, which is 28 + CRYPTOPP_CONSTANT(DIGESTSIZE = 28); + /// \brief Block size, in bytes + /// \details LSH_256 uses LSH256_MSG_BLK_BYTE_LEN for block size, which is 128 + CRYPTOPP_CONSTANT(BLOCKSIZE = LSH256_Base::BLOCKSIZE); + + /// \brief The algorithm's name + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like AES or AES/GCM. + /// Some algorithms do not have standard names yet. For example, there is no standard + /// algorithm name for Shoup's ECIES. + /// \note StaticAlgorithmName is not universally implemented yet. + static std::string StaticAlgorithmName() { return "LSH-224"; } + + /// \brief Construct a LSH-224 + /// \details LSH_TYPE_224 is the magic value 0x000001C defined in lsh.cpp. + LSH224() : LSH256_Base(0x000001C, DIGESTSIZE) { Restart(); } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } +}; + +/// \brief LSH-256 hash function +/// \sa LSH +/// on the Korea Internet & Security Agency (KISA) website. +/// \since Crypto++ 8.6 +class LSH256 : public LSH256_Base +{ +public: + /// \brief Digest size, in bytes + /// \details LSH_256 uses LSH_GET_HASHBYTE(algType) for digest size, which is 32 + CRYPTOPP_CONSTANT(DIGESTSIZE = 32); + /// \brief Block size, in bytes + /// \details LSH_256 uses LSH256_MSG_BLK_BYTE_LEN for block size, which is 128 + CRYPTOPP_CONSTANT(BLOCKSIZE = LSH256_Base::BLOCKSIZE); + + /// \brief The algorithm's name + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like AES or AES/GCM. + /// Some algorithms do not have standard names yet. For example, there is no standard + /// algorithm name for Shoup's ECIES. + /// \note StaticAlgorithmName is not universally implemented yet. + static std::string StaticAlgorithmName() { return "LSH-256"; } + + /// \brief Construct a LSH-256 + /// \details LSH_TYPE_256 is the magic value 0x0000020 defined in lsh.cpp. + LSH256() : LSH256_Base(0x0000020, DIGESTSIZE) { Restart(); } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } +}; + +/// \brief LSH-384 and LSH-512 hash base class +/// \details LSH512_Base is the base class for both LSH-384 and LSH-512 +/// \since Crypto++ 8.6 +class LSH512_Base : public HashTransformation +{ +public: + /// \brief Block size, in bytes + /// \details LSH_512 uses LSH512_MSG_BLK_BYTE_LEN for block size, which is 256 + CRYPTOPP_CONSTANT(BLOCKSIZE = 256); + + virtual ~LSH512_Base() {} + + unsigned int BlockSize() const { return BLOCKSIZE; } + unsigned int DigestSize() const { return m_digestSize; } + unsigned int OptimalDataAlignment() const { return GetAlignmentOf(); } + + void Restart(); + void Update(const byte *input, size_t size); + void TruncatedFinal(byte *hash, size_t size); + + std::string AlgorithmProvider() const; + +protected: + LSH512_Base(unsigned int algType, unsigned int digestSize) + : m_digestSize(digestSize) { m_state[80] = algType; } + +protected: + // Working state is: + // * cv_l = 8 64-bit words + // * cv_r = 8 64-bit words + // * submsg_e_l = 8 64-bit words + // * submsg_e_r = 8 64-bit words + // * submsg_o_l = 8 64-bit words + // * submsg_o_r = 8 64-bit words + // * last_block = 32 64-bit words (256 bytes) + // * algType + // * remainingBitLength + FixedSizeSecBlock m_state; + // word32 m_algType, m_remainingBitLength; + word32 m_digestSize; +}; + +/// \brief LSH-384 hash function +/// \sa LSH +/// on the Korea Internet & Security Agency (KISA) website. +/// \since Crypto++ 8.6 +class LSH384 : public LSH512_Base +{ +public: + /// \brief Digest size, in bytes + /// \details LSH_512 uses LSH_GET_HASHBYTE(algType) for digest size, which is 48 + CRYPTOPP_CONSTANT(DIGESTSIZE = 48); + /// \brief Block size, in bytes + /// \details LSH_512 uses LSH512_MSG_BLK_BYTE_LEN for block size, which is 256 + CRYPTOPP_CONSTANT(BLOCKSIZE = LSH512_Base::BLOCKSIZE); + + /// \brief The algorithm's name + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like AES or AES/GCM. + /// Some algorithms do not have standard names yet. For example, there is no standard + /// algorithm name for Shoup's ECIES. + /// \note StaticAlgorithmName is not universally implemented yet. + static std::string StaticAlgorithmName() { return "LSH-384"; } + + /// \brief Construct a LSH-384 + /// \details LSH_TYPE_384 is the magic value 0x0010030 defined in lsh.cpp. + LSH384() : LSH512_Base(0x0010030, DIGESTSIZE) { Restart(); } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } +}; + +/// \brief LSH-512 hash function +/// \sa LSH +/// on the Korea Internet & Security Agency (KISA) website. +/// \since Crypto++ 8.6 +class LSH512 : public LSH512_Base +{ +public: + /// \brief Digest size, in bytes + /// \details LSH_512 uses LSH_GET_HASHBYTE(algType) for digest size, which is 64 + CRYPTOPP_CONSTANT(DIGESTSIZE = 64); + /// \brief Block size, in bytes + /// \details LSH_512 uses LSH512_MSG_BLK_BYTE_LEN for block size, which is 256 + CRYPTOPP_CONSTANT(BLOCKSIZE = LSH512_Base::BLOCKSIZE); + + /// \brief The algorithm's name + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like AES or AES/GCM. + /// Some algorithms do not have standard names yet. For example, there is no standard + /// algorithm name for Shoup's ECIES. + /// \note StaticAlgorithmName is not universally implemented yet. + static std::string StaticAlgorithmName() { return "LSH-512"; } + + /// \brief Construct a LSH-512 + /// \details LSH_TYPE_512 is the magic value 0x0010040 defined in lsh.cpp. + LSH512() : LSH512_Base(0x0010040, DIGESTSIZE) { Restart(); } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } +}; + +/// \brief LSH-512-256 hash function +/// \sa LSH +/// on the Korea Internet & Security Agency (KISA) website. +/// \since Crypto++ 8.6 +class LSH512_256 : public LSH512_Base +{ +public: + /// \brief Digest size, in bytes + /// \details LSH_512 uses LSH_GET_HASHBYTE(algType) for digest size, which is 32 + CRYPTOPP_CONSTANT(DIGESTSIZE = 32); + /// \brief Block size, in bytes + /// \details LSH_512 uses LSH512_MSG_BLK_BYTE_LEN for block size, which is 256 + CRYPTOPP_CONSTANT(BLOCKSIZE = LSH512_Base::BLOCKSIZE); + + /// \brief The algorithm's name + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like AES or AES/GCM. + /// Some algorithms do not have standard names yet. For example, there is no standard + /// algorithm name for Shoup's ECIES. + /// \note StaticAlgorithmName is not universally implemented yet. + static std::string StaticAlgorithmName() { return "LSH-512-256"; } + + /// \brief Construct a LSH-512-256 + /// \details LSH_TYPE_512_256 is the magic value 0x0010020 defined in lsh.cpp. + LSH512_256() : LSH512_Base(0x0010020, DIGESTSIZE) { Restart(); } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } +}; + +NAMESPACE_END + +#endif // CRYPTOPP_LSH_H diff --git a/external/ours/library/crypto/src/shared/original/lsh256.cpp b/external/ours/library/crypto/src/shared/original/lsh256.cpp new file mode 100755 index 000000000..0f895bb40 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh256.cpp @@ -0,0 +1,817 @@ +// lsh.cpp - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + +#include "pch.h" +#include "config.h" + +#include "lsh.h" +#include "cpu.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +/* LSH Constants */ + +const unsigned int LSH256_MSG_BLK_BYTE_LEN = 128; +// const unsigned int LSH256_MSG_BLK_BIT_LEN = 1024; +// const unsigned int LSH256_CV_BYTE_LEN = 64; +const unsigned int LSH256_HASH_VAL_MAX_BYTE_LEN = 32; + +// const unsigned int MSG_BLK_WORD_LEN = 32; +const unsigned int CV_WORD_LEN = 16; +const unsigned int CONST_WORD_LEN = 8; +const unsigned int HASH_VAL_MAX_WORD_LEN = 8; +// const unsigned int WORD_BIT_LEN = 32; +const unsigned int NUM_STEPS = 26; + +const unsigned int ROT_EVEN_ALPHA = 29; +const unsigned int ROT_EVEN_BETA = 1; +const unsigned int ROT_ODD_ALPHA = 5; +const unsigned int ROT_ODD_BETA = 17; + +const unsigned int LSH_TYPE_256_256 = 0x0000020; +const unsigned int LSH_TYPE_256_224 = 0x000001C; + +// const unsigned int LSH_TYPE_224 = LSH_TYPE_256_224; +// const unsigned int LSH_TYPE_256 = LSH_TYPE_256_256; + +/* Error Code */ + +const unsigned int LSH_SUCCESS = 0x0; +// const unsigned int LSH_ERR_NULL_PTR = 0x2401; +// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402; +const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403; +const unsigned int LSH_ERR_INVALID_STATE = 0x2404; + +/* Index into our state array */ + +const unsigned int AlgorithmType = 80; +const unsigned int RemainingBits = 81; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(LSH) + +/* -------------------------------------------------------- * +* LSH: iv +* -------------------------------------------------------- */ + +//extern const word32 LSH256_IV224[CV_WORD_LEN]; +//extern const word32 LSH256_IV256[CV_WORD_LEN]; +//extern const word32 LSH256_StepConstants[CONST_WORD_LEN * NUM_STEPS]; + +CRYPTOPP_ALIGN_DATA(32) +extern +const word32 LSH256_IV224[CV_WORD_LEN] = { + 0x068608D3, 0x62D8F7A7, 0xD76652AB, 0x4C600A43, 0xBDC40AA8, 0x1ECA0B68, 0xDA1A89BE, 0x3147D354, + 0x707EB4F9, 0xF65B3862, 0x6B0B2ABE, 0x56B8EC0A, 0xCF237286, 0xEE0D1727, 0x33636595, 0x8BB8D05F +}; + +CRYPTOPP_ALIGN_DATA(32) +extern +const word32 LSH256_IV256[CV_WORD_LEN] = { + 0x46a10f1f, 0xfddce486, 0xb41443a8, 0x198e6b9d, 0x3304388d, 0xb0f5a3c7, 0xb36061c4, 0x7adbd553, + 0x105d5378, 0x2f74de54, 0x5c2f2d95, 0xf2553fbe, 0x8051357a, 0x138668c8, 0x47aa4484, 0xe01afb41 +}; + +/* -------------------------------------------------------- * +* LSH: step constants +* -------------------------------------------------------- */ + +extern +const word32 LSH256_StepConstants[CONST_WORD_LEN * NUM_STEPS] = { + 0x917caf90, 0x6c1b10a2, 0x6f352943, 0xcf778243, 0x2ceb7472, 0x29e96ff2, 0x8a9ba428, 0x2eeb2642, + 0x0e2c4021, 0x872bb30e, 0xa45e6cb2, 0x46f9c612, 0x185fe69e, 0x1359621b, 0x263fccb2, 0x1a116870, + 0x3a6c612f, 0xb2dec195, 0x02cb1f56, 0x40bfd858, 0x784684b6, 0x6cbb7d2e, 0x660c7ed8, 0x2b79d88a, + 0xa6cd9069, 0x91a05747, 0xcdea7558, 0x00983098, 0xbecb3b2e, 0x2838ab9a, 0x728b573e, 0xa55262b5, + 0x745dfa0f, 0x31f79ed8, 0xb85fce25, 0x98c8c898, 0x8a0669ec, 0x60e445c2, 0xfde295b0, 0xf7b5185a, + 0xd2580983, 0x29967709, 0x182df3dd, 0x61916130, 0x90705676, 0x452a0822, 0xe07846ad, 0xaccd7351, + 0x2a618d55, 0xc00d8032, 0x4621d0f5, 0xf2f29191, 0x00c6cd06, 0x6f322a67, 0x58bef48d, 0x7a40c4fd, + 0x8beee27f, 0xcd8db2f2, 0x67f2c63b, 0xe5842383, 0xc793d306, 0xa15c91d6, 0x17b381e5, 0xbb05c277, + 0x7ad1620a, 0x5b40a5bf, 0x5ab901a2, 0x69a7a768, 0x5b66d9cd, 0xfdee6877, 0xcb3566fc, 0xc0c83a32, + 0x4c336c84, 0x9be6651a, 0x13baa3fc, 0x114f0fd1, 0xc240a728, 0xec56e074, 0x009c63c7, 0x89026cf2, + 0x7f9ff0d0, 0x824b7fb5, 0xce5ea00f, 0x605ee0e2, 0x02e7cfea, 0x43375560, 0x9d002ac7, 0x8b6f5f7b, + 0x1f90c14f, 0xcdcb3537, 0x2cfeafdd, 0xbf3fc342, 0xeab7b9ec, 0x7a8cb5a3, 0x9d2af264, 0xfacedb06, + 0xb052106e, 0x99006d04, 0x2bae8d09, 0xff030601, 0xa271a6d6, 0x0742591d, 0xc81d5701, 0xc9a9e200, + 0x02627f1e, 0x996d719d, 0xda3b9634, 0x02090800, 0x14187d78, 0x499b7624, 0xe57458c9, 0x738be2c9, + 0x64e19d20, 0x06df0f36, 0x15d1cb0e, 0x0b110802, 0x2c95f58c, 0xe5119a6d, 0x59cd22ae, 0xff6eac3c, + 0x467ebd84, 0xe5ee453c, 0xe79cd923, 0x1c190a0d, 0xc28b81b8, 0xf6ac0852, 0x26efd107, 0x6e1ae93b, + 0xc53c41ca, 0xd4338221, 0x8475fd0a, 0x35231729, 0x4e0d3a7a, 0xa2b45b48, 0x16c0d82d, 0x890424a9, + 0x017e0c8f, 0x07b5a3f5, 0xfa73078e, 0x583a405e, 0x5b47b4c8, 0x570fa3ea, 0xd7990543, 0x8d28ce32, + 0x7f8a9b90, 0xbd5998fc, 0x6d7a9688, 0x927a9eb6, 0xa2fc7d23, 0x66b38e41, 0x709e491a, 0xb5f700bf, + 0x0a262c0f, 0x16f295b9, 0xe8111ef5, 0x0d195548, 0x9f79a0c5, 0x1a41cfa7, 0x0ee7638a, 0xacf7c074, + 0x30523b19, 0x09884ecf, 0xf93014dd, 0x266e9d55, 0x191a6664, 0x5c1176c1, 0xf64aed98, 0xa4b83520, + 0x828d5449, 0x91d71dd8, 0x2944f2d6, 0x950bf27b, 0x3380ca7d, 0x6d88381d, 0x4138868e, 0x5ced55c4, + 0x0fe19dcb, 0x68f4f669, 0x6e37c8ff, 0xa0fe6e10, 0xb44b47b0, 0xf5c0558a, 0x79bf14cf, 0x4a431a20, + 0xf17f68da, 0x5deb5fd1, 0xa600c86d, 0x9f6c7eb0, 0xff92f864, 0xb615e07f, 0x38d3e448, 0x8d5d3a6a, + 0x70e843cb, 0x494b312e, 0xa6c93613, 0x0beb2f4f, 0x928b5d63, 0xcbf66035, 0x0cb82c80, 0xea97a4f7, + 0x592c0f3b, 0x947c5f77, 0x6fff49b9, 0xf71a7e5a, 0x1de8c0f5, 0xc2569600, 0xc4e4ac8c, 0x823c9ce1 +}; + +NAMESPACE_END // LSH +NAMESPACE_END // Crypto++ + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::rotlFixed; +using CryptoPP::rotlConstant; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; +using CryptoPP::ConditionalByteReverse; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +using CryptoPP::LSH::LSH256_IV224; +using CryptoPP::LSH::LSH256_IV256; +using CryptoPP::LSH::LSH256_StepConstants; + +typedef byte lsh_u8; +typedef word32 lsh_u32; +typedef word32 lsh_uint; +typedef word32 lsh_err; +typedef word32 lsh_type; + +struct LSH256_Context +{ + LSH256_Context(word32* state, word32 algType, word32& remainingBitLength) : + cv_l(state+0), cv_r(state+8), sub_msgs(state+16), + last_block(reinterpret_cast(state+48)), + remain_databitlen(remainingBitLength), + alg_type(static_cast(algType)) {} + + lsh_u32* cv_l; // start of our state block + lsh_u32* cv_r; + lsh_u32* sub_msgs; + lsh_u8* last_block; + lsh_u32& remain_databitlen; + lsh_type alg_type; +}; + +struct LSH256_Internal +{ + LSH256_Internal(word32* state) : + submsg_e_l(state+16), submsg_e_r(state+24), + submsg_o_l(state+32), submsg_o_r(state+40) { } + + lsh_u32* submsg_e_l; /* even left sub-message */ + lsh_u32* submsg_e_r; /* even right sub-message */ + lsh_u32* submsg_o_l; /* odd left sub-message */ + lsh_u32* submsg_o_r; /* odd right sub-message */ +}; + +const word32 g_gamma256[8] = { 0, 8, 16, 24, 24, 16, 8, 0 }; + +/* LSH AlgType Macro */ + +inline bool LSH_IS_LSH512(lsh_uint val) { + return (val & 0xf0000) == 0; +} + +inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) { + return val >> 24; +} + +inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) { + return val & 0xffff; +} + +inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) { + return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val); +} + +inline lsh_u32 loadLE32(lsh_u32 v) { + return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v); +} + +lsh_u32 ROTL(lsh_u32 x, lsh_u32 r) { + return rotlFixed(x, r); +} + +// Original code relied upon unaligned lsh_u32 buffer +inline void load_msg_blk(LSH256_Internal* i_state, const lsh_u8 msgblk[LSH256_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + typedef GetBlock InBlock; + + InBlock input(msgblk); + input(submsg_e_l[0])(submsg_e_l[1])(submsg_e_l[2])(submsg_e_l[3]) + (submsg_e_l[4])(submsg_e_l[5])(submsg_e_l[6])(submsg_e_l[7]) + (submsg_e_r[0])(submsg_e_r[1])(submsg_e_r[2])(submsg_e_r[3]) + (submsg_e_r[4])(submsg_e_r[5])(submsg_e_r[6])(submsg_e_r[7]) + (submsg_o_l[0])(submsg_o_l[1])(submsg_o_l[2])(submsg_o_l[3]) + (submsg_o_l[4])(submsg_o_l[5])(submsg_o_l[6])(submsg_o_l[7]) + (submsg_o_r[0])(submsg_o_r[1])(submsg_o_r[2])(submsg_o_r[3]) + (submsg_o_r[4])(submsg_o_r[5])(submsg_o_r[6])(submsg_o_r[7]); +} + +inline void msg_exp_even(LSH256_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + lsh_u32 temp; + temp = submsg_e_l[0]; + submsg_e_l[0] = submsg_o_l[0] + submsg_e_l[3]; + submsg_e_l[3] = submsg_o_l[3] + submsg_e_l[1]; + submsg_e_l[1] = submsg_o_l[1] + submsg_e_l[2]; + submsg_e_l[2] = submsg_o_l[2] + temp; + temp = submsg_e_l[4]; + submsg_e_l[4] = submsg_o_l[4] + submsg_e_l[7]; + submsg_e_l[7] = submsg_o_l[7] + submsg_e_l[6]; + submsg_e_l[6] = submsg_o_l[6] + submsg_e_l[5]; + submsg_e_l[5] = submsg_o_l[5] + temp; + temp = submsg_e_r[0]; + submsg_e_r[0] = submsg_o_r[0] + submsg_e_r[3]; + submsg_e_r[3] = submsg_o_r[3] + submsg_e_r[1]; + submsg_e_r[1] = submsg_o_r[1] + submsg_e_r[2]; + submsg_e_r[2] = submsg_o_r[2] + temp; + temp = submsg_e_r[4]; + submsg_e_r[4] = submsg_o_r[4] + submsg_e_r[7]; + submsg_e_r[7] = submsg_o_r[7] + submsg_e_r[6]; + submsg_e_r[6] = submsg_o_r[6] + submsg_e_r[5]; + submsg_e_r[5] = submsg_o_r[5] + temp; +} + +inline void msg_exp_odd(LSH256_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + lsh_u32 temp; + temp = submsg_o_l[0]; + submsg_o_l[0] = submsg_e_l[0] + submsg_o_l[3]; + submsg_o_l[3] = submsg_e_l[3] + submsg_o_l[1]; + submsg_o_l[1] = submsg_e_l[1] + submsg_o_l[2]; + submsg_o_l[2] = submsg_e_l[2] + temp; + temp = submsg_o_l[4]; + submsg_o_l[4] = submsg_e_l[4] + submsg_o_l[7]; + submsg_o_l[7] = submsg_e_l[7] + submsg_o_l[6]; + submsg_o_l[6] = submsg_e_l[6] + submsg_o_l[5]; + submsg_o_l[5] = submsg_e_l[5] + temp; + temp = submsg_o_r[0]; + submsg_o_r[0] = submsg_e_r[0] + submsg_o_r[3]; + submsg_o_r[3] = submsg_e_r[3] + submsg_o_r[1]; + submsg_o_r[1] = submsg_e_r[1] + submsg_o_r[2]; + submsg_o_r[2] = submsg_e_r[2] + temp; + temp = submsg_o_r[4]; + submsg_o_r[4] = submsg_e_r[4] + submsg_o_r[7]; + submsg_o_r[7] = submsg_e_r[7] + submsg_o_r[6]; + submsg_o_r[6] = submsg_e_r[6] + submsg_o_r[5]; + submsg_o_r[5] = submsg_e_r[5] + temp; +} + +inline void load_sc(const lsh_u32** p_const_v, size_t i) +{ + CRYPTOPP_ASSERT(p_const_v != NULLPTR); + + *p_const_v = &LSH256_StepConstants[i]; +} + +inline void msg_add_even(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + + cv_l[0] ^= submsg_e_l[0]; cv_l[1] ^= submsg_e_l[1]; + cv_l[2] ^= submsg_e_l[2]; cv_l[3] ^= submsg_e_l[3]; + cv_l[4] ^= submsg_e_l[4]; cv_l[5] ^= submsg_e_l[5]; + cv_l[6] ^= submsg_e_l[6]; cv_l[7] ^= submsg_e_l[7]; + cv_r[0] ^= submsg_e_r[0]; cv_r[1] ^= submsg_e_r[1]; + cv_r[2] ^= submsg_e_r[2]; cv_r[3] ^= submsg_e_r[3]; + cv_r[4] ^= submsg_e_r[4]; cv_r[5] ^= submsg_e_r[5]; + cv_r[6] ^= submsg_e_r[6]; cv_r[7] ^= submsg_e_r[7]; +} + +inline void msg_add_odd(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + cv_l[0] ^= submsg_o_l[0]; cv_l[1] ^= submsg_o_l[1]; + cv_l[2] ^= submsg_o_l[2]; cv_l[3] ^= submsg_o_l[3]; + cv_l[4] ^= submsg_o_l[4]; cv_l[5] ^= submsg_o_l[5]; + cv_l[6] ^= submsg_o_l[6]; cv_l[7] ^= submsg_o_l[7]; + cv_r[0] ^= submsg_o_r[0]; cv_r[1] ^= submsg_o_r[1]; + cv_r[2] ^= submsg_o_r[2]; cv_r[3] ^= submsg_o_r[3]; + cv_r[4] ^= submsg_o_r[4]; cv_r[5] ^= submsg_o_r[5]; + cv_r[6] ^= submsg_o_r[6]; cv_r[7] ^= submsg_o_r[7]; +} + +inline void add_blk(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + cv_l[0] += cv_r[0]; + cv_l[1] += cv_r[1]; + cv_l[2] += cv_r[2]; + cv_l[3] += cv_r[3]; + cv_l[4] += cv_r[4]; + cv_l[5] += cv_r[5]; + cv_l[6] += cv_r[6]; + cv_l[7] += cv_r[7]; +} + +template +inline void rotate_blk(lsh_u32 cv[8]) +{ + cv[0] = rotlConstant(cv[0]); + cv[1] = rotlConstant(cv[1]); + cv[2] = rotlConstant(cv[2]); + cv[3] = rotlConstant(cv[3]); + cv[4] = rotlConstant(cv[4]); + cv[5] = rotlConstant(cv[5]); + cv[6] = rotlConstant(cv[6]); + cv[7] = rotlConstant(cv[7]); +} + +inline void xor_with_const(lsh_u32 cv_l[8], const lsh_u32 const_v[8]) +{ + cv_l[0] ^= const_v[0]; + cv_l[1] ^= const_v[1]; + cv_l[2] ^= const_v[2]; + cv_l[3] ^= const_v[3]; + cv_l[4] ^= const_v[4]; + cv_l[5] ^= const_v[5]; + cv_l[6] ^= const_v[6]; + cv_l[7] ^= const_v[7]; +} + +inline void rotate_msg_gamma(lsh_u32 cv_r[8]) +{ + cv_r[1] = rotlFixed(cv_r[1], g_gamma256[1]); + cv_r[2] = rotlFixed(cv_r[2], g_gamma256[2]); + cv_r[3] = rotlFixed(cv_r[3], g_gamma256[3]); + cv_r[4] = rotlFixed(cv_r[4], g_gamma256[4]); + cv_r[5] = rotlFixed(cv_r[5], g_gamma256[5]); + cv_r[6] = rotlFixed(cv_r[6], g_gamma256[6]); +} + +inline void word_perm(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + lsh_u32 temp; + temp = cv_l[0]; + cv_l[0] = cv_l[6]; + cv_l[6] = cv_r[6]; + cv_r[6] = cv_r[2]; + cv_r[2] = cv_l[1]; + cv_l[1] = cv_l[4]; + cv_l[4] = cv_r[4]; + cv_r[4] = cv_r[0]; + cv_r[0] = cv_l[2]; + cv_l[2] = cv_l[5]; + cv_l[5] = cv_r[7]; + cv_r[7] = cv_r[1]; + cv_r[1] = temp; + temp = cv_l[3]; + cv_l[3] = cv_l[7]; + cv_l[7] = cv_r[5]; + cv_r[5] = cv_r[3]; + cv_r[3] = temp; +}; + +/* -------------------------------------------------------- * +* step function +* -------------------------------------------------------- */ + +template +inline void mix(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 const_v[8]) +{ + add_blk(cv_l, cv_r); + rotate_blk(cv_l); + xor_with_const(cv_l, const_v); + add_blk(cv_r, cv_l); + rotate_blk(cv_r); + add_blk(cv_l, cv_r); + rotate_msg_gamma(cv_r); +} + +/* -------------------------------------------------------- * +* compression function +* -------------------------------------------------------- */ + +inline void compress(LSH256_Context* ctx, const lsh_u8 pdMsgBlk[LSH256_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + LSH256_Internal s_state(ctx->cv_l); + LSH256_Internal* i_state = &s_state; + + const lsh_u32* const_v = NULL; + lsh_u32* cv_l = ctx->cv_l; + lsh_u32* cv_r = ctx->cv_r; + + load_msg_blk(i_state, pdMsgBlk); + + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 0); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + for (size_t i = 1; i < NUM_STEPS / 2; i++) + { + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_exp_odd(i_state); + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); +} + +/* -------------------------------------------------------- */ + +inline void load_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 iv[16]) +{ + cv_l[0] = iv[0]; + cv_l[1] = iv[1]; + cv_l[2] = iv[2]; + cv_l[3] = iv[3]; + cv_l[4] = iv[4]; + cv_l[5] = iv[5]; + cv_l[6] = iv[6]; + cv_l[7] = iv[7]; + cv_r[0] = iv[8]; + cv_r[1] = iv[9]; + cv_r[2] = iv[10]; + cv_r[3] = iv[11]; + cv_r[4] = iv[12]; + cv_r[5] = iv[13]; + cv_r[6] = iv[14]; + cv_r[7] = iv[15]; +} + +inline void zero_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + memset(cv_l, 0x00, 8*sizeof(lsh_u32)); + memset(cv_r, 0x00, 8*sizeof(lsh_u32)); +} + +inline void zero_submsgs(LSH256_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + lsh_u32* sub_msgs = ctx->sub_msgs; + memset(sub_msgs, 0x00, 32*sizeof(lsh_u32)); +} + +inline void init224(LSH256_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV224); +} + +inline void init256(LSH256_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV256); +} + +/* -------------------------------------------------------- */ + +inline void fin(LSH256_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + for (size_t i = 0; i < HASH_VAL_MAX_WORD_LEN; i++){ + ctx->cv_l[i] = loadLE32(ctx->cv_l[i] ^ ctx->cv_r[i]); + } +} + +/* -------------------------------------------------------- */ + +inline void get_hash(LSH256_Context* ctx, lsh_u8* pbHashVal) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + CRYPTOPP_ASSERT(pbHashVal != NULLPTR); + + lsh_uint alg_type = ctx->alg_type; + lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type); + lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type); + + // Multiplying by looks odd... + memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len); + if (hash_val_bit_len){ + pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len); + } +} + +/* -------------------------------------------------------- */ + +lsh_err lsh256_init(LSH256_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + lsh_u32 alg_type = ctx->alg_type; + const lsh_u32* const_v = NULL; + ctx->remain_databitlen = 0; + + switch (alg_type) + { + case LSH_TYPE_256_256: + init256(ctx); + return LSH_SUCCESS; + case LSH_TYPE_256_224: + init224(ctx); + return LSH_SUCCESS; + default: + break; + } + + lsh_u32* cv_l = ctx->cv_l; + lsh_u32* cv_r = ctx->cv_r; + + zero_iv(cv_l, cv_r); + cv_l[0] = LSH256_HASH_VAL_MAX_BYTE_LEN; + cv_l[1] = LSH_GET_HASHBIT(alg_type); + + for (size_t i = 0; i < NUM_STEPS / 2; i++) + { + //Mix + load_sc(&const_v, i * 16); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + load_sc(&const_v, i * 16 + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + return LSH_SUCCESS; +} + +lsh_err lsh256_update(LSH256_Context* ctx, const lsh_u8* data, size_t databitlen) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(databitlen % 8 == 0); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + if (databitlen == 0){ + return LSH_SUCCESS; + } + + // We are byte oriented. tail bits will always be 0. + size_t databytelen = databitlen >> 3; + // lsh_uint pos2 = databitlen & 0x7; + const size_t pos2 = 0; + + size_t remain_msg_byte = ctx->remain_databitlen >> 3; + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + if (remain_msg_bit > 0){ + return LSH_ERR_INVALID_DATABITLEN; + } + + if (databytelen + remain_msg_byte < LSH256_MSG_BLK_BYTE_LEN) + { + memcpy(ctx->last_block + remain_msg_byte, data, databytelen); + ctx->remain_databitlen += (lsh_uint)databitlen; + remain_msg_byte += (lsh_uint)databytelen; + if (pos2){ + ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + } + return LSH_SUCCESS; + } + + if (remain_msg_byte > 0){ + size_t more_byte = LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte; + memcpy(ctx->last_block + remain_msg_byte, data, more_byte); + compress(ctx, ctx->last_block); + data += more_byte; + databytelen -= more_byte; + remain_msg_byte = 0; + ctx->remain_databitlen = 0; + } + + while (databytelen >= LSH256_MSG_BLK_BYTE_LEN) + { + // This call to compress caused some trouble. + // The data pointer can become unaligned in the + // previous block. + compress(ctx, data); + data += LSH256_MSG_BLK_BYTE_LEN; + databytelen -= LSH256_MSG_BLK_BYTE_LEN; + } + + if (databytelen > 0){ + memcpy(ctx->last_block, data, databytelen); + ctx->remain_databitlen = (lsh_uint)(databytelen << 3); + } + + if (pos2){ + ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + ctx->remain_databitlen += pos2; + } + + return LSH_SUCCESS; +} + +lsh_err lsh256_final(LSH256_Context* ctx, lsh_u8* hashval) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(hashval != NULLPTR); + + // We are byte oriented. tail bits will always be 0. + size_t remain_msg_byte = ctx->remain_databitlen >> 3; + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + + if (remain_msg_bit){ + ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit)); + } + else{ + ctx->last_block[remain_msg_byte] = 0x80; + } + memset(ctx->last_block + remain_msg_byte + 1, 0, LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte - 1); + + compress(ctx, ctx->last_block); + + fin(ctx); + get_hash(ctx, hashval); + + return LSH_SUCCESS; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_ENABLE_64BIT_SSE) +# if defined(CRYPTOPP_AVX2_AVAILABLE) + extern void LSH256_Base_Restart_AVX2(word32* state); + extern void LSH256_Base_Update_AVX2(word32* state, const byte *input, size_t size); + extern void LSH256_Base_TruncatedFinal_AVX2(word32* state, byte *hash, size_t size); +# endif +# if defined(CRYPTOPP_SSSE3_AVAILABLE) + extern void LSH256_Base_Restart_SSSE3(word32* state); + extern void LSH256_Base_Update_SSSE3(word32* state, const byte *input, size_t size); + extern void LSH256_Base_TruncatedFinal_SSSE3(word32* state, byte *hash, size_t size); +# endif +#endif + +void LSH256_Base_Restart_CXX(word32* state) +{ + state[RemainingBits] = 0; + LSH256_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_init(&ctx); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_init failed"); +} + +void LSH256_Base_Update_CXX(word32* state, const byte *input, size_t size) +{ + LSH256_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_update(&ctx, input, 8*size); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_update failed"); +} + +void LSH256_Base_TruncatedFinal_CXX(word32* state, byte *hash, size_t) +{ + LSH256_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_final(&ctx, hash); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_final failed"); +} + +std::string LSH256_Base::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_ENABLE_64BIT_SSE) +#if defined(CRYPTOPP_AVX2_AVAILABLE) + if (HasAVX2()) + return "AVX2"; + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return "SSSE3"; + else +#endif +#endif // CRYPTOPP_ENABLE_64BIT_SSE + + return "C++"; +} + +void LSH256_Base::Restart() +{ +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasAVX2()) + LSH256_Base_Restart_AVX2(m_state); + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasSSSE3()) + LSH256_Base_Restart_SSSE3(m_state); + else +#endif + + LSH256_Base_Restart_CXX(m_state); +} + +void LSH256_Base::Update(const byte *input, size_t size) +{ + CRYPTOPP_ASSERT(input != NULLPTR); + CRYPTOPP_ASSERT(size); + +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasAVX2()) + LSH256_Base_Update_AVX2(m_state, input, size); + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasSSSE3()) + LSH256_Base_Update_SSSE3(m_state, input, size); + else +#endif + + LSH256_Base_Update_CXX(m_state, input, size); +} + +void LSH256_Base::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + ThrowIfInvalidTruncatedSize(size); + + // TODO: determine if LSH256 supports truncated hashes. See the code + // in get_hash(), where a bit-length is added to the last output + // byte of the hash function. + byte fullHash[LSH256_HASH_VAL_MAX_BYTE_LEN]; + bool copyOut = (size < DigestSize()); + +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasAVX2()) + LSH256_Base_TruncatedFinal_AVX2(m_state, copyOut ? fullHash : hash, size); + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasSSSE3()) + LSH256_Base_TruncatedFinal_SSSE3(m_state, copyOut ? fullHash : hash, size); + else +#endif + + LSH256_Base_TruncatedFinal_CXX(m_state, copyOut ? fullHash : hash, size); + + if (copyOut) + memcpy(hash, fullHash, size); + + Restart(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/lsh256_avx.cpp b/external/ours/library/crypto/src/shared/original/lsh256_avx.cpp new file mode 100755 index 000000000..a8c0ef23c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh256_avx.cpp @@ -0,0 +1,648 @@ +// lsh.cpp - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + +#include "pch.h" +#include "config.h" + +#include "lsh.h" +#include "misc.h" + +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + +#if defined(CRYPTOPP_AVX2_AVAILABLE) +# include +# include +#endif + +// GCC at 4.5. Clang is unknown. Also see https://stackoverflow.com/a/42493893. +#if (CRYPTOPP_GCC_VERSION >= 40500) +# include +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +/* LSH Constants */ + +const unsigned int LSH256_MSG_BLK_BYTE_LEN = 128; +// const unsigned int LSH256_MSG_BLK_BIT_LEN = 1024; +// const unsigned int LSH256_CV_BYTE_LEN = 64; +const unsigned int LSH256_HASH_VAL_MAX_BYTE_LEN = 32; + +// const unsigned int MSG_BLK_WORD_LEN = 32; +const unsigned int CV_WORD_LEN = 16; +const unsigned int CONST_WORD_LEN = 8; +// const unsigned int HASH_VAL_MAX_WORD_LEN = 8; +// const unsigned int WORD_BIT_LEN = 32; +const unsigned int NUM_STEPS = 26; + +const unsigned int ROT_EVEN_ALPHA = 29; +const unsigned int ROT_EVEN_BETA = 1; +const unsigned int ROT_ODD_ALPHA = 5; +const unsigned int ROT_ODD_BETA = 17; + +const unsigned int LSH_TYPE_256_256 = 0x0000020; +const unsigned int LSH_TYPE_256_224 = 0x000001C; + +// const unsigned int LSH_TYPE_224 = LSH_TYPE_256_224; +// const unsigned int LSH_TYPE_256 = LSH_TYPE_256_256; + +/* Error Code */ + +const unsigned int LSH_SUCCESS = 0x0; +// const unsigned int LSH_ERR_NULL_PTR = 0x2401; +// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402; +const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403; +const unsigned int LSH_ERR_INVALID_STATE = 0x2404; + +/* Index into our state array */ + +const unsigned int AlgorithmType = 80; +const unsigned int RemainingBits = 81; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(LSH) + +// lsh256.cpp +extern const word32 LSH256_IV224[CV_WORD_LEN]; +extern const word32 LSH256_IV256[CV_WORD_LEN]; +extern const word32 LSH256_StepConstants[CONST_WORD_LEN * NUM_STEPS]; + +NAMESPACE_END // LSH +NAMESPACE_END // Crypto++ + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::rotlFixed; +using CryptoPP::rotlConstant; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; +using CryptoPP::ConditionalByteReverse; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +typedef byte lsh_u8; +typedef word32 lsh_u32; +typedef word32 lsh_uint; +typedef word32 lsh_err; +typedef word32 lsh_type; + +using CryptoPP::LSH::LSH256_IV224; +using CryptoPP::LSH::LSH256_IV256; +using CryptoPP::LSH::LSH256_StepConstants; + +struct LSH256_AVX2_Context +{ + LSH256_AVX2_Context(word32* state, word32 algType, word32& remainingBitLength) : + cv_l(state+0), cv_r(state+8), sub_msgs(state+16), + last_block(reinterpret_cast(state+48)), + remain_databitlen(remainingBitLength), + alg_type(static_cast(algType)) {} + + lsh_u32* cv_l; // start of our state block + lsh_u32* cv_r; + lsh_u32* sub_msgs; + lsh_u8* last_block; + lsh_u32& remain_databitlen; + lsh_type alg_type; +}; + +struct LSH256_AVX2_Internal +{ + LSH256_AVX2_Internal(word32* state) : + submsg_e_l(state+16), submsg_e_r(state+24), + submsg_o_l(state+32), submsg_o_r(state+40) { } + + lsh_u32* submsg_e_l; /* even left sub-message */ + lsh_u32* submsg_e_r; /* even right sub-message */ + lsh_u32* submsg_o_l; /* odd left sub-message */ + lsh_u32* submsg_o_r; /* odd right sub-message */ +}; + +// Zero the upper 128 bits of all YMM registers on exit. +// It avoids AVX state transition penalties when saving state. +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735 +// makes using zeroupper a little tricky. + +struct AVX_Cleanup +{ + ~AVX_Cleanup() { + _mm256_zeroupper(); + } +}; + +// const word32 g_gamma256[8] = { 0, 8, 16, 24, 24, 16, 8, 0 }; + +/* LSH AlgType Macro */ + +inline bool LSH_IS_LSH512(lsh_uint val) { + return (val & 0xf0000) == 0; +} + +inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) { + return val >> 24; +} + +inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) { + return val & 0xffff; +} + +inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) { + return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val); +} + +inline lsh_u32 loadLE32(lsh_u32 v) { + return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v); +} + +lsh_u32 ROTL(lsh_u32 x, lsh_u32 r) { + return rotlFixed(x, r); +} + +// Original code relied upon unaligned lsh_u32 buffer +inline void load_msg_blk(LSH256_AVX2_Internal* i_state, const lsh_u8 msgblk[LSH256_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + _mm256_storeu_si256(M256_CAST(submsg_e_l+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+0))); + _mm256_storeu_si256(M256_CAST(submsg_e_r+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+32))); + _mm256_storeu_si256(M256_CAST(submsg_o_l+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+64))); + _mm256_storeu_si256(M256_CAST(submsg_o_r+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+96))); +} + +inline void msg_exp_even(LSH256_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + const __m256i mask = _mm256_set_epi32(0x1b1a1918, 0x17161514, + 0x13121110, 0x1f1e1d1c, 0x07060504, 0x03020100, 0x0b0a0908, 0x0f0e0d0c); + + _mm256_storeu_si256(M256_CAST(submsg_e_l+0), _mm256_add_epi32( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+0)), + _mm256_shuffle_epi8( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+0)), mask))); + _mm256_storeu_si256(M256_CAST(submsg_e_r+0), _mm256_add_epi32( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+0)), + _mm256_shuffle_epi8( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+0)), mask))); +} + +inline void msg_exp_odd(LSH256_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + const __m256i mask = _mm256_set_epi32(0x1b1a1918, 0x17161514, + 0x13121110, 0x1f1e1d1c, 0x07060504, 0x03020100, 0x0b0a0908, 0x0f0e0d0c); + + _mm256_storeu_si256(M256_CAST(submsg_o_l+0), _mm256_add_epi32( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+0)), + _mm256_shuffle_epi8( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+0)), mask))); + _mm256_storeu_si256(M256_CAST(submsg_o_r+0), _mm256_add_epi32( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+0)), + _mm256_shuffle_epi8( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+0)), mask))); +} + +inline void load_sc(const lsh_u32** p_const_v, size_t i) +{ + CRYPTOPP_ASSERT(p_const_v != NULLPTR); + + *p_const_v = &LSH256_StepConstants[i]; +} + +inline void msg_add_even(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + + _mm256_storeu_si256(M256_CAST(cv_l+0), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+0)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+0)))); + _mm256_storeu_si256(M256_CAST(cv_r+0), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+0)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+0)))); +} + +inline void msg_add_odd(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l)))); + _mm256_storeu_si256(M256_CAST(cv_r), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_r)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r)))); +} + +inline void add_blk(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_add_epi32( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(cv_r)))); +} + +template +inline void rotate_blk(lsh_u32 cv[8]) +{ + _mm256_storeu_si256(M256_CAST(cv), _mm256_or_si256( + _mm256_slli_epi32(_mm256_loadu_si256(CONST_M256_CAST(cv)), R), + _mm256_srli_epi32(_mm256_loadu_si256(CONST_M256_CAST(cv)), 32-R))); +} + +inline void xor_with_const(lsh_u32 cv_l[8], const lsh_u32 const_v[8]) +{ + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(const_v)))); +} + +inline void rotate_msg_gamma(lsh_u32 cv_r[8]) +{ + // g_gamma256[8] = { 0, 8, 16, 24, 24, 16, 8, 0 }; + _mm256_storeu_si256(M256_CAST(cv_r+0), + _mm256_shuffle_epi8(_mm256_loadu_si256(CONST_M256_CAST(cv_r+0)), + _mm256_set_epi8( + /* hi lane */ 15,14,13,12, 10,9,8,11, 5,4,7,6, 0,3,2,1, + /* lo lane */ 12,15,14,13, 9,8,11,10, 6,5,4,7, 3,2,1,0))); +} + +inline void word_perm(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + __m256i temp = _mm256_shuffle_epi32( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), _MM_SHUFFLE(3,1,0,2)); + _mm256_storeu_si256(M256_CAST(cv_r), + _mm256_shuffle_epi32( + _mm256_loadu_si256(CONST_M256_CAST(cv_r)), _MM_SHUFFLE(1,2,3,0))); + _mm256_storeu_si256(M256_CAST(cv_l), + _mm256_permute2x128_si256(temp, + _mm256_loadu_si256(CONST_M256_CAST(cv_r)), _MM_SHUFFLE(0,3,0,1))); + _mm256_storeu_si256(M256_CAST(cv_r), + _mm256_permute2x128_si256(temp, + _mm256_loadu_si256(CONST_M256_CAST(cv_r)), _MM_SHUFFLE(0,2,0,0))); +}; + +/* -------------------------------------------------------- * +* step function +* -------------------------------------------------------- */ + +template +inline void mix(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 const_v[8]) +{ + add_blk(cv_l, cv_r); + rotate_blk(cv_l); + xor_with_const(cv_l, const_v); + add_blk(cv_r, cv_l); + rotate_blk(cv_r); + add_blk(cv_l, cv_r); + rotate_msg_gamma(cv_r); +} + +/* -------------------------------------------------------- * +* compression function +* -------------------------------------------------------- */ + +inline void compress(LSH256_AVX2_Context* ctx, const lsh_u8 pdMsgBlk[LSH256_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + LSH256_AVX2_Internal s_state(ctx->cv_l); + LSH256_AVX2_Internal* i_state = &s_state; + + const lsh_u32* const_v = NULL; + lsh_u32* cv_l = ctx->cv_l; + lsh_u32* cv_r = ctx->cv_r; + + load_msg_blk(i_state, pdMsgBlk); + + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 0); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + for (size_t i = 1; i < NUM_STEPS / 2; i++) + { + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_exp_odd(i_state); + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); +} + +/* -------------------------------------------------------- */ + +inline void load_iv(word32 cv_l[8], word32 cv_r[8], const word32 iv[16]) +{ + // The IV's are 32-byte aligned so we can use aligned loads. + _mm256_storeu_si256(M256_CAST(cv_l+0), + _mm256_load_si256(CONST_M256_CAST(iv+0))); + _mm256_storeu_si256(M256_CAST(cv_r+0), + _mm256_load_si256(CONST_M256_CAST(iv+8))); +} + +inline void zero_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + _mm256_storeu_si256(M256_CAST(cv_l+0), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(cv_r+0), _mm256_setzero_si256()); +} + +inline void zero_submsgs(LSH256_AVX2_Context* ctx) +{ + lsh_u32* sub_msgs = ctx->sub_msgs; + + _mm256_storeu_si256(M256_CAST(sub_msgs+ 0), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(sub_msgs+ 8), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(sub_msgs+16), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(sub_msgs+24), _mm256_setzero_si256()); +} + +inline void init224(LSH256_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV224); +} + +inline void init256(LSH256_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV256); +} + +/* -------------------------------------------------------- */ + +inline void fin(LSH256_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + _mm256_storeu_si256(M256_CAST(ctx->cv_l+0), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(ctx->cv_l+0)), + _mm256_loadu_si256(CONST_M256_CAST(ctx->cv_r+0)))); +} + +/* -------------------------------------------------------- */ + +inline void get_hash(LSH256_AVX2_Context* ctx, lsh_u8* pbHashVal) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + CRYPTOPP_ASSERT(pbHashVal != NULLPTR); + + lsh_uint alg_type = ctx->alg_type; + lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type); + lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type); + + // Multiplying by looks odd... + memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len); + if (hash_val_bit_len){ + pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len); + } +} + +/* -------------------------------------------------------- */ + +lsh_err lsh256_init_avx2(LSH256_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + lsh_u32 alg_type = ctx->alg_type; + const lsh_u32* const_v = NULL; + ctx->remain_databitlen = 0; + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. + AVX_Cleanup cleanup; + + switch (alg_type) + { + case LSH_TYPE_256_256: + init256(ctx); + return LSH_SUCCESS; + case LSH_TYPE_256_224: + init224(ctx); + return LSH_SUCCESS; + default: + break; + } + + lsh_u32* cv_l = ctx->cv_l; + lsh_u32* cv_r = ctx->cv_r; + + zero_iv(cv_l, cv_r); + cv_l[0] = LSH256_HASH_VAL_MAX_BYTE_LEN; + cv_l[1] = LSH_GET_HASHBIT(alg_type); + + for (size_t i = 0; i < NUM_STEPS / 2; i++) + { + //Mix + load_sc(&const_v, i * 16); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + load_sc(&const_v, i * 16 + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + return LSH_SUCCESS; +} + +lsh_err lsh256_update_avx2(LSH256_AVX2_Context* ctx, const lsh_u8* data, size_t databitlen) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(databitlen % 8 == 0); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. + AVX_Cleanup cleanup; + + if (databitlen == 0){ + return LSH_SUCCESS; + } + + // We are byte oriented. tail bits will always be 0. + size_t databytelen = databitlen >> 3; + // lsh_uint pos2 = databitlen & 0x7; + const size_t pos2 = 0; + + size_t remain_msg_byte = ctx->remain_databitlen >> 3; + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + if (remain_msg_bit > 0){ + return LSH_ERR_INVALID_DATABITLEN; + } + + if (databytelen + remain_msg_byte < LSH256_MSG_BLK_BYTE_LEN) + { + memcpy(ctx->last_block + remain_msg_byte, data, databytelen); + ctx->remain_databitlen += (lsh_uint)databitlen; + remain_msg_byte += (lsh_uint)databytelen; + if (pos2){ + ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + } + return LSH_SUCCESS; + } + + if (remain_msg_byte > 0){ + size_t more_byte = LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte; + memcpy(ctx->last_block + remain_msg_byte, data, more_byte); + compress(ctx, ctx->last_block); + data += more_byte; + databytelen -= more_byte; + remain_msg_byte = 0; + ctx->remain_databitlen = 0; + } + + while (databytelen >= LSH256_MSG_BLK_BYTE_LEN) + { + // This call to compress caused some trouble. + // The data pointer can become unaligned in the + // previous block. + compress(ctx, data); + data += LSH256_MSG_BLK_BYTE_LEN; + databytelen -= LSH256_MSG_BLK_BYTE_LEN; + } + + if (databytelen > 0){ + memcpy(ctx->last_block, data, databytelen); + ctx->remain_databitlen = (lsh_uint)(databytelen << 3); + } + + if (pos2){ + ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + ctx->remain_databitlen += pos2; + } + + return LSH_SUCCESS; +} + +lsh_err lsh256_final_avx2(LSH256_AVX2_Context* ctx, lsh_u8* hashval) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(hashval != NULLPTR); + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. + AVX_Cleanup cleanup; + + // We are byte oriented. tail bits will always be 0. + size_t remain_msg_byte = ctx->remain_databitlen >> 3; + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + + if (remain_msg_bit){ + ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit)); + } + else{ + ctx->last_block[remain_msg_byte] = 0x80; + } + memset(ctx->last_block + remain_msg_byte + 1, 0, LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte - 1); + + compress(ctx, ctx->last_block); + + fin(ctx); + get_hash(ctx, hashval); + + return LSH_SUCCESS; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +extern +void LSH256_Base_Restart_AVX2(word32* state) +{ + state[RemainingBits] = 0; + LSH256_AVX2_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_init_avx2(&ctx); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_init_avx2 failed"); +} + +extern +void LSH256_Base_Update_AVX2(word32* state, const byte *input, size_t size) +{ + LSH256_AVX2_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_update_avx2(&ctx, input, 8*size); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_update_avx2 failed"); +} + +extern +void LSH256_Base_TruncatedFinal_AVX2(word32* state, byte *hash, size_t) +{ + LSH256_AVX2_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_final_avx2(&ctx, hash); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_final_avx2 failed"); +} + +NAMESPACE_END + +#endif // CRYPTOPP_AVX2_AVAILABLE diff --git a/external/ours/library/crypto/src/shared/original/lsh256_sse.cpp b/external/ours/library/crypto/src/shared/original/lsh256_sse.cpp new file mode 100755 index 000000000..4417142cf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh256_sse.cpp @@ -0,0 +1,710 @@ +// lsh.cpp - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + +#include "pch.h" +#include "config.h" + +#include "lsh.h" +#include "cpu.h" +#include "misc.h" + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) +# include +# include +#endif + +#if defined(CRYPTOPP_XOP_AVAILABLE) +# include +#endif + +// GCC at 4.5. Clang is unknown. Also see https://stackoverflow.com/a/42493893. +#if (CRYPTOPP_GCC_VERSION >= 40500) +# include +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +/* LSH Constants */ + +const unsigned int LSH256_MSG_BLK_BYTE_LEN = 128; +// const unsigned int LSH256_MSG_BLK_BIT_LEN = 1024; +// const unsigned int LSH256_CV_BYTE_LEN = 64; +const unsigned int LSH256_HASH_VAL_MAX_BYTE_LEN = 32; + +// const unsigned int MSG_BLK_WORD_LEN = 32; +const unsigned int CV_WORD_LEN = 16; +const unsigned int CONST_WORD_LEN = 8; +// const unsigned int HASH_VAL_MAX_WORD_LEN = 8; +// const unsigned int WORD_BIT_LEN = 32; +const unsigned int NUM_STEPS = 26; + +const unsigned int ROT_EVEN_ALPHA = 29; +const unsigned int ROT_EVEN_BETA = 1; +const unsigned int ROT_ODD_ALPHA = 5; +const unsigned int ROT_ODD_BETA = 17; + +const unsigned int LSH_TYPE_256_256 = 0x0000020; +const unsigned int LSH_TYPE_256_224 = 0x000001C; + +// const unsigned int LSH_TYPE_224 = LSH_TYPE_256_224; +// const unsigned int LSH_TYPE_256 = LSH_TYPE_256_256; + +/* Error Code */ + +const unsigned int LSH_SUCCESS = 0x0; +// const unsigned int LSH_ERR_NULL_PTR = 0x2401; +// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402; +const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403; +const unsigned int LSH_ERR_INVALID_STATE = 0x2404; + +/* Index into our state array */ + +const unsigned int AlgorithmType = 80; +const unsigned int RemainingBits = 81; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(LSH) + +// lsh256.cpp +extern const word32 LSH256_IV224[CV_WORD_LEN]; +extern const word32 LSH256_IV256[CV_WORD_LEN]; +extern const word32 LSH256_StepConstants[CONST_WORD_LEN * NUM_STEPS]; + +NAMESPACE_END // LSH +NAMESPACE_END // Crypto++ + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::rotlFixed; +using CryptoPP::rotlConstant; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; +using CryptoPP::ConditionalByteReverse; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +typedef byte lsh_u8; +typedef word32 lsh_u32; +typedef word32 lsh_uint; +typedef word32 lsh_err; +typedef word32 lsh_type; + +using CryptoPP::LSH::LSH256_IV224; +using CryptoPP::LSH::LSH256_IV256; +using CryptoPP::LSH::LSH256_StepConstants; + +struct LSH256_SSSE3_Context +{ + LSH256_SSSE3_Context(word32* state, word32 algType, word32& remainingBitLength) : + cv_l(state+0), cv_r(state+8), sub_msgs(state+16), + last_block(reinterpret_cast(state+48)), + remain_databitlen(remainingBitLength), + alg_type(static_cast(algType)) {} + + lsh_u32* cv_l; // start of our state block + lsh_u32* cv_r; + lsh_u32* sub_msgs; + lsh_u8* last_block; + lsh_u32& remain_databitlen; + lsh_type alg_type; +}; + +struct LSH256_SSSE3_Internal +{ + LSH256_SSSE3_Internal(word32* state) : + submsg_e_l(state+16), submsg_e_r(state+24), + submsg_o_l(state+32), submsg_o_r(state+40) { } + + lsh_u32* submsg_e_l; /* even left sub-message */ + lsh_u32* submsg_e_r; /* even right sub-message */ + lsh_u32* submsg_o_l; /* odd left sub-message */ + lsh_u32* submsg_o_r; /* odd right sub-message */ +}; + +// const word32 g_gamma256[8] = { 0, 8, 16, 24, 24, 16, 8, 0 }; + +/* LSH AlgType Macro */ + +inline bool LSH_IS_LSH512(lsh_uint val) { + return (val & 0xf0000) == 0; +} + +inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) { + return val >> 24; +} + +inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) { + return val & 0xffff; +} + +inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) { + return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val); +} + +inline lsh_u32 loadLE32(lsh_u32 v) { + return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v); +} + +lsh_u32 ROTL(lsh_u32 x, lsh_u32 r) { + return rotlFixed(x, r); +} + +// Original code relied upon unaligned lsh_u32 buffer +inline void load_msg_blk(LSH256_SSSE3_Internal* i_state, const lsh_u8 msgblk[LSH256_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + _mm_storeu_si128(M128_CAST(submsg_e_l+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+0))); + _mm_storeu_si128(M128_CAST(submsg_e_l+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+16))); + _mm_storeu_si128(M128_CAST(submsg_e_r+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+32))); + _mm_storeu_si128(M128_CAST(submsg_e_r+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+48))); + _mm_storeu_si128(M128_CAST(submsg_o_l+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+64))); + _mm_storeu_si128(M128_CAST(submsg_o_l+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+80))); + _mm_storeu_si128(M128_CAST(submsg_o_r+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+96))); + _mm_storeu_si128(M128_CAST(submsg_o_r+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+112))); +} + +inline void msg_exp_even(LSH256_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + _mm_storeu_si128(M128_CAST(submsg_e_l+0), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+0)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+0)), _MM_SHUFFLE(1,0,2,3)))); + + _mm_storeu_si128(M128_CAST(submsg_e_l+4), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)), _MM_SHUFFLE(2,1,0,3)))); + + _mm_storeu_si128(M128_CAST(submsg_e_r+0), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+0)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+0)), _MM_SHUFFLE(1,0,2,3)))); + + _mm_storeu_si128(M128_CAST(submsg_e_r+4), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)), _MM_SHUFFLE(2,1,0,3)))); +} + +inline void msg_exp_odd(LSH256_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + _mm_storeu_si128(M128_CAST(submsg_o_l+0), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+0)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+0)), _MM_SHUFFLE(1,0,2,3)))); + + _mm_storeu_si128(M128_CAST(submsg_o_l+4), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)), _MM_SHUFFLE(2,1,0,3)))); + + _mm_storeu_si128(M128_CAST(submsg_o_r+0), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+0)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+0)), _MM_SHUFFLE(1,0,2,3)))); + + _mm_storeu_si128(M128_CAST(submsg_o_r+4), _mm_add_epi32( + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)), _MM_SHUFFLE(3,2,1,0)), + _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)), _MM_SHUFFLE(2,1,0,3)))); +} + +inline void load_sc(const lsh_u32** p_const_v, size_t i) +{ + CRYPTOPP_ASSERT(p_const_v != NULLPTR); + + *p_const_v = &LSH256_StepConstants[i]; +} + +inline void msg_add_even(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_e_l = i_state->submsg_e_l; + lsh_u32* submsg_e_r = i_state->submsg_e_r; + + _mm_storeu_si128(M128_CAST(cv_l+0), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+0)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+0)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)))); + _mm_storeu_si128(M128_CAST(cv_r+0), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+0)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+0)))); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)))); +} + +inline void msg_add_odd(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u32* submsg_o_l = i_state->submsg_o_l; + lsh_u32* submsg_o_r = i_state->submsg_o_r; + + _mm_storeu_si128(M128_CAST(cv_l), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)))); + _mm_storeu_si128(M128_CAST(cv_r), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r)))); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)))); +} + +inline void add_blk(lsh_u32 cv_l[8], const lsh_u32 cv_r[8]) +{ + _mm_storeu_si128(M128_CAST(cv_l), _mm_add_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(cv_r)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_add_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)))); +} + +template +inline void rotate_blk(lsh_u32 cv[8]) +{ +#if defined(CRYPTOPP_XOP_AVAILABLE) + _mm_storeu_si128(M128_CAST(cv), + _mm_roti_epi32(_mm_loadu_si128(CONST_M128_CAST(cv)), R)); + _mm_storeu_si128(M128_CAST(cv+4), + _mm_roti_epi32(_mm_loadu_si128(CONST_M128_CAST(cv+4)), R)); +#else + _mm_storeu_si128(M128_CAST(cv), _mm_or_si128( + _mm_slli_epi32(_mm_loadu_si128(CONST_M128_CAST(cv)), R), + _mm_srli_epi32(_mm_loadu_si128(CONST_M128_CAST(cv)), 32-R))); + _mm_storeu_si128(M128_CAST(cv+4), _mm_or_si128( + _mm_slli_epi32(_mm_loadu_si128(CONST_M128_CAST(cv+4)), R), + _mm_srli_epi32(_mm_loadu_si128(CONST_M128_CAST(cv+4)), 32-R))); +#endif +} + +inline void xor_with_const(lsh_u32* cv_l, const lsh_u32* const_v) +{ + _mm_storeu_si128(M128_CAST(cv_l), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(const_v)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(const_v+4)))); +} + +inline void rotate_msg_gamma(lsh_u32 cv_r[8]) +{ + // g_gamma256[8] = { 0, 8, 16, 24, 24, 16, 8, 0 }; + _mm_storeu_si128(M128_CAST(cv_r+0), + _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(cv_r+0)), + _mm_set_epi8(12,15,14,13, 9,8,11,10, 6,5,4,7, 3,2,1,0))); + _mm_storeu_si128(M128_CAST(cv_r+4), + _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_set_epi8(15,14,13,12, 10,9,8,11, 5,4,7,6, 0,3,2,1))); +} + +inline void word_perm(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + _mm_storeu_si128(M128_CAST(cv_l+0), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_l+0)), _MM_SHUFFLE(3,1,0,2))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), _MM_SHUFFLE(3,1,0,2))); + _mm_storeu_si128(M128_CAST(cv_r+0), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_r+0)), _MM_SHUFFLE(1,2,3,0))); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)), _MM_SHUFFLE(1,2,3,0))); + + __m128i temp = _mm_loadu_si128(CONST_M128_CAST(cv_l+0)); + _mm_storeu_si128(M128_CAST(cv_l+0), + _mm_loadu_si128(CONST_M128_CAST(cv_l+4))); + _mm_storeu_si128(M128_CAST(cv_l+4), + _mm_loadu_si128(CONST_M128_CAST(cv_r+4))); + _mm_storeu_si128(M128_CAST(cv_r+4), + _mm_loadu_si128(CONST_M128_CAST(cv_r+0))); + _mm_storeu_si128(M128_CAST(cv_r+0), temp); +}; + +/* -------------------------------------------------------- * +* step function +* -------------------------------------------------------- */ + +template +inline void mix(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 const_v[8]) +{ + add_blk(cv_l, cv_r); + rotate_blk(cv_l); + xor_with_const(cv_l, const_v); + add_blk(cv_r, cv_l); + rotate_blk(cv_r); + add_blk(cv_l, cv_r); + rotate_msg_gamma(cv_r); +} + +/* -------------------------------------------------------- * +* compression function +* -------------------------------------------------------- */ + +inline void compress(LSH256_SSSE3_Context* ctx, const lsh_u8 pdMsgBlk[LSH256_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + LSH256_SSSE3_Internal s_state(ctx->cv_l); + LSH256_SSSE3_Internal* i_state = &s_state; + + const lsh_u32* const_v = NULL; + lsh_u32* cv_l = ctx->cv_l; + lsh_u32* cv_r = ctx->cv_r; + + load_msg_blk(i_state, pdMsgBlk); + + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 0); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + for (size_t i = 1; i < NUM_STEPS / 2; i++) + { + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_exp_odd(i_state); + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); +} + +/* -------------------------------------------------------- */ + +inline void load_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 iv[16]) +{ + _mm_storeu_si128(M128_CAST(cv_l+ 0), + _mm_load_si128(CONST_M128_CAST(iv+ 0))); + _mm_storeu_si128(M128_CAST(cv_l+ 4), + _mm_load_si128(CONST_M128_CAST(iv+ 4))); + _mm_storeu_si128(M128_CAST(cv_r+ 0), + _mm_load_si128(CONST_M128_CAST(iv+ 8))); + _mm_storeu_si128(M128_CAST(cv_r+ 4), + _mm_load_si128(CONST_M128_CAST(iv+12))); +} + +inline void zero_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8]) +{ + _mm_storeu_si128(M128_CAST(cv_l+0), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_r+0), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_setzero_si128()); +} + +inline void zero_submsgs(LSH256_SSSE3_Context* ctx) +{ + lsh_u32* sub_msgs = ctx->sub_msgs; + + _mm_storeu_si128(M128_CAST(sub_msgs+ 0), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+ 4), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+ 8), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+12), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+16), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+20), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+24), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+28), _mm_setzero_si128()); +} + +inline void init224(LSH256_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV224); +} + +inline void init256(LSH256_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV256); +} + +/* -------------------------------------------------------- */ + +inline void fin(LSH256_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + _mm_storeu_si128(M128_CAST(ctx->cv_l+0), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_l+0)), + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_r+0)))); + _mm_storeu_si128(M128_CAST(ctx->cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_r+4)))); +} + +/* -------------------------------------------------------- */ + +inline void get_hash(LSH256_SSSE3_Context* ctx, lsh_u8* pbHashVal) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + CRYPTOPP_ASSERT(pbHashVal != NULLPTR); + + lsh_uint alg_type = ctx->alg_type; + lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type); + lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type); + + // Multiplying by sizeof(lsh_u8) looks odd... + memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len); + if (hash_val_bit_len){ + pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len); + } +} + +/* -------------------------------------------------------- */ + +lsh_err lsh256_ssse3_init(LSH256_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + lsh_u32 alg_type = ctx->alg_type; + const lsh_u32* const_v = NULL; + ctx->remain_databitlen = 0; + + switch (alg_type) + { + case LSH_TYPE_256_256: + init256(ctx); + return LSH_SUCCESS; + case LSH_TYPE_256_224: + init224(ctx); + return LSH_SUCCESS; + default: + break; + } + + lsh_u32* cv_l = ctx->cv_l; + lsh_u32* cv_r = ctx->cv_r; + + zero_iv(cv_l, cv_r); + cv_l[0] = LSH256_HASH_VAL_MAX_BYTE_LEN; + cv_l[1] = LSH_GET_HASHBIT(alg_type); + + for (size_t i = 0; i < NUM_STEPS / 2; i++) + { + //Mix + load_sc(&const_v, i * 16); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + load_sc(&const_v, i * 16 + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + return LSH_SUCCESS; +} + +lsh_err lsh256_ssse3_update(LSH256_SSSE3_Context* ctx, const lsh_u8* data, size_t databitlen) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(databitlen % 8 == 0); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + if (databitlen == 0){ + return LSH_SUCCESS; + } + + // We are byte oriented. tail bits will always be 0. + size_t databytelen = databitlen >> 3; + // lsh_uint pos2 = databitlen & 0x7; + const size_t pos2 = 0; + + size_t remain_msg_byte = ctx->remain_databitlen >> 3; + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + if (remain_msg_bit > 0){ + return LSH_ERR_INVALID_DATABITLEN; + } + + if (databytelen + remain_msg_byte < LSH256_MSG_BLK_BYTE_LEN) + { + memcpy(ctx->last_block + remain_msg_byte, data, databytelen); + ctx->remain_databitlen += (lsh_uint)databitlen; + remain_msg_byte += (lsh_uint)databytelen; + if (pos2){ + ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + } + return LSH_SUCCESS; + } + + if (remain_msg_byte > 0){ + size_t more_byte = LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte; + memcpy(ctx->last_block + remain_msg_byte, data, more_byte); + compress(ctx, ctx->last_block); + data += more_byte; + databytelen -= more_byte; + remain_msg_byte = 0; + ctx->remain_databitlen = 0; + } + + while (databytelen >= LSH256_MSG_BLK_BYTE_LEN) + { + // This call to compress caused some trouble. + // The data pointer can become unaligned in the + // previous block. + compress(ctx, data); + data += LSH256_MSG_BLK_BYTE_LEN; + databytelen -= LSH256_MSG_BLK_BYTE_LEN; + } + + if (databytelen > 0){ + memcpy(ctx->last_block, data, databytelen); + ctx->remain_databitlen = (lsh_uint)(databytelen << 3); + } + + if (pos2){ + ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + ctx->remain_databitlen += pos2; + } + + return LSH_SUCCESS; +} + +lsh_err lsh256_ssse3_final(LSH256_SSSE3_Context* ctx, lsh_u8* hashval) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(hashval != NULLPTR); + + // We are byte oriented. tail bits will always be 0. + size_t remain_msg_byte = ctx->remain_databitlen >> 3; + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + + if (remain_msg_bit){ + ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit)); + } + else{ + ctx->last_block[remain_msg_byte] = 0x80; + } + memset(ctx->last_block + remain_msg_byte + 1, 0, LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte - 1); + + compress(ctx, ctx->last_block); + + fin(ctx); + get_hash(ctx, hashval); + + return LSH_SUCCESS; +} + +ANONYMOUS_NAMESPACE_END // Anonymous + +NAMESPACE_BEGIN(CryptoPP) + +extern +void LSH256_Base_Restart_SSSE3(word32* state) +{ + state[RemainingBits] = 0; + LSH256_SSSE3_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_ssse3_init(&ctx); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_ssse3_init failed"); +} + +extern +void LSH256_Base_Update_SSSE3(word32* state, const byte *input, size_t size) +{ + LSH256_SSSE3_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_ssse3_update(&ctx, input, 8*size); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_ssse3_update failed"); +} + +extern +void LSH256_Base_TruncatedFinal_SSSE3(word32* state, byte *hash, size_t) +{ + LSH256_SSSE3_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh256_ssse3_final(&ctx, hash); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_ssse3_final failed"); +} + +NAMESPACE_END + +#endif // CRYPTOPP_SSSE3_AVAILABLE diff --git a/external/ours/library/crypto/src/shared/original/lsh512.cpp b/external/ours/library/crypto/src/shared/original/lsh512.cpp new file mode 100755 index 000000000..8f24f3bad --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh512.cpp @@ -0,0 +1,893 @@ +// lsh.cpp - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + + +#include "pch.h" +#include "config.h" + +#include "lsh.h" +#include "cpu.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +/* LSH Constants */ + +const unsigned int LSH512_MSG_BLK_BYTE_LEN = 256; +// const unsigned int LSH512_MSG_BLK_BIT_LEN = 2048; +// const unsigned int LSH512_CV_BYTE_LEN = 128; +const unsigned int LSH512_HASH_VAL_MAX_BYTE_LEN = 64; + +// const unsigned int MSG_BLK_WORD_LEN = 32; +const unsigned int CV_WORD_LEN = 16; +const unsigned int CONST_WORD_LEN = 8; +const unsigned int HASH_VAL_MAX_WORD_LEN = 8; +const unsigned int NUM_STEPS = 28; + +const unsigned int ROT_EVEN_ALPHA = 23; +const unsigned int ROT_EVEN_BETA = 59; +const unsigned int ROT_ODD_ALPHA = 7; +const unsigned int ROT_ODD_BETA = 3; + +const unsigned int LSH_TYPE_512_512 = 0x0010040; +const unsigned int LSH_TYPE_512_384 = 0x0010030; +const unsigned int LSH_TYPE_512_256 = 0x0010020; +const unsigned int LSH_TYPE_512_224 = 0x001001C; + +// const unsigned int LSH_TYPE_384 = LSH_TYPE_512_384; +// const unsigned int LSH_TYPE_512 = LSH_TYPE_512_512; + +/* Error Code */ + +const unsigned int LSH_SUCCESS = 0x0; +// const unsigned int LSH_ERR_NULL_PTR = 0x2401; +// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402; +const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403; +const unsigned int LSH_ERR_INVALID_STATE = 0x2404; + +/* Index into our state array */ + +const unsigned int AlgorithmType = 80; +const unsigned int RemainingBits = 81; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(LSH) + +/* -------------------------------------------------------- * +* LSH: iv +* -------------------------------------------------------- */ + +//extern const word64 LSH512_IV224[CV_WORD_LEN]; +//extern const word64 LSH512_IV256[CV_WORD_LEN]; +//extern const word64 LSH512_IV384[CV_WORD_LEN]; +//extern const word64 LSH512_IV512[CV_WORD_LEN]; +//extern const word64 LSH512_StepConstants[CONST_WORD_LEN * NUM_STEPS]; + +CRYPTOPP_ALIGN_DATA(32) +extern +const word64 LSH512_IV224[CV_WORD_LEN] = { + W64LIT(0x0C401E9FE8813A55), W64LIT(0x4A5F446268FD3D35), W64LIT(0xFF13E452334F612A), W64LIT(0xF8227661037E354A), + W64LIT(0xA5F223723C9CA29D), W64LIT(0x95D965A11AED3979), W64LIT(0x01E23835B9AB02CC), W64LIT(0x52D49CBAD5B30616), + W64LIT(0x9E5C2027773F4ED3), W64LIT(0x66A5C8801925B701), W64LIT(0x22BBC85B4C6779D9), W64LIT(0xC13171A42C559C23), + W64LIT(0x31E2B67D25BE3813), W64LIT(0xD522C4DEED8E4D83), W64LIT(0xA79F5509B43FBAFE), W64LIT(0xE00D2CD88B4B6C6A), +}; + +CRYPTOPP_ALIGN_DATA(32) +extern +const word64 LSH512_IV256[CV_WORD_LEN] = { + W64LIT(0x6DC57C33DF989423), W64LIT(0xD8EA7F6E8342C199), W64LIT(0x76DF8356F8603AC4), W64LIT(0x40F1B44DE838223A), + W64LIT(0x39FFE7CFC31484CD), W64LIT(0x39C4326CC5281548), W64LIT(0x8A2FF85A346045D8), W64LIT(0xFF202AA46DBDD61E), + W64LIT(0xCF785B3CD5FCDB8B), W64LIT(0x1F0323B64A8150BF), W64LIT(0xFF75D972F29EA355), W64LIT(0x2E567F30BF1CA9E1), + W64LIT(0xB596875BF8FF6DBA), W64LIT(0xFCCA39B089EF4615), W64LIT(0xECFF4017D020B4B6), W64LIT(0x7E77384C772ED802), +}; + +CRYPTOPP_ALIGN_DATA(32) +extern +const word64 LSH512_IV384[CV_WORD_LEN] = { + W64LIT(0x53156A66292808F6), W64LIT(0xB2C4F362B204C2BC), W64LIT(0xB84B7213BFA05C4E), W64LIT(0x976CEB7C1B299F73), + W64LIT(0xDF0CC63C0570AE97), W64LIT(0xDA4441BAA486CE3F), W64LIT(0x6559F5D9B5F2ACC2), W64LIT(0x22DACF19B4B52A16), + W64LIT(0xBBCDACEFDE80953A), W64LIT(0xC9891A2879725B3E), W64LIT(0x7C9FE6330237E440), W64LIT(0xA30BA550553F7431), + W64LIT(0xBB08043FB34E3E30), W64LIT(0xA0DEC48D54618EAD), W64LIT(0x150317267464BC57), W64LIT(0x32D1501FDE63DC93) +}; + +CRYPTOPP_ALIGN_DATA(32) +extern +const word64 LSH512_IV512[CV_WORD_LEN] = { + W64LIT(0xadd50f3c7f07094e), W64LIT(0xe3f3cee8f9418a4f), W64LIT(0xb527ecde5b3d0ae9), W64LIT(0x2ef6dec68076f501), + W64LIT(0x8cb994cae5aca216), W64LIT(0xfbb9eae4bba48cc7), W64LIT(0x650a526174725fea), W64LIT(0x1f9a61a73f8d8085), + W64LIT(0xb6607378173b539b), W64LIT(0x1bc99853b0c0b9ed), W64LIT(0xdf727fc19b182d47), W64LIT(0xdbef360cf893a457), + W64LIT(0x4981f5e570147e80), W64LIT(0xd00c4490ca7d3e30), W64LIT(0x5d73940c0e4ae1ec), W64LIT(0x894085e2edb2d819) +}; + +/* -------------------------------------------------------- * +* LSH: step constants +* -------------------------------------------------------- */ + +extern +const word64 LSH512_StepConstants[CONST_WORD_LEN * NUM_STEPS] = { + W64LIT(0x97884283c938982a), W64LIT(0xba1fca93533e2355), W64LIT(0xc519a2e87aeb1c03), W64LIT(0x9a0fc95462af17b1), + W64LIT(0xfc3dda8ab019a82b), W64LIT(0x02825d079a895407), W64LIT(0x79f2d0a7ee06a6f7), W64LIT(0xd76d15eed9fdf5fe), + W64LIT(0x1fcac64d01d0c2c1), W64LIT(0xd9ea5de69161790f), W64LIT(0xdebc8b6366071fc8), W64LIT(0xa9d91db711c6c94b), + W64LIT(0x3a18653ac9c1d427), W64LIT(0x84df64a223dd5b09), W64LIT(0x6cc37895f4ad9e70), W64LIT(0x448304c8d7f3f4d5), + W64LIT(0xea91134ed29383e0), W64LIT(0xc4484477f2da88e8), W64LIT(0x9b47eec96d26e8a6), W64LIT(0x82f6d4c8d89014f4), + W64LIT(0x527da0048b95fb61), W64LIT(0x644406c60138648d), W64LIT(0x303c0e8aa24c0edc), W64LIT(0xc787cda0cbe8ca19), + W64LIT(0x7ba46221661764ca), W64LIT(0x0c8cbc6acd6371ac), W64LIT(0xe336b836940f8f41), W64LIT(0x79cb9da168a50976), + W64LIT(0xd01da49021915cb3), W64LIT(0xa84accc7399cf1f1), W64LIT(0x6c4a992cee5aeb0c), W64LIT(0x4f556e6cb4b2e3e0), + W64LIT(0x200683877d7c2f45), W64LIT(0x9949273830d51db8), W64LIT(0x19eeeecaa39ed124), W64LIT(0x45693f0a0dae7fef), + W64LIT(0xedc234b1b2ee1083), W64LIT(0xf3179400d68ee399), W64LIT(0xb6e3c61b4945f778), W64LIT(0xa4c3db216796c42f), + W64LIT(0x268a0b04f9ab7465), W64LIT(0xe2705f6905f2d651), W64LIT(0x08ddb96e426ff53d), W64LIT(0xaea84917bc2e6f34), + W64LIT(0xaff6e664a0fe9470), W64LIT(0x0aab94d765727d8c), W64LIT(0x9aa9e1648f3d702e), W64LIT(0x689efc88fe5af3d3), + W64LIT(0xb0950ffea51fd98b), W64LIT(0x52cfc86ef8c92833), W64LIT(0xe69727b0b2653245), W64LIT(0x56f160d3ea9da3e2), + W64LIT(0xa6dd4b059f93051f), W64LIT(0xb6406c3cd7f00996), W64LIT(0x448b45f3ccad9ec8), W64LIT(0x079b8587594ec73b), + W64LIT(0x45a50ea3c4f9653b), W64LIT(0x22983767c1f15b85), W64LIT(0x7dbed8631797782b), W64LIT(0x485234be88418638), + W64LIT(0x842850a5329824c5), W64LIT(0xf6aca914c7f9a04c), W64LIT(0xcfd139c07a4c670c), W64LIT(0xa3210ce0a8160242), + W64LIT(0xeab3b268be5ea080), W64LIT(0xbacf9f29b34ce0a7), W64LIT(0x3c973b7aaf0fa3a8), W64LIT(0x9a86f346c9c7be80), + W64LIT(0xac78f5d7cabcea49), W64LIT(0xa355bddcc199ed42), W64LIT(0xa10afa3ac6b373db), W64LIT(0xc42ded88be1844e5), + W64LIT(0x9e661b271cff216a), W64LIT(0x8a6ec8dd002d8861), W64LIT(0xd3d2b629beb34be4), W64LIT(0x217a3a1091863f1a), + W64LIT(0x256ecda287a733f5), W64LIT(0xf9139a9e5b872fe5), W64LIT(0xac0535017a274f7c), W64LIT(0xf21b7646d65d2aa9), + W64LIT(0x048142441c208c08), W64LIT(0xf937a5dd2db5e9eb), W64LIT(0xa688dfe871ff30b7), W64LIT(0x9bb44aa217c5593b), + W64LIT(0x943c702a2edb291a), W64LIT(0x0cae38f9e2b715de), W64LIT(0xb13a367ba176cc28), W64LIT(0x0d91bd1d3387d49b), + W64LIT(0x85c386603cac940c), W64LIT(0x30dd830ae39fd5e4), W64LIT(0x2f68c85a712fe85d), W64LIT(0x4ffeecb9dd1e94d6), + W64LIT(0xd0ac9a590a0443ae), W64LIT(0xbae732dc99ccf3ea), W64LIT(0xeb70b21d1842f4d9), W64LIT(0x9f4eda50bb5c6fa8), + W64LIT(0x4949e69ce940a091), W64LIT(0x0e608dee8375ba14), W64LIT(0x983122cba118458c), W64LIT(0x4eeba696fbb36b25), + W64LIT(0x7d46f3630e47f27e), W64LIT(0xa21a0f7666c0dea4), W64LIT(0x5c22cf355b37cec4), W64LIT(0xee292b0c17cc1847), + W64LIT(0x9330838629e131da), W64LIT(0x6eee7c71f92fce22), W64LIT(0xc953ee6cb95dd224), W64LIT(0x3a923d92af1e9073), + W64LIT(0xc43a5671563a70fb), W64LIT(0xbc2985dd279f8346), W64LIT(0x7ef2049093069320), W64LIT(0x17543723e3e46035), + W64LIT(0xc3b409b00b130c6d), W64LIT(0x5d6aee6b28fdf090), W64LIT(0x1d425b26172ff6ed), W64LIT(0xcccfd041cdaf03ad), + W64LIT(0xfe90c7c790ab6cbf), W64LIT(0xe5af6304c722ca02), W64LIT(0x70f695239999b39e), W64LIT(0x6b8b5b07c844954c), + W64LIT(0x77bdb9bb1e1f7a30), W64LIT(0xc859599426ee80ed), W64LIT(0x5f9d813d4726e40a), W64LIT(0x9ca0120f7cb2b179), + W64LIT(0x8f588f583c182cbd), W64LIT(0x951267cbe9eccce7), W64LIT(0x678bb8bd334d520e), W64LIT(0xf6e662d00cd9e1b7), + W64LIT(0x357774d93d99aaa7), W64LIT(0x21b2edbb156f6eb5), W64LIT(0xfd1ebe846e0aee69), W64LIT(0x3cb2218c2f642b15), + W64LIT(0xe7e7e7945444ea4c), W64LIT(0xa77a33b5d6b9b47c), W64LIT(0xf34475f0809f6075), W64LIT(0xdd4932dce6bb99ad), + W64LIT(0xacec4e16d74451dc), W64LIT(0xd4a0a8d084de23d6), W64LIT(0x1bdd42f278f95866), W64LIT(0xeed3adbb938f4051), + W64LIT(0xcfcf7be8992f3733), W64LIT(0x21ade98c906e3123), W64LIT(0x37ba66711fffd668), W64LIT(0x267c0fc3a255478a), + W64LIT(0x993a64ee1b962e88), W64LIT(0x754979556301faaa), W64LIT(0xf920356b7251be81), W64LIT(0xc281694f22cf923f), + W64LIT(0x9f4b6481c8666b02), W64LIT(0xcf97761cfe9f5444), W64LIT(0xf220d7911fd63e9f), W64LIT(0xa28bd365f79cd1b0), + W64LIT(0xd39f5309b1c4b721), W64LIT(0xbec2ceb864fca51f), W64LIT(0x1955a0ddc410407a), W64LIT(0x43eab871f261d201), + W64LIT(0xeaafe64a2ed16da1), W64LIT(0x670d931b9df39913), W64LIT(0x12f868b0f614de91), W64LIT(0x2e5f395d946e8252), + W64LIT(0x72f25cbb767bd8f4), W64LIT(0x8191871d61a1c4dd), W64LIT(0x6ef67ea1d450ba93), W64LIT(0x2ea32a645433d344), + W64LIT(0x9a963079003f0f8b), W64LIT(0x74a0aeb9918cac7a), W64LIT(0x0b6119a70af36fa3), W64LIT(0x8d9896f202f0d480), + W64LIT(0x654f1831f254cd66), W64LIT(0x1318a47f0366a25e), W64LIT(0x65752076250b4e01), W64LIT(0xd1cd8eb888071772), + W64LIT(0x30c6a9793f4e9b25), W64LIT(0x154f684b1e3926ee), W64LIT(0x6c7ac0b1fe6312ae), W64LIT(0x262f88f4f3c5550d), + W64LIT(0xb4674a24472233cb), W64LIT(0x2bbd23826a090071), W64LIT(0xda95969b30594f66), W64LIT(0x9f5c47408f1e8a43), + W64LIT(0xf77022b88de9c055), W64LIT(0x64b7b36957601503), W64LIT(0xe73b72b06175c11a), W64LIT(0x55b87de8b91a6233), + W64LIT(0x1bb16e6b6955ff7f), W64LIT(0xe8e0a5ec7309719c), W64LIT(0x702c31cb89a8b640), W64LIT(0xfba387cfada8cde2), + W64LIT(0x6792db4677aa164c), W64LIT(0x1c6b1cc0b7751867), W64LIT(0x22ae2311d736dc01), W64LIT(0x0e3666a1d37c9588), + W64LIT(0xcd1fd9d4bf557e9a), W64LIT(0xc986925f7c7b0e84), W64LIT(0x9c5dfd55325ef6b0), W64LIT(0x9f2b577d5676b0dd), + W64LIT(0xfa6e21be21c062b3), W64LIT(0x8787dd782c8d7f83), W64LIT(0xd0d134e90e12dd23), W64LIT(0x449d087550121d96), + W64LIT(0xecf9ae9414d41967), W64LIT(0x5018f1dbf789934d), W64LIT(0xfa5b52879155a74c), W64LIT(0xca82d4d3cd278e7c), + W64LIT(0x688fdfdfe22316ad), W64LIT(0x0f6555a4ba0d030a), W64LIT(0xa2061df720f000f3), W64LIT(0xe1a57dc5622fb3da), + W64LIT(0xe6a842a8e8ed8153), W64LIT(0x690acdd3811ce09d), W64LIT(0x55adda18e6fcf446), W64LIT(0x4d57a8a0f4b60b46), + W64LIT(0xf86fbfc20539c415), W64LIT(0x74bafa5ec7100d19), W64LIT(0xa824151810f0f495), W64LIT(0x8723432791e38ebb), + W64LIT(0x8eeaeb91d66ed539), W64LIT(0x73d8a1549dfd7e06), W64LIT(0x0387f2ffe3f13a9b), W64LIT(0xa5004995aac15193), + W64LIT(0x682f81c73efdda0d), W64LIT(0x2fb55925d71d268d), W64LIT(0xcc392d2901e58a3d), W64LIT(0xaa666ab975724a42) +}; + +NAMESPACE_END // LSH +NAMESPACE_END // Crypto++ + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlFixed; +using CryptoPP::rotlConstant; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; +using CryptoPP::ConditionalByteReverse; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +using CryptoPP::LSH::LSH512_IV224; +using CryptoPP::LSH::LSH512_IV256; +using CryptoPP::LSH::LSH512_IV384; +using CryptoPP::LSH::LSH512_IV512; +using CryptoPP::LSH::LSH512_StepConstants; + +typedef byte lsh_u8; +typedef word32 lsh_u32; +typedef word64 lsh_u64; +typedef word32 lsh_uint; +typedef word32 lsh_err; +typedef word32 lsh_type; + +struct LSH512_Context +{ + LSH512_Context(word64* state, word64 algType, word64& remainingBitLength) : + cv_l(state+0), cv_r(state+8), sub_msgs(state+16), + last_block(reinterpret_cast(state+48)), + remain_databitlen(remainingBitLength), + alg_type(static_cast(algType)) {} + + lsh_u64* cv_l; // start of our state block + lsh_u64* cv_r; + lsh_u64* sub_msgs; + lsh_u8* last_block; + lsh_u64& remain_databitlen; + lsh_type alg_type; +}; + +struct LSH512_Internal +{ + LSH512_Internal(word64* state) : + submsg_e_l(state+16), submsg_e_r(state+24), + submsg_o_l(state+32), submsg_o_r(state+40) { } + + lsh_u64* submsg_e_l; /* even left sub-message */ + lsh_u64* submsg_e_r; /* even right sub-message */ + lsh_u64* submsg_o_l; /* odd left sub-message */ + lsh_u64* submsg_o_r; /* odd right sub-message */ +}; + +const lsh_u32 g_gamma512[8] = { 0, 16, 32, 48, 8, 24, 40, 56 }; + +/* LSH AlgType Macro */ + +inline bool LSH_IS_LSH512(lsh_uint val) { + return (val & 0xf0000) == 0x10000; +} + +inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) { + return val >> 24; +} + +inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) { + return val & 0xffff; +} + +inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) { + return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val); +} + +inline lsh_u64 loadLE64(lsh_u64 v) { + return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v); +} + +lsh_u64 ROTL64(lsh_u64 x, lsh_u32 r) { + return rotlFixed(x, r); +} + +// Original code relied upon unaligned lsh_u64 buffer +inline void load_msg_blk(LSH512_Internal* i_state, const lsh_u8* msgblk) +{ + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + typedef GetBlock InBlock; + + InBlock input(msgblk); + input(submsg_e_l[0])(submsg_e_l[1])(submsg_e_l[2])(submsg_e_l[3]) + (submsg_e_l[4])(submsg_e_l[5])(submsg_e_l[6])(submsg_e_l[7]) + (submsg_e_r[0])(submsg_e_r[1])(submsg_e_r[2])(submsg_e_r[3]) + (submsg_e_r[4])(submsg_e_r[5])(submsg_e_r[6])(submsg_e_r[7]) + (submsg_o_l[0])(submsg_o_l[1])(submsg_o_l[2])(submsg_o_l[3]) + (submsg_o_l[4])(submsg_o_l[5])(submsg_o_l[6])(submsg_o_l[7]) + (submsg_o_r[0])(submsg_o_r[1])(submsg_o_r[2])(submsg_o_r[3]) + (submsg_o_r[4])(submsg_o_r[5])(submsg_o_r[6])(submsg_o_r[7]); +} + +inline void msg_exp_even(LSH512_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + lsh_u64 temp; + temp = submsg_e_l[0]; + submsg_e_l[0] = submsg_o_l[0] + submsg_e_l[3]; + submsg_e_l[3] = submsg_o_l[3] + submsg_e_l[1]; + submsg_e_l[1] = submsg_o_l[1] + submsg_e_l[2]; + submsg_e_l[2] = submsg_o_l[2] + temp; + temp = submsg_e_l[4]; + submsg_e_l[4] = submsg_o_l[4] + submsg_e_l[7]; + submsg_e_l[7] = submsg_o_l[7] + submsg_e_l[6]; + submsg_e_l[6] = submsg_o_l[6] + submsg_e_l[5]; + submsg_e_l[5] = submsg_o_l[5] + temp; + temp = submsg_e_r[0]; + submsg_e_r[0] = submsg_o_r[0] + submsg_e_r[3]; + submsg_e_r[3] = submsg_o_r[3] + submsg_e_r[1]; + submsg_e_r[1] = submsg_o_r[1] + submsg_e_r[2]; + submsg_e_r[2] = submsg_o_r[2] + temp; + temp = submsg_e_r[4]; + submsg_e_r[4] = submsg_o_r[4] + submsg_e_r[7]; + submsg_e_r[7] = submsg_o_r[7] + submsg_e_r[6]; + submsg_e_r[6] = submsg_o_r[6] + submsg_e_r[5]; + submsg_e_r[5] = submsg_o_r[5] + temp; +} + +inline void msg_exp_odd(LSH512_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + lsh_u64 temp; + temp = submsg_o_l[0]; + submsg_o_l[0] = submsg_e_l[0] + submsg_o_l[3]; + submsg_o_l[3] = submsg_e_l[3] + submsg_o_l[1]; + submsg_o_l[1] = submsg_e_l[1] + submsg_o_l[2]; + submsg_o_l[2] = submsg_e_l[2] + temp; + temp = submsg_o_l[4]; + submsg_o_l[4] = submsg_e_l[4] + submsg_o_l[7]; + submsg_o_l[7] = submsg_e_l[7] + submsg_o_l[6]; + submsg_o_l[6] = submsg_e_l[6] + submsg_o_l[5]; + submsg_o_l[5] = submsg_e_l[5] + temp; + temp = submsg_o_r[0]; + submsg_o_r[0] = submsg_e_r[0] + submsg_o_r[3]; + submsg_o_r[3] = submsg_e_r[3] + submsg_o_r[1]; + submsg_o_r[1] = submsg_e_r[1] + submsg_o_r[2]; + submsg_o_r[2] = submsg_e_r[2] + temp; + temp = submsg_o_r[4]; + submsg_o_r[4] = submsg_e_r[4] + submsg_o_r[7]; + submsg_o_r[7] = submsg_e_r[7] + submsg_o_r[6]; + submsg_o_r[6] = submsg_e_r[6] + submsg_o_r[5]; + submsg_o_r[5] = submsg_e_r[5] + temp; +} + +inline void load_sc(const lsh_u64** p_const_v, size_t i) +{ + *p_const_v = &LSH512_StepConstants[i]; +} + +inline void msg_add_even(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + + cv_l[0] ^= submsg_e_l[0]; cv_l[1] ^= submsg_e_l[1]; + cv_l[2] ^= submsg_e_l[2]; cv_l[3] ^= submsg_e_l[3]; + cv_l[4] ^= submsg_e_l[4]; cv_l[5] ^= submsg_e_l[5]; + cv_l[6] ^= submsg_e_l[6]; cv_l[7] ^= submsg_e_l[7]; + cv_r[0] ^= submsg_e_r[0]; cv_r[1] ^= submsg_e_r[1]; + cv_r[2] ^= submsg_e_r[2]; cv_r[3] ^= submsg_e_r[3]; + cv_r[4] ^= submsg_e_r[4]; cv_r[5] ^= submsg_e_r[5]; + cv_r[6] ^= submsg_e_r[6]; cv_r[7] ^= submsg_e_r[7]; +} + +inline void msg_add_odd(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + cv_l[0] ^= submsg_o_l[0]; cv_l[1] ^= submsg_o_l[1]; + cv_l[2] ^= submsg_o_l[2]; cv_l[3] ^= submsg_o_l[3]; + cv_l[4] ^= submsg_o_l[4]; cv_l[5] ^= submsg_o_l[5]; + cv_l[6] ^= submsg_o_l[6]; cv_l[7] ^= submsg_o_l[7]; + cv_r[0] ^= submsg_o_r[0]; cv_r[1] ^= submsg_o_r[1]; + cv_r[2] ^= submsg_o_r[2]; cv_r[3] ^= submsg_o_r[3]; + cv_r[4] ^= submsg_o_r[4]; cv_r[5] ^= submsg_o_r[5]; + cv_r[6] ^= submsg_o_r[6]; cv_r[7] ^= submsg_o_r[7]; +} + +inline void add_blk(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + cv_l[0] += cv_r[0]; + cv_l[1] += cv_r[1]; + cv_l[2] += cv_r[2]; + cv_l[3] += cv_r[3]; + cv_l[4] += cv_r[4]; + cv_l[5] += cv_r[5]; + cv_l[6] += cv_r[6]; + cv_l[7] += cv_r[7]; +} + +template +inline void rotate_blk(lsh_u64 cv[8]) +{ + cv[0] = rotlConstant(cv[0]); + cv[1] = rotlConstant(cv[1]); + cv[2] = rotlConstant(cv[2]); + cv[3] = rotlConstant(cv[3]); + cv[4] = rotlConstant(cv[4]); + cv[5] = rotlConstant(cv[5]); + cv[6] = rotlConstant(cv[6]); + cv[7] = rotlConstant(cv[7]); +} + +inline void xor_with_const(lsh_u64 cv_l[8], const lsh_u64* const_v) +{ + cv_l[0] ^= const_v[0]; + cv_l[1] ^= const_v[1]; + cv_l[2] ^= const_v[2]; + cv_l[3] ^= const_v[3]; + cv_l[4] ^= const_v[4]; + cv_l[5] ^= const_v[5]; + cv_l[6] ^= const_v[6]; + cv_l[7] ^= const_v[7]; +} + +inline void rotate_msg_gamma(lsh_u64 cv_r[8]) +{ + cv_r[1] = ROTL64(cv_r[1], g_gamma512[1]); + cv_r[2] = ROTL64(cv_r[2], g_gamma512[2]); + cv_r[3] = ROTL64(cv_r[3], g_gamma512[3]); + cv_r[4] = ROTL64(cv_r[4], g_gamma512[4]); + cv_r[5] = ROTL64(cv_r[5], g_gamma512[5]); + cv_r[6] = ROTL64(cv_r[6], g_gamma512[6]); + cv_r[7] = ROTL64(cv_r[7], g_gamma512[7]); +} + +inline void word_perm(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + lsh_u64 temp; + temp = cv_l[0]; + cv_l[0] = cv_l[6]; + cv_l[6] = cv_r[6]; + cv_r[6] = cv_r[2]; + cv_r[2] = cv_l[1]; + cv_l[1] = cv_l[4]; + cv_l[4] = cv_r[4]; + cv_r[4] = cv_r[0]; + cv_r[0] = cv_l[2]; + cv_l[2] = cv_l[5]; + cv_l[5] = cv_r[7]; + cv_r[7] = cv_r[1]; + cv_r[1] = temp; + temp = cv_l[3]; + cv_l[3] = cv_l[7]; + cv_l[7] = cv_r[5]; + cv_r[5] = cv_r[3]; + cv_r[3] = temp; +}; + +/* -------------------------------------------------------- * +* step function +* -------------------------------------------------------- */ + +template +inline void mix(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 const_v[8]) +{ + add_blk(cv_l, cv_r); + rotate_blk(cv_l); + xor_with_const(cv_l, const_v); + add_blk(cv_r, cv_l); + rotate_blk(cv_r); + add_blk(cv_l, cv_r); + rotate_msg_gamma(cv_r); +} + +/* -------------------------------------------------------- * +* compression function +* -------------------------------------------------------- */ + +inline void compress(LSH512_Context* ctx, const lsh_u8 pdMsgBlk[LSH512_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + LSH512_Internal s_state(ctx->cv_l); + LSH512_Internal* i_state = &s_state; + + const lsh_u64* const_v = NULL; + lsh_u64 *cv_l = ctx->cv_l; + lsh_u64 *cv_r = ctx->cv_r; + + load_msg_blk(i_state, pdMsgBlk); + + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 0); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + for (size_t i = 1; i < NUM_STEPS / 2; i++) + { + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_exp_odd(i_state); + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); +} + +/* -------------------------------------------------------- */ + +inline void load_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 iv[16]) +{ + cv_l[0] = iv[0]; + cv_l[1] = iv[1]; + cv_l[2] = iv[2]; + cv_l[3] = iv[3]; + cv_l[4] = iv[4]; + cv_l[5] = iv[5]; + cv_l[6] = iv[6]; + cv_l[7] = iv[7]; + cv_r[0] = iv[8]; + cv_r[1] = iv[9]; + cv_r[2] = iv[10]; + cv_r[3] = iv[11]; + cv_r[4] = iv[12]; + cv_r[5] = iv[13]; + cv_r[6] = iv[14]; + cv_r[7] = iv[15]; +} + +inline void zero_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + memset(cv_l, 0, 8*sizeof(lsh_u64)); + memset(cv_r, 0, 8*sizeof(lsh_u64)); +} + +inline void zero_submsgs(LSH512_Context* ctx) +{ + lsh_u64* sub_msgs = ctx->sub_msgs; + + memset(sub_msgs, 0x00, 32*sizeof(lsh_u64)); +} + +inline void init224(LSH512_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV224); +} + +inline void init256(LSH512_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV256); +} + +inline void init384(LSH512_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV384); +} + +inline void init512(LSH512_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV512); +} + +/* -------------------------------------------------------- */ + +inline void fin(LSH512_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + for (size_t i = 0; i < HASH_VAL_MAX_WORD_LEN; i++){ + ctx->cv_l[i] = loadLE64(ctx->cv_l[i] ^ ctx->cv_r[i]); + } +} + +/* -------------------------------------------------------- */ + +inline void get_hash(LSH512_Context* ctx, lsh_u8* pbHashVal) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + CRYPTOPP_ASSERT(pbHashVal != NULLPTR); + + lsh_uint alg_type = ctx->alg_type; + lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type); + lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type); + + // Multiplying by looks odd... + memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len); + if (hash_val_bit_len){ + pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len); + } +} + +/* -------------------------------------------------------- */ + +lsh_err lsh512_init(LSH512_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + lsh_u32 alg_type = ctx->alg_type; + const lsh_u64* const_v = NULL; + ctx->remain_databitlen = 0; + + switch (alg_type){ + case LSH_TYPE_512_512: + init512(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_384: + init384(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_256: + init256(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_224: + init224(ctx); + return LSH_SUCCESS; + default: + break; + } + + lsh_u64* cv_l = ctx->cv_l; + lsh_u64* cv_r = ctx->cv_r; + + zero_iv(cv_l, cv_r); + cv_l[0] = LSH512_HASH_VAL_MAX_BYTE_LEN; + cv_l[1] = LSH_GET_HASHBIT(alg_type); + + for (size_t i = 0; i < NUM_STEPS / 2; i++) + { + //Mix + load_sc(&const_v, i * 16); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + load_sc(&const_v, i * 16 + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + return LSH_SUCCESS; +} + +lsh_err lsh512_update(LSH512_Context* ctx, const lsh_u8* data, size_t databitlen) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(databitlen % 8 == 0); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + if (databitlen == 0){ + return LSH_SUCCESS; + } + + // We are byte oriented. tail bits will always be 0. + size_t databytelen = databitlen >> 3; + // lsh_uint pos2 = databitlen & 0x7; + const size_t pos2 = 0; + + size_t remain_msg_byte = static_cast(ctx->remain_databitlen >> 3); + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + if (remain_msg_bit > 0){ + return LSH_ERR_INVALID_DATABITLEN; + } + + if (databytelen + remain_msg_byte < LSH512_MSG_BLK_BYTE_LEN){ + memcpy(ctx->last_block + remain_msg_byte, data, databytelen); + ctx->remain_databitlen += (lsh_uint)databitlen; + remain_msg_byte += (lsh_uint)databytelen; + if (pos2){ + ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + } + return LSH_SUCCESS; + } + + if (remain_msg_byte > 0){ + size_t more_byte = LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte; + memcpy(ctx->last_block + remain_msg_byte, data, more_byte); + compress(ctx, ctx->last_block); + data += more_byte; + databytelen -= more_byte; + remain_msg_byte = 0; + ctx->remain_databitlen = 0; + } + + while (databytelen >= LSH512_MSG_BLK_BYTE_LEN) + { + // This call to compress caused some trouble. + // The data pointer can become unaligned in the + // previous block. + compress(ctx, data); + data += LSH512_MSG_BLK_BYTE_LEN; + databytelen -= LSH512_MSG_BLK_BYTE_LEN; + } + + if (databytelen > 0){ + memcpy(ctx->last_block, data, databytelen); + ctx->remain_databitlen = (lsh_uint)(databytelen << 3); + } + + if (pos2){ + ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + ctx->remain_databitlen += pos2; + } + return LSH_SUCCESS; +} + +lsh_err lsh512_final(LSH512_Context* ctx, lsh_u8* hashval) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(hashval != NULLPTR); + + // We are byte oriented. tail bits will always be 0. + size_t remain_msg_byte = static_cast(ctx->remain_databitlen >> 3); + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + + if (remain_msg_bit){ + ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit)); + } + else{ + ctx->last_block[remain_msg_byte] = 0x80; + } + memset(ctx->last_block + remain_msg_byte + 1, 0, LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte - 1); + + compress(ctx, ctx->last_block); + + fin(ctx); + get_hash(ctx, hashval); + + return LSH_SUCCESS; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_ENABLE_64BIT_SSE) +# if defined(CRYPTOPP_AVX2_AVAILABLE) + extern void LSH512_Base_Restart_AVX2(word64* state); + extern void LSH512_Base_Update_AVX2(word64* state, const byte *input, size_t size); + extern void LSH512_Base_TruncatedFinal_AVX2(word64* state, byte *hash, size_t size); +# endif +# if defined(CRYPTOPP_SSSE3_AVAILABLE) + extern void LSH512_Base_Restart_SSSE3(word64* state); + extern void LSH512_Base_Update_SSSE3(word64* state, const byte *input, size_t size); + extern void LSH512_Base_TruncatedFinal_SSSE3(word64* state, byte *hash, size_t size); +# endif +#endif + +std::string LSH512_Base::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_ENABLE_64BIT_SSE) +#if defined(CRYPTOPP_AVX2_AVAILABLE) + if (HasAVX2()) + return "AVX2"; + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return "SSSE3"; + else +#endif +#endif // CRYPTOPP_ENABLE_64BIT_SSE + + return "C++"; +} + +void LSH512_Base_Restart_CXX(word64* state) +{ + state[RemainingBits] = 0; + LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_init(&ctx); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_init failed"); +} + +void LSH512_Base_Update_CXX(word64* state, const byte *input, size_t size) +{ + LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_update(&ctx, input, 8*size); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_update failed"); +} + +void LSH512_Base_TruncatedFinal_CXX(word64* state, byte *hash, size_t) +{ + LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_final(&ctx, hash); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_final failed"); +} + + +void LSH512_Base::Restart() +{ +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasAVX2()) + LSH512_Base_Restart_AVX2(m_state); + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasSSSE3()) + LSH512_Base_Restart_SSSE3(m_state); + else +#endif + + LSH512_Base_Restart_CXX(m_state); +} + +void LSH512_Base::Update(const byte *input, size_t size) +{ + CRYPTOPP_ASSERT(input != NULLPTR); + CRYPTOPP_ASSERT(size); + +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasAVX2()) + LSH512_Base_Update_AVX2(m_state, input, size); + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasSSSE3()) + LSH512_Base_Update_SSSE3(m_state, input, size); + else +#endif + + LSH512_Base_Update_CXX(m_state, input, size); +} + +void LSH512_Base::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + ThrowIfInvalidTruncatedSize(size); + + // TODO: determine if LSH512 supports truncated hashes. See the code + // in get_hash(), where a bit-length is added to the last output + // byte of the hash function. + byte fullHash[LSH512_HASH_VAL_MAX_BYTE_LEN]; + bool copyOut = (size < DigestSize()); + +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasAVX2()) + LSH512_Base_TruncatedFinal_AVX2(m_state, copyOut ? fullHash : hash, size); + else +#endif +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + if (HasSSSE3()) + LSH512_Base_TruncatedFinal_SSSE3(m_state, copyOut ? fullHash : hash, size); + else +#endif + + LSH512_Base_TruncatedFinal_CXX(m_state, copyOut ? fullHash : hash, size); + + if (copyOut) + memcpy(hash, fullHash, size); + + Restart(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/lsh512_avx.cpp b/external/ours/library/crypto/src/shared/original/lsh512_avx.cpp new file mode 100755 index 000000000..5065967d0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh512_avx.cpp @@ -0,0 +1,760 @@ +// lsh.cpp - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + +#include "pch.h" +#include "config.h" + +#include "lsh.h" +#include "misc.h" + +#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + +#if defined(CRYPTOPP_AVX2_AVAILABLE) +# include +# include +#endif + +// GCC at 4.5. Clang is unknown. Also see https://stackoverflow.com/a/42493893. +#if (CRYPTOPP_GCC_VERSION >= 40500) +# include +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +/* LSH Constants */ + +const unsigned int LSH512_MSG_BLK_BYTE_LEN = 256; +// const unsigned int LSH512_MSG_BLK_BIT_LEN = 2048; +// const unsigned int LSH512_CV_BYTE_LEN = 128; +const unsigned int LSH512_HASH_VAL_MAX_BYTE_LEN = 64; + +// const unsigned int MSG_BLK_WORD_LEN = 32; +const unsigned int CV_WORD_LEN = 16; +const unsigned int CONST_WORD_LEN = 8; +// const unsigned int HASH_VAL_MAX_WORD_LEN = 8; +const unsigned int NUM_STEPS = 28; + +const unsigned int ROT_EVEN_ALPHA = 23; +const unsigned int ROT_EVEN_BETA = 59; +const unsigned int ROT_ODD_ALPHA = 7; +const unsigned int ROT_ODD_BETA = 3; + +const unsigned int LSH_TYPE_512_512 = 0x0010040; +const unsigned int LSH_TYPE_512_384 = 0x0010030; +const unsigned int LSH_TYPE_512_256 = 0x0010020; +const unsigned int LSH_TYPE_512_224 = 0x001001C; + +// const unsigned int LSH_TYPE_384 = LSH_TYPE_512_384; +// const unsigned int LSH_TYPE_512 = LSH_TYPE_512_512; + +/* Error Code */ + +const unsigned int LSH_SUCCESS = 0x0; +// const unsigned int LSH_ERR_NULL_PTR = 0x2401; +// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402; +const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403; +const unsigned int LSH_ERR_INVALID_STATE = 0x2404; + +/* Index into our state array */ + +const unsigned int AlgorithmType = 80; +const unsigned int RemainingBits = 81; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(LSH) + +// lsh512.cpp +extern const word64 LSH512_IV224[CV_WORD_LEN]; +extern const word64 LSH512_IV256[CV_WORD_LEN]; +extern const word64 LSH512_IV384[CV_WORD_LEN]; +extern const word64 LSH512_IV512[CV_WORD_LEN]; +extern const word64 LSH512_StepConstants[CONST_WORD_LEN * NUM_STEPS]; + +NAMESPACE_END // LSH +NAMESPACE_END // Crypto++ + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlFixed; +using CryptoPP::rotlConstant; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; +using CryptoPP::ConditionalByteReverse; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +using CryptoPP::LSH::LSH512_IV224; +using CryptoPP::LSH::LSH512_IV256; +using CryptoPP::LSH::LSH512_IV384; +using CryptoPP::LSH::LSH512_IV512; +using CryptoPP::LSH::LSH512_StepConstants; + +typedef byte lsh_u8; +typedef word32 lsh_u32; +typedef word64 lsh_u64; +typedef word32 lsh_uint; +typedef word32 lsh_err; +typedef word32 lsh_type; + +struct LSH512_AVX2_Context +{ + LSH512_AVX2_Context(word64* state, word64 algType, word64& remainingBitLength) : + cv_l(state+0), cv_r(state+8), sub_msgs(state+16), + last_block(reinterpret_cast(state+48)), + remain_databitlen(remainingBitLength), + alg_type(static_cast(algType)) {} + + lsh_u64* cv_l; // start of our state block + lsh_u64* cv_r; + lsh_u64* sub_msgs; + lsh_u8* last_block; + lsh_u64& remain_databitlen; + lsh_type alg_type; +}; + +struct LSH512_AVX2_Internal +{ + LSH512_AVX2_Internal(word64* state) : + submsg_e_l(state+16), submsg_e_r(state+24), + submsg_o_l(state+32), submsg_o_r(state+40) { } + + lsh_u64* submsg_e_l; /* even left sub-message */ + lsh_u64* submsg_e_r; /* even right sub-message */ + lsh_u64* submsg_o_l; /* odd left sub-message */ + lsh_u64* submsg_o_r; /* odd right sub-message */ +}; + +// Zero the upper 128 bits of all YMM registers on exit. +// It avoids AVX state transition penalties when saving state. +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735 +// makes using zeroupper a little tricky. + +struct AVX_Cleanup +{ + ~AVX_Cleanup() { + _mm256_zeroupper(); + } +}; + +// const lsh_u32 g_gamma512[8] = { 0, 16, 32, 48, 8, 24, 40, 56 }; + +/* LSH AlgType Macro */ + +inline bool LSH_IS_LSH512(lsh_uint val) { + return (val & 0xf0000) == 0x10000; +} + +inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) { + return val >> 24; +} + +inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) { + return val & 0xffff; +} + +inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) { + return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val); +} + +inline lsh_u64 loadLE64(lsh_u64 v) { + return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v); +} + +lsh_u64 ROTL64(lsh_u64 x, lsh_u32 r) { + return rotlFixed(x, r); +} + +// Original code relied upon unaligned lsh_u64 buffer +inline void load_msg_blk(LSH512_AVX2_Internal* i_state, const lsh_u8 msgblk[LSH512_MSG_BLK_BYTE_LEN]) +{ + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + _mm256_storeu_si256(M256_CAST(submsg_e_l+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+0))); + _mm256_storeu_si256(M256_CAST(submsg_e_l+4), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+32))); + + _mm256_storeu_si256(M256_CAST(submsg_e_r+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+64))); + _mm256_storeu_si256(M256_CAST(submsg_e_r+4), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+96))); + + _mm256_storeu_si256(M256_CAST(submsg_o_l+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+128))); + _mm256_storeu_si256(M256_CAST(submsg_o_l+4), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+160))); + + _mm256_storeu_si256(M256_CAST(submsg_o_r+0), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+192))); + _mm256_storeu_si256(M256_CAST(submsg_o_r+4), + _mm256_loadu_si256(CONST_M256_CAST(msgblk+224))); +} + +inline void msg_exp_even(LSH512_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + _mm256_storeu_si256(M256_CAST(submsg_e_l+0), _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+0)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+0)), + _MM_SHUFFLE(1,0,2,3)))); + _mm256_storeu_si256(M256_CAST(submsg_e_l+4), _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+4)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+4)), + _MM_SHUFFLE(2,1,0,3)))); + + _mm256_storeu_si256(M256_CAST(submsg_e_r+0), _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+0)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+0)), + _MM_SHUFFLE(1,0,2,3)))); + _mm256_storeu_si256(M256_CAST(submsg_e_r+4), _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+4)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+4)), + _MM_SHUFFLE(2,1,0,3)))); +} + +inline void msg_exp_odd(LSH512_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + _mm256_storeu_si256(M256_CAST(submsg_o_l+0), + _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+0)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+0)), + _MM_SHUFFLE(1,0,2,3)))); + _mm256_storeu_si256(M256_CAST(submsg_o_l+4), + _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+4)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+4)), + _MM_SHUFFLE(2,1,0,3)))); + + _mm256_storeu_si256(M256_CAST(submsg_o_r+0), + _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+0)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+0)), + _MM_SHUFFLE(1,0,2,3)))); + _mm256_storeu_si256(M256_CAST(submsg_o_r+4), + _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+4)), + _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+4)), + _MM_SHUFFLE(2,1,0,3)))); +} + +inline void load_sc(const lsh_u64** p_const_v, size_t i) +{ + *p_const_v = &LSH512_StepConstants[i]; +} + +inline void msg_add_even(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l)))); + _mm256_storeu_si256(M256_CAST(cv_r), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_r)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r)))); + + _mm256_storeu_si256(M256_CAST(cv_l+4), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+4)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_l+4)))); + _mm256_storeu_si256(M256_CAST(cv_r+4), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+4)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_e_r+4)))); +} + +inline void msg_add_odd(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_AVX2_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l)))); + _mm256_storeu_si256(M256_CAST(cv_r), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_r)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r)))); + + _mm256_storeu_si256(M256_CAST(cv_l+4), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+4)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_l+4)))); + _mm256_storeu_si256(M256_CAST(cv_r+4), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+4)), + _mm256_loadu_si256(CONST_M256_CAST(submsg_o_r+4)))); +} + +inline void add_blk(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(cv_r)))); + _mm256_storeu_si256(M256_CAST(cv_l+4), _mm256_add_epi64( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+4)), + _mm256_loadu_si256(CONST_M256_CAST(cv_r+4)))); +} + +template +inline void rotate_blk(lsh_u64 cv[8]) +{ + _mm256_storeu_si256(M256_CAST(cv), _mm256_or_si256( + _mm256_slli_epi64(_mm256_loadu_si256(CONST_M256_CAST(cv)), R), + _mm256_srli_epi64(_mm256_loadu_si256(CONST_M256_CAST(cv)), 64-R))); + _mm256_storeu_si256(M256_CAST(cv+4), _mm256_or_si256( + _mm256_slli_epi64(_mm256_loadu_si256(CONST_M256_CAST(cv+4)), R), + _mm256_srli_epi64(_mm256_loadu_si256(CONST_M256_CAST(cv+4)), 64-R))); +} + +inline void xor_with_const(lsh_u64 cv_l[8], const lsh_u64 const_v[8]) +{ + _mm256_storeu_si256(M256_CAST(cv_l), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l)), + _mm256_loadu_si256(CONST_M256_CAST(const_v)))); + _mm256_storeu_si256(M256_CAST(cv_l+4), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+4)), + _mm256_loadu_si256(CONST_M256_CAST(const_v+4)))); +} + +inline void rotate_msg_gamma(lsh_u64 cv_r[8]) +{ + // g_gamma512[8] = { 0, 16, 32, 48, 8, 24, 40, 56 }; + _mm256_storeu_si256(M256_CAST(cv_r+0), + _mm256_shuffle_epi8( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+0)), + _mm256_set_epi8( + /* hi lane */ 9,8,15,14, 13,12,11,10, 3,2,1,0, 7,6,5,4, + /* lo lane */ 13,12,11,10, 9,8,15,14, 7,6,5,4, 3,2,1,0))); + _mm256_storeu_si256(M256_CAST(cv_r+4), + _mm256_shuffle_epi8( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+4)), + _mm256_set_epi8( + /* hi lane */ 8,15,14,13, 12,11,10,9, 2,1,0,7, 6,5,4,3, + /* lo lane */ 12,11,10,9, 8,15,14,13, 6,5,4,3, 2,1,0,7))); +} + +inline void word_perm(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + __m256i temp[2]; + _mm256_storeu_si256(M256_CAST(cv_l+0), _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+0)), _MM_SHUFFLE(3,1,0,2))); + _mm256_storeu_si256(M256_CAST(cv_l+4), _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(cv_l+4)), _MM_SHUFFLE(3,1,0,2))); + _mm256_storeu_si256(M256_CAST(cv_r+0), _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+0)), _MM_SHUFFLE(1,2,3,0))); + _mm256_storeu_si256(M256_CAST(cv_r+4), _mm256_permute4x64_epi64( + _mm256_loadu_si256(CONST_M256_CAST(cv_r+4)), _MM_SHUFFLE(1,2,3,0))); + + temp[0] = _mm256_loadu_si256(CONST_M256_CAST(cv_l+0)); + temp[1] = _mm256_loadu_si256(CONST_M256_CAST(cv_r+0)); + + _mm256_storeu_si256(M256_CAST(cv_l+0), + _mm256_loadu_si256(CONST_M256_CAST(cv_l+4))); + _mm256_storeu_si256(M256_CAST(cv_l+4), + _mm256_loadu_si256(CONST_M256_CAST(cv_r+4))); + + _mm256_storeu_si256(M256_CAST(cv_r+0), temp[0]); + _mm256_storeu_si256(M256_CAST(cv_r+4), temp[1]); +}; + +/* -------------------------------------------------------- * +* step function +* -------------------------------------------------------- */ + +template +inline void mix(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 const_v[8]) +{ + add_blk(cv_l, cv_r); + rotate_blk(cv_l); + xor_with_const(cv_l, const_v); + add_blk(cv_r, cv_l); + rotate_blk(cv_r); + add_blk(cv_l, cv_r); + rotate_msg_gamma(cv_r); +} + +/* -------------------------------------------------------- * +* compression function +* -------------------------------------------------------- */ + +inline void compress(LSH512_AVX2_Context* ctx, const lsh_u8 pdMsgBlk[LSH512_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + LSH512_AVX2_Internal s_state(ctx->cv_l); + LSH512_AVX2_Internal* i_state = &s_state; + + const lsh_u64* const_v = NULL; + lsh_u64 *cv_l = ctx->cv_l; + lsh_u64 *cv_r = ctx->cv_r; + + load_msg_blk(i_state, pdMsgBlk); + + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 0); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + for (size_t i = 1; i < NUM_STEPS / 2; i++) + { + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_exp_odd(i_state); + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); +} + +/* -------------------------------------------------------- */ + +inline void load_iv(word64 cv_l[8], word64 cv_r[8], const word64 iv[16]) +{ + // The IV's are 32-byte aligned so we can use aligned loads. + _mm256_storeu_si256(M256_CAST(cv_l+0), + _mm256_load_si256(CONST_M256_CAST(iv+0))); + _mm256_storeu_si256(M256_CAST(cv_l+4), + _mm256_load_si256(CONST_M256_CAST(iv+4))); + + _mm256_storeu_si256(M256_CAST(cv_r+0), + _mm256_load_si256(CONST_M256_CAST(iv+8))); + _mm256_storeu_si256(M256_CAST(cv_r+4), + _mm256_load_si256(CONST_M256_CAST(iv+12))); +} + +inline void zero_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + _mm256_storeu_si256(M256_CAST(cv_l+0), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(cv_l+4), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(cv_r+0), _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(cv_r+4), _mm256_setzero_si256()); +} + +inline void zero_submsgs(LSH512_AVX2_Context* ctx) +{ + lsh_u64* sub_msgs = ctx->sub_msgs; + + _mm256_storeu_si256(M256_CAST(sub_msgs+ 0), + _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(sub_msgs+ 4), + _mm256_setzero_si256()); + + _mm256_storeu_si256(M256_CAST(sub_msgs+ 8), + _mm256_setzero_si256()); + _mm256_storeu_si256(M256_CAST(sub_msgs+12), + _mm256_setzero_si256()); +} + +inline void init224(LSH512_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV224); +} + +inline void init256(LSH512_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV256); +} + +inline void init384(LSH512_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV384); +} + +inline void init512(LSH512_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV512); +} + +/* -------------------------------------------------------- */ + +inline void fin(LSH512_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + _mm256_storeu_si256(M256_CAST(ctx->cv_l+0), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(ctx->cv_l+0)), + _mm256_loadu_si256(CONST_M256_CAST(ctx->cv_r+0)))); + + _mm256_storeu_si256(M256_CAST(ctx->cv_l+4), _mm256_xor_si256( + _mm256_loadu_si256(CONST_M256_CAST(ctx->cv_l+4)), + _mm256_loadu_si256(CONST_M256_CAST(ctx->cv_r+4)))); +} + +/* -------------------------------------------------------- */ + +inline void get_hash(LSH512_AVX2_Context* ctx, lsh_u8* pbHashVal) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + CRYPTOPP_ASSERT(pbHashVal != NULLPTR); + + lsh_uint alg_type = ctx->alg_type; + lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type); + lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type); + + // Multiplying by sizeof(lsh_u8) looks odd... + memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len); + if (hash_val_bit_len){ + pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len); + } +} + +/* -------------------------------------------------------- */ + +lsh_err lsh512_init_avx2(LSH512_AVX2_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + lsh_u32 alg_type = ctx->alg_type; + const lsh_u64* const_v = NULL; + ctx->remain_databitlen = 0; + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. + AVX_Cleanup cleanup; + + switch (alg_type){ + case LSH_TYPE_512_512: + init512(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_384: + init384(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_256: + init256(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_224: + init224(ctx); + return LSH_SUCCESS; + default: + break; + } + + lsh_u64* cv_l = ctx->cv_l; + lsh_u64* cv_r = ctx->cv_r; + + zero_iv(cv_l, cv_r); + cv_l[0] = LSH512_HASH_VAL_MAX_BYTE_LEN; + cv_l[1] = LSH_GET_HASHBIT(alg_type); + + for (size_t i = 0; i < NUM_STEPS / 2; i++) + { + //Mix + load_sc(&const_v, i * 16); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + load_sc(&const_v, i * 16 + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + return LSH_SUCCESS; +} + +lsh_err lsh512_update_avx2(LSH512_AVX2_Context* ctx, const lsh_u8* data, size_t databitlen) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(databitlen % 8 == 0); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. + AVX_Cleanup cleanup; + + if (databitlen == 0){ + return LSH_SUCCESS; + } + + // We are byte oriented. tail bits will always be 0. + size_t databytelen = databitlen >> 3; + // lsh_uint pos2 = databitlen & 0x7; + const size_t pos2 = 0; + + size_t remain_msg_byte = static_cast(ctx->remain_databitlen >> 3); + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + if (remain_msg_bit > 0){ + return LSH_ERR_INVALID_DATABITLEN; + } + + if (databytelen + remain_msg_byte < LSH512_MSG_BLK_BYTE_LEN){ + memcpy(ctx->last_block + remain_msg_byte, data, databytelen); + ctx->remain_databitlen += (lsh_uint)databitlen; + remain_msg_byte += (lsh_uint)databytelen; + if (pos2){ + ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + } + return LSH_SUCCESS; + } + + if (remain_msg_byte > 0){ + size_t more_byte = LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte; + memcpy(ctx->last_block + remain_msg_byte, data, more_byte); + compress(ctx, ctx->last_block); + data += more_byte; + databytelen -= more_byte; + remain_msg_byte = 0; + ctx->remain_databitlen = 0; + } + + while (databytelen >= LSH512_MSG_BLK_BYTE_LEN) + { + // This call to compress caused some trouble. + // The data pointer can become unaligned in the + // previous block. + compress(ctx, data); + data += LSH512_MSG_BLK_BYTE_LEN; + databytelen -= LSH512_MSG_BLK_BYTE_LEN; + } + + if (databytelen > 0){ + memcpy(ctx->last_block, data, databytelen); + ctx->remain_databitlen = (lsh_uint)(databytelen << 3); + } + + if (pos2){ + ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + ctx->remain_databitlen += pos2; + } + return LSH_SUCCESS; +} + +lsh_err lsh512_final_avx2(LSH512_AVX2_Context* ctx, lsh_u8* hashval) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(hashval != NULLPTR); + + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. + AVX_Cleanup cleanup; + + // We are byte oriented. tail bits will always be 0. + size_t remain_msg_byte = static_cast(ctx->remain_databitlen >> 3); + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + + if (remain_msg_bit){ + ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit)); + } + else{ + ctx->last_block[remain_msg_byte] = 0x80; + } + memset(ctx->last_block + remain_msg_byte + 1, 0, LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte - 1); + + compress(ctx, ctx->last_block); + + fin(ctx); + get_hash(ctx, hashval); + + return LSH_SUCCESS; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +extern +void LSH512_Base_Restart_AVX2(word64* state) +{ + state[RemainingBits] = 0; + LSH512_AVX2_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_init_avx2(&ctx); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_init_avx2 failed"); +} + +extern +void LSH512_Base_Update_AVX2(word64* state, const byte *input, size_t size) +{ + LSH512_AVX2_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_update_avx2(&ctx, input, 8*size); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_update_avx2 failed"); +} + +extern +void LSH512_Base_TruncatedFinal_AVX2(word64* state, byte *hash, size_t) +{ + LSH512_AVX2_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_final_avx2(&ctx, hash); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_final_avx2 failed"); +} + +NAMESPACE_END + +#endif // CRYPTOPP_AVX2_AVAILABLE diff --git a/external/ours/library/crypto/src/shared/original/lsh512_sse.cpp b/external/ours/library/crypto/src/shared/original/lsh512_sse.cpp new file mode 100755 index 000000000..0eb102939 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lsh512_sse.cpp @@ -0,0 +1,938 @@ +// lsh.cpp - written and placed in the public domain by Jeffrey Walton +// Based on the specification and source code provided by +// Korea Internet & Security Agency (KISA) website. Also +// see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do +// and https://seed.kisa.or.kr/kisa/Board/22/detailView.do. + +// We are hitting some sort of GCC bug in the LSH AVX2 code path. +// Clang is OK on the AVX2 code path. We believe it is GCC Issue +// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It +// makes using zeroupper a little tricky. + +#include "pch.h" +#include "config.h" + +#include "lsh.h" +#include "misc.h" + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE) + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) +# include +# include +#endif + +#if defined(CRYPTOPP_XOP_AVAILABLE) +# include +#endif + +// GCC at 4.5. Clang is unknown. Also see https://stackoverflow.com/a/42493893. +#if (CRYPTOPP_GCC_VERSION >= 40500) +# include +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +/* LSH Constants */ + +const unsigned int LSH512_MSG_BLK_BYTE_LEN = 256; +// const unsigned int LSH512_MSG_BLK_BIT_LEN = 2048; +// const unsigned int LSH512_CV_BYTE_LEN = 128; +const unsigned int LSH512_HASH_VAL_MAX_BYTE_LEN = 64; + +// const unsigned int MSG_BLK_WORD_LEN = 32; +const unsigned int CV_WORD_LEN = 16; +const unsigned int CONST_WORD_LEN = 8; +// const unsigned int HASH_VAL_MAX_WORD_LEN = 8; +const unsigned int NUM_STEPS = 28; + +const unsigned int ROT_EVEN_ALPHA = 23; +const unsigned int ROT_EVEN_BETA = 59; +const unsigned int ROT_ODD_ALPHA = 7; +const unsigned int ROT_ODD_BETA = 3; + +const unsigned int LSH_TYPE_512_512 = 0x0010040; +const unsigned int LSH_TYPE_512_384 = 0x0010030; +const unsigned int LSH_TYPE_512_256 = 0x0010020; +const unsigned int LSH_TYPE_512_224 = 0x001001C; + +// const unsigned int LSH_TYPE_384 = LSH_TYPE_512_384; +// const unsigned int LSH_TYPE_512 = LSH_TYPE_512_512; + +/* Error Code */ + +const unsigned int LSH_SUCCESS = 0x0; +// const unsigned int LSH_ERR_NULL_PTR = 0x2401; +// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402; +const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403; +const unsigned int LSH_ERR_INVALID_STATE = 0x2404; + +/* Index into our state array */ + +const unsigned int AlgorithmType = 80; +const unsigned int RemainingBits = 81; + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(LSH) + +// lsh512.cpp +extern const word64 LSH512_IV224[CV_WORD_LEN]; +extern const word64 LSH512_IV256[CV_WORD_LEN]; +extern const word64 LSH512_IV384[CV_WORD_LEN]; +extern const word64 LSH512_IV512[CV_WORD_LEN]; +extern const word64 LSH512_StepConstants[CONST_WORD_LEN * NUM_STEPS]; + +NAMESPACE_END // LSH +NAMESPACE_END // Crypto++ + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlFixed; +using CryptoPP::rotlConstant; + +using CryptoPP::GetBlock; +using CryptoPP::LittleEndian; +using CryptoPP::ConditionalByteReverse; +using CryptoPP::LITTLE_ENDIAN_ORDER; + +using CryptoPP::LSH::LSH512_IV224; +using CryptoPP::LSH::LSH512_IV256; +using CryptoPP::LSH::LSH512_IV384; +using CryptoPP::LSH::LSH512_IV512; +using CryptoPP::LSH::LSH512_StepConstants; + +typedef byte lsh_u8; +typedef word32 lsh_u32; +typedef word64 lsh_u64; +typedef word32 lsh_uint; +typedef word32 lsh_err; +typedef word32 lsh_type; + +struct LSH512_SSSE3_Context +{ + LSH512_SSSE3_Context(word64* state, word64 algType, word64& remainingBitLength) : + cv_l(state+0), cv_r(state+8), sub_msgs(state+16), + last_block(reinterpret_cast(state+48)), + remain_databitlen(remainingBitLength), + alg_type(static_cast(algType)) {} + + lsh_u64* cv_l; // start of our state block + lsh_u64* cv_r; + lsh_u64* sub_msgs; + lsh_u8* last_block; + lsh_u64& remain_databitlen; + lsh_type alg_type; +}; + +struct LSH512_SSSE3_Internal +{ + LSH512_SSSE3_Internal(word64* state) : + submsg_e_l(state+16), submsg_e_r(state+24), + submsg_o_l(state+32), submsg_o_r(state+40) { } + + lsh_u64* submsg_e_l; /* even left sub-message */ + lsh_u64* submsg_e_r; /* even right sub-message */ + lsh_u64* submsg_o_l; /* odd left sub-message */ + lsh_u64* submsg_o_r; /* odd right sub-message */ +}; + +// const lsh_u32 g_gamma512[8] = { 0, 16, 32, 48, 8, 24, 40, 56 }; + +/* LSH AlgType Macro */ + +inline bool LSH_IS_LSH512(lsh_uint val) { + return (val & 0xf0000) == 0x10000; +} + +inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) { + return val >> 24; +} + +inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) { + return val & 0xffff; +} + +inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) { + return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val); +} + +inline lsh_u64 loadLE64(lsh_u64 v) { + return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v); +} + +lsh_u64 ROTL64(lsh_u64 x, lsh_u32 r) { + return rotlFixed(x, r); +} + +// Original code relied upon unaligned lsh_u64 buffer +inline void load_msg_blk(LSH512_SSSE3_Internal* i_state, const lsh_u8 msgblk[LSH512_MSG_BLK_BYTE_LEN]) +{ + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + _mm_storeu_si128(M128_CAST(submsg_e_l+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+0))); + _mm_storeu_si128(M128_CAST(submsg_e_l+2), + _mm_loadu_si128(CONST_M128_CAST(msgblk+16))); + _mm_storeu_si128(M128_CAST(submsg_e_l+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+32))); + _mm_storeu_si128(M128_CAST(submsg_e_l+6), + _mm_loadu_si128(CONST_M128_CAST(msgblk+48))); + + _mm_storeu_si128(M128_CAST(submsg_e_r+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+64))); + _mm_storeu_si128(M128_CAST(submsg_e_r+2), + _mm_loadu_si128(CONST_M128_CAST(msgblk+80))); + _mm_storeu_si128(M128_CAST(submsg_e_r+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+96))); + _mm_storeu_si128(M128_CAST(submsg_e_r+6), + _mm_loadu_si128(CONST_M128_CAST(msgblk+112))); + + _mm_storeu_si128(M128_CAST(submsg_o_l+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+128))); + _mm_storeu_si128(M128_CAST(submsg_o_l+2), + _mm_loadu_si128(CONST_M128_CAST(msgblk+144))); + _mm_storeu_si128(M128_CAST(submsg_o_l+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+160))); + _mm_storeu_si128(M128_CAST(submsg_o_l+6), + _mm_loadu_si128(CONST_M128_CAST(msgblk+176))); + + _mm_storeu_si128(M128_CAST(submsg_o_r+0), + _mm_loadu_si128(CONST_M128_CAST(msgblk+192))); + _mm_storeu_si128(M128_CAST(submsg_o_r+2), + _mm_loadu_si128(CONST_M128_CAST(msgblk+208))); + _mm_storeu_si128(M128_CAST(submsg_o_r+4), + _mm_loadu_si128(CONST_M128_CAST(msgblk+224))); + _mm_storeu_si128(M128_CAST(submsg_o_r+6), + _mm_loadu_si128(CONST_M128_CAST(msgblk+240))); +} + +inline void msg_exp_even(LSH512_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + __m128i temp; + _mm_storeu_si128(M128_CAST(submsg_e_l+2), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+2)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+0)); + _mm_storeu_si128(M128_CAST(submsg_e_l+0), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+2))); + _mm_storeu_si128(M128_CAST(submsg_e_l+2), temp); + _mm_storeu_si128(M128_CAST(submsg_e_l+6), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+6)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)); + _mm_storeu_si128(M128_CAST(submsg_e_l+4), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)))); + _mm_storeu_si128(M128_CAST(submsg_e_l+6), _mm_unpackhi_epi64( + temp, _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+6)))); + _mm_storeu_si128(M128_CAST(submsg_e_r+2), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+2)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+0)); + _mm_storeu_si128(M128_CAST(submsg_e_r+0), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+2))); + _mm_storeu_si128(M128_CAST(submsg_e_r+2), temp); + _mm_storeu_si128(M128_CAST(submsg_e_r+6), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+6)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)); + _mm_storeu_si128(M128_CAST(submsg_e_r+4), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)))); + _mm_storeu_si128(M128_CAST(submsg_e_r+6), _mm_unpackhi_epi64( + temp, _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+6)))); + + _mm_storeu_si128(M128_CAST(submsg_e_l+0), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+0)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+0)))); + _mm_storeu_si128(M128_CAST(submsg_e_l+2), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+2)))); + _mm_storeu_si128(M128_CAST(submsg_e_l+4), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)))); + _mm_storeu_si128(M128_CAST(submsg_e_l+6), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+6)))); + + _mm_storeu_si128(M128_CAST(submsg_e_r+0), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+0)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+0)))); + _mm_storeu_si128(M128_CAST(submsg_e_r+2), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+2)))); + _mm_storeu_si128(M128_CAST(submsg_e_r+4), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)))); + _mm_storeu_si128(M128_CAST(submsg_e_r+6), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+6)))); +} + +inline void msg_exp_odd(LSH512_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + __m128i temp; + _mm_storeu_si128(M128_CAST(submsg_o_l+2), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+2)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+0)); + _mm_storeu_si128(M128_CAST(submsg_o_l+0), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+2))); + _mm_storeu_si128(M128_CAST(submsg_o_l+2), temp); + _mm_storeu_si128(M128_CAST(submsg_o_l+6), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+6)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)); + _mm_storeu_si128(M128_CAST(submsg_o_l+4), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)))); + _mm_storeu_si128(M128_CAST(submsg_o_l+6), _mm_unpackhi_epi64( + temp, _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+6)))); + _mm_storeu_si128(M128_CAST(submsg_o_r+2), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+2)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+0)); + _mm_storeu_si128(M128_CAST(submsg_o_r+0), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+2))); + _mm_storeu_si128(M128_CAST(submsg_o_r+2), temp); + _mm_storeu_si128(M128_CAST(submsg_o_r+6), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+6)), _MM_SHUFFLE(1,0,3,2))); + + temp = _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)); + _mm_storeu_si128(M128_CAST(submsg_o_r+4), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)))); + _mm_storeu_si128(M128_CAST(submsg_o_r+6), _mm_unpackhi_epi64( + temp, _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+6)))); + + _mm_storeu_si128(M128_CAST(submsg_o_l+0), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+0)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+0)))); + _mm_storeu_si128(M128_CAST(submsg_o_l+2), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+2)))); + _mm_storeu_si128(M128_CAST(submsg_o_l+4), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)))); + _mm_storeu_si128(M128_CAST(submsg_o_l+6), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+6)))); + + _mm_storeu_si128(M128_CAST(submsg_o_r+0), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+0)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+0)))); + _mm_storeu_si128(M128_CAST(submsg_o_r+2), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+2)))); + _mm_storeu_si128(M128_CAST(submsg_o_r+4), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)))); + _mm_storeu_si128(M128_CAST(submsg_o_r+6), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+6)))); +} + +inline void load_sc(const lsh_u64** p_const_v, size_t i) +{ + *p_const_v = &LSH512_StepConstants[i]; +} + +inline void msg_add_even(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_e_l = i_state->submsg_e_l; + lsh_u64* submsg_e_r = i_state->submsg_e_r; + + _mm_storeu_si128(M128_CAST(cv_l), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l)))); + _mm_storeu_si128(M128_CAST(cv_r), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r)))); + _mm_storeu_si128(M128_CAST(cv_l+2), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+2)))); + _mm_storeu_si128(M128_CAST(cv_r+2), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+2)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+4)))); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+4)))); + _mm_storeu_si128(M128_CAST(cv_l+6), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_l+6)))); + _mm_storeu_si128(M128_CAST(cv_r+6), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_e_r+6)))); +} + +inline void msg_add_odd(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_SSSE3_Internal* i_state) +{ + CRYPTOPP_ASSERT(i_state != NULLPTR); + + lsh_u64* submsg_o_l = i_state->submsg_o_l; + lsh_u64* submsg_o_r = i_state->submsg_o_r; + + _mm_storeu_si128(M128_CAST(cv_l), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l)))); + _mm_storeu_si128(M128_CAST(cv_r), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r)))); + _mm_storeu_si128(M128_CAST(cv_l+2), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+2)))); + _mm_storeu_si128(M128_CAST(cv_r+2), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+2)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+2)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+4)))); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+4)))); + _mm_storeu_si128(M128_CAST(cv_l+6), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_l+6)))); + _mm_storeu_si128(M128_CAST(cv_r+6), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_r+6)), + _mm_loadu_si128(CONST_M128_CAST(submsg_o_r+6)))); +} + +inline void add_blk(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + _mm_storeu_si128(M128_CAST(cv_l), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(cv_r)))); + _mm_storeu_si128(M128_CAST(cv_l+2), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_l+2)), + _mm_loadu_si128(CONST_M128_CAST(cv_r+2)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)))); + _mm_storeu_si128(M128_CAST(cv_l+6), _mm_add_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_l+6)), + _mm_loadu_si128(CONST_M128_CAST(cv_r+6)))); +} + +template +inline void rotate_blk(lsh_u64 cv[8]) +{ +#if defined(CRYPTOPP_XOP_AVAILABLE) + _mm_storeu_si128(M128_CAST(cv), + _mm_roti_epi64(_mm_loadu_si128(CONST_M128_CAST(cv)), R)); + _mm_storeu_si128(M128_CAST(cv+2), + _mm_roti_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+2)), R)); + _mm_storeu_si128(M128_CAST(cv+4), + _mm_roti_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+4)), R)); + _mm_storeu_si128(M128_CAST(cv+6), + _mm_roti_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+6)), R)); + +#else + _mm_storeu_si128(M128_CAST(cv), _mm_or_si128( + _mm_slli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv)), R), + _mm_srli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv)), 64-R))); + _mm_storeu_si128(M128_CAST(cv+2), _mm_or_si128( + _mm_slli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+2)), R), + _mm_srli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+2)), 64-R))); + _mm_storeu_si128(M128_CAST(cv+4), _mm_or_si128( + _mm_slli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+4)), R), + _mm_srli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+4)), 64-R))); + _mm_storeu_si128(M128_CAST(cv+6), _mm_or_si128( + _mm_slli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+6)), R), + _mm_srli_epi64(_mm_loadu_si128(CONST_M128_CAST(cv+6)), 64-R))); +#endif +} + +inline void xor_with_const(lsh_u64 cv_l[8], const lsh_u64 const_v[8]) +{ + _mm_storeu_si128(M128_CAST(cv_l), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l)), + _mm_loadu_si128(CONST_M128_CAST(const_v)))); + _mm_storeu_si128(M128_CAST(cv_l+2), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+2)), + _mm_loadu_si128(CONST_M128_CAST(const_v+2)))); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(const_v+4)))); + _mm_storeu_si128(M128_CAST(cv_l+6), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(cv_l+6)), + _mm_loadu_si128(CONST_M128_CAST(const_v+6)))); +} + +inline void rotate_msg_gamma(lsh_u64 cv_r[8]) +{ + // g_gamma512[8] = { 0, 16, 32, 48, 8, 24, 40, 56 }; + _mm_storeu_si128(M128_CAST(cv_r+0), + _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(cv_r+0)), + _mm_set_epi8(13,12,11,10, 9,8,15,14, 7,6,5,4, 3,2,1,0))); + _mm_storeu_si128(M128_CAST(cv_r+2), + _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(cv_r+2)), + _mm_set_epi8(9,8,15,14, 13,12,11,10, 3,2,1,0, 7,6,5,4))); + + _mm_storeu_si128(M128_CAST(cv_r+4), + _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_set_epi8(12,11,10,9, 8,15,14,13, 6,5,4,3, 2,1,0,7))); + _mm_storeu_si128(M128_CAST(cv_r+6), + _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(cv_r+6)), + _mm_set_epi8(8,15,14,13, 12,11,10,9, 2,1,0,7, 6,5,4,3))); +} + +inline void word_perm(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + __m128i temp[2]; + temp[0] = _mm_loadu_si128(CONST_M128_CAST(cv_l+0)); + _mm_storeu_si128(M128_CAST(cv_l+0), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_l+2)), + _mm_loadu_si128(CONST_M128_CAST(cv_l+0)))); + _mm_storeu_si128(M128_CAST(cv_l+2), _mm_unpackhi_epi64( + temp[0], _mm_loadu_si128(CONST_M128_CAST(cv_l+2)))); + + temp[0] = _mm_loadu_si128(CONST_M128_CAST(cv_l+4)); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_l+6)), + _mm_loadu_si128(CONST_M128_CAST(cv_l+4)))); + _mm_storeu_si128(M128_CAST(cv_l+6), _mm_unpackhi_epi64( + temp[0], _mm_loadu_si128(CONST_M128_CAST(cv_l+6)))); + _mm_storeu_si128(M128_CAST(cv_r+2), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_r+2)), _MM_SHUFFLE(1,0,3,2))); + + temp[0] = _mm_loadu_si128(CONST_M128_CAST(cv_r+0)); + _mm_storeu_si128(M128_CAST(cv_r+0), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_r+0)), + _mm_loadu_si128(CONST_M128_CAST(cv_r+2)))); + _mm_storeu_si128(M128_CAST(cv_r+2), _mm_unpackhi_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_r+2)), temp[0])); + _mm_storeu_si128(M128_CAST(cv_r+6), _mm_shuffle_epi32( + _mm_loadu_si128(CONST_M128_CAST(cv_r+6)), _MM_SHUFFLE(1,0,3,2))); + + temp[0] = _mm_loadu_si128(CONST_M128_CAST(cv_r+4)); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_unpacklo_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_r+4)), + _mm_loadu_si128(CONST_M128_CAST(cv_r+6)))); + _mm_storeu_si128(M128_CAST(cv_r+6), _mm_unpackhi_epi64( + _mm_loadu_si128(CONST_M128_CAST(cv_r+6)), temp[0])); + + temp[0] = _mm_loadu_si128(CONST_M128_CAST(cv_l+0)); + temp[1] = _mm_loadu_si128(CONST_M128_CAST(cv_l+2)); + + _mm_storeu_si128(M128_CAST(cv_l+0), + _mm_loadu_si128(CONST_M128_CAST(cv_l+4))); + _mm_storeu_si128(M128_CAST(cv_l+2), + _mm_loadu_si128(CONST_M128_CAST(cv_l+6))); + _mm_storeu_si128(M128_CAST(cv_l+4), + _mm_loadu_si128(CONST_M128_CAST(cv_r+4))); + _mm_storeu_si128(M128_CAST(cv_l+6), + _mm_loadu_si128(CONST_M128_CAST(cv_r+6))); + _mm_storeu_si128(M128_CAST(cv_r+4), + _mm_loadu_si128(CONST_M128_CAST(cv_r+0))); + _mm_storeu_si128(M128_CAST(cv_r+6), + _mm_loadu_si128(CONST_M128_CAST(cv_r+2))); + + _mm_storeu_si128(M128_CAST(cv_r+0), temp[0]); + _mm_storeu_si128(M128_CAST(cv_r+2), temp[1]); +}; + +/* -------------------------------------------------------- * +* step function +* -------------------------------------------------------- */ + +template +inline void mix(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 const_v[8]) +{ + add_blk(cv_l, cv_r); + rotate_blk(cv_l); + xor_with_const(cv_l, const_v); + add_blk(cv_r, cv_l); + rotate_blk(cv_r); + add_blk(cv_l, cv_r); + rotate_msg_gamma(cv_r); +} + +/* -------------------------------------------------------- * +* compression function +* -------------------------------------------------------- */ + +inline void compress(LSH512_SSSE3_Context* ctx, const lsh_u8 pdMsgBlk[LSH512_MSG_BLK_BYTE_LEN]) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + LSH512_SSSE3_Internal s_state(ctx->cv_l); + LSH512_SSSE3_Internal* i_state = &s_state; + + const lsh_u64* const_v = NULL; + lsh_u64 *cv_l = ctx->cv_l; + lsh_u64 *cv_r = ctx->cv_r; + + load_msg_blk(i_state, pdMsgBlk); + + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 0); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + for (size_t i = 1; i < NUM_STEPS / 2; i++) + { + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + msg_exp_odd(i_state); + msg_add_odd(cv_l, cv_r, i_state); + load_sc(&const_v, 16 * i + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + msg_exp_even(i_state); + msg_add_even(cv_l, cv_r, i_state); +} + +/* -------------------------------------------------------- */ + +inline void load_iv(word64 cv_l[8], word64 cv_r[8], const word64 iv[16]) +{ + // The IV's are 32-byte aligned so we can use aligned loads. + _mm_storeu_si128(M128_CAST(cv_l+0), + _mm_load_si128(CONST_M128_CAST(iv+0))); + _mm_storeu_si128(M128_CAST(cv_l+2), + _mm_load_si128(CONST_M128_CAST(iv+2))); + _mm_storeu_si128(M128_CAST(cv_l+4), + _mm_load_si128(CONST_M128_CAST(iv+4))); + _mm_storeu_si128(M128_CAST(cv_l+6), + _mm_load_si128(CONST_M128_CAST(iv+6))); + _mm_storeu_si128(M128_CAST(cv_r+0), + _mm_load_si128(CONST_M128_CAST(iv+8))); + _mm_storeu_si128(M128_CAST(cv_r+2), + _mm_load_si128(CONST_M128_CAST(iv+10))); + _mm_storeu_si128(M128_CAST(cv_r+4), + _mm_load_si128(CONST_M128_CAST(iv+12))); + _mm_storeu_si128(M128_CAST(cv_r+6), + _mm_load_si128(CONST_M128_CAST(iv+14))); +} + +inline void zero_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8]) +{ + _mm_storeu_si128(M128_CAST(cv_l+0), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_l+2), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_l+4), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_l+6), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_r+0), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_r+2), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_r+4), _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(cv_r+6), _mm_setzero_si128()); +} + +inline void zero_submsgs(LSH512_SSSE3_Context* ctx) +{ + lsh_u64* sub_msgs = ctx->sub_msgs; + + _mm_storeu_si128(M128_CAST(sub_msgs+ 0), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+ 2), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+ 4), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+ 6), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+ 8), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+10), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+12), + _mm_setzero_si128()); + _mm_storeu_si128(M128_CAST(sub_msgs+14), + _mm_setzero_si128()); +} + +inline void init224(LSH512_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV224); +} + +inline void init256(LSH512_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV256); +} + +inline void init384(LSH512_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV384); +} + +inline void init512(LSH512_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + zero_submsgs(ctx); + load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV512); +} + +/* -------------------------------------------------------- */ + +inline void fin(LSH512_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + + _mm_storeu_si128(M128_CAST(ctx->cv_l+0), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_l+0)), + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_r+0)))); + _mm_storeu_si128(M128_CAST(ctx->cv_l+2), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_l+2)), + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_r+2)))); + _mm_storeu_si128(M128_CAST(ctx->cv_l+4), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_l+4)), + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_r+4)))); + _mm_storeu_si128(M128_CAST(ctx->cv_l+6), _mm_xor_si128( + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_l+6)), + _mm_loadu_si128(CONST_M128_CAST(ctx->cv_r+6)))); +} + +/* -------------------------------------------------------- */ + +inline void get_hash(LSH512_SSSE3_Context* ctx, lsh_u8* pbHashVal) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + CRYPTOPP_ASSERT(pbHashVal != NULLPTR); + + lsh_uint alg_type = ctx->alg_type; + lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type); + lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type); + + // Multiplying by sizeof(lsh_u8) looks odd... + memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len); + if (hash_val_bit_len){ + pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len); + } +} + +/* -------------------------------------------------------- */ + +lsh_err lsh512_init_ssse3(LSH512_SSSE3_Context* ctx) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + lsh_u32 alg_type = ctx->alg_type; + const lsh_u64* const_v = NULL; + ctx->remain_databitlen = 0; + + switch (alg_type){ + case LSH_TYPE_512_512: + init512(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_384: + init384(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_256: + init256(ctx); + return LSH_SUCCESS; + case LSH_TYPE_512_224: + init224(ctx); + return LSH_SUCCESS; + default: + break; + } + + lsh_u64* cv_l = ctx->cv_l; + lsh_u64* cv_r = ctx->cv_r; + + zero_iv(cv_l, cv_r); + cv_l[0] = LSH512_HASH_VAL_MAX_BYTE_LEN; + cv_l[1] = LSH_GET_HASHBIT(alg_type); + + for (size_t i = 0; i < NUM_STEPS / 2; i++) + { + //Mix + load_sc(&const_v, i * 16); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + + load_sc(&const_v, i * 16 + 8); + mix(cv_l, cv_r, const_v); + word_perm(cv_l, cv_r); + } + + return LSH_SUCCESS; +} + +lsh_err lsh512_update_ssse3(LSH512_SSSE3_Context* ctx, const lsh_u8* data, size_t databitlen) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(databitlen % 8 == 0); + CRYPTOPP_ASSERT(ctx->alg_type != 0); + + if (databitlen == 0){ + return LSH_SUCCESS; + } + + // We are byte oriented. tail bits will always be 0. + size_t databytelen = databitlen >> 3; + // lsh_uint pos2 = databitlen & 0x7; + const size_t pos2 = 0; + + size_t remain_msg_byte = static_cast(ctx->remain_databitlen >> 3); + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + if (remain_msg_bit > 0){ + return LSH_ERR_INVALID_DATABITLEN; + } + + if (databytelen + remain_msg_byte < LSH512_MSG_BLK_BYTE_LEN){ + memcpy(ctx->last_block + remain_msg_byte, data, databytelen); + ctx->remain_databitlen += (lsh_uint)databitlen; + remain_msg_byte += (lsh_uint)databytelen; + if (pos2){ + ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + } + return LSH_SUCCESS; + } + + if (remain_msg_byte > 0){ + size_t more_byte = LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte; + memcpy(ctx->last_block + remain_msg_byte, data, more_byte); + compress(ctx, ctx->last_block); + data += more_byte; + databytelen -= more_byte; + remain_msg_byte = 0; + ctx->remain_databitlen = 0; + } + + while (databytelen >= LSH512_MSG_BLK_BYTE_LEN) + { + // This call to compress caused some trouble. + // The data pointer can become unaligned in the + // previous block. + compress(ctx, data); + data += LSH512_MSG_BLK_BYTE_LEN; + databytelen -= LSH512_MSG_BLK_BYTE_LEN; + } + + if (databytelen > 0){ + memcpy(ctx->last_block, data, databytelen); + ctx->remain_databitlen = (lsh_uint)(databytelen << 3); + } + + if (pos2){ + ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff); + ctx->remain_databitlen += pos2; + } + return LSH_SUCCESS; +} + +lsh_err lsh512_final_ssse3(LSH512_SSSE3_Context* ctx, lsh_u8* hashval) +{ + CRYPTOPP_ASSERT(ctx != NULLPTR); + CRYPTOPP_ASSERT(hashval != NULLPTR); + + // We are byte oriented. tail bits will always be 0. + size_t remain_msg_byte = static_cast(ctx->remain_databitlen >> 3); + // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7; + const size_t remain_msg_bit = 0; + + if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){ + return LSH_ERR_INVALID_STATE; + } + + if (remain_msg_bit){ + ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit)); + } + else{ + ctx->last_block[remain_msg_byte] = 0x80; + } + memset(ctx->last_block + remain_msg_byte + 1, 0, LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte - 1); + + compress(ctx, ctx->last_block); + + fin(ctx); + get_hash(ctx, hashval); + + return LSH_SUCCESS; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +extern +void LSH512_Base_Restart_SSSE3(word64* state) +{ + state[RemainingBits] = 0; + LSH512_SSSE3_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_init_ssse3(&ctx); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_init_ssse3 failed"); +} + +extern +void LSH512_Base_Update_SSSE3(word64* state, const byte *input, size_t size) +{ + LSH512_SSSE3_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_update_ssse3(&ctx, input, 8*size); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_update_ssse3 failed"); +} + +extern +void LSH512_Base_TruncatedFinal_SSSE3(word64* state, byte *hash, size_t) +{ + LSH512_SSSE3_Context ctx(state, state[AlgorithmType], state[RemainingBits]); + lsh_err err = lsh512_final_ssse3(&ctx, hash); + + if (err != LSH_SUCCESS) + throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_final_ssse3 failed"); +} + +NAMESPACE_END + +#endif // CRYPTOPP_SSSE3_AVAILABLE diff --git a/external/ours/library/crypto/src/shared/original/lubyrack.h b/external/ours/library/crypto/src/shared/original/lubyrack.h new file mode 100755 index 000000000..a5d6a18db --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/lubyrack.h @@ -0,0 +1,137 @@ +// lubyrack.h - originally written and placed in the public domain by Wei Dai + +/// \file lubyrack.h +/// \brief Classes for the Luby-Rackoff block cipher + +#ifndef CRYPTOPP_LUBYRACK_H +#define CRYPTOPP_LUBYRACK_H + +#include "simple.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Luby-Rackoff block cipher information +template +struct LR_Info : public VariableKeyLength<16, 0, 2*(INT_MAX/2), 2>, public FixedBlockSize<2*T::DIGESTSIZE> +{ + static std::string StaticAlgorithmName() {return std::string("LR/")+T::StaticAlgorithmName();} +}; + +/// \brief Luby-Rackoff block cipher +template +class LR : public LR_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl > + { + public: + // VC60 workaround: have to define these functions within class definition + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) + { + this->AssertValidKeyLength(length); + + L = length/2; + buffer.New(2*S); + digest.New(S); + key.Assign(userKey, 2*L); + } + + protected: + CRYPTOPP_CONSTANT(S=T::DIGESTSIZE); + unsigned int L; // key length / 2 + SecByteBlock key; + + mutable T hm; + mutable SecByteBlock buffer, digest; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + +#define KL this->key +#define KR this->key+this->L +#define BL this->buffer +#define BR this->buffer+this->S +#define IL inBlock +#define IR inBlock+this->S +#define OL outBlock +#define OR outBlock+this->S + + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const + { + this->hm.Update(KL, this->L); + this->hm.Update(IL, this->S); + this->hm.Final(BR); + xorbuf(BR, IR, this->S); + + this->hm.Update(KR, this->L); + this->hm.Update(BR, this->S); + this->hm.Final(BL); + xorbuf(BL, IL, this->S); + + this->hm.Update(KL, this->L); + this->hm.Update(BL, this->S); + this->hm.Final(this->digest); + xorbuf(BR, this->digest, this->S); + + this->hm.Update(KR, this->L); + this->hm.Update(OR, this->S); + this->hm.Final(this->digest); + xorbuf(BL, this->digest, this->S); + + if (xorBlock) + xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); + else + memcpy_s(outBlock, 2*this->S, this->buffer, 2*this->S); + } + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const + { + this->hm.Update(KR, this->L); + this->hm.Update(IR, this->S); + this->hm.Final(BL); + xorbuf(BL, IL, this->S); + + this->hm.Update(KL, this->L); + this->hm.Update(BL, this->S); + this->hm.Final(BR); + xorbuf(BR, IR, this->S); + + this->hm.Update(KR, this->L); + this->hm.Update(BR, this->S); + this->hm.Final(this->digest); + xorbuf(BL, this->digest, this->S); + + this->hm.Update(KL, this->L); + this->hm.Update(OL, this->S); + this->hm.Final(this->digest); + xorbuf(BR, this->digest, this->S); + + if (xorBlock) + xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); + else + memcpy(outBlock, this->buffer, 2*this->S); + } +#undef KL +#undef KR +#undef BL +#undef BR +#undef IL +#undef IR +#undef OL +#undef OR + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/luc.cpp b/external/ours/library/crypto/src/shared/original/luc.cpp new file mode 100755 index 000000000..9a25662c3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/luc.cpp @@ -0,0 +1,231 @@ +// luc.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "luc.h" +#include "asn.h" +#include "sha.h" +#include "integer.h" +#include "nbtheory.h" +#include "algparam.h" +#include "pkcspad.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void LUC_TestInstantiations() +{ + LUC_HMP::Signer t1; + LUCFunction t2; + InvertibleLUCFunction t3; +} +#endif + +void DL_Algorithm_LUC_HMP::Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const +{ + const Integer &q = params.GetSubgroupOrder(); + r = params.ExponentiateBase(k); + s = (k + x*(r+e)) % q; +} + +bool DL_Algorithm_LUC_HMP::Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const +{ + const Integer p = params.GetGroupOrder()-1; + const Integer &q = params.GetSubgroupOrder(); + + Integer Vsg = params.ExponentiateBase(s); + Integer Vry = publicKey.ExponentiatePublicElement((r+e)%q); + return (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p; +} + +Integer DL_BasePrecomputation_LUC::Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const +{ + return Lucas(exponent, m_g, static_cast(group).GetModulus()); +} + +void DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const +{ + for (unsigned int i=0; i Integer::One() && m_n.IsOdd(); + CRYPTOPP_ASSERT(pass); + pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n; + CRYPTOPP_ASSERT(pass); + return pass; +} + +bool LUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) + ; +} + +void LUCFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) + ; +} + +// ***************************************************************************** +// private key operations: + +class LUCPrimeSelector : public PrimeSelector +{ +public: + LUCPrimeSelector(const Integer &e) : m_e(e) {} + bool IsAcceptable(const Integer &candidate) const + { + return RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1); + } + Integer m_e; +}; + +void InvertibleLUCFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleLUCFunction: specified modulus size is too small"); + + m_e = alg.GetValueWithDefault("PublicExponent", Integer(17)); + + if (m_e < 5 || m_e.IsEven()) + throw InvalidArgument("InvertibleLUCFunction: invalid public exponent"); + + LUCPrimeSelector selector(m_e); + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + ("PointerToPrimeSelector", selector.GetSelectorPointer()); + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); +} + +void InvertibleLUCFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e) +{ + GenerateRandom(rng, MakeParameters("ModulusSize", (int)keybits)("PublicExponent", e)); +} + +void InvertibleLUCFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + + Integer version(seq); + if (!!version) // make sure version is 0 + BERDecodeError(); + + m_n.BERDecode(seq); + m_e.BERDecode(seq); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_u.BERDecode(seq); + seq.MessageEnd(); +} + +void InvertibleLUCFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + + const byte version[] = {INTEGER, 1, 0}; + seq.Put(version, sizeof(version)); + m_n.DEREncode(seq); + m_e.DEREncode(seq); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_u.DEREncode(seq); + seq.MessageEnd(); +} + +Integer InvertibleLUCFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + // not clear how to do blinding with LUC + CRYPTOPP_UNUSED(rng); + DoQuickSanityCheck(); + return InverseLucas(m_e, x, m_q, m_p, m_u); +} + +bool InvertibleLUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = LUCFunction::Validate(rng, level); + CRYPTOPP_ASSERT(pass); + pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_u.IsPositive() && m_u < m_p; + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && RelativelyPrime(m_e, m_p+1); + CRYPTOPP_ASSERT(pass); + pass = pass && RelativelyPrime(m_e, m_p-1); + CRYPTOPP_ASSERT(pass); + pass = pass && RelativelyPrime(m_e, m_q+1); + CRYPTOPP_ASSERT(pass); + pass = pass && RelativelyPrime(m_e, m_q-1); + CRYPTOPP_ASSERT(pass); + pass = pass && m_u * m_q % m_p == 1; + CRYPTOPP_ASSERT(pass); + } + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool InvertibleLUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleLUCFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/luc.h b/external/ours/library/crypto/src/shared/original/luc.h new file mode 100755 index 000000000..9483a6d81 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/luc.h @@ -0,0 +1,338 @@ +// luc.h - originally written and placed in the public domain by Wei Dai + +/// \file luc.h +/// \brief Classes for the LUC cryptosystem +/// \details This class is here for historical and pedagogical interest. It has no practical advantages over other +/// trapdoor functions and probably shouldn't be used in production software. The discrete log based LUC schemes +/// defined later in this .h file may be of more practical interest. +/// \since Crypto++ 2.1 + +#ifndef CRYPTOPP_LUC_H +#define CRYPTOPP_LUC_H + +#include "cryptlib.h" +#include "gfpcrypt.h" +#include "integer.h" +#include "algebra.h" +#include "secblock.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4127 4189) +#endif + +#include "pkcspad.h" +#include "integer.h" +#include "oaep.h" +#include "dh.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief The LUC function. +/// \details This class is here for historical and pedagogical interest. It has no practical advantages over other +/// trapdoor functions and probably shouldn't be used in production software. The discrete log based LUC schemes +/// defined later in this .h file may be of more practical interest. +/// \since Crypto++ 2.1 +class LUCFunction : public TrapdoorFunction, public PublicKey +{ + typedef LUCFunction ThisClass; + +public: + virtual ~LUCFunction() {} + + /// \brief Initialize a LUC public key with {n,e} + /// \param n the modulus + /// \param e the public exponent + void Initialize(const Integer &n, const Integer &e) + {m_n = n; m_e = e;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return m_n;} + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // non-derived interface + const Integer & GetModulus() const {return m_n;} + const Integer & GetPublicExponent() const {return m_e;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetPublicExponent(const Integer &e) {m_e = e;} + +protected: + Integer m_n, m_e; +}; + +/// \brief The LUC inverse function. +/// \details This class is here for historical and pedagogical interest. It has no practical advantages over other +/// trapdoor functions and probably shouldn't be used in production software. The discrete log based LUC schemes +/// defined later in this .h file may be of more practical interest. +/// \since Crypto++ 2.1 +class InvertibleLUCFunction : public LUCFunction, public TrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleLUCFunction ThisClass; + +public: + virtual ~InvertibleLUCFunction() {} + + /// \brief Create a LUC private key + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulus, in bits + /// \param eStart the desired starting public exponent + /// \details Initialize() creates a new keypair using a starting public exponent of 17. + /// \details This function overload of Initialize() creates a new keypair because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &eStart=17); + + /// \brief Initialize a LUC private key with {n,e,p,q,dp,dq,u} + /// \param n modulus + /// \param e public exponent + /// \param p first prime factor + /// \param q second prime factor + /// \param u q-1 mod p + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q, const Integer &u) + {m_n = n; m_e = e; m_p = p; m_q = q; m_u = u;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize, PublicExponent (default 17)) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + // non-derived interface + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_p, m_q, m_u; +}; + +/// \brief LUC cryptosystem +/// \since Crypto++ 2.1 +struct LUC +{ + static std::string StaticAlgorithmName() {return "LUC";} + typedef LUCFunction PublicKey; + typedef InvertibleLUCFunction PrivateKey; +}; + +/// \brief LUC encryption scheme +/// \tparam STANDARD signature standard +/// \details This class is here for historical and pedagogical interest. It has no practical advantages over other +/// trapdoor functions and probably shouldn't be used in production software. The discrete log based LUC schemes +/// defined later in this .h file may be of more practical interest. +/// \since Crypto++ 2.1 +template +struct LUCES : public TF_ES +{ +}; + +/// \brief LUC signature scheme with appendix +/// \tparam STANDARD signature standard +/// \tparam H hash transformation +/// \details This class is here for historical and pedagogical interest. It has no practical advantages over other +/// trapdoor functions and probably shouldn't be used in production software. The discrete log based LUC schemes +/// defined later in this .h file may be of more practical interest. +/// \since Crypto++ 2.1 +template +struct LUCSS : public TF_SS +{ +}; + +// analogous to the RSA schemes defined in PKCS #1 v2.0 +typedef LUCES >::Decryptor LUCES_OAEP_SHA_Decryptor; +typedef LUCES >::Encryptor LUCES_OAEP_SHA_Encryptor; + +typedef LUCSS::Signer LUCSSA_PKCS1v15_SHA_Signer; +typedef LUCSS::Verifier LUCSSA_PKCS1v15_SHA_Verifier; + +// ******************************************************** + +/// \brief LUC GroupParameters precomputation +/// \details No actual precomputation is performed +/// \since Crypto++ 2.1 +class DL_GroupPrecomputation_LUC : public DL_GroupPrecomputation +{ +public: + virtual ~DL_GroupPrecomputation_LUC() {} + + const AbstractGroup & GetGroup() const {CRYPTOPP_ASSERT(false); throw 0;} + Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);} + + // non-inherited + void SetModulus(const Integer &v) {m_p = v;} + const Integer & GetModulus() const {return m_p;} + +private: + Integer m_p; +}; + +/// \brief LUC Precomputation +/// \since Crypto++ 2.1 +class DL_BasePrecomputation_LUC : public DL_FixedBasePrecomputation +{ +public: + virtual ~DL_BasePrecomputation_LUC() {} + + // DL_FixedBasePrecomputation + bool IsInitialized() const {return m_g.NotZero();} + void SetBase(const DL_GroupPrecomputation &group, const Integer &base) + {CRYPTOPP_UNUSED(group); m_g = base;} + const Integer & GetBase(const DL_GroupPrecomputation &group) const + {CRYPTOPP_UNUSED(group); return m_g;} + void Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) + {CRYPTOPP_UNUSED(group); CRYPTOPP_UNUSED(maxExpBits); CRYPTOPP_UNUSED(storage);} + void Load(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) + {CRYPTOPP_UNUSED(group); CRYPTOPP_UNUSED(storedPrecomputation);} + void Save(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) const + {CRYPTOPP_UNUSED(group); CRYPTOPP_UNUSED(storedPrecomputation);} + Integer Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const; + Integer CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const + { + CRYPTOPP_UNUSED(group); CRYPTOPP_UNUSED(exponent); CRYPTOPP_UNUSED(pc2); CRYPTOPP_UNUSED(exponent2); + // shouldn't be called + throw NotImplemented("DL_BasePrecomputation_LUC: CascadeExponentiate not implemented"); + } + +private: + Integer m_g; +}; + +/// \brief LUC GroupParameters specialization +/// \since Crypto++ 2.1 +class DL_GroupParameters_LUC : public DL_GroupParameters_IntegerBasedImpl +{ +public: + virtual ~DL_GroupParameters_LUC() {} + + // DL_GroupParameters + bool IsIdentity(const Integer &element) const {return element == Integer::Two();} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + Element MultiplyElements(const Element &a, const Element &b) const + { + CRYPTOPP_UNUSED(a); CRYPTOPP_UNUSED(b); + throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented"); + } + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const + { + CRYPTOPP_UNUSED(element1); CRYPTOPP_UNUSED(exponent1); CRYPTOPP_UNUSED(element2); CRYPTOPP_UNUSED(exponent2); + throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented"); + } + + // NameValuePairs interface + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue).Assignable(); + } + +private: + int GetFieldType() const {return 2;} +}; + +/// \brief GF(p) group parameters that default to safe primes +/// \since Crypto++ 2.1 +class DL_GroupParameters_LUC_DefaultSafePrime : public DL_GroupParameters_LUC +{ +public: + typedef NoCofactorMultiplication DefaultCofactorOption; + +protected: + unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} +}; + +/// \brief LUC HMP signature algorithm +/// \since Crypto++ 2.1 +class DL_Algorithm_LUC_HMP : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "LUC-HMP";} + + virtual ~DL_Algorithm_LUC_HMP() {} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const; + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const; + + size_t RLen(const DL_GroupParameters ¶ms) const + {return params.GetGroupOrder().ByteCount();} +}; + +/// \brief LUC signature keys +/// \since Crypto++ 2.1 +struct DL_SignatureKeys_LUC +{ + typedef DL_GroupParameters_LUC GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +/// \brief LUC-HMP, based on "Digital signature schemes based on Lucas functions" by Patrick Horster, Markus Michels, Holger Petersen +/// \tparam H hash transformation +/// \details This class is here for historical and pedagogical interest. It has no practical advantages over other +/// trapdoor functions and probably shouldn't be used in production software. The discrete log based LUC schemes +/// defined later in this .h file may be of more practical interest. +/// \since Crypto++ 2.1 +template +struct LUC_HMP : public DL_SS +{ +}; + +/// \brief LUC encryption keys +/// \since Crypto++ 2.1 +struct DL_CryptoKeys_LUC +{ + typedef DL_GroupParameters_LUC_DefaultSafePrime GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +/// \brief LUC Integrated Encryption Scheme +/// \tparam COFACTOR_OPTION cofactor multiplication option +/// \tparam HASH HashTransformation derived class used for key drivation and MAC computation +/// \tparam DHAES_MODE flag indicating if the MAC includes additional context parameters such as u·V, v·U and label +/// \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits +/// \sa CofactorMultiplicationOption +/// \since Crypto++ 2.1, Crypto++ 5.7 for Bouncy Castle and Botan compatibility +template +struct LUC_IES + : public DL_ES< + DL_CryptoKeys_LUC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, + LUC_IES<> > +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "LUC-IES";} // non-standard name +}; + +// ******************************************************** + +/// \brief LUC-DH +typedef DH_Domain LUC_DH; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/mars.cpp b/external/ours/library/crypto/src/shared/original/mars.cpp new file mode 100755 index 000000000..a8d69439f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/mars.cpp @@ -0,0 +1,154 @@ +// mars.cpp - originally written and placed in the public domain by Wei Dai + +// includes IBM's key setup "tweak" proposed in August 1999 (http://www.research.ibm.com/security/key-setup.txt) + +#include "pch.h" +#include "mars.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void MARS::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + // Initialize T[] with the key data + FixedSizeSecBlock T; + GetUserKey(LITTLE_ENDIAN_ORDER, T.begin(), 15, userKey, length); + T[length/4] = length/4; + + for (unsigned int j=0; j<4; j++) // compute 10 words of K[] in each iteration + { + unsigned int i; + // Do linear transformation + for (i=0; i<15; i++) + T[i] = T[i] ^ rotlConstant<3>(T[(i + 8) % 15] ^ T[(i + 13) % 15]) ^ (4 * i + j); + + // Do four rounds of stirring + for (unsigned int k=0; k<4; k++) + for (i=0; i<15; i++) + T[i] = rotlConstant<9>(T[i] + Sbox[T[(i + 14) % 15] % 512]); + + // Store next 10 key words into K[] + for (i=0; i<10; i++) + m_k[10*j+i] = T[4*i%15]; + } + + // Modify multiplication key-words + for(unsigned int i = 5; i < 37; i += 2) + { + word32 m, w = m_k[i] | 3; + m = (~w ^ (w<<1)) & (~w ^ (w>>1)) & 0x7ffffffe; + m &= m>>1; m &= m>>2; m &= m>>4; + m |= m<<1; m |= m<<2; m |= m<<4; + m &= 0x7ffffffc; + w ^= rotlMod(Sbox[265 + (m_k[i] & 3)], m_k[i-1]) & m; + m_k[i] = w; + } +} + +#define S(a) Sbox[(a)&0x1ff] +#define S0(a) Sbox[(a)&0xff] +#define S1(a) Sbox[((a)&0xff) + 256] + +typedef BlockGetAndPut Block; + +void MARS::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + unsigned int i; + word32 a, b, c, d, l, m, r, t; + const word32 *k = m_k; + + Block::Get(inBlock)(a)(b)(c)(d); + + a += k[0]; b += k[1]; c += k[2]; d += k[3]; + + for (i=0; i<8; i++) + { + b = (b ^ S0(a)) + S1(a>>8); + c += S0(a>>16); + a = rotrConstant<24>(a); + d ^= S1(a); + a += (i%4==0) ? d : 0; + a += (i%4==1) ? b : 0; + t = a; a = b; b = c; c = d; d = t; + } + + for (i=0; i<16; i++) + { + t = rotlConstant<13>(a); + r = rotlConstant<10>(t * k[2 * i + 5]); + m = a + k[2*i+4]; + l = rotlMod((S(m) ^ rotrConstant<5>(r) ^ r), r); + c += rotlMod(m, rotrConstant<5>(r)); + (i<8 ? b : d) += l; + (i<8 ? d : b) ^= r; + a = b; b = c; c = d; d = t; + } + + for (i=0; i<8; i++) + { + a -= (i%4==2) ? d : 0; + a -= (i%4==3) ? b : 0; + b ^= S1(a); + c -= S0(a>>24); + t = rotlConstant<24>(a); + d = (d - S1(a>>16)) ^ S0(t); + a = b; b = c; c = d; d = t; + } + + a -= k[36]; b -= k[37]; c -= k[38]; d -= k[39]; + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d); +} + +void MARS::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + unsigned int i; + word32 a, b, c, d, l, m, r, t; + const word32 *k = m_k; + + Block::Get(inBlock)(d)(c)(b)(a); + + d += k[36]; c += k[37]; b += k[38]; a += k[39]; + + for (i=0; i<8; i++) + { + b = (b ^ S0(a)) + S1(a>>8); + c += S0(a>>16); + a = rotrConstant<24>(a); + d ^= S1(a); + a += (i%4==0) ? d : 0; + a += (i%4==1) ? b : 0; + t = a; a = b; b = c; c = d; d = t; + } + + for (i=0; i<16; i++) + { + t = rotrConstant<13>(a); + r = rotlConstant<10>(a * k[35 - 2 * i]); + m = t + k[34-2*i]; + l = rotlMod((S(m) ^ rotrConstant<5>(r) ^ r), r); + c -= rotlMod(m, rotrConstant<5>(r)); + (i<8 ? b : d) -= l; + (i<8 ? d : b) ^= r; + a = b; b = c; c = d; d = t; + } + + for (i=0; i<8; i++) + { + a -= (i%4==2) ? d : 0; + a -= (i%4==3) ? b : 0; + b ^= S1(a); + c -= S0(a>>24); + t = rotlConstant<24>(a); + d = (d - S1(a>>16)) ^ S0(t); + a = b; b = c; c = d; d = t; + } + + d -= k[0]; c -= k[1]; b -= k[2]; a -= k[3]; + + Block::Put(xorBlock, outBlock)(d)(c)(b)(a); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/mars.h b/external/ours/library/crypto/src/shared/original/mars.h new file mode 100755 index 000000000..1a1f20191 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/mars.h @@ -0,0 +1,60 @@ +// mars.h - originally written and placed in the public domain by Wei Dai + +/// \file mars.h +/// \brief Classes for the MARS block cipher (IBM AES submission) +/// \since Crypto++ 3.0 + +#ifndef CRYPTOPP_MARS_H +#define CRYPTOPP_MARS_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief MARS block cipher information +/// \since Crypto++ 3.0 +struct MARS_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 56, 8> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "MARS";} +}; + +/// \brief MARS block cipher +/// \sa MARS +/// \since Crypto++ 3.0 +class MARS : public MARS_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static const word32 Sbox[512]; + + FixedSizeSecBlock m_k; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef MARS::Encryption MARSEncryption; +typedef MARS::Decryption MARSDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/marss.cpp b/external/ours/library/crypto/src/shared/original/marss.cpp new file mode 100755 index 000000000..25c40d6cd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/marss.cpp @@ -0,0 +1,140 @@ +// MARS S-Box + +#include "pch.h" +#include "mars.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word32 MARS::Base::Sbox[512] = { + 0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, + 0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93, + 0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d, + 0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4, + 0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83, + 0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac, + 0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4, + 0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26, + 0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4, + 0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086, + 0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c, + 0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253, + 0xae136749, 0xe82aae86, 0x93365104, 0x99404a66, + 0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e, + 0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b, + 0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a, + 0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45, + 0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb, + 0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958, + 0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215, + 0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c, + 0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c, + 0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462, + 0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44, + 0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca, + 0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df, + 0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8, + 0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae, + 0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31, + 0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365, + 0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3, + 0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55, + 0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53, + 0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7, + 0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8, + 0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063, + 0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13, + 0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371, + 0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6, + 0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b, + 0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073, + 0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1, + 0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd, + 0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294, + 0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7, + 0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98, + 0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f, + 0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d, + 0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550, + 0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48, + 0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149, + 0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9, + 0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131, + 0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e, + 0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3, + 0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52, + 0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76, + 0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f, + 0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59, + 0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8, + 0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029, + 0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca, + 0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3, + 0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030, + 0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69, + 0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734, + 0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b, + 0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03, + 0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3, + 0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3, + 0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf, + 0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568, + 0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6, + 0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10, + 0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce, + 0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047, + 0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f, + 0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158, + 0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969, + 0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f, + 0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb, + 0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05, + 0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3, + 0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33, + 0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650, + 0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd, + 0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e, + 0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246, + 0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089, + 0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e, + 0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2, + 0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b, + 0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee, + 0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba, + 0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c, + 0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5, + 0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20, + 0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47, + 0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54, + 0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72, + 0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d, + 0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6, + 0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9, + 0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68, + 0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2, + 0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f, + 0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4, + 0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7, + 0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44, + 0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038, + 0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c, + 0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53, + 0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9, + 0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336, + 0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235, + 0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185, + 0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf, + 0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558, + 0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830, + 0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85, + 0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf, + 0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6, + 0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319, + 0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469, + 0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb, + 0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b, + 0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0, + 0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee +}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/md2.cpp b/external/ours/library/crypto/src/shared/original/md2.cpp new file mode 100755 index 000000000..b0dc7e8b0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/md2.cpp @@ -0,0 +1,120 @@ +// md2.cpp - modified by Wei Dai from Andrew M. Kuchling's md2.c +// The original code and all modifications are in the public domain. + +// This is the original introductory comment: + +/* + * md2.c : MD2 hash algorithm. + * + * Part of the Python Cryptography Toolkit, version 1.1 + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. + * + */ + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "md2.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +MD2::MD2() + : m_X(48), m_C(16), m_buf(16) +{ + Init(); +} + +void MD2::Init() +{ + memset(m_X, 0, 48); + memset(m_C, 0, 16); + memset(m_buf, 0, 16); + m_count = 0; +} + +void MD2::Update(const byte *buf, size_t len) +{ + static const byte S[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 + }; + + while (len) + { + unsigned int L = UnsignedMin(16U-m_count, len); + memcpy(m_buf+m_count, buf, L); + m_count+=L; + buf+=L; + len-=L; + if (m_count==16) + { + byte t; + int i,j; + + m_count=0; + memcpy(m_X+16, m_buf, 16); + t=m_C[15]; + for(i=0; i<16; i++) + { + m_X[32+i]=m_X[16+i]^m_X[i]; + t=m_C[i]^=S[m_buf[i]^t]; + } + + t=0; + for(i=0; i<18; i++) + { + for(j=0; j<48; j+=8) + { + t=m_X[j+0]^=S[t]; + t=m_X[j+1]^=S[t]; + t=m_X[j+2]^=S[t]; + t=m_X[j+3]^=S[t]; + t=m_X[j+4]^=S[t]; + t=m_X[j+5]^=S[t]; + t=m_X[j+6]^=S[t]; + t=m_X[j+7]^=S[t]; + } + t = byte((t+i) & 0xFF); + } + } + } +} + +void MD2::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + byte padding[16]; + word32 padlen; + unsigned int i; + + padlen= 16-m_count; + for(i=0; iMD2 +/// \since Crypto++ 3.0 +class MD2 : public HashTransformation +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "MD2";} + + MD2(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + unsigned int BlockSize() const {return BLOCKSIZE;} + std::string AlgorithmName() const {return StaticAlgorithmName();} + + CRYPTOPP_CONSTANT(DIGESTSIZE = 16); + CRYPTOPP_CONSTANT(BLOCKSIZE = 16); + +private: + void Transform(); + void Init(); + SecByteBlock m_X, m_C, m_buf; + unsigned int m_count; +}; + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/md4.cpp b/external/ours/library/crypto/src/shared/original/md4.cpp new file mode 100755 index 000000000..f14588cc3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/md4.cpp @@ -0,0 +1,110 @@ +// md4.cpp - modified by Wei Dai from Andrew M. Kuchling's md4.c +// The original code and all modifications are in the public domain. + +// This is the original introductory comment: + +/* + * md4.c : MD4 hash algorithm. + * + * Part of the Python Cryptography Toolkit, version 1.1 + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. + * + */ + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "md4.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +void MD4::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; +} + +void MD4::Transform (word32 *digest, const word32 *in) +{ +// #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + + word32 A, B, C, D; + + A=digest[0]; + B=digest[1]; + C=digest[2]; + D=digest[3]; + +#define function(a,b,c,d,k,s) a=rotlVariable(a+F(b,c,d)+in[k],s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 1, 7); + function(C,D,A,B, 2,11); + function(B,C,D,A, 3,19); + function(A,B,C,D, 4, 3); + function(D,A,B,C, 5, 7); + function(C,D,A,B, 6,11); + function(B,C,D,A, 7,19); + function(A,B,C,D, 8, 3); + function(D,A,B,C, 9, 7); + function(C,D,A,B,10,11); + function(B,C,D,A,11,19); + function(A,B,C,D,12, 3); + function(D,A,B,C,13, 7); + function(C,D,A,B,14,11); + function(B,C,D,A,15,19); + +#undef function +#define function(a,b,c,d,k,s) a=rotlVariable(a+G(b,c,d)+in[k]+0x5a827999,s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 4, 5); + function(C,D,A,B, 8, 9); + function(B,C,D,A,12,13); + function(A,B,C,D, 1, 3); + function(D,A,B,C, 5, 5); + function(C,D,A,B, 9, 9); + function(B,C,D,A,13,13); + function(A,B,C,D, 2, 3); + function(D,A,B,C, 6, 5); + function(C,D,A,B,10, 9); + function(B,C,D,A,14,13); + function(A,B,C,D, 3, 3); + function(D,A,B,C, 7, 5); + function(C,D,A,B,11, 9); + function(B,C,D,A,15,13); + +#undef function +#define function(a,b,c,d,k,s) a=rotlVariable(a+H(b,c,d)+in[k]+0x6ed9eba1,s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 8, 9); + function(C,D,A,B, 4,11); + function(B,C,D,A,12,15); + function(A,B,C,D, 2, 3); + function(D,A,B,C,10, 9); + function(C,D,A,B, 6,11); + function(B,C,D,A,14,15); + function(A,B,C,D, 1, 3); + function(D,A,B,C, 9, 9); + function(C,D,A,B, 5,11); + function(B,C,D,A,13,15); + function(A,B,C,D, 3, 3); + function(D,A,B,C,11, 9); + function(C,D,A,B, 7,11); + function(B,C,D,A,15,15); + + digest[0]+=A; + digest[1]+=B; + digest[2]+=C; + digest[3]+=D; +} + +} +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/md4.h b/external/ours/library/crypto/src/shared/original/md4.h new file mode 100755 index 000000000..8edb166db --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/md4.h @@ -0,0 +1,35 @@ +#ifndef CRYPTOPP_MD4_H +#define CRYPTOPP_MD4_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +namespace Weak1 { + +/// MD4 +/*! \warning MD4 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ +class MD4 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "MD4";} +}; + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/md5.cpp b/external/ours/library/crypto/src/shared/original/md5.cpp index 68f60925a..99a0e34b9 100755 --- a/external/ours/library/crypto/src/shared/original/md5.cpp +++ b/external/ours/library/crypto/src/shared/original/md5.cpp @@ -1,109 +1,124 @@ -// md5.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c -// any modifications are placed in the public domain - -#include "FirstCrypto.h" -#include "md5.h" - -NAMESPACE_BEGIN(CryptoPP) - -void MD5::Init() -{ - digest[0u] = 0x67452301L; - digest[1u] = 0xefcdab89L; - digest[2u] = 0x98badcfeL; - digest[3u] = 0x10325476L; -} - -void MD5::Transform (word32 *digest, const word32 *in) -{ -// #define F1(x, y, z) (x & y | ~x & z) -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -#define MD5STEP(f, w, x, y, z, data, s) \ - w = rotlFixed(w + f(x, y, z) + data, s) + x - - word32 a, b, c, d; - - a=digest[0]; - b=digest[1]; - c=digest[2]; - d=digest[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - digest[0]+=a; - digest[1]+=b; - digest[2]+=c; - digest[3]+=d; -} - -NAMESPACE_END +// md5.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c +// any modifications are placed in the public domain + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "md5.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Weak1) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void MD5_TestInstantiations() +{ + MD5 x; +} +#endif + +void MD5::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; +} + +void MD5::Transform (word32 *digest, const word32 *data) +{ + CRYPTOPP_ASSERT(digest); + CRYPTOPP_ASSERT(data); + +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, data, s) \ + w = rotlFixed(w + f(x, y, z) + data, s) + x + + word32 a, b, c, d; + + a=digest[0]; + b=digest[1]; + c=digest[2]; + d=digest[3]; + + MD5STEP(F1, a, b, c, d, data[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, data[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, data[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, data[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, data[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, data[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, data[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, data[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, data[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, data[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, data[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, data[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, data[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, data[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, data[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, data[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, data[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, data[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, data[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, data[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, data[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, data[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, data[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, data[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, data[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, data[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, data[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, data[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, data[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, data[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, data[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, data[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, data[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, data[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, data[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, data[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, data[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, data[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, data[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, data[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, data[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, data[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, data[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, data[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, data[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, data[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, data[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, data[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, data[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, data[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, data[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, data[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, data[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, data[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, data[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, data[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, data[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, data[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, data[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, data[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, data[9] + 0xeb86d391, 21); + + digest[0]+=a; + digest[1]+=b; + digest[2]+=c; + digest[3]+=d; +} + +NAMESPACE_END // Weak +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/md5.h b/external/ours/library/crypto/src/shared/original/md5.h index d58d6eabd..b64c83044 100755 --- a/external/ours/library/crypto/src/shared/original/md5.h +++ b/external/ours/library/crypto/src/shared/original/md5.h @@ -1,24 +1,35 @@ -#ifndef CRYPTOPP_MD5_H -#define CRYPTOPP_MD5_H - -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// MD5 -/** 128 Bit Hash */ -class MD5 : public IteratedHash -{ -public: - enum {DIGESTSIZE = 16}; - MD5() : IteratedHash(DIGESTSIZE) {Init();} - static void Transform(word32 *digest, const word32 *data); - -protected: - void Init(); - void vTransform(const word32 *data) {Transform(digest, data);} -}; - -NAMESPACE_END - -#endif +#ifndef CRYPTOPP_MD5_H +#define CRYPTOPP_MD5_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +namespace Weak1 { + +/// \brief MD5 message digest +/// \sa MD5 +/// \since Crypto++ 1.0 +class MD5 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "MD5";} +}; + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/mdc.h b/external/ours/library/crypto/src/shared/original/mdc.h new file mode 100755 index 000000000..e6926fcc9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/mdc.h @@ -0,0 +1,84 @@ +// mdc.h - originally written and placed in the public domain by Wei Dai + +/// \file mdc.h +/// \brief Classes for the MDC message digest + +#ifndef CRYPTOPP_MDC_H +#define CRYPTOPP_MDC_H + +#include "seckey.h" +#include "secblock.h" +#include "misc.h" + +// GCC cast warning +#define HashWordPtr(x) ((HashWordType*)(void*)(x)) +#define ConstHashWordPtr(x) ((const HashWordType*)(const void*)(x)) + +NAMESPACE_BEGIN(CryptoPP) + +/// \tparam B BlockCipher derived class +/// \brief MDC_Info cipher information +template +struct MDC_Info : public FixedBlockSize, public FixedKeyLength +{ + static std::string StaticAlgorithmName() {return std::string("MDC/")+B::StaticAlgorithmName();} +}; + +/// \brief MDC cipher +/// \tparam H HashTransformation derived class +/// \details MDC() is a construction by Peter Gutmann to turn an iterated hash function into a PRF +/// \sa MDC +template +class MDC : public MDC_Info +{ + /// \brief MDC cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl > + { + typedef typename H::HashWordType HashWordType; + + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) + { + CRYPTOPP_UNUSED(params); + this->AssertValidKeyLength(length); + ConditionalByteReverse(BIG_ENDIAN_ORDER, Key(), ConstHashWordPtr(userKey), this->KEYLENGTH); + } + + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const + { + ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), ConstHashWordPtr(inBlock), this->BLOCKSIZE); + H::Transform(Buffer(), Key()); + + if (xorBlock) + { + ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), Buffer(), this->BLOCKSIZE); + xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE); + } + else + { + ConditionalByteReverse(BIG_ENDIAN_ORDER, HashWordPtr(outBlock), Buffer(), this->BLOCKSIZE); + } + } + + bool IsPermutation() const {return false;} + + unsigned int OptimalDataAlignment() const {return sizeof(HashWordType);} + + private: + HashWordType *Key() {return HashWordPtr(m_key.data());} + const HashWordType *Key() const {return ConstHashWordPtr(m_key.data());} + HashWordType *Buffer() const {return HashWordPtr(m_buffer.data());} + + // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup + FixedSizeSecBlock::KEYLENGTH, AllocatorWithCleanup > m_key; + mutable FixedSizeSecBlock::BLOCKSIZE, AllocatorWithCleanup > m_buffer; + }; + +public: + // use BlockCipher interface + typedef BlockCipherFinal Encryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/mersenne.h b/external/ours/library/crypto/src/shared/original/mersenne.h new file mode 100755 index 000000000..3ec6f4c60 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/mersenne.h @@ -0,0 +1,231 @@ +// mersenne.h - written and placed in public domain by Jeffrey Walton. + +/// \file mersenne.h +/// \brief Class file for Mersenne Twister +/// \warning MersenneTwister is suitable for Monte-Carlo simulations, where uniformaly distrubuted +/// numbers are required quickly. It should not be used for cryptographic purposes. +/// \since Crypto++ 5.6.3 +#ifndef CRYPTOPP_MERSENNE_TWISTER_H +#define CRYPTOPP_MERSENNE_TWISTER_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Mersenne Twister class for Monte-Carlo simulations +/// \tparam K Magic constant +/// \tparam M Period parameter +/// \tparam N Size of the state vector +/// \tparam F Multiplier constant +/// \tparam S Initial seed +/// \details Provides the MersenneTwister implementation. The class is a header-only implementation. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \warning MersenneTwister is suitable for simulations, where uniformaly distrubuted numbers are +/// required quickly. It should not be used for cryptographic purposes. +/// \sa MT19937, MT19937ar +/// \since Crypto++ 5.6.3 +template +class MersenneTwister : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return (S==5489 ? "MT19937ar" : (S==4537 ? "MT19937" : "MT19937x")); } + + ~MersenneTwister() {} + + /// \brief Construct a Mersenne Twister + /// \param seed 32-bit seed + /// \details Defaults to template parameter S due to changing algorithm + /// parameters over time + MersenneTwister(word32 seed = S) : m_idx(N) + { + Reset(seed); + } + + bool CanIncorporateEntropy() const {return true;} + + /// \brief Update RNG state with additional unpredictable values + /// \param input the entropy to add to the generator + /// \param length the size of the input buffer + /// \details MersenneTwister uses the first 32-bits of input to reseed the + /// generator. If fewer bytes are provided, then the seed is padded with 0's. + void IncorporateEntropy(const byte *input, size_t length) + { + // Handle word32 size blocks + FixedSizeSecBlock temp; + temp[0] = 0; + + if (length > 4) + length = 4; + + for (size_t i=0; i temp; + for (size_t i=0; i < size/4; i++, output += 4) + { + temp[0] = NextMersenneWord(); + memcpy(output, temp+0, 4); + } + + // No tail bytes + if (size%4 == 0) + return; + + // Handle tail bytes + temp[0] = NextMersenneWord(); + switch (size%4) + { + case 3: output[2] = CRYPTOPP_GET_BYTE_AS_BYTE(temp[0], 1); /* fall through */ + case 2: output[1] = CRYPTOPP_GET_BYTE_AS_BYTE(temp[0], 2); /* fall through */ + case 1: output[0] = CRYPTOPP_GET_BYTE_AS_BYTE(temp[0], 3); break; + + default: CRYPTOPP_ASSERT(0);; + } + } + + /// \brief Generate a random 32-bit word in the range min to max, inclusive + /// \return random 32-bit word in the range min to max, inclusive + /// \details If the 32-bit candidate is not within the range, then it is discarded + /// and a new candidate is used. + word32 GenerateWord32(word32 min=0, word32 max=0xffffffffL) + { + const word32 range = max-min; + if (range == 0xffffffffL) + return NextMersenneWord(); + + const int maxBits = BitPrecision(range); + word32 value; + + do{ + value = Crop(NextMersenneWord(), maxBits); + } while (value > range); + + return value+min; + } + + /// \brief Generate and discard n bytes + /// \param n the number of bytes to discard, rounded up to a word32 size + /// \details If n is not a multiple of word32, then unused bytes are + /// not accumulated for subsequent calls to GenerateBlock. Rather, the unused + /// tail bytes are discarded, and the stream is continued at the next + /// word32 boundary from the state array. + void DiscardBytes(size_t n) + { + for(size_t i=0; i < RoundUpToMultipleOf(n, 4U); i++) + NextMersenneWord(); + } + +protected: + + void Reset(word32 seed) + { + m_idx = N; + + m_state[0] = seed; + for (unsigned int i = 1; i < N+1; i++) + m_state[i] = word32(F * (m_state[i-1] ^ (m_state[i-1] >> 30)) + i); + } + + /// \brief Returns the next 32-bit word from the state array + /// \return the next 32-bit word from the state array + /// \details fetches the next word frm the state array, performs bit operations on + /// it, and then returns the value to the caller. + word32 NextMersenneWord() + { + if (m_idx >= N) { Twist(); } + + word32 temp = m_state[m_idx++]; + + temp ^= (temp >> 11); + temp ^= (temp << 7) & 0x9D2C5680; // 0x9D2C5680 (2636928640) + temp ^= (temp << 15) & 0xEFC60000; // 0xEFC60000 (4022730752) + + return temp ^ (temp >> 18); + } + + /// \brief Performs the twist operaton on the state array + void Twist() + { + static const word32 magic[2]={0x0UL, K}; + word32 kk, temp; + + CRYPTOPP_ASSERT(N >= M); + for (kk=0;kk> 1) ^ magic[temp & 0x1UL]; + } + + for (;kk> 1) ^ magic[temp & 0x1UL]; + } + + temp = (m_state[N-1] & 0x80000000)|(m_state[0] & 0x7FFFFFFF); + m_state[N-1] = m_state[M-1] ^ (temp >> 1) ^ magic[temp & 0x1UL]; + + // Reset index + m_idx = 0; + + // Wipe temp + SecureWipeArray(&temp, 1); + } + +private: + + /// \brief 32-bit word state array of size N + FixedSizeSecBlock m_state; + /// \brief the current index into the state array + word32 m_idx; +}; + +/// \brief Original MT19937 generator provided in the ACM paper. +/// \details MT19937 uses 4537 as default initial seed. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa MT19937ar, Mersenne twister: +/// a 623-dimensionally equidistributed uniform pseudo-random number generator +/// \since Crypto++ 5.6.3 +#if CRYPTOPP_DOXYGEN_PROCESSING +class MT19937 : public MersenneTwister<0x9908B0DF /*2567483615*/, 397, 624, 0x10DCD /*69069*/, 4537> {}; +#else +typedef MersenneTwister<0x9908B0DF /*2567483615*/, 397, 624, 0x10DCD /*69069*/, 4537> MT19937; +#endif + +/// \brief Updated MT19937 generator adapted to provide an array for initialization. +/// \details MT19937 uses 5489 as default initial seed. Use this generator when interoperating with C++11's +/// mt19937 class. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa MT19937, Mersenne Twister +/// with improved initialization +/// \since Crypto++ 5.6.3 +#if CRYPTOPP_DOXYGEN_PROCESSING +class MT19937ar : public MersenneTwister<0x9908B0DF /*2567483615*/, 397, 624, 0x6C078965 /*1812433253*/, 5489> {}; +#else +typedef MersenneTwister<0x9908B0DF /*2567483615*/, 397, 624, 0x6C078965 /*1812433253*/, 5489> MT19937ar; +#endif + +NAMESPACE_END + +#endif // CRYPTOPP_MERSENNE_TWISTER_H diff --git a/external/ours/library/crypto/src/shared/original/misc.cpp b/external/ours/library/crypto/src/shared/original/misc.cpp index c1a7d078f..5ff76b713 100755 --- a/external/ours/library/crypto/src/shared/original/misc.cpp +++ b/external/ours/library/crypto/src/shared/original/misc.cpp @@ -1,77 +1,394 @@ -// misc.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "misc.h" -#include "words.h" - -NAMESPACE_BEGIN(CryptoPP) - -byte OAEP_P_DEFAULT[1]; - -void xorbuf(byte *buf, const byte *mask, unsigned int count) -{ - if (((size_t)buf | (size_t)mask | count) % WORD_SIZE == 0) - XorWords((word *)buf, (const word *)mask, count/WORD_SIZE); - else - { - for (unsigned int i=0; i0; i/=2) - value ^= value >> i; - return (unsigned int)value&1; -} - -unsigned int BytePrecision(unsigned long value) -{ - unsigned int i; - for (i=sizeof(value); i; --i) - if (value >> (i-1)*8) - break; - - return i; -} - -unsigned int BitPrecision(unsigned long value) -{ - if (!value) - return 0; - - unsigned int l=0, h=8*sizeof(value); - - while (h-l > 1) - { - unsigned int t = (l+h)/2; - if (value >> t) - l = t; - else - h = t; - } - - return h; -} - -unsigned long Crop(unsigned long value, unsigned int size) -{ - if (size < 8*sizeof(value)) - return (value & ((1L << size) - 1)); - else - return value; -} - -NAMESPACE_END +// misc.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4189) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6237) +# endif +#endif + +#ifndef CRYPTOPP_IMPORTS + +#include "misc.h" +#include "trap.h" +#include "words.h" +#include "stdcpp.h" +#include "integer.h" +#include "secblock.h" + +// Hack for OpenBSD and GCC 4.2.1. I believe they are stuck at 4.2.1 due to GPLv3. +#if defined(__OpenBSD__) +# if defined (CRYPTOPP_GCC_VERSION) && (CRYPTOPP_GCC_VERSION < 43000) +# undef CRYPTOPP_DISABLE_ASM +# define CRYPTOPP_DISABLE_ASM 1 +# endif +#endif + +#ifndef CRYPTOPP_DISABLE_ASM +# if defined(__SSE2__) +# include +# endif +# if defined(__AVX__) +# include +# endif + +# if defined(__aarch64__) || defined(__aarch32__) || defined(_M_ARM64) +# if defined(CRYPTOPP_ARM_NEON_HEADER) +# include +# endif +# endif +#endif // CRYPTOPP_DISABLE_ASM + +NAMESPACE_BEGIN(CryptoPP) + +byte* BytePtr(SecByteBlock& str) +{ + // Caller wants a writeable pointer + CRYPTOPP_ASSERT(str.empty() == false); + + if (str.empty()) + return NULLPTR; + return reinterpret_cast(str.data()); +} + +const byte* ConstBytePtr(const SecByteBlock& str) +{ + if (str.empty()) + return NULLPTR; + return reinterpret_cast(str.data()); +} + +size_t BytePtrSize(const SecByteBlock& str) +{ + return str.size(); +} + +// xorbuf simplified at https://github.com/weidai11/cryptopp/issues/1020 +void xorbuf(byte *buf, const byte *mask, size_t count) +{ + CRYPTOPP_ASSERT(buf != NULLPTR); + CRYPTOPP_ASSERT(mask != NULLPTR); + CRYPTOPP_ASSERT(count > 0); + +#ifndef CRYPTOPP_DISABLE_ASM +# if defined(__AVX__) + while (count >= 32) + { + __m256i b = _mm256_loadu_si256(reinterpret_cast(buf)); + __m256i m = _mm256_loadu_si256(reinterpret_cast(mask)); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(buf), _mm256_castps_si256( + _mm256_xor_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(m)))); + buf += 32; mask += 32; count -= 32; + } + // https://software.intel.com/en-us/articles/avoiding-avx-sse-transition-penalties + _mm256_zeroupper(); +# endif +# if defined(__SSE2__) + while (count >= 16) + { + __m128i b = _mm_loadu_si128(reinterpret_cast(buf)); + __m128i m = _mm_loadu_si128(reinterpret_cast(mask)); + _mm_storeu_si128(reinterpret_cast<__m128i*>(buf), _mm_castps_si128( + _mm_xor_ps(_mm_castsi128_ps(b), _mm_castsi128_ps(m)))); + buf += 16; mask += 16; count -= 16; + } +# endif +# if defined(__aarch64__) || defined(__aarch32__) || defined(_M_ARM64) + while (count >= 16) + { + vst1q_u8(buf, veorq_u8(vld1q_u8(buf), vld1q_u8(mask))); + buf += 16; mask += 16; count -= 16; + } +# endif +#endif // CRYPTOPP_DISABLE_ASM + +#if CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 + // word64 and stride of 8 slows things down on x86_64. + // word64 and stride of 8 makes no difference on ARM. + // word64 and stride of 16 benefits PowerPC. + while (count >= 16) + { + word64 r[2], b[2], m[2]; + memcpy(&b, buf, 16); memcpy(&m, mask, 16); + + r[0] = b[0] ^ m[0]; + r[1] = b[1] ^ m[1]; + memcpy(buf, &r, 16); + + buf += 16; mask += 16; count -= 16; + } +#endif + + // One of the arch specific xor's may have cleared the request + if (count == 0) return; + + while (count >= 4) + { + word32 r, b, m; + memcpy(&b, buf, 4); memcpy(&m, mask, 4); + + r = b ^ m; + memcpy(buf, &r, 4); + + buf += 4; mask += 4; count -= 4; + } + + for (size_t i=0; i 0); + +#ifndef CRYPTOPP_DISABLE_ASM +# if defined(__AVX__) + while (count >= 32) + { + __m256i b = _mm256_loadu_si256(reinterpret_cast(input)); + __m256i m = _mm256_loadu_si256(reinterpret_cast(mask)); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(output), _mm256_castps_si256( + _mm256_xor_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(m)))); + output += 32; input += 32; mask += 32; count -= 32; + } + // https://software.intel.com/en-us/articles/avoiding-avx-sse-transition-penalties + _mm256_zeroupper(); +# endif +# if defined(__SSE2__) + while (count >= 16) + { + __m128i b = _mm_loadu_si128(reinterpret_cast(input)); + __m128i m = _mm_loadu_si128(reinterpret_cast(mask)); + _mm_storeu_si128(reinterpret_cast<__m128i*>(output), _mm_castps_si128( + _mm_xor_ps(_mm_castsi128_ps(b), _mm_castsi128_ps(m)))); + output += 16; input += 16; mask += 16; count -= 16; + } +# endif +# if defined(__aarch64__) || defined(__aarch32__) || defined(_M_ARM64) + while (count >= 16) + { + vst1q_u8(output, veorq_u8(vld1q_u8(input), vld1q_u8(mask))); + output += 16; input += 16; mask += 16; count -= 16; + } +# endif +#endif // CRYPTOPP_DISABLE_ASM + +#if CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 + // word64 and stride of 8 slows things down on x86_64. + // word64 and stride of 8 makes no difference on ARM. + // word64 and stride of 16 benefits PowerPC. + while (count >= 16) + { + word64 b[2], m[2], r[2]; + memcpy(&b, input, 16); memcpy(&m, mask, 16); + + r[0] = b[0] ^ m[0]; + r[1] = b[1] ^ m[1]; + memcpy(output, &r, 16); + + output += 16; input += 16; mask += 16; count -= 16; + } +#endif + + // One of the arch specific xor's may have cleared the request + if (count == 0) return; + + while (count >= 4) + { + word32 b, m, r; + memcpy(&b, input, 4); memcpy(&m, mask, 4); + + r = b ^ m; + memcpy(output, &r, 4); + + output += 4; input += 4; mask += 4; count -= 4; + } + + for (size_t i=0; i 0); + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_ARM64 || CRYPTOPP_BOOL_PPC64 || CRYPTOPP_BOOL_MIPS64 || CRYPTOPP_BOOL_SPARC64 + word64 acc64 = 0; + while (count >= 8) + { + word64 b, m; + memcpy(&b, buf, 8); memcpy(&m, mask, 8); + acc64 |= b ^ m; + + buf += 8; mask += 8; count -= 8; + } + + word32 acc8 = (acc64 >> 32) | (acc64 & 0xffffffff); + acc8 = static_cast(acc8) | static_cast(acc8 >> 8) | + static_cast(acc8 >> 16) | static_cast(acc8 >> 24); +#else + word32 acc32 = 0; + while (count >= 4) + { + word32 b, m; + memcpy(&b, buf, 4); memcpy(&m, mask, 4); + acc32 |= b ^ m; + + buf += 4; mask += 4; count -= 4; + } + + word32 acc8 = acc32; + acc8 = static_cast(acc8) | static_cast(acc8 >> 8) | + static_cast(acc8 >> 16) | static_cast(acc8 >> 24); +#endif + + for (size_t i=0; i= 1400) + size_t len=0, size=0; + errno_t err = 0; + + //const wchar_t* ptr = str; + //while (*ptr++) len++; + len = wcslen(str)+1; + + err = wcstombs_s(&size, NULLPTR, 0, str, len*sizeof(wchar_t)); + CRYPTOPP_ASSERT(err == 0); + if (err != 0) + { + if (throwOnError) + throw InvalidArgument("StringNarrow: wcstombs_s() failed with error " + IntToString(err)); + else + return std::string(); + } + + result.resize(size); + err = wcstombs_s(&size, &result[0], size, str, len*sizeof(wchar_t)); + CRYPTOPP_ASSERT(err == 0); + if (err != 0) + { + if (throwOnError) + throw InvalidArgument("StringNarrow: wcstombs_s() failed with error " + IntToString(err)); + else + return std::string(); + } + + // The safe routine's size includes the NULL. + if (!result.empty() && result[size - 1] == '\0') + result.erase(size - 1); +#else + size_t size = wcstombs(NULLPTR, str, 0); + CRYPTOPP_ASSERT(size != (size_t)-1); + if (size == (size_t)-1) + { + if (throwOnError) + throw InvalidArgument("StringNarrow: wcstombs() failed"); + else + return std::string(); + } + + result.resize(size); + size = wcstombs(&result[0], str, size); + CRYPTOPP_ASSERT(size != (size_t)-1); + if (size == (size_t)-1) + { + if (throwOnError) + throw InvalidArgument("StringNarrow: wcstombs() failed"); + else + return std::string(); + } +#endif + + return result; +} + +std::wstring StringWiden(const char *str, bool throwOnError) +{ + CRYPTOPP_ASSERT(str); + std::wstring result; + + // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55 +#if (CRYPTOPP_MSC_VERSION >= 1400) + size_t len=0, size=0; + errno_t err = 0; + + //const char* ptr = str; + //while (*ptr++) len++; + len = std::strlen(str)+1; + + err = mbstowcs_s(&size, NULLPTR, 0, str, len); + CRYPTOPP_ASSERT(err == 0); + if (err != 0) + { + if (throwOnError) + throw InvalidArgument("StringWiden: wcstombs_s() failed with error " + IntToString(err)); + else + return std::wstring(); + } + + result.resize(size); + err = mbstowcs_s(&size, &result[0], size, str, len); + CRYPTOPP_ASSERT(err == 0); + if (err != 0) + { + if (throwOnError) + throw InvalidArgument("StringWiden: wcstombs_s() failed with error " + IntToString(err)); + else + return std::wstring(); + } + + // The safe routine's size includes the NULL. + if (!result.empty() && result[size - 1] == '\0') + result.erase(size - 1); +#else + size_t size = mbstowcs(NULLPTR, str, 0); + CRYPTOPP_ASSERT(size != (size_t)-1); + if (size == (size_t)-1) + { + if (throwOnError) + throw InvalidArgument("StringWiden: mbstowcs() failed"); + else + return std::wstring(); + } + + result.resize(size); + size = mbstowcs(&result[0], str, size); + CRYPTOPP_ASSERT(size != (size_t)-1); + if (size == (size_t)-1) + { + if (throwOnError) + throw InvalidArgument("StringWiden: mbstowcs() failed"); + else + return std::wstring(); + } +#endif + + return result; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/misc.h b/external/ours/library/crypto/src/shared/original/misc.h index 862970a96..87cc877d3 100755 --- a/external/ours/library/crypto/src/shared/original/misc.h +++ b/external/ours/library/crypto/src/shared/original/misc.h @@ -1,689 +1,2776 @@ -#ifndef CRYPTOPP_MISC_H -#define CRYPTOPP_MISC_H - -#include "config.h" -#include -#include // CodeWarrior doesn't have memory.h -#include -#include - -#ifdef INTEL_INTRINSICS -#include -#endif - -NAMESPACE_BEGIN(CryptoPP) - -// ************** misc functions *************** - -#define GETBYTE(x, y) (uint32_t)(((x)>>(8*(y)))&255) -// this one may be faster on a Pentium -// #define GETBYTE(x, y) (((byte *)&(x))[y]) - -uint32_t Parity(unsigned long); -uint32_t BytePrecision(unsigned long); -uint32_t BitPrecision(unsigned long); -unsigned long Crop(unsigned long, uint32_t size); - -inline uint32_t bitsToBytes(uint32_t bitCount) -{ - return ((bitCount+7)/(8)); -} - -inline uint32_t bytesToWords(uint32_t byteCount) -{ - return ((byteCount+WORD_SIZE-1)/WORD_SIZE); -} - -inline uint32_t bitsToWords(uint32_t bitCount) -{ - return ((bitCount+WORD_BITS-1)/(WORD_BITS)); -} - -void xorbuf(byte *buf, const byte *mask, uint32_t count); -void xorbuf(byte *output, const byte *input, const byte *mask, uint32_t count); - -inline uint32_t RoundDownToMultipleOf(uint32_t n, uint32_t m) -{ - return n - n%m; -} - -inline uint32_t RoundUpToMultipleOf(uint32_t n, uint32_t m) -{ - return RoundDownToMultipleOf(n+m-1, m); -} - -template -inline bool IsAligned(const void *p) -{ - return (uintptr_t)p % sizeof(T) == 0; -} - -inline bool CheckEndianess(bool highFirst) -{ -#ifdef IS_LITTLE_ENDIAN - return !highFirst; -#else - return highFirst; -#endif -} - -template // can't use because GCC 2.95.2 doesn't have it -std::string IntToString(T a) -{ - if (a == 0) - return "0"; - bool negate = false; - if (a < 0) - { - negate = true; - a = -a; - } - std::string result; - while (a > 0) - { - result = char('0' + a % 10) + result; - a = a / 10; - } - if (negate) - result = "-" + result; - return result; -} - -// ************** rotate functions *************** - -template inline T rotlFixed(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x<>(sizeof(T)*8-y)); -} - -template inline T rotrFixed(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x>>y) | (x<<(sizeof(T)*8-y)); -} - -template inline T rotlVariable(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x<>(sizeof(T)*8-y)); -} - -template inline T rotrVariable(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x>>y) | (x<<(sizeof(T)*8-y)); -} - -template inline T rotlMod(T x, uint32_t y) -{ - y %= sizeof(T)*8; - return (x<>(sizeof(T)*8-y)); -} - -template inline T rotrMod(T x, uint32_t y) -{ - y %= sizeof(T)*8; - return (x>>y) | (x<<(sizeof(T)*8-y)); -} - -#ifdef INTEL_INTRINSICS - -template<> inline word32 rotlFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? _lrotl(x, y) : x; -} - -template<> inline word32 rotrFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? _lrotr(x, y) : x; -} - -template<> inline word32 rotlVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return _lrotl(x, y); -} - -template<> inline word32 rotrVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return _lrotr(x, y); -} - -template<> inline word32 rotlMod(word32 x, uint32_t y) -{ - return _lrotl(x, y); -} - -template<> inline word32 rotrMod(word32 x, uint32_t y) -{ - return _lrotr(x, y); -} - -#endif // #ifdef INTEL_INTRINSICS - -#ifdef PPC_INTRINSICS - -template<> inline word32 rotlFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? __rlwinm(x,y,0,31) : x; -} - -template<> inline word32 rotrFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? __rlwinm(x,32-y,0,31) : x; -} - -template<> inline word32 rotlVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return (__rlwnm(x,32-y,0,31)); -} - -template<> inline word32 rotlMod(word32 x, uint32_t y) -{ - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrMod(word32 x, uint32_t y) -{ - return (__rlwnm(x,32-y,0,31)); -} - -#endif // #ifdef PPC_INTRINSICS - -// ************** endian reversal *************** - -inline word16 byteReverse(word16 value) -{ - return rotlFixed(value, 8U); -} - -inline word32 byteReverse(word32 value) -{ -#ifdef PPC_INTRINSICS - // PPC: load reverse indexed instruction - return (word32)__lwbrx(&value,0); -#elif defined(FAST_ROTATE) - // 5 instructions with rotate instruction, 9 without - return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); -#else - // 6 instructions with rotate instruction, 8 without - value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); - return rotlFixed(value, 16U); -#endif -} - -#ifdef WORD64_AVAILABLE -inline word64 byteReverse(word64 value) -{ -#ifdef SLOW_WORD64 - return (word64(byteReverse(word32(value))) << 32) | byteReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); - value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); - return rotlFixed(value, 32U); -#endif -} -#endif - -inline byte bitReverse(byte value) -{ - value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); - value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); - return rotlFixed(value, 4); -} - -inline word16 bitReverse(word16 value) -{ - value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); - value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); - value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); - return byteReverse(value); -} - -inline word32 bitReverse(word32 value) -{ - value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1); - value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2); - value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4); - return byteReverse(value); -} - -#ifdef WORD64_AVAILABLE -inline word64 bitReverse(word64 value) -{ -#ifdef SLOW_WORD64 - return (word64(bitReverse(word32(value))) << 32) | bitReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1); - value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2); - value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); - return byteReverse(value); -#endif -} -#endif - -template -inline T bitReverse(T value) -{ - if (sizeof(T) == 1) - return bitReverse((byte)value); - else if (sizeof(T) == 2) - return bitReverse((word16)value); - else if (sizeof(T) == 4) - return bitReverse((word32)value); - else - { -#ifdef WORD64_AVAILABLE - assert(sizeof(T) == 8); - return bitReverse((word64)value); -#else - assert(false); - return 0; -#endif - } -} - -template -void byteReverse(T *out, const T *in, uint32_t byteCount) -{ - uint32_t count = (byteCount+sizeof(T)-1)/sizeof(T); - for (uint32_t i=0; i -inline void GetUserKeyLittleEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) -{ - const uint32_t U = sizeof(T); - assert(inlen <= outlen*U); - memcpy(out, in, inlen); - memset((byte *)out+inlen, 0, outlen*U-inlen); -#ifndef IS_LITTLE_ENDIAN - byteReverse(out, out, inlen); -#endif -} - -template -inline void GetUserKeyBigEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) -{ - const uint32_t U = sizeof(T); - assert(inlen <= outlen*U); - memcpy(out, in, inlen); - memset((byte *)out+inlen, 0, outlen*U-inlen); -#ifdef IS_LITTLE_ENDIAN - byteReverse(out, out, inlen); -#endif -} - -// Fetch 2 words from user's buffer into "a", "b" in LITTLE-endian order -template -inline void GetBlockLittleEndian(const byte *block, T &a, T &b) -{ -#ifdef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); -#endif -} - -// Put 2 words back into user's buffer in LITTLE-endian order -template -inline void PutBlockLittleEndian(byte *block, T a, T b) -{ -#ifdef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); -#endif -} - -// Fetch 4 words from user's buffer into "a", "b", "c", "d" in LITTLE-endian order -template -inline void GetBlockLittleEndian(const byte *block, T &a, T &b, T &c, T &d) -{ -#ifdef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; - c = ((T *)block)[2]; - d = ((T *)block)[3]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); - c = byteReverse(((T *)block)[2]); - d = byteReverse(((T *)block)[3]); -#endif -} - -// Put 4 words back into user's buffer in LITTLE-endian order -template -inline void PutBlockLittleEndian(byte *block, T a, T b, T c, T d) -{ -#ifdef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; - ((T *)block)[2] = c; - ((T *)block)[3] = d; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); - ((T *)block)[2] = byteReverse(c); - ((T *)block)[3] = byteReverse(d); -#endif -} - -// Fetch 2 words from user's buffer into "a", "b" in BIG-endian order -template -inline void GetBlockBigEndian(const byte *block, T &a, T &b) -{ -#ifndef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); -#endif -} - -// Put 2 words back into user's buffer in BIG-endian order -template -inline void PutBlockBigEndian(byte *block, T a, T b) -{ -#ifndef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); -#endif -} - -// Fetch 4 words from user's buffer into "a", "b", "c", "d" in BIG-endian order -template -inline void GetBlockBigEndian(const byte *block, T &a, T &b, T &c, T &d) -{ -#ifndef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; - c = ((T *)block)[2]; - d = ((T *)block)[3]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); - c = byteReverse(((T *)block)[2]); - d = byteReverse(((T *)block)[3]); -#endif -} - -// Put 4 words back into user's buffer in BIG-endian order -template -inline void PutBlockBigEndian(byte *block, T a, T b, T c, T d) -{ -#ifndef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; - ((T *)block)[2] = c; - ((T *)block)[3] = d; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); - ((T *)block)[2] = byteReverse(c); - ((T *)block)[3] = byteReverse(d); -#endif -} - -template -std::string WordToString(T value, bool highFirst = true) -{ - if (!CheckEndianess(highFirst)) - value = byteReverse(value); - - return std::string((char *)&value, sizeof(value)); -} - -template -T StringToWord(const std::string &str, bool highFirst = true) -{ - T value = 0; - memcpy(&value, str.data(), STDMIN(sizeof(value), str.size())); - return CheckEndianess(highFirst) ? value : byteReverse(value); -} - -// ************** key length query *************** - -/// support query of fixed key length -template -class FixedKeyLength -{ -public: - enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N}; - /// returns the key length - static uint32_t KeyLength(uint32_t) {return KEYLENGTH;} -}; - -/// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) -template -class VariableKeyLength -{ -public: - enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q}; - /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) - static uint32_t KeyLength(uint32_t n) - { - assert(KEYLENGTH_MULTIPLE > 0 && MIN_KEYLENGTH % KEYLENGTH_MULTIPLE == 0 && MAX_KEYLENGTH % KEYLENGTH_MULTIPLE == 0); - if (n < MIN_KEYLENGTH) - return MIN_KEYLENGTH; - else if (n > MAX_KEYLENGTH) - return MAX_KEYLENGTH; - else - return RoundUpToMultipleOf(n, KEYLENGTH_MULTIPLE); - } -}; - -/// support query of key length that's the same as another class -template -class SameKeyLengthAs -{ -public: - enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH}; - /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) - static uint32_t KeyLength(uint32_t keylength) - {return T::KeyLength(keylength);} -}; - -// ************** secure memory allocation *************** - -#ifdef SECALLOC_DEFAULT -#define SecAlloc(type, number) (new type[(number)]) -#define SecFree(ptr, number) (memset((ptr), 0, (number)*sizeof(*(ptr))), delete [] (ptr)) -#else -#define SecAlloc(type, number) (new type[(number)]) -#define SecFree(ptr, number) (delete [] (ptr)) -#endif - -//! a block of memory allocated using SecAlloc -template struct SecBlock -{ - explicit SecBlock(uint32_t size=0) - : size(size) {ptr = SecAlloc(T, size);} - SecBlock(const SecBlock &t) - : size(t.size) {ptr = SecAlloc(T, size); memcpy(ptr, t.ptr, size*sizeof(T));} - SecBlock(const T *t, uint32_t len) - : size(len) {ptr = SecAlloc(T, len); memcpy(ptr, t, len*sizeof(T));} - ~SecBlock() - {SecFree(ptr, size);} - -#if defined(__GNUC__) || defined(__BCPLUSPLUS__) - operator const void *() const - {return ptr;} - operator void *() - {return ptr;} -#endif -#if defined(__GNUC__) // reduce warnings - operator const void *() - {return ptr;} -#endif - - operator const T *() const - {return ptr;} - operator T *() - {return ptr;} -#if defined(__GNUC__) // reduce warnings - operator const T *() - {return ptr;} -#endif - -// CodeWarrior defines _MSC_VER -#if !defined(_MSC_VER) || defined(__MWERKS__) - T *operator +(uint32_t offset) - {return ptr+offset;} - const T *operator +(uint32_t offset) const - {return ptr+offset;} - T& operator[](uint32_t index) - {assert(index &t) - { - New(t.size); - memcpy(ptr, t.ptr, size*sizeof(T)); - } - - SecBlock& operator=(const SecBlock &t) - { - Assign(t); - return *this; - } - - bool operator==(const SecBlock &t) const - { - return size == t.size && memcmp(ptr, t.ptr, size*sizeof(T)) == 0; - } - - bool operator!=(const SecBlock &t) const - { - return !operator==(t); - } - - void New(uint32_t newSize) - { - if (newSize != size) - { - T *newPtr = SecAlloc(T, newSize); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void CleanNew(uint32_t newSize) - { - if (newSize != size) - { - T *newPtr = SecAlloc(T, newSize); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - memset(ptr, 0, size*sizeof(T)); - } - - void Grow(uint32_t newSize) - { - if (newSize > size) - { - T *newPtr = SecAlloc(T, newSize); - memcpy(newPtr, ptr, size*sizeof(T)); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void CleanGrow(uint32_t newSize) - { - if (newSize > size) - { - T *newPtr = SecAlloc(T, newSize); - memcpy(newPtr, ptr, size*sizeof(T)); - memset(newPtr+size, 0, (newSize-size)*sizeof(T)); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void Resize(uint32_t newSize) - { - if (newSize != size) - { - T *newPtr = SecAlloc(T, newSize); - memcpy(newPtr, ptr, STDMIN(newSize, size)*sizeof(T)); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void swap(SecBlock &b); - - uint32_t size; - T *ptr; -}; - -template void SecBlock::swap(SecBlock &b) -{ - std::swap(size, b.size); - std::swap(ptr, b.ptr); -} - -typedef SecBlock SecByteBlock; -typedef SecBlock SecWordBlock; - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template -inline void swap(CryptoPP::SecBlock &a, CryptoPP::SecBlock &b) -{ - a.swap(b); -} - -NAMESPACE_END - -#endif // MISC_H +// misc.h - originally written and placed in the public domain by Wei Dai + +/// \file misc.h +/// \brief Utility functions for the Crypto++ library. + +#ifndef CRYPTOPP_MISC_H +#define CRYPTOPP_MISC_H + +#include "config.h" + +#include "cryptlib.h" +#include "secblockfwd.h" +#include "smartptr.h" +#include "stdcpp.h" +#include "trap.h" + +#if !defined(CRYPTOPP_DOXYGEN_PROCESSING) + +#if (CRYPTOPP_MSC_VERSION) +# pragma warning(push) +# pragma warning(disable: 4146 4514) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6326) +# endif +#endif + +// Issue 340 and Issue 793 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#ifdef _MSC_VER + #if _MSC_VER >= 1400 + // VC2005 workaround: disable declarations that conflict with winnt.h + #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1 + #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2 + #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3 + #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4 + #include + #undef _interlockedbittestandset + #undef _interlockedbittestandreset + #undef _interlockedbittestandset64 + #undef _interlockedbittestandreset64 + #define CRYPTOPP_FAST_ROTATE(x) 1 + #elif _MSC_VER >= 1300 + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) + #else + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) + #endif +#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ + (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) +#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions + #define CRYPTOPP_FAST_ROTATE(x) 1 +#else + #define CRYPTOPP_FAST_ROTATE(x) 0 +#endif + +#ifdef __BORLANDC__ +#include +#include +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && defined(__linux__) +#define CRYPTOPP_BYTESWAP_AVAILABLE 1 +#include +#endif + +// Limit to ARM A-32. Aarch64 is failing self tests. +#if defined(__arm__) && (defined(__GNUC__) || defined(__clang__)) && (__ARM_ARCH >= 6) +#define CRYPTOPP_ARM_BYTEREV_AVAILABLE 1 +#endif + +// Limit to ARM A-32. Aarch64 is failing self tests. +#if defined(__arm__) && (defined(__GNUC__) || defined(__clang__)) && (__ARM_ARCH >= 7) +#define CRYPTOPP_ARM_BITREV_AVAILABLE 1 +#endif + +#if defined(__BMI__) +# include +# include +#endif // GCC and BMI + +// More LLVM bullshit. Apple Clang 6.0 does not define them. +// Later version of Clang defines them and results in warnings. +#if defined(__clang__) +# ifndef _blsr_u32 +# define _blsr_u32 __blsr_u32 +# endif +# ifndef _blsr_u64 +# define _blsr_u64 __blsr_u64 +# endif +# ifndef _tzcnt_u32 +# define _tzcnt_u32 __tzcnt_u32 +# endif +# ifndef _tzcnt_u64 +# define _tzcnt_u64 __tzcnt_u64 +# endif +#endif + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +#if CRYPTOPP_DOXYGEN_PROCESSING +/// \brief The maximum value of a machine word +/// \details SIZE_MAX provides the maximum value of a machine word. The value +/// is 0xffffffff on 32-bit targets, and 0xffffffffffffffff on 64-bit +/// targets. +/// \details If SIZE_MAX is not defined, then __SIZE_MAX__ is used if +/// defined. If not defined, then SIZE_T_MAX is used if defined. If not defined, +/// then the library uses std::numeric_limits::max(). +/// \details The library prefers __SIZE_MAX__ or __SIZE_T_MAX__ because +/// they are effectively constexpr that is optimized well by all compilers. +/// std::numeric_limits::max() is not always a constexpr, and +/// it is not always optimized well. +# define SIZE_MAX ... +#else +// Its amazing portability problems still plague this simple concept in 2015. +// http://stackoverflow.com/questions/30472731/which-c-standard-header-defines-size-max +// Avoid NOMINMAX macro on Windows. http://support.microsoft.com/en-us/kb/143208 +#ifndef SIZE_MAX +# if defined(__SIZE_MAX__) +# define SIZE_MAX __SIZE_MAX__ +# elif defined(SIZE_T_MAX) +# define SIZE_MAX SIZE_T_MAX +# elif defined(__SIZE_TYPE__) +# define SIZE_MAX (~(__SIZE_TYPE__)0) +# else +# define SIZE_MAX ((std::numeric_limits::max)()) +# endif +#endif + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +NAMESPACE_BEGIN(CryptoPP) + +// Forward declaration for IntToString specialization +class Integer; + +// ************** compile-time assertion *************** + +#if CRYPTOPP_DOXYGEN_PROCESSING +/// \brief Compile time assertion +/// \param expr the expression to evaluate +/// \details Asserts the expression expr during compile. If C++14 and +/// N3928 are available, then C++14 static_assert is used. Otherwise, +/// a CompileAssert structure is used. When the structure is used +/// a negative-sized array triggers the assert at compile time. +# define CRYPTOPP_COMPILE_ASSERT(expr) { ... } +#elif defined(CRYPTOPP_CXX17_STATIC_ASSERT) +# define CRYPTOPP_COMPILE_ASSERT(expr) static_assert(expr) +#else // CRYPTOPP_DOXYGEN_PROCESSING +template +struct CompileAssert +{ + static char dummy[2*b-1]; +}; + +#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) +#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y) +#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y + +#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS) +# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) +#else +# if defined(__GNUC__) || defined(__clang__) +# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \ + static CompileAssert<(assertion)> \ + CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused)) +# else +# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \ + static CompileAssert<(assertion)> \ + CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) +# endif // GCC or Clang +#endif + +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +// ************** count elements in an array *************** + +#if CRYPTOPP_DOXYGEN_PROCESSING +/// \brief Counts elements in an array +/// \param arr an array of elements +/// \details COUNTOF counts elements in an array. On Windows COUNTOF(x) is defined +/// to _countof(x) to ensure correct results for pointers. +/// \note COUNTOF does not produce correct results with pointers, and an array must be used. +/// sizeof(x)/sizeof(x[0]) suffers the same problem. The risk is eliminated by using +/// _countof(x) on Windows. Windows will provide the immunity for other platforms. +# define COUNTOF(arr) +#else +// VS2005 added _countof +#ifndef COUNTOF +# if defined(_MSC_VER) && (_MSC_VER >= 1400) +# define COUNTOF(x) _countof(x) +# else +# define COUNTOF(x) (sizeof(x)/sizeof(x[0])) +# endif +#endif // COUNTOF +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +// ************** misc classes *************** + +/// \brief An Empty class +/// \details The Empty class can be used as a template parameter BASE when no base class exists. +class CRYPTOPP_DLL Empty +{ +}; + +#if !defined(CRYPTOPP_DOXYGEN_PROCESSING) +template +class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2 +{ +}; + +template +class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3 +{ +}; +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +/// \tparam T class or type +/// \brief Uses encapsulation to hide an object in derived classes +/// \details The object T is declared as protected. +template +class ObjectHolder +{ +protected: + T m_object; +}; + +/// \brief Ensures an object is not copyable +/// \details NotCopyable ensures an object is not copyable by making the +/// copy constructor and assignment operator private. Deleters are used +/// under C++11. +/// \sa Clonable class +class NotCopyable +{ +public: + NotCopyable() {} +#if CRYPTOPP_CXX11_DELETED_FUNCTIONS + NotCopyable(const NotCopyable &) = delete; + void operator=(const NotCopyable &) = delete; +#else +private: + NotCopyable(const NotCopyable &); + void operator=(const NotCopyable &); +#endif +}; + +/// \brief An object factory function +/// \tparam T class or type +/// \details NewObject overloads operator()(). +template +struct NewObject +{ + T* operator()() const {return new T;} +}; + +#if CRYPTOPP_DOXYGEN_PROCESSING +/// \brief A memory barrier +/// \details MEMORY_BARRIER attempts to ensure reads and writes are completed +/// in the absence of a language synchronization point. It is used by the +/// Singleton class if the compiler supports it. The barrier is provided at the +/// customary places in a double-checked initialization. +/// \details Internally, MEMORY_BARRIER uses std::atomic_thread_fence if +/// C++11 atomics are available. Otherwise, intrinsic(_ReadWriteBarrier), +/// _ReadWriteBarrier() or __asm__("" ::: "memory") is used. +#define MEMORY_BARRIER ... +#else +#if defined(CRYPTOPP_CXX11_ATOMIC) +# define MEMORY_BARRIER() std::atomic_thread_fence(std::memory_order_acq_rel) +#elif (_MSC_VER >= 1400) +# pragma intrinsic(_ReadWriteBarrier) +# define MEMORY_BARRIER() _ReadWriteBarrier() +#elif defined(__INTEL_COMPILER) +# define MEMORY_BARRIER() __memory_barrier() +#elif defined(__GNUC__) || defined(__clang__) +# define MEMORY_BARRIER() __asm__ __volatile__ ("" ::: "memory") +#else +# define MEMORY_BARRIER() +#endif +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +/// \brief Restricts the instantiation of a class to one static object without locks +/// \tparam T the class or type +/// \tparam F the object factory for T +/// \tparam instance an instance counter for the class object +/// \details This class safely initializes a static object in a multi-threaded environment. For C++03 +/// and below it will do so without using locks for portability. If two threads call Ref() at the same +/// time, they may get back different references, and one object may end up being memory leaked. This +/// is by design and it avoids a subtle initialization problem in a multi-threaded environment with thread +/// local storage on early Windows platforms, like Windows XP and Windows 2003. +/// \details For C++11 and above, a standard double-checked locking pattern with thread fences +/// are used. The locks and fences are standard and do not hinder portability. +/// \details Microsoft's C++11 implementation provides the necessary primitive support on Windows Vista and +/// above when using Visual Studio 2015 (cl.exe version 19.00). If C++11 is desired, you should +/// set WINVER or _WIN32_WINNT to 0x600 (or above), and compile with Visual Studio 2015. +/// \sa Double-Checked Locking +/// is Fixed In C++11, Dynamic +/// Initialization and Destruction with Concurrency and +/// Thread Local Storage (TLS) on MSDN. +/// \since Crypto++ 5.2 +template , int instance=0> +class Singleton +{ +public: + Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {} + + // prevent this function from being inlined + CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const; + +private: + F m_objectFactory; +}; + +/// \brief Return a reference to the inner Singleton object +/// \tparam T the class or type +/// \tparam F the object factory for T +/// \tparam instance an instance counter for the class object +/// \details Ref() is used to create the object using the object factory. The +/// object is only created once with the limitations discussed in the class documentation. +/// \sa Double-Checked Locking is Fixed In C++11 +/// \since Crypto++ 5.2 +template + const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const +{ +#if defined(CRYPTOPP_CXX11_ATOMIC) && defined(CRYPTOPP_CXX11_SYNCHRONIZATION) && defined(CRYPTOPP_CXX11_STATIC_INIT) + static std::mutex s_mutex; + static std::atomic s_pObject; + + T *p = s_pObject.load(std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_acquire); + + if (p) + return *p; + + std::lock_guard lock(s_mutex); + p = s_pObject.load(std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_acquire); + + if (p) + return *p; + + T *newObject = m_objectFactory(); + s_pObject.store(newObject, std::memory_order_relaxed); + std::atomic_thread_fence(std::memory_order_release); + + return *newObject; +#else + static volatile simple_ptr s_pObject; + T *p = s_pObject.m_p; + MEMORY_BARRIER(); + + if (p) + return *p; + + T *newObject = m_objectFactory(); + p = s_pObject.m_p; + MEMORY_BARRIER(); + + if (p) + { + delete newObject; + return *p; + } + + s_pObject.m_p = newObject; + MEMORY_BARRIER(); + + return *newObject; +#endif +} + +// ************** misc functions *************** + +/// \brief Create a pointer with an offset +/// \tparam PTR a pointer type +/// \tparam OFF a size type +/// \param pointer a pointer +/// \param offset a offset into the pointer +/// \details PtrAdd can be used to squash Clang and GCC +/// UBsan findings for pointer addition and subtraction. +template +inline PTR PtrAdd(PTR pointer, OFF offset) +{ + return pointer+static_cast(offset); +} + +/// \brief Create a pointer with an offset +/// \tparam PTR a pointer type +/// \tparam OFF a size type +/// \param pointer a pointer +/// \param offset a offset into the pointer +/// \details PtrSub can be used to squash Clang and GCC +/// UBsan findings for pointer addition and subtraction. +template +inline PTR PtrSub(PTR pointer, OFF offset) +{ + return pointer-static_cast(offset); +} + +/// \brief Determine pointer difference +/// \tparam PTR a pointer type +/// \param pointer1 the first pointer +/// \param pointer2 the second pointer +/// \details PtrDiff can be used to squash Clang and GCC +/// UBsan findings for pointer addition and subtraction. +/// pointer1 and pointer2 must point to the same object or +/// array (or one past the end), and yields the number of +/// elements (not bytes) difference. +template +inline ptrdiff_t PtrDiff(const PTR pointer1, const PTR pointer2) +{ + return pointer1 - pointer2; +} + +/// \brief Determine pointer difference +/// \tparam PTR a pointer type +/// \param pointer1 the first pointer +/// \param pointer2 the second pointer +/// \details PtrByteDiff can be used to squash Clang and GCC +/// UBsan findings for pointer addition and subtraction. +/// pointer1 and pointer2 must point to the same object or +/// array (or one past the end), and yields the number of +/// bytes (not elements) difference. +template +inline size_t PtrByteDiff(const PTR pointer1, const PTR pointer2) +{ + return (size_t)(reinterpret_cast(pointer1) - reinterpret_cast(pointer2)); +} + +/// \brief Pointer to the first element of a string +/// \param str std::string +/// \details BytePtr returns NULL pointer for an empty string. +/// \return Pointer to the first element of a string +/// \since Crypto++ 8.0 +inline byte* BytePtr(std::string& str) +{ + // Caller wants a writable pointer + CRYPTOPP_ASSERT(str.empty() == false); + + if (str.empty()) + return NULLPTR; + return reinterpret_cast(&str[0]); +} + +/// \brief Pointer to the first element of a string +/// \param str SecByteBlock +/// \details BytePtr returns NULL pointer for an empty string. +/// \return Pointer to the first element of a string +/// \since Crypto++ 8.3 +byte* BytePtr(SecByteBlock& str); + +/// \brief Const pointer to the first element of a string +/// \param str std::string +/// \details ConstBytePtr returns non-NULL pointer for an empty string. +/// \return Pointer to the first element of a string +/// \since Crypto++ 8.0 +inline const byte* ConstBytePtr(const std::string& str) +{ + if (str.empty()) + return NULLPTR; + return reinterpret_cast(&str[0]); +} + +/// \brief Const pointer to the first element of a string +/// \param str SecByteBlock +/// \details ConstBytePtr returns non-NULL pointer for an empty string. +/// \return Pointer to the first element of a string +/// \since Crypto++ 8.3 +const byte* ConstBytePtr(const SecByteBlock& str); + +/// \brief Size of a string +/// \param str std::string +/// \return size of a string +/// \since Crypto++ 8.3 +inline size_t BytePtrSize(const std::string& str) +{ + return str.size(); +} + +/// \brief Size of a string +/// \param str SecByteBlock +/// \return size of a string +/// \since Crypto++ 8.3 +size_t BytePtrSize(const SecByteBlock& str); + +/// \brief Integer value +/// \details EnumToInt avoids C++20 enum-enum conversion +/// warnings under GCC and Clang. C++11 and above use a +/// constexpr function. C++03 and below use a macro due +/// to [lack of] constexpr-ness in early versions of C++. +/// \since Crypto++ 8.6 +#if (CRYPTOPP_CXX11_CONSTEXPR) +template +constexpr int EnumToInt(T v) { + return static_cast(v); +} +#else +# define EnumToInt(v) static_cast(v) +#endif + +#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB) + +/// \brief Bounds checking replacement for memcpy() +/// \param dest pointer to the destination memory block +/// \param sizeInBytes size of the destination memory block, in bytes +/// \param src pointer to the source memory block +/// \param count the number of bytes to copy +/// \throw InvalidArgument +/// \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially +/// unsafe functions like memcpy(), strcpy() and memmove(). However, +/// not all standard libraries provides them, like Glibc. The library's +/// memcpy_s() is a near-drop in replacement. Its only a near-replacement +/// because the library's version throws an InvalidArgument on a bounds violation. +/// \details memcpy_s() and memmove_s() are guarded by __STDC_WANT_SECURE_LIB__. +/// If __STDC_WANT_SECURE_LIB__ is not defined or defined to 0, then the library +/// makes memcpy_s() and memmove_s() available. The library will also optionally +/// make the symbols available if CRYPTOPP_WANT_SECURE_LIB is defined. +/// CRYPTOPP_WANT_SECURE_LIB is in config.h, but it is disabled by default. +/// \details memcpy_s() will assert the pointers src and dest are not NULL +/// in debug builds. Passing NULL for either pointer is undefined behavior. +inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count) +{ + // Safer functions on Windows for C&A, http://github.com/weidai11/cryptopp/issues/55 + + // Pointers must be valid; otherwise undefined behavior + CRYPTOPP_ASSERT(dest != NULLPTR); CRYPTOPP_ASSERT(src != NULLPTR); + // Restricted pointers. We want to check ranges, but it is not clear how to do it. + CRYPTOPP_ASSERT(src != dest); + // Destination buffer must be large enough to satisfy request + CRYPTOPP_ASSERT(sizeInBytes >= count); + + if (count > sizeInBytes) + throw InvalidArgument("memcpy_s: buffer overflow"); + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4996) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6386) +# endif +#endif + if (src != NULLPTR && dest != NULLPTR) + std::memcpy(dest, src, count); +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif +} + +/// \brief Bounds checking replacement for memmove() +/// \param dest pointer to the destination memory block +/// \param sizeInBytes size of the destination memory block, in bytes +/// \param src pointer to the source memory block +/// \param count the number of bytes to copy +/// \throw InvalidArgument +/// \details ISO/IEC TR-24772 provides bounds checking interfaces for potentially +/// unsafe functions like memcpy(), strcpy() and memmove(). However, +/// not all standard libraries provides them, like Glibc. The library's +/// memmove_s() is a near-drop in replacement. Its only a near-replacement +/// because the library's version throws an InvalidArgument on a bounds violation. +/// \details memcpy_s() and memmove_s() are guarded by __STDC_WANT_SECURE_LIB__. +/// If __STDC_WANT_SECURE_LIB__ is not defined or defined to 0, then the library +/// makes memcpy_s() and memmove_s() available. The library will also optionally +/// make the symbols available if CRYPTOPP_WANT_SECURE_LIB is defined. +/// CRYPTOPP_WANT_SECURE_LIB is in config.h, but it is disabled by default. +/// \details memmove_s() will assert the pointers src and dest are not NULL +/// in debug builds. Passing NULL for either pointer is undefined behavior. +inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count) +{ + // Safer functions on Windows for C&A, http://github.com/weidai11/cryptopp/issues/55 + + // Pointers must be valid; otherwise undefined behavior + CRYPTOPP_ASSERT(dest != NULLPTR); CRYPTOPP_ASSERT(src != NULLPTR); + // Destination buffer must be large enough to satisfy request + CRYPTOPP_ASSERT(sizeInBytes >= count); + + if (count > sizeInBytes) + throw InvalidArgument("memmove_s: buffer overflow"); + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4996) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6386) +# endif +#endif + if (src != NULLPTR && dest != NULLPTR) + std::memmove(dest, src, count); +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif +} + +#if __BORLANDC__ >= 0x620 +// C++Builder 2010 workaround: can't use std::memcpy_s +// because it doesn't allow 0 lengths +# define memcpy_s CryptoPP::memcpy_s +# define memmove_s CryptoPP::memmove_s +#endif + +#endif // __STDC_WANT_SECURE_LIB__ + +/// \brief Swaps two variables which are arrays +/// \tparam T class or type +/// \param a the first value +/// \param b the second value +/// \details C++03 does not provide support for std::swap(__m128i a, __m128i b) +/// because __m128i is an unsigned long long[2]. Most compilers +/// support it out of the box, but Sun Studio C++ compilers 12.2 and 12.3 do not. +/// \sa How to swap two __m128i variables +/// in C++03 given its an opaque type and an array? on Stack Overflow. +template +inline void vec_swap(T& a, T& b) +{ + // __m128i is an unsigned long long[2], and support for swapping it was + // not added until C++11. SunCC 12.1 - 12.3 fail to consume the swap; while + // SunCC 12.4 consumes it without -std=c++11. +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) + T t; + t=a, a=b, b=t; +#else + std::swap(a, b); +#endif +} + +/// \brief Memory block initializer +/// \param ptr pointer to the memory block being written +/// \param val the integer value to write for each byte +/// \param num the size of the source memory block, in bytes +/// \details Internally the function calls memset with the value val. +/// memset_z can be used to initialize a freshly allocated memory block. +/// To zeroize a memory block on destruction use SecureWipeBuffer. +/// \return the pointer to the memory block +/// \sa SecureWipeBuffer +inline void * memset_z(void *ptr, int val, size_t num) +{ +// avoid extraneous warning on GCC 4.3.2 Ubuntu 8.10 +#if CRYPTOPP_GCC_VERSION >= 30001 || CRYPTOPP_LLVM_CLANG_VERSION >= 20800 || \ + CRYPTOPP_APPLE_CLANG_VERSION >= 30000 + if (__builtin_constant_p(num) && num==0) + return ptr; +#endif + return std::memset(ptr, val, num); +} + +/// \brief Replacement function for std::min +/// \tparam T class or type +/// \param a the first value +/// \param b the second value +/// \return the minimum value based on a comparison of b \< a using operator\< +/// \details STDMIN was provided because the library could not easily use std::min or std::max in Windows or Cygwin 1.1.0 +template inline const T& STDMIN(const T& a, const T& b) +{ + return b < a ? b : a; +} + +/// \brief Replacement function for std::max +/// \tparam T class or type +/// \param a the first value +/// \param b the second value +/// \return the minimum value based on a comparison of a \< b using operator\< +/// \details STDMAX was provided because the library could not easily use std::min or std::max in Windows or Cygwin 1.1.0 +template inline const T& STDMAX(const T& a, const T& b) +{ + return a < b ? b : a; +} + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4389) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-compare" +# pragma GCC diagnostic ignored "-Wstrict-overflow" +# if (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) +# pragma GCC diagnostic ignored "-Wtautological-compare" +# elif (CRYPTOPP_GCC_VERSION >= 40300) +# pragma GCC diagnostic ignored "-Wtype-limits" +# endif +#endif + +/// \brief Safe comparison of values that could be negative and incorrectly promoted +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param a the first value +/// \param b the second value +/// \return the minimum value based on a comparison a and b using operator<. +/// \details The comparison b \< a is performed and the value returned is a's type T1. +template inline const T1 UnsignedMin(const T1& a, const T2& b) +{ + CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0)); + if (sizeof(T1)<=sizeof(T2)) + return b < (T2)a ? (T1)b : a; + else + return (T1)b < a ? (T1)b : a; +} + +/// \brief Tests whether a conversion from -> to is safe to perform +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param from the first value +/// \param to the second value +/// \return true if its safe to convert from into to, false otherwise. +template +inline bool SafeConvert(T1 from, T2 &to) +{ + to = static_cast(from); + if (from != to || (from > 0) != (to > 0)) + return false; + return true; +} + +/// \brief Converts a value to a string +/// \tparam T class or type +/// \param value the value to convert +/// \param base the base to use during the conversion +/// \return the string representation of value in base. +template +std::string IntToString(T value, unsigned int base = 10) +{ + // Hack... set the high bit for uppercase. + const unsigned int HIGH_BIT = (1U << 31); + const char CH = !!(base & HIGH_BIT) ? 'A' : 'a'; + base &= ~HIGH_BIT; + + CRYPTOPP_ASSERT(base >= 2); + if (value == 0) + return "0"; + + bool negate = false; + if (value < 0) + { + negate = true; + value = 0-value; // VC .NET does not like -a + } + std::string result; + while (value > 0) + { + T digit = value % base; + result = char((digit < 10 ? '0' : (CH - 10)) + digit) + result; + value /= base; + } + if (negate) + result = "-" + result; + return result; +} + +/// \brief Converts an unsigned value to a string +/// \param value the value to convert +/// \param base the base to use during the conversion +/// \return the string representation of value in base. +/// \details this template function specialization was added to suppress +/// Coverity findings on IntToString() with unsigned types. +template <> CRYPTOPP_DLL +std::string IntToString(word64 value, unsigned int base); + +/// \brief Converts an Integer to a string +/// \param value the Integer to convert +/// \param base the base to use during the conversion +/// \return the string representation of value in base. +/// \details This is a template specialization of IntToString(). Use it +/// like IntToString(): +///
+///  // Print integer in base 10
+///  Integer n...
+///  std::string s = IntToString(n, 10);
+/// 
+/// \details The string is presented with lowercase letters by default. A +/// hack is available to switch to uppercase letters without modifying +/// the function signature. +///
+///  // Print integer in base 16, uppercase letters
+///  Integer n...
+///  const unsigned int UPPER = (1 << 31);
+///  std::string s = IntToString(n, (UPPER | 16));
+template <> CRYPTOPP_DLL +std::string IntToString(Integer value, unsigned int base); + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue + +// this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack +#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y))) +// these may be faster on other CPUs/compilers +// #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255) +// #define GETBYTE(x, y) (((byte *)&(x))[y]) + +#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y))) + +/// \brief Returns the parity of a value +/// \tparam T class or type +/// \param value the value to provide the parity +/// \return 1 if the number 1-bits in the value is odd, 0 otherwise +template +unsigned int Parity(T value) +{ + for (unsigned int i=8*sizeof(value)/2; i>0; i/=2) + value ^= value >> i; + return (unsigned int)value&1; +} + +/// \brief Returns the number of 8-bit bytes or octets required for a value +/// \tparam T class or type +/// \param value the value to test +/// \return the minimum number of 8-bit bytes or octets required to represent a value +template +unsigned int BytePrecision(const T &value) +{ + if (!value) + return 0; + + unsigned int l=0, h=8*sizeof(value); + while (h-l > 8) + { + unsigned int t = (l+h)/2; + if (value >> t) + l = t; + else + h = t; + } + + return h/8; +} + +/// \brief Returns the number of bits required for a value +/// \tparam T class or type +/// \param value the value to test +/// \return the maximum number of bits required to represent a value. +template +unsigned int BitPrecision(const T &value) +{ + if (!value) + return 0; + + unsigned int l=0, h=8*sizeof(value); + + while (h-l > 1) + { + unsigned int t = (l+h)/2; + if (value >> t) + l = t; + else + h = t; + } + + return h; +} + +/// Determines the number of trailing 0-bits in a value +/// \param v the 32-bit value to test +/// \return the number of trailing 0-bits in v, starting at the least significant bit position +/// \details TrailingZeros returns the number of trailing 0-bits in v, starting at the least +/// significant bit position. The return value is undefined if there are no 1-bits set in the value v. +/// \note The function does not return 0 if no 1-bits are set because 0 collides with a 1-bit at the 0-th position. +inline unsigned int TrailingZeros(word32 v) +{ + // GCC 4.7 and VS2012 provides tzcnt on AVX2/BMI enabled processors + // We don't enable for Microsoft because it requires a runtime check. + // http://msdn.microsoft.com/en-us/library/hh977023%28v=vs.110%29.aspx + CRYPTOPP_ASSERT(v != 0); +#if defined(__BMI__) + return (unsigned int)_tzcnt_u32(v); +#elif defined(__GNUC__) && (CRYPTOPP_GCC_VERSION >= 30400) + return (unsigned int)__builtin_ctz(v); +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + unsigned long result; + _BitScanForward(&result, v); + return static_cast(result); +#else + // from http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup + static const int MultiplyDeBruijnBitPosition[32] = + { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + return MultiplyDeBruijnBitPosition[((word32)((v & -v) * 0x077CB531U)) >> 27]; +#endif +} + +/// Determines the number of trailing 0-bits in a value +/// \param v the 64-bit value to test +/// \return the number of trailing 0-bits in v, starting at the least significant bit position +/// \details TrailingZeros returns the number of trailing 0-bits in v, starting at the least +/// significant bit position. The return value is undefined if there are no 1-bits set in the value v. +/// \note The function does not return 0 if no 1-bits are set because 0 collides with a 1-bit at the 0-th position. +inline unsigned int TrailingZeros(word64 v) +{ + // GCC 4.7 and VS2012 provides tzcnt on AVX2/BMI enabled processors + // We don't enable for Microsoft because it requires a runtime check. + // http://msdn.microsoft.com/en-us/library/hh977023%28v=vs.110%29.aspx + CRYPTOPP_ASSERT(v != 0); +#if defined(__BMI__) && defined(__x86_64__) + return (unsigned int)_tzcnt_u64(v); +#elif defined(__GNUC__) && (CRYPTOPP_GCC_VERSION >= 30400) + return (unsigned int)__builtin_ctzll(v); +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) && (defined(_M_X64) || defined(_M_IA64)) + unsigned long result; + _BitScanForward64(&result, v); + return static_cast(result); +#else + return word32(v) ? TrailingZeros(word32(v)) : 32 + TrailingZeros(word32(v>>32)); +#endif +} + +/// \brief Truncates the value to the specified number of bits. +/// \tparam T class or type +/// \param value the value to truncate or mask +/// \param bits the number of bits to truncate or mask +/// \return the value truncated to the specified number of bits, starting at the least +/// significant bit position +/// \details This function masks the low-order bits of value and returns the result. The +/// mask is created with (1 << bits) - 1. +template +inline T Crop(T value, size_t bits) +{ + if (bits < 8*sizeof(value)) + return T(value & ((T(1) << bits) - 1)); + else + return value; +} + +/// \brief Returns the number of 8-bit bytes or octets required for the specified number of bits +/// \param bitCount the number of bits +/// \return the minimum number of 8-bit bytes or octets required by bitCount +/// \details BitsToBytes is effectively a ceiling function based on 8-bit bytes. +inline size_t BitsToBytes(size_t bitCount) +{ + return ((bitCount+7)/(8)); +} + +/// \brief Returns the number of words required for the specified number of bytes +/// \param byteCount the number of bytes +/// \return the minimum number of words required by byteCount +/// \details BytesToWords is effectively a ceiling function based on WORD_SIZE. +/// WORD_SIZE is defined in config.h +inline size_t BytesToWords(size_t byteCount) +{ + return ((byteCount+WORD_SIZE-1)/WORD_SIZE); +} + +/// \brief Returns the number of words required for the specified number of bits +/// \param bitCount the number of bits +/// \return the minimum number of words required by bitCount +/// \details BitsToWords is effectively a ceiling function based on WORD_BITS. +/// WORD_BITS is defined in config.h +inline size_t BitsToWords(size_t bitCount) +{ + return ((bitCount+WORD_BITS-1)/(WORD_BITS)); +} + +/// \brief Returns the number of double words required for the specified number of bits +/// \param bitCount the number of bits +/// \return the minimum number of double words required by bitCount +/// \details BitsToDwords is effectively a ceiling function based on 2*WORD_BITS. +/// WORD_BITS is defined in config.h +inline size_t BitsToDwords(size_t bitCount) +{ + return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS)); +} + +/// Performs an XOR of a buffer with a mask +/// \param buf the buffer to XOR with the mask +/// \param mask the mask to XOR with the buffer +/// \param count the size of the buffers, in bytes +/// \details The function effectively visits each element in the buffers and performs +/// buf[i] ^= mask[i]. buf and mask must be of equal size. +CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count); + +/// Performs an XOR of an input buffer with a mask and stores the result in an output buffer +/// \param output the destination buffer +/// \param input the source buffer to XOR with the mask +/// \param mask the mask buffer to XOR with the input buffer +/// \param count the size of the buffers, in bytes +/// \details The function effectively visits each element in the buffers and performs +/// output[i] = input[i] ^ mask[i]. output, input and mask must be of equal size. +CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count); + +/// \brief Performs a near constant-time comparison of two equally sized buffers +/// \param buf1 the first buffer +/// \param buf2 the second buffer +/// \param count the size of the buffers, in bytes +/// \details VerifyBufsEqual performs an XOR of the elements in two equally sized +/// buffers and returns a result based on the XOR operation. A count of 0 returns +/// true because two empty buffers are considered equal. +/// \details The function is near constant-time because CPU micro-code timings could +/// affect the "constant-ness". Calling code is responsible for mitigating timing +/// attacks if the buffers are not equally sized. +/// \sa ModPowerOf2 +CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count); + +/// \brief Tests whether a value is a power of 2 +/// \param value the value to test +/// \return true if value is a power of 2, false otherwise +/// \details The function creates a mask of value - 1 and returns the result +/// of an AND operation compared to 0. If value is 0 or less than 0, then the function +/// returns false. +template +inline bool IsPowerOf2(const T &value) +{ + return value > 0 && (value & (value-1)) == 0; +} + +#if defined(__BMI__) +template <> +inline bool IsPowerOf2(const word32 &value) +{ + return value > 0 && _blsr_u32(value) == 0; +} + +# if defined(__x86_64__) +template <> +inline bool IsPowerOf2(const word64 &value) +{ + return value > 0 && _blsr_u64(value) == 0; +} +# endif // __x86_64__ +#endif // __BMI__ + +/// \brief Provide the minimum value for a type +/// \tparam T type of class +/// \return the minimum value of the type or class +/// \details NumericLimitsMin() was introduced for Clang at Issue 364, +/// Apple Clang 6.0 and numeric_limits::max() returns 0. +/// \details NumericLimitsMin() requires a specialization for T, +/// meaning std::numeric_limits::is_specialized must return +/// true. In the case of word128 Clang did not specialize +/// numeric_limits for the type. +/// \since Crypto++ 8.1 +template +inline T NumericLimitsMin() +{ + CRYPTOPP_ASSERT(std::numeric_limits::is_specialized); + return (std::numeric_limits::min)(); +} + +/// \brief Provide the maximum value for a type +/// \tparam T type of class +/// \return the maximum value of the type or class +/// \details NumericLimitsMax() was introduced for Clang at Issue 364, +/// Apple Clang 6.0 and numeric_limits::max() returns 0. +/// \details NumericLimitsMax() requires a specialization for T, +/// meaning std::numeric_limits::is_specialized must return +/// true. In the case of word128 Clang did not specialize +/// numeric_limits for the type. +/// \since Crypto++ 8.1 +template +inline T NumericLimitsMax() +{ + CRYPTOPP_ASSERT(std::numeric_limits::is_specialized); + return (std::numeric_limits::max)(); +} + +// NumericLimitsMin and NumericLimitsMax added for word128 types, +// see http://github.com/weidai11/cryptopp/issues/364 +#if defined(CRYPTOPP_WORD128_AVAILABLE) +template<> +inline word128 NumericLimitsMin() +{ + return 0; +} +template<> +inline word128 NumericLimitsMax() +{ + return (static_cast(LWORD_MAX) << 64U) | LWORD_MAX; +} +#endif + +/// \brief Performs a saturating subtract clamped at 0 +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param a the minuend +/// \param b the subtrahend +/// \return the difference produced by the saturating subtract +/// \details Saturating arithmetic restricts results to a fixed range. Results that are +/// less than 0 are clamped at 0. +/// \details Use of saturating arithmetic in places can be advantageous because it can +/// avoid a branch by using an instruction like a conditional move (CMOVE). +template +inline T1 SaturatingSubtract(const T1 &a, const T2 &b) +{ + // Generated ASM of a typical clamp, http://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html + return T1((a > b) ? (a - b) : 0); +} + +/// \brief Performs a saturating subtract clamped at 1 +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param a the minuend +/// \param b the subtrahend +/// \return the difference produced by the saturating subtract +/// \details Saturating arithmetic restricts results to a fixed range. Results that are +/// less than 1 are clamped at 1. +/// \details Use of saturating arithmetic in places can be advantageous because it can +/// avoid a branch by using an instruction like a conditional move (CMOVE). +template +inline T1 SaturatingSubtract1(const T1 &a, const T2 &b) +{ + // Generated ASM of a typical clamp, http://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html + return T1((a > b) ? (a - b) : 1); +} + +/// \brief Reduces a value to a power of 2 +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param a the first value +/// \param b the second value +/// \return ModPowerOf2() returns a & (b-1). b must be a power of 2. +/// Use IsPowerOf2() to determine if b is a suitable candidate. +/// \sa IsPowerOf2 +template +inline T2 ModPowerOf2(const T1 &a, const T2 &b) +{ + CRYPTOPP_ASSERT(IsPowerOf2(b)); + // Coverity finding CID 170383 Overflowed return value (INTEGER_OVERFLOW) + return T2(a) & SaturatingSubtract(b,1U); +} + +/// \brief Rounds a value down to a multiple of a second value +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param n the value to reduce +/// \param m the value to reduce n to a multiple +/// \return the possibly unmodified value \n +/// \details RoundDownToMultipleOf is effectively a floor function based on m. The function returns +/// the value n - n\%m. If n is a multiple of m, then the original value is returned. +/// \note T1 and T2 should be unsigned arithmetic types. If T1 or +/// T2 is signed, then the value should be non-negative. The library asserts in +/// debug builds when practical, but allows you to perform the operation in release builds. +template +inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m) +{ + // http://github.com/weidai11/cryptopp/issues/364 +#if !defined(CRYPTOPP_APPLE_CLANG_VERSION) || (CRYPTOPP_APPLE_CLANG_VERSION >= 80000) + CRYPTOPP_ASSERT(std::numeric_limits::is_integer); + CRYPTOPP_ASSERT(std::numeric_limits::is_integer); +#endif + + CRYPTOPP_ASSERT(!std::numeric_limits::is_signed || n > 0); + CRYPTOPP_ASSERT(!std::numeric_limits::is_signed || m > 0); + + if (IsPowerOf2(m)) + return n - ModPowerOf2(n, m); + else + return n - n%m; +} + +/// \brief Rounds a value up to a multiple of a second value +/// \tparam T1 class or type +/// \tparam T2 class or type +/// \param n the value to reduce +/// \param m the value to reduce n to a multiple +/// \return the possibly unmodified value \n +/// \details RoundUpToMultipleOf is effectively a ceiling function based on m. The function +/// returns the value n + n\%m. If n is a multiple of m, then the original value is +/// returned. If the value n would overflow, then an InvalidArgument exception is thrown. +/// \note T1 and T2 should be unsigned arithmetic types. If T1 or +/// T2 is signed, then the value should be non-negative. The library asserts in +/// debug builds when practical, but allows you to perform the operation in release builds. +template +inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m) +{ + // http://github.com/weidai11/cryptopp/issues/364 +#if !defined(CRYPTOPP_APPLE_CLANG_VERSION) || (CRYPTOPP_APPLE_CLANG_VERSION >= 80000) + CRYPTOPP_ASSERT(std::numeric_limits::is_integer); + CRYPTOPP_ASSERT(std::numeric_limits::is_integer); +#endif + + CRYPTOPP_ASSERT(!std::numeric_limits::is_signed || n > 0); + CRYPTOPP_ASSERT(!std::numeric_limits::is_signed || m > 0); + + if (NumericLimitsMax() - m + 1 < n) + throw InvalidArgument("RoundUpToMultipleOf: integer overflow"); + return RoundDownToMultipleOf(T1(n+m-1), m); +} + +/// \brief Returns the minimum alignment requirements of a type +/// \tparam T class or type +/// \return the minimum alignment requirements of T, in bytes +/// \details Internally the function calls C++11's alignof if +/// available. If not available, then the function uses compiler +/// specific extensions such as __alignof and _alignof_. +/// If an extension is not available, then the function uses +/// sizeof(T). +template +inline unsigned int GetAlignmentOf() +{ +#if defined(CRYPTOPP_CXX11_ALIGNOF) + return alignof(T); +#elif (_MSC_VER >= 1300) + return __alignof(T); +#elif defined(__GNUC__) + return __alignof__(T); +#elif defined(__SUNPRO_CC) + return __alignof__(T); +#elif defined(__IBM_ALIGNOF__) + return __alignof__(T); +#elif CRYPTOPP_BOOL_SLOW_WORD64 + return UnsignedMin(4U, sizeof(T)); +#else + return sizeof(T); +#endif +} + +/// \brief Determines whether ptr is aligned to a minimum value +/// \param ptr the pointer being checked for alignment +/// \param alignment the alignment value to test the pointer against +/// \return true if ptr is aligned on at least alignment +/// boundary, false otherwise +/// \details Internally the function tests whether alignment is 1. If so, +/// the function returns true. If not, then the function effectively +/// performs a modular reduction and returns true if the residue is 0. +inline bool IsAlignedOn(const void *ptr, unsigned int alignment) +{ + const uintptr_t x = reinterpret_cast(ptr); + return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2(x, alignment) == 0 : x % alignment == 0); +} + +/// \brief Determines whether ptr is minimally aligned +/// \tparam T class or type +/// \param ptr the pointer to check for alignment +/// \return true if ptr is aligned to at least T +/// boundary, false otherwise +/// \details Internally the function calls IsAlignedOn with a second +/// parameter of GetAlignmentOf. +template +inline bool IsAligned(const void *ptr) +{ + return IsAlignedOn(ptr, GetAlignmentOf()); +} + +#if (CRYPTOPP_LITTLE_ENDIAN) +typedef LittleEndian NativeByteOrder; +#elif (CRYPTOPP_BIG_ENDIAN) +typedef BigEndian NativeByteOrder; +#else +# error "Unable to determine endianness" +#endif + +/// \brief Returns NativeByteOrder as an enumerated ByteOrder value +/// \return LittleEndian if the native byte order is little-endian, +/// and BigEndian if the native byte order is big-endian +/// \details NativeByteOrder is a typedef depending on the platform. +/// If CRYPTOPP_LITTLE_ENDIAN is set in config.h, then +/// GetNativeByteOrder returns LittleEndian. If CRYPTOPP_BIG_ENDIAN +/// is set, then GetNativeByteOrder returns BigEndian. +/// \note There are other byte orders besides little- and big-endian, +/// and they include bi-endian and PDP-endian. If a system is neither +/// little-endian nor big-endian, then a compile time error occurs. +inline ByteOrder GetNativeByteOrder() +{ + return NativeByteOrder::ToEnum(); +} + +/// \brief Determines whether order follows native byte ordering +/// \param order the ordering being tested against native byte ordering +/// \return true if order follows native byte ordering, false otherwise +inline bool NativeByteOrderIs(ByteOrder order) +{ + return order == GetNativeByteOrder(); +} + +/// \brief Returns the direction the cipher is being operated +/// \tparam T class or type +/// \param obj the cipher object being queried +/// \return ENCRYPTION if the cipher obj is being operated in its forward direction, +/// DECRYPTION otherwise +/// \details A cipher can be operated in a "forward" direction (encryption) or a "reverse" +/// direction (decryption). The operations do not have to be symmetric, meaning a second +/// application of the transformation does not necessarily return the original message. +/// That is, E(D(m)) may not equal E(E(m)); and D(E(m)) may not +/// equal D(D(m)). +template +inline CipherDir GetCipherDir(const T &obj) +{ + return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION; +} + +/// \brief Performs an addition with carry on a block of bytes +/// \param inout the byte block +/// \param size the size of the block, in bytes +/// \details Performs an addition with carry by adding 1 on a block of bytes starting at the least +/// significant byte. Once carry is 0, the function terminates and returns to the caller. +/// \note The function is not constant time because it stops processing when the carry is 0. +inline void IncrementCounterByOne(byte *inout, unsigned int size) +{ + CRYPTOPP_ASSERT(inout != NULLPTR); + + unsigned int carry=1; + while (carry && size != 0) + { + // On carry inout[n] equals 0 + carry = ! ++inout[size-1]; + size--; + } +} + +/// \brief Performs an addition with carry on a block of bytes +/// \param output the destination block of bytes +/// \param input the source block of bytes +/// \param size the size of the block +/// \details Performs an addition with carry on a block of bytes starting at the least significant +/// byte. Once carry is 0, the remaining bytes from input are copied to output using memcpy. +/// \details The function is close to near-constant time because it operates on all the bytes in the blocks. +inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int size) +{ + CRYPTOPP_ASSERT(output != NULLPTR); + CRYPTOPP_ASSERT(input != NULLPTR); + + unsigned int carry=1; + while (carry && size != 0) + { + // On carry output[n] equals 0 + carry = ! (output[size-1] = input[size-1] + 1); + size--; + } + + while (size != 0) + { + output[size-1] = input[size-1]; + size--; + } +} + +/// \brief Performs a branch-less swap of values a and b if condition c is true +/// \tparam T class or type +/// \param c the condition to perform the swap +/// \param a the first value +/// \param b the second value +template +inline void ConditionalSwap(bool c, T &a, T &b) +{ + T t = c * (a ^ b); + a ^= t; + b ^= t; +} + +/// \brief Performs a branch-less swap of pointers a and b if condition c is true +/// \tparam T class or type +/// \param c the condition to perform the swap +/// \param a the first pointer +/// \param b the second pointer +template +inline void ConditionalSwapPointers(bool c, T &a, T &b) +{ + ptrdiff_t t = size_t(c) * (a - b); + a -= t; + b += t; +} + +// see http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/protect-secrets.html +// and http://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data + +/// \brief Sets each element of an array to 0 +/// \tparam T class or type +/// \param buf an array of elements +/// \param n the number of elements in the array +/// \details The operation performs a wipe or zeroization. The function +/// attempts to survive optimizations and dead code removal. +template +void SecureWipeBuffer(T *buf, size_t n) +{ + // GCC 4.3.2 on Cygwin optimizes away the first store if this + // loop is done in the forward direction + volatile T *p = buf+n; + while (n--) + *(--p) = 0; +} + +#if !defined(CRYPTOPP_DISABLE_ASM) && \ + (_MSC_VER >= 1400 || defined(__GNUC__)) && \ + (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) + +/// \brief Sets each byte of an array to 0 +/// \param buf an array of bytes +/// \param n the number of elements in the array +/// \details The operation performs a wipe or zeroization. The function +/// attempts to survive optimizations and dead code removal. +template<> inline void SecureWipeBuffer(byte *buf, size_t n) +{ + volatile byte *p = buf; +#ifdef __GNUC__ + asm volatile("rep stosb" : "+c"(n), "+D"(p) : "a"(0) : "memory"); +#else + __stosb(reinterpret_cast(reinterpret_cast(p)), 0, n); +#endif +} + +/// \brief Sets each 16-bit element of an array to 0 +/// \param buf an array of 16-bit words +/// \param n the number of elements in the array +/// \details The operation performs a wipe or zeroization. The function +/// attempts to survive optimizations and dead code removal. +template<> inline void SecureWipeBuffer(word16 *buf, size_t n) +{ + volatile word16 *p = buf; +#ifdef __GNUC__ + asm volatile("rep stosw" : "+c"(n), "+D"(p) : "a"(0) : "memory"); +#else + __stosw(reinterpret_cast(reinterpret_cast(p)), 0, n); +#endif +} + +/// \brief Sets each 32-bit element of an array to 0 +/// \param buf an array of 32-bit words +/// \param n the number of elements in the array +/// \details The operation performs a wipe or zeroization. The function +/// attempts to survive optimizations and dead code removal. +template<> inline void SecureWipeBuffer(word32 *buf, size_t n) +{ + volatile word32 *p = buf; +#ifdef __GNUC__ + asm volatile("rep stosl" : "+c"(n), "+D"(p) : "a"(0) : "memory"); +#else + __stosd(reinterpret_cast(reinterpret_cast(p)), 0, n); +#endif +} + +/// \brief Sets each 64-bit element of an array to 0 +/// \param buf an array of 64-bit words +/// \param n the number of elements in the array +/// \details The operation performs a wipe or zeroization. The function +/// attempts to survive optimizations and dead code removal. +template<> inline void SecureWipeBuffer(word64 *buf, size_t n) +{ +#if CRYPTOPP_BOOL_X64 + volatile word64 *p = buf; +# ifdef __GNUC__ + asm volatile("rep stosq" : "+c"(n), "+D"(p) : "a"(0) : "memory"); +# else + __stosq(const_cast(p), 0, n); +# endif +#else + SecureWipeBuffer(reinterpret_cast(buf), 2*n); +#endif +} + +#endif // CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 + +#if !defined(CRYPTOPP_DISABLE_ASM) && (_MSC_VER >= 1700) && defined(_M_ARM) +template<> inline void SecureWipeBuffer(byte *buf, size_t n) +{ + char *p = reinterpret_cast(buf+n); + while (n--) + __iso_volatile_store8(--p, 0); +} + +template<> inline void SecureWipeBuffer(word16 *buf, size_t n) +{ + short *p = reinterpret_cast(buf+n); + while (n--) + __iso_volatile_store16(--p, 0); +} + +template<> inline void SecureWipeBuffer(word32 *buf, size_t n) +{ + int *p = reinterpret_cast(buf+n); + while (n--) + __iso_volatile_store32(--p, 0); +} + +template<> inline void SecureWipeBuffer(word64 *buf, size_t n) +{ + __int64 *p = reinterpret_cast<__int64*>(buf+n); + while (n--) + __iso_volatile_store64(--p, 0); +} +#endif + +/// \brief Sets each element of an array to 0 +/// \tparam T class or type +/// \param buf an array of elements +/// \param n the number of elements in the array +/// \details The operation performs a wipe or zeroization. The function +/// attempts to survive optimizations and dead code removal. +template +inline void SecureWipeArray(T *buf, size_t n) +{ + if (sizeof(T) % 8 == 0 && GetAlignmentOf() % GetAlignmentOf() == 0) + SecureWipeBuffer(reinterpret_cast(static_cast(buf)), n * (sizeof(T)/8)); + else if (sizeof(T) % 4 == 0 && GetAlignmentOf() % GetAlignmentOf() == 0) + SecureWipeBuffer(reinterpret_cast(static_cast(buf)), n * (sizeof(T)/4)); + else if (sizeof(T) % 2 == 0 && GetAlignmentOf() % GetAlignmentOf() == 0) + SecureWipeBuffer(reinterpret_cast(static_cast(buf)), n * (sizeof(T)/2)); + else + SecureWipeBuffer(reinterpret_cast(static_cast(buf)), n * sizeof(T)); +} + +/// \brief Converts a wide character C-string to a multibyte string +/// \param str C-string consisting of wide characters +/// \param throwOnError flag indicating the function should throw on error +/// \return str converted to a multibyte string or an empty string. +/// \details StringNarrow() converts a wide string to a narrow string using C++ std::wcstombs() under +/// the executing thread's locale. A locale must be set before using this function, and it can be +/// set with std::setlocale() if needed. Upon success, the converted string is returned. +/// \details Upon failure with throwOnError as false, the function returns an empty string. If +/// throwOnError as true, the function throws an InvalidArgument() exception. +/// \note If you try to convert, say, the Chinese character for "bone" from UTF-16 (0x9AA8) to UTF-8 +/// (0xE9 0xAA 0xA8), then you must ensure the locale is available. If the locale is not available, +/// then a 0x21 error is returned on Windows which eventually results in an InvalidArgument() exception. +std::string StringNarrow(const wchar_t *str, bool throwOnError = true); + +/// \brief Converts a multibyte C-string to a wide character string +/// \param str C-string consisting of wide characters +/// \param throwOnError flag indicating the function should throw on error +/// \return str converted to a multibyte string or an empty string. +/// \details StringWiden() converts a narrow string to a wide string using C++ std::mbstowcs() under +/// the executing thread's locale. A locale must be set before using this function, and it can be +/// set with std::setlocale() if needed. Upon success, the converted string is returned. +/// \details Upon failure with throwOnError as false, the function returns an empty string. If +/// throwOnError as true, the function throws an InvalidArgument() exception. +/// \note If you try to convert, say, the Chinese character for "bone" from UTF-8 (0xE9 0xAA 0xA8) +/// to UTF-16 (0x9AA8), then you must ensure the locale is available. If the locale is not available, +/// then a 0x21 error is returned on Windows which eventually results in an InvalidArgument() exception. +std::wstring StringWiden(const char *str, bool throwOnError = true); + +// ************** rotate functions *************** + +/// \brief Performs a left rotate +/// \tparam R the number of bit positions to rotate the value +/// \tparam T the word type +/// \param x the value to rotate +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details R must be in the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// Use rotlMod if the rotate amount R is outside the range. +/// \details Use rotlConstant when the rotate amount is constant. The template function was added +/// because Clang did not propagate the constant when passed as a function parameter. Clang's +/// need for a constexpr meant rotlFixed failed to compile on occasion. +/// \note rotlConstant attempts to enlist a rotate IMM instruction because its often faster +/// than a rotate REG. Immediate rotates can be up to three times faster than their register +/// counterparts. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 6.0 +template inline T rotlConstant(T x) +{ + // Portable rotate that reduces to single instruction... + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57157, + // http://software.intel.com/en-us/forums/topic/580884 + // and http://llvm.org/bugs/show_bug.cgi?id=24226 + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + CRYPTOPP_ASSERT(static_cast(R) < THIS_SIZE); + return T((x<>(-R&MASK))); +} + +/// \brief Performs a right rotate +/// \tparam R the number of bit positions to rotate the value +/// \tparam T the word type +/// \param x the value to rotate +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details R must be in the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// Use rotrMod if the rotate amount R is outside the range. +/// \details Use rotrConstant when the rotate amount is constant. The template function was added +/// because Clang did not propagate the constant when passed as a function parameter. Clang's +/// need for a constexpr meant rotrFixed failed to compile on occasion. +/// \note rotrConstant attempts to enlist a rotate IMM instruction because its often faster +/// than a rotate REG. Immediate rotates can be up to three times faster than their register +/// counterparts. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +template inline T rotrConstant(T x) +{ + // Portable rotate that reduces to single instruction... + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57157, + // http://software.intel.com/en-us/forums/topic/580884 + // and http://llvm.org/bugs/show_bug.cgi?id=24226 + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + CRYPTOPP_ASSERT(static_cast(R) < THIS_SIZE); + return T((x >> R)|(x<<(-R&MASK))); +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details y must be in the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// Use rotlMod if the rotate amount y is outside the range. +/// \note rotlFixed attempts to enlist a rotate IMM instruction because its often faster +/// than a rotate REG. Immediate rotates can be up to three times faster than their register +/// counterparts. New code should use rotlConstant, which accepts the rotate amount as a +/// template parameter. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 6.0 +template inline T rotlFixed(T x, unsigned int y) +{ + // Portable rotate that reduces to single instruction... + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57157, + // http://software.intel.com/en-us/forums/topic/580884 + // and http://llvm.org/bugs/show_bug.cgi?id=24226 + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + CRYPTOPP_ASSERT(static_cast(y) < THIS_SIZE); + return T((x<>(-y&MASK))); +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details y must be in the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// Use rotrMod if the rotate amount y is outside the range. +/// \note rotrFixed attempts to enlist a rotate IMM instruction because its often faster +/// than a rotate REG. Immediate rotates can be up to three times faster than their register +/// counterparts. New code should use rotrConstant, which accepts the rotate amount as a +/// template parameter. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 3.0 +template inline T rotrFixed(T x, unsigned int y) +{ + // Portable rotate that reduces to single instruction... + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57157, + // http://software.intel.com/en-us/forums/topic/580884 + // and http://llvm.org/bugs/show_bug.cgi?id=24226 + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + CRYPTOPP_ASSERT(static_cast(y) < THIS_SIZE); + return T((x >> y)|(x<<(-y&MASK))); +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details y must be in the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// Use rotlMod if the rotate amount y is outside the range. +/// \note rotlVariable attempts to enlist a rotate IMM instruction because its often faster +/// than a rotate REG. Immediate rotates can be up to three times faster than their register +/// counterparts. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 3.0 +template inline T rotlVariable(T x, unsigned int y) +{ + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + CRYPTOPP_ASSERT(static_cast(y) < THIS_SIZE); + return T((x<>(-y&MASK))); +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details y must be in the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// Use rotrMod if the rotate amount y is outside the range. +/// \note rotrVariable attempts to enlist a rotate IMM instruction because its often faster +/// than a rotate REG. Immediate rotates can be up to three times faster than their register +/// counterparts. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 3.0 +template inline T rotrVariable(T x, unsigned int y) +{ + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + CRYPTOPP_ASSERT(static_cast(y) < THIS_SIZE); + return T((x>>y)|(x<<(-y&MASK))); +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details y is reduced to the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrVariable will use either rotate IMM or rotate REG. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 3.0 +template inline T rotlMod(T x, unsigned int y) +{ + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + return T((x<<(y&MASK))|(x>>(-y&MASK))); +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits wide. +/// \details y is reduced to the range [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrVariable will use either rotate IMM or rotate REG. +/// \sa rotlConstant, rotrConstant, rotlFixed, rotrFixed, rotlVariable, rotrVariable +/// \since Crypto++ 3.0 +template inline T rotrMod(T x, unsigned int y) +{ + CRYPTOPP_CONSTANT(THIS_SIZE = sizeof(T)*8); + CRYPTOPP_CONSTANT(MASK = THIS_SIZE-1); + return T((x>>(y&MASK))|(x<<(-y&MASK))); +} + +#ifdef _MSC_VER + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the 32-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotl provided by +/// . The value x to be rotated is 32-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotlFixed will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word32 rotlFixed(word32 x, unsigned int y) +{ + // Uses Microsoft call, bound to C/C++ language rules. + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _lrotl(x, static_cast(y)) : x; +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the 32-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotr provided by +/// . The value x to be rotated is 32-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrFixed will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word32 rotrFixed(word32 x, unsigned int y) +{ + // Uses Microsoft call, bound to C/C++ language rules. + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _lrotr(x, static_cast(y)) : x; +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the 32-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotl provided by +/// . The value x to be rotated is 32-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotlVariable will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word32 rotlVariable(word32 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return _lrotl(x, static_cast(y)); +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the 32-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotr provided by +/// . The value x to be rotated is 32-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrVariable will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word32 rotrVariable(word32 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return _lrotr(x, static_cast(y)); +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the 32-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotl provided by +/// . The value x to be rotated is 32-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \since Crypto++ 3.0 +template<> inline word32 rotlMod(word32 x, unsigned int y) +{ + y %= 8*sizeof(x); + return _lrotl(x, static_cast(y)); +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the 32-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotr provided by +/// . The value x to be rotated is 32-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \since Crypto++ 3.0 +template<> inline word32 rotrMod(word32 x, unsigned int y) +{ + y %= 8*sizeof(x); + return _lrotr(x, static_cast(y)); +} + +#endif // #ifdef _MSC_VER + +#if (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL)) +// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the 64-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotl provided by +/// . The value x to be rotated is 64-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrFixed will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word64 rotlFixed(word64 x, unsigned int y) +{ + // Uses Microsoft call, bound to C/C++ language rules. + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _rotl64(x, static_cast(y)) : x; +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the 64-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotr provided by +/// . The value x to be rotated is 64-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrFixed will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word64 rotrFixed(word64 x, unsigned int y) +{ + // Uses Microsoft call, bound to C/C++ language rules. + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _rotr64(x, static_cast(y)) : x; +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the 64-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotl provided by +/// . The value x to be rotated is 64-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotlVariable will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word64 rotlVariable(word64 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return _rotl64(x, static_cast(y)); +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the 64-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotr provided by +/// . The value x to be rotated is 64-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \note rotrVariable will assert in Debug builds if is outside the allowed range. +/// \since Crypto++ 3.0 +template<> inline word64 rotrVariable(word64 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _rotr64(x, static_cast(y)) : x; +} + +/// \brief Performs a left rotate +/// \tparam T the word type +/// \param x the 64-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotl provided by +/// . The value x to be rotated is 64-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \since Crypto++ 3.0 +template<> inline word64 rotlMod(word64 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _rotl64(x, static_cast(y)) : x; +} + +/// \brief Performs a right rotate +/// \tparam T the word type +/// \param x the 64-bit value to rotate +/// \param y the number of bit positions to rotate the value +/// \details This is a Microsoft specific implementation using _lrotr provided by +/// . The value x to be rotated is 64-bits. y must be in the range +/// [0, sizeof(T)*8 - 1] to avoid undefined behavior. +/// \since Crypto++ 3.0 +template<> inline word64 rotrMod(word64 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 8*sizeof(x)); + return y ? _rotr64(x, static_cast(y)) : x; +} + +#endif // #if _MSC_VER >= 1310 + +#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) +// Intel C++ Compiler 10.0 gives undefined externals with these +template<> inline word16 rotlFixed(word16 x, unsigned int y) +{ + // Intrinsic, not bound to C/C++ language rules. + return _rotl16(x, static_cast(y)); +} + +template<> inline word16 rotrFixed(word16 x, unsigned int y) +{ + // Intrinsic, not bound to C/C++ language rules. + return _rotr16(x, static_cast(y)); +} + +template<> inline word16 rotlVariable(word16 x, unsigned int y) +{ + return _rotl16(x, static_cast(y)); +} + +template<> inline word16 rotrVariable(word16 x, unsigned int y) +{ + return _rotr16(x, static_cast(y)); +} + +template<> inline word16 rotlMod(word16 x, unsigned int y) +{ + return _rotl16(x, static_cast(y)); +} + +template<> inline word16 rotrMod(word16 x, unsigned int y) +{ + return _rotr16(x, static_cast(y)); +} + +template<> inline byte rotlFixed(byte x, unsigned int y) +{ + // Intrinsic, not bound to C/C++ language rules. + return _rotl8(x, static_cast(y)); +} + +template<> inline byte rotrFixed(byte x, unsigned int y) +{ + // Intrinsic, not bound to C/C++ language rules. + return _rotr8(x, static_cast(y)); +} + +template<> inline byte rotlVariable(byte x, unsigned int y) +{ + return _rotl8(x, static_cast(y)); +} + +template<> inline byte rotrVariable(byte x, unsigned int y) +{ + return _rotr8(x, static_cast(y)); +} + +template<> inline byte rotlMod(byte x, unsigned int y) +{ + return _rotl8(x, static_cast(y)); +} + +template<> inline byte rotrMod(byte x, unsigned int y) +{ + return _rotr8(x, static_cast(y)); +} + +#endif // #if _MSC_VER >= 1400 + +#if (defined(__MWERKS__) && TARGET_CPU_PPC) + +template<> inline word32 rotlFixed(word32 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 32); + return y ? __rlwinm(x,y,0,31) : x; +} + +template<> inline word32 rotrFixed(word32 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 32); + return y ? __rlwinm(x,32-y,0,31) : x; +} + +template<> inline word32 rotlVariable(word32 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 32); + return (__rlwnm(x,y,0,31)); +} + +template<> inline word32 rotrVariable(word32 x, unsigned int y) +{ + CRYPTOPP_ASSERT(y < 32); + return (__rlwnm(x,32-y,0,31)); +} + +template<> inline word32 rotlMod(word32 x, unsigned int y) +{ + return (__rlwnm(x,y,0,31)); +} + +template<> inline word32 rotrMod(word32 x, unsigned int y) +{ + return (__rlwnm(x,32-y,0,31)); +} + +#endif // __MWERKS__ && TARGET_CPU_PPC + +// ************** endian reversal *************** + +/// \brief Gets a byte from a value +/// \param order the ByteOrder of the value +/// \param value the value to retrieve the byte +/// \param index the location of the byte to retrieve +template +inline unsigned int GetByte(ByteOrder order, T value, unsigned int index) +{ + if (order == LITTLE_ENDIAN_ORDER) + return GETBYTE(value, index); + else + return GETBYTE(value, sizeof(T)-index-1); +} + +/// \brief Reverses bytes in a 8-bit value +/// \param value the 8-bit value to reverse +/// \note ByteReverse returns the value passed to it since there is nothing to +/// reverse. +inline byte ByteReverse(byte value) +{ + return value; +} + +/// \brief Reverses bytes in a 16-bit value +/// \param value the 16-bit value to reverse +/// \details ByteReverse calls bswap if available. Otherwise the function +/// performs a 8-bit rotate on the word16. +inline word16 ByteReverse(word16 value) +{ +#if defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_16(value); +#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL)) + return _byteswap_ushort(value); +#else + return rotlFixed(value, 8U); +#endif +} + +/// \brief Reverses bytes in a 32-bit value +/// \param value the 32-bit value to reverse +/// \details ByteReverse calls bswap if available. Otherwise the function uses +/// a combination of rotates on the word32. +inline word32 ByteReverse(word32 value) +{ +#if defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_32(value); +#elif defined(CRYPTOPP_ARM_BYTEREV_AVAILABLE) + word32 rvalue; + __asm__ ("rev %0, %1" : "=r" (rvalue) : "r" (value)); + return rvalue; +#elif defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) + __asm__ ("bswap %0" : "=r" (value) : "0" (value)); + return value; +#elif defined(__MWERKS__) && TARGET_CPU_PPC + return (word32)__lwbrx(&value,0); +#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL)) + return _byteswap_ulong(value); +#elif CRYPTOPP_FAST_ROTATE(32) && !defined(__xlC__) + // 5 instructions with rotate instruction, 9 without + return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); +#else + // 6 instructions with rotate instruction, 8 without + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return rotlFixed(value, 16U); +#endif +} + +/// \brief Reverses bytes in a 64-bit value +/// \param value the 64-bit value to reverse +/// \details ByteReverse calls bswap if available. Otherwise the function uses +/// a combination of rotates on the word64. +inline word64 ByteReverse(word64 value) +{ +#if defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_64(value); +#elif defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__) + __asm__ ("bswap %0" : "=r" (value) : "0" (value)); + return value; +#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL)) + return _byteswap_uint64(value); +#elif CRYPTOPP_BOOL_SLOW_WORD64 + return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); + value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); + return rotlFixed(value, 32U); +#endif +} + +/// \brief Reverses bits in a 8-bit value +/// \param value the 8-bit value to reverse +/// \details BitReverse performs a combination of shifts on the byte. +inline byte BitReverse(byte value) +{ + value = byte((value & 0xAA) >> 1) | byte((value & 0x55) << 1); + value = byte((value & 0xCC) >> 2) | byte((value & 0x33) << 2); + return rotlFixed(value, 4U); +} + +/// \brief Reverses bits in a 16-bit value +/// \param value the 16-bit value to reverse +/// \details BitReverse performs a combination of shifts on the word16. +inline word16 BitReverse(word16 value) +{ +#if defined(CRYPTOPP_ARM_BITREV_AVAILABLE) + // 4 instructions on ARM. + word32 rvalue; + __asm__ ("rbit %0, %1" : "=r" (rvalue) : "r" (value)); + return word16(rvalue >> 16); +#else + // 15 instructions on ARM. + value = word16((value & 0xAAAA) >> 1) | word16((value & 0x5555) << 1); + value = word16((value & 0xCCCC) >> 2) | word16((value & 0x3333) << 2); + value = word16((value & 0xF0F0) >> 4) | word16((value & 0x0F0F) << 4); + return ByteReverse(value); +#endif +} + +/// \brief Reverses bits in a 32-bit value +/// \param value the 32-bit value to reverse +/// \details BitReverse performs a combination of shifts on the word32. +inline word32 BitReverse(word32 value) +{ +#if defined(CRYPTOPP_ARM_BITREV_AVAILABLE) + // 2 instructions on ARM. + word32 rvalue; + __asm__ ("rbit %0, %1" : "=r" (rvalue) : "r" (value)); + return rvalue; +#else + // 19 instructions on ARM. + value = word32((value & 0xAAAAAAAA) >> 1) | word32((value & 0x55555555) << 1); + value = word32((value & 0xCCCCCCCC) >> 2) | word32((value & 0x33333333) << 2); + value = word32((value & 0xF0F0F0F0) >> 4) | word32((value & 0x0F0F0F0F) << 4); + return ByteReverse(value); +#endif +} + +/// \brief Reverses bits in a 64-bit value +/// \param value the 64-bit value to reverse +/// \details BitReverse performs a combination of shifts on the word64. +inline word64 BitReverse(word64 value) +{ +#if CRYPTOPP_BOOL_SLOW_WORD64 + return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32)); +#else + value = word64((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | word64((value & W64LIT(0x5555555555555555)) << 1); + value = word64((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | word64((value & W64LIT(0x3333333333333333)) << 2); + value = word64((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | word64((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); + return ByteReverse(value); +#endif +} + +/// \brief Reverses bits in a value +/// \param value the value to reverse +/// \details The template overload of BitReverse operates on signed and unsigned values. +/// Internally the size of T is checked, and then value is cast to a byte, +/// word16, word32 or word64. After the cast, the appropriate BitReverse +/// overload is called. +template +inline T BitReverse(T value) +{ + if (sizeof(T) == 1) + return (T)BitReverse((byte)value); + else if (sizeof(T) == 2) + return (T)BitReverse((word16)value); + else if (sizeof(T) == 4) + return (T)BitReverse((word32)value); + else if (sizeof(T) == 8) + return (T)BitReverse((word64)value); + else + { + CRYPTOPP_ASSERT(0); + return (T)BitReverse((word64)value); + } +} + +/// \brief Reverses bytes in a value depending upon endianness +/// \tparam T the class or type +/// \param order the ByteOrder of the data +/// \param value the value to conditionally reverse +/// \details Internally, the ConditionalByteReverse calls NativeByteOrderIs. +/// If order matches native byte order, then the original value is returned. +/// If not, then ByteReverse is called on the value before returning to the caller. +template +inline T ConditionalByteReverse(ByteOrder order, T value) +{ + return NativeByteOrderIs(order) ? value : ByteReverse(value); +} + +/// \brief Reverses bytes in an element from an array of elements +/// \tparam T the class or type +/// \param out the output array of elements +/// \param in the input array of elements +/// \param byteCount the total number of bytes in the array +/// \details Internally, ByteReverse visits each element in the in array +/// calls ByteReverse on it, and writes the result to out. +/// \details ByteReverse does not process tail byes, or bytes that are +/// not part of a full element. If T is int (and int is 4 bytes), then +/// byteCount = 10 means only the first 2 elements or 8 bytes are +/// reversed. +/// \details The following program should help illustrate the behavior. +///
vector v1, v2;
+///
+/// v1.push_back(1);
+/// v1.push_back(2);
+/// v1.push_back(3);
+/// v1.push_back(4);
+///
+/// v2.resize(v1.size());
+/// ByteReverse(&v2[0], &v1[0], 16);
+///
+/// cout << "V1: ";
+/// for(unsigned int i = 0; i < v1.size(); i++)
+///   cout << std::hex << v1[i] << " ";
+/// cout << endl;
+///
+/// cout << "V2: ";
+/// for(unsigned int i = 0; i < v2.size(); i++)
+///   cout << std::hex << v2[i] << " ";
+/// cout << endl;
+/// The program above results in the following output. +///
V1: 00000001 00000002 00000003 00000004
+/// V2: 01000000 02000000 03000000 04000000
+/// \sa ConditionalByteReverse +template +void ByteReverse(T *out, const T *in, size_t byteCount) +{ + // Alignment check due to Issues 690 + CRYPTOPP_ASSERT(byteCount % sizeof(T) == 0); + CRYPTOPP_ASSERT(IsAligned(in)); + CRYPTOPP_ASSERT(IsAligned(out)); + + size_t count = byteCount/sizeof(T); + for (size_t i=0; ibyteCount = 10 means only the first 2 elements or 8 bytes are +/// reversed. +/// \sa ByteReverse +template +inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount) +{ + if (!NativeByteOrderIs(order)) + ByteReverse(out, in, byteCount); + else if (in != out) + memcpy_s(out, byteCount, in, byteCount); +} + +template +inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen) +{ + const size_t U = sizeof(T); + CRYPTOPP_ASSERT(inlen <= outlen*U); + memcpy_s(out, outlen*U, in, inlen); + memset_z((byte *)out+inlen, 0, outlen*U-inlen); + ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U)); +} + +inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *) +{ + CRYPTOPP_UNUSED(order); + return block[0]; +} + +inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *) +{ + return (order == BIG_ENDIAN_ORDER) + ? block[1] | (block[0] << 8) + : block[0] | (block[1] << 8); +} + +inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *) +{ + return (order == BIG_ENDIAN_ORDER) + ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24) + : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24); +} + +inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *) +{ + return (order == BIG_ENDIAN_ORDER) + ? + (word64(block[7]) | + (word64(block[6]) << 8) | + (word64(block[5]) << 16) | + (word64(block[4]) << 24) | + (word64(block[3]) << 32) | + (word64(block[2]) << 40) | + (word64(block[1]) << 48) | + (word64(block[0]) << 56)) + : + (word64(block[0]) | + (word64(block[1]) << 8) | + (word64(block[2]) << 16) | + (word64(block[3]) << 24) | + (word64(block[4]) << 32) | + (word64(block[5]) << 40) | + (word64(block[6]) << 48) | + (word64(block[7]) << 56)); +} + +inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock) +{ + CRYPTOPP_UNUSED(order); + block[0] = static_cast(xorBlock ? (value ^ xorBlock[0]) : value); +} + +inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock) +{ + if (order == BIG_ENDIAN_ORDER) + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + } + else + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + } + } +} + +inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock) +{ + if (order == BIG_ENDIAN_ORDER) + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + } + else + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + } + } +} + +inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock) +{ + if (order == BIG_ENDIAN_ORDER) + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + } + else + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + } + } +} + +/// \brief Access a block of memory +/// \tparam T class or type +/// \param assumeAligned flag indicating alignment +/// \param order the ByteOrder of the data +/// \param block the byte buffer to be processed +/// \return the word in the specified byte order +/// \details GetWord() provides alternate read access to a block of memory. The flag assumeAligned indicates +/// if the memory block is aligned for class or type T. The enumeration ByteOrder is BIG_ENDIAN_ORDER or +/// LITTLE_ENDIAN_ORDER. +/// \details An example of reading two word32 values from a block of memory is shown below. w +/// will be 0x03020100. +///
+///   word32 w;
+///   byte buffer[4] = {0,1,2,3};
+///   w = GetWord(false, LITTLE_ENDIAN_ORDER, buffer);
+/// 
+template +inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block) +{ + CRYPTOPP_UNUSED(assumeAligned); + + T temp = 0; + if (block != NULLPTR) {std::memcpy(&temp, block, sizeof(T));} + return ConditionalByteReverse(order, temp); +} + +/// \brief Access a block of memory +/// \tparam T class or type +/// \param assumeAligned flag indicating alignment +/// \param order the ByteOrder of the data +/// \param result the word in the specified byte order +/// \param block the byte buffer to be processed +/// \details GetWord() provides alternate read access to a block of memory. The flag assumeAligned indicates +/// if the memory block is aligned for class or type T. The enumeration ByteOrder is BIG_ENDIAN_ORDER or +/// LITTLE_ENDIAN_ORDER. +/// \details An example of reading two word32 values from a block of memory is shown below. w +/// will be 0x03020100. +///
+///   word32 w;
+///   byte buffer[4] = {0,1,2,3};
+///   w = GetWord(false, LITTLE_ENDIAN_ORDER, buffer);
+/// 
+template +inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block) +{ + result = GetWord(assumeAligned, order, block); +} + +/// \brief Access a block of memory +/// \tparam T class or type +/// \param assumeAligned flag indicating alignment +/// \param order the ByteOrder of the data +/// \param block the destination byte buffer +/// \param value the word in the specified byte order +/// \param xorBlock an optional byte buffer to xor +/// \details PutWord() provides alternate write access to a block of memory. The flag assumeAligned indicates +/// if the memory block is aligned for class or type T. The enumeration ByteOrder is BIG_ENDIAN_ORDER or +/// LITTLE_ENDIAN_ORDER. +template +inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULLPTR) +{ + CRYPTOPP_UNUSED(assumeAligned); + + T t1, t2; + t1 = ConditionalByteReverse(order, value); + if (xorBlock != NULLPTR) {std::memcpy(&t2, xorBlock, sizeof(T)); t1 ^= t2;} + if (block != NULLPTR) {std::memcpy(block, &t1, sizeof(T));} +} + +/// \brief Access a block of memory +/// \tparam T class or type +/// \tparam B enumeration indicating endianness +/// \tparam A flag indicating alignment +/// \details GetBlock() provides alternate read access to a block of memory. The enumeration B is +/// BigEndian or LittleEndian. The flag A indicates if the memory block is aligned for class or type T. +/// Repeatedly applying operator() results in advancing in the block of memory. +/// \details An example of reading two word32 values from a block of memory is shown below. w1 +/// will be 0x03020100 and w1 will be 0x07060504. +///
+///   word32 w1, w2;
+///   byte buffer[8] = {0,1,2,3,4,5,6,7};
+///   GetBlock block(buffer);
+///   block(w1)(w2);
+/// 
+template +class GetBlock +{ +public: + /// \brief Construct a GetBlock + /// \param block the memory block + GetBlock(const void *block) + : m_block((const byte *)block) {} + + /// \brief Access a block of memory + /// \tparam U class or type + /// \param x the value to read + /// \return pointer to the remainder of the block after reading x + template + inline GetBlock & operator()(U &x) + { + CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T)); + x = GetWord(A, B::ToEnum(), m_block); + m_block += sizeof(T); + return *this; + } + +private: + const byte *m_block; +}; + +/// \brief Access a block of memory +/// \tparam T class or type +/// \tparam B enumeration indicating endianness +/// \tparam A flag indicating alignment +/// \details PutBlock() provides alternate write access to a block of memory. The enumeration B is +/// BigEndian or LittleEndian. The flag A indicates if the memory block is aligned for class or type T. +/// Repeatedly applying operator() results in advancing in the block of memory. +/// \details An example of writing two word32 values from a block of memory is shown below. After the code +/// executes, the byte buffer will be {0,1,2,3,4,5,6,7}. +///
+///   word32 w1=0x03020100, w2=0x07060504;
+///   byte buffer[8];
+///   PutBlock block(NULLPTR, buffer);
+///   block(w1)(w2);
+/// 
+template +class PutBlock +{ +public: + /// \brief Construct a PutBlock + /// \param block the memory block + /// \param xorBlock optional mask + PutBlock(const void *xorBlock, void *block) + : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {} + + /// \brief Access a block of memory + /// \tparam U class or type + /// \param x the value to write + /// \return pointer to the remainder of the block after writing x + template + inline PutBlock & operator()(U x) + { + PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock); + m_block += sizeof(T); + if (m_xorBlock) + m_xorBlock += sizeof(T); + return *this; + } + +private: + const byte *m_xorBlock; + byte *m_block; +}; + +/// \brief Access a block of memory +/// \tparam T class or type +/// \tparam B enumeration indicating endianness +/// \tparam GA flag indicating alignment for the Get operation +/// \tparam PA flag indicating alignment for the Put operation +/// \details GetBlock() provides alternate write access to a block of memory. The enumeration B is +/// BigEndian or LittleEndian. The flag A indicates if the memory block is aligned for class or type T. +/// \sa GetBlock() and PutBlock(). +template +struct BlockGetAndPut +{ + // function needed because of C++ grammatical ambiguity between expression-statements and declarations + static inline GetBlock Get(const void *block) {return GetBlock(block);} + typedef PutBlock Put; +}; + +/// \brief Convert a word to a string +/// \tparam T class or type +/// \param value the word to convert +/// \param order byte order +/// \return a string representing the value of the word +template +std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER) +{ + if (!NativeByteOrderIs(order)) + value = ByteReverse(value); + + return std::string((char *)&value, sizeof(value)); +} + +/// \brief Convert a string to a word +/// \tparam T class or type +/// \param str the string to convert +/// \param order byte order +/// \return a word representing the value of the string +template +T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER) +{ + T value = 0; + memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value))); + return NativeByteOrderIs(order) ? value : ByteReverse(value); +} + +// ************** help remove warning on g++ *************** + +/// \brief Safely shift values when undefined behavior could occur +/// \tparam overflow boolean flag indicating if overflow is present +/// \details SafeShifter safely shifts values when undefined behavior could occur under C/C++ rules. +/// The class behaves much like a saturating arithmetic class, clamping values rather than allowing +/// the compiler to remove undefined behavior. +/// \sa SafeShifter, SafeShifter +template struct SafeShifter; + +/// \brief Shifts a value in the presence of overflow +/// \details the true template parameter indicates overflow would occur. +/// In this case, SafeShifter clamps the value and returns 0. +template<> struct SafeShifter +{ + /// \brief Right shifts a value that overflows + /// \tparam T class or type + /// \return 0 + /// \details Since overflow == true, the value 0 is always returned. + /// \sa SafeLeftShift + template + static inline T RightShift(T value, unsigned int bits) + { + CRYPTOPP_UNUSED(value); CRYPTOPP_UNUSED(bits); + return 0; + } + + /// \brief Left shifts a value that overflows + /// \tparam T class or type + /// \return 0 + /// \details Since overflow == true, the value 0 is always returned. + /// \sa SafeRightShift + template + static inline T LeftShift(T value, unsigned int bits) + { + CRYPTOPP_UNUSED(value); CRYPTOPP_UNUSED(bits); + return 0; + } +}; + +/// \brief Shifts a value in the absence of overflow +/// \details the false template parameter indicates overflow would not occur. +/// In this case, SafeShifter returns the shfted value. +template<> struct SafeShifter +{ + /// \brief Right shifts a value that does not overflow + /// \tparam T class or type + /// \return the shifted value + /// \details Since overflow == false, the shifted value is returned. + /// \sa SafeLeftShift + template + static inline T RightShift(T value, unsigned int bits) + { + return value >> bits; + } + + /// \brief Left shifts a value that does not overflow + /// \tparam T class or type + /// \return the shifted value + /// \details Since overflow == false, the shifted value is returned. + /// \sa SafeRightShift + template + static inline T LeftShift(T value, unsigned int bits) + { + return value << bits; + } +}; + +/// \brief Safely right shift values when undefined behavior could occur +/// \tparam bits the number of bit positions to shift the value +/// \tparam T class or type +/// \param value the value to right shift +/// \result the shifted value or 0 +/// \details SafeRightShift safely shifts the value to the right when undefined behavior +/// could occur under C/C++ rules. SafeRightShift will return the shifted value or 0 +/// if undefined behavior would occur. +template +inline T SafeRightShift(T value) +{ + return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits); +} + +/// \brief Safely left shift values when undefined behavior could occur +/// \tparam bits the number of bit positions to shift the value +/// \tparam T class or type +/// \param value the value to left shift +/// \result the shifted value or 0 +/// \details SafeLeftShift safely shifts the value to the left when undefined behavior +/// could occur under C/C++ rules. SafeLeftShift will return the shifted value or 0 +/// if undefined behavior would occur. +template +inline T SafeLeftShift(T value) +{ + return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits); +} + +/// \brief Finds first element not in a range +/// \tparam InputIt Input iterator type +/// \tparam T class or type +/// \param first iterator to first element +/// \param last iterator to last element +/// \param value the value used as a predicate +/// \return iterator to the first element in the range that is not value +template +inline InputIt FindIfNot(InputIt first, InputIt last, const T &value) { +#ifdef CRYPTOPP_CXX11_LAMBDA + return std::find_if(first, last, [&value](const T &o) { + return value!=o; + }); +#else + return std::find_if(first, last, std::bind2nd(std::not_equal_to(), value)); +#endif +} + +// ************** use one buffer for multiple data members *************** + +#define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+0);} size_t SS1() {return sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(void *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate; + +NAMESPACE_END + +#if (CRYPTOPP_MSC_VERSION) +# pragma warning(pop) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/modarith.h b/external/ours/library/crypto/src/shared/original/modarith.h new file mode 100755 index 000000000..a92aafe97 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/modarith.h @@ -0,0 +1,344 @@ +// modarith.h - originally written and placed in the public domain by Wei Dai + +/// \file modarith.h +/// \brief Class file for performing modular arithmetic. + +#ifndef CRYPTOPP_MODARITH_H +#define CRYPTOPP_MODARITH_H + +// implementations are in integer.cpp + +#include "cryptlib.h" +#include "integer.h" +#include "algebra.h" +#include "secblock.h" +#include "misc.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain; + +/// \brief Ring of congruence classes modulo n +/// \details This implementation represents each congruence class as +/// the smallest non-negative integer in that class. +/// \details const Element& returned by member functions are +/// references to internal data members. Since each object may have +/// only one such data member for holding results, you should use the +/// class like this: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+/// The following code will produce incorrect results: +///
    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// \details If a ModularArithmetic() is copied or assigned the modulus +/// is copied, but not the internal data members. The internal data +/// members are undefined after copy or assignment. +/// \sa Integer on the +/// Crypto++ wiki. +class CRYPTOPP_DLL ModularArithmetic : public AbstractRing +{ +public: + + typedef int RandomizationParameter; + typedef Integer Element; + + virtual ~ModularArithmetic() {} + + /// \brief Construct a ModularArithmetic + /// \param modulus congruence class modulus + ModularArithmetic(const Integer &modulus = Integer::One()) + : m_modulus(modulus), m_result(static_cast(0), modulus.reg.size()) {} + + /// \brief Copy construct a ModularArithmetic + /// \param ma other ModularArithmetic + ModularArithmetic(const ModularArithmetic &ma) + : AbstractRing(ma), m_modulus(ma.m_modulus), m_result(static_cast(0), m_modulus.reg.size()) {} + + /// \brief Assign a ModularArithmetic + /// \param ma other ModularArithmetic + ModularArithmetic& operator=(const ModularArithmetic &ma) { + if (this != &ma) + { + m_modulus = ma.m_modulus; + m_result = Integer(static_cast(0), m_modulus.reg.size()); + } + return *this; + } + + /// \brief Construct a ModularArithmetic + /// \param bt BER encoded ModularArithmetic + ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters + + /// \brief Clone a ModularArithmetic + /// \return pointer to a new ModularArithmetic + /// \details Clone effectively copy constructs a new ModularArithmetic. The caller is + /// responsible for deleting the pointer returned from this method. + virtual ModularArithmetic * Clone() const {return new ModularArithmetic(*this);} + + /// \brief Encodes in DER format + /// \param bt BufferedTransformation object + void DEREncode(BufferedTransformation &bt) const; + + /// \brief Encodes element in DER format + /// \param out BufferedTransformation object + /// \param a Element to encode + void DEREncodeElement(BufferedTransformation &out, const Element &a) const; + + /// \brief Decodes element in DER format + /// \param in BufferedTransformation object + /// \param a Element to decode + void BERDecodeElement(BufferedTransformation &in, Element &a) const; + + /// \brief Retrieves the modulus + /// \return the modulus + const Integer& GetModulus() const {return m_modulus;} + + /// \brief Sets the modulus + /// \param newModulus the new modulus + void SetModulus(const Integer &newModulus) + {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());} + + /// \brief Retrieves the representation + /// \return true if the if the modulus is in Montgomery form for multiplication, false otherwise + virtual bool IsMontgomeryRepresentation() const {return false;} + + /// \brief Reduces an element in the congruence class + /// \param a element to convert + /// \return the reduced element + /// \details ConvertIn is useful for derived classes, like MontgomeryRepresentation, which + /// must convert between representations. + virtual Integer ConvertIn(const Integer &a) const + {return a%m_modulus;} + + /// \brief Reduces an element in the congruence class + /// \param a element to convert + /// \return the reduced element + /// \details ConvertOut is useful for derived classes, like MontgomeryRepresentation, which + /// must convert between representations. + virtual Integer ConvertOut(const Integer &a) const + {return a;} + + /// \brief Divides an element by 2 + /// \param a element to convert + const Integer& Half(const Integer &a) const; + + /// \brief Compare two elements for equality + /// \param a first element + /// \param b second element + /// \return true if the elements are equal, false otherwise + /// \details Equal() tests the elements for equality using a==b + bool Equal(const Integer &a, const Integer &b) const + {return a==b;} + + /// \brief Provides the Identity element + /// \return the Identity element + const Integer& Identity() const + {return Integer::Zero();} + + /// \brief Adds elements in the ring + /// \param a first element + /// \param b second element + /// \return the sum of a and b + const Integer& Add(const Integer &a, const Integer &b) const; + + /// \brief TODO + /// \param a first element + /// \param b second element + /// \return TODO + Integer& Accumulate(Integer &a, const Integer &b) const; + + /// \brief Inverts the element in the ring + /// \param a first element + /// \return the inverse of the element + const Integer& Inverse(const Integer &a) const; + + /// \brief Subtracts elements in the ring + /// \param a first element + /// \param b second element + /// \return the difference of a and b. The element a must provide a Subtract member function. + const Integer& Subtract(const Integer &a, const Integer &b) const; + + /// \brief TODO + /// \param a first element + /// \param b second element + /// \return TODO + Integer& Reduce(Integer &a, const Integer &b) const; + + /// \brief Doubles an element in the ring + /// \param a the element + /// \return the element doubled + /// \details Double returns Add(a, a). The element a must provide an Add member function. + const Integer& Double(const Integer &a) const + {return Add(a, a);} + + /// \brief Retrieves the multiplicative identity + /// \return the multiplicative identity + /// \details the base class implementations returns 1. + const Integer& MultiplicativeIdentity() const + {return Integer::One();} + + /// \brief Multiplies elements in the ring + /// \param a the multiplicand + /// \param b the multiplier + /// \return the product of a and b + /// \details Multiply returns a*b\%n. + const Integer& Multiply(const Integer &a, const Integer &b) const + {return m_result1 = a*b%m_modulus;} + + /// \brief Square an element in the ring + /// \param a the element + /// \return the element squared + /// \details Square returns a*a\%n. The element a must provide a Square member function. + const Integer& Square(const Integer &a) const + {return m_result1 = a.Squared()%m_modulus;} + + /// \brief Determines whether an element is a unit in the ring + /// \param a the element + /// \return true if the element is a unit after reduction, false otherwise. + bool IsUnit(const Integer &a) const + {return Integer::Gcd(a, m_modulus).IsUnit();} + + /// \brief Calculate the multiplicative inverse of an element in the ring + /// \param a the element + /// \details MultiplicativeInverse returns a-1\%n. The element a must + /// provide a InverseMod member function. + const Integer& MultiplicativeInverse(const Integer &a) const + {return m_result1 = a.InverseMod(m_modulus);} + + /// \brief Divides elements in the ring + /// \param a the dividend + /// \param b the divisor + /// \return the quotient + /// \details Divide returns a*b-1\%n. + const Integer& Divide(const Integer &a, const Integer &b) const + {return Multiply(a, MultiplicativeInverse(b));} + + /// \brief TODO + /// \param x first element + /// \param e1 first exponent + /// \param y second element + /// \param e2 second exponent + /// \return TODO + Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const; + + /// \brief Exponentiates a base to multiple exponents in the ring + /// \param results an array of Elements + /// \param base the base to raise to the exponents + /// \param exponents an array of exponents + /// \param exponentsCount the number of exponents in the array + /// \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the + /// result at the respective position in the results array. + /// \details SimultaneousExponentiate() must be implemented in a derived class. + /// \pre COUNTOF(results) == exponentsCount + /// \pre COUNTOF(exponents) == exponentsCount + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + + /// \brief Provides the maximum bit size of an element in the ring + /// \return maximum bit size of an element + unsigned int MaxElementBitLength() const + {return (m_modulus-1).BitCount();} + + /// \brief Provides the maximum byte size of an element in the ring + /// \return maximum byte size of an element + unsigned int MaxElementByteLength() const + {return (m_modulus-1).ByteCount();} + + /// \brief Provides a random element in the ring + /// \param rng RandomNumberGenerator used to generate material + /// \param ignore_for_now unused + /// \return a random element that is uniformly distributed + /// \details RandomElement constructs a new element in the range [0,n-1], inclusive. + /// The element's class must provide a constructor with the signature Element(RandomNumberGenerator rng, + /// Element min, Element max). + Element RandomElement(RandomNumberGenerator &rng, const RandomizationParameter &ignore_for_now = 0) const + // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct + { + CRYPTOPP_UNUSED(ignore_for_now); + return Element(rng, Integer::Zero(), m_modulus - Integer::One()) ; + } + + /// \brief Compares two ModularArithmetic for equality + /// \param rhs other ModularArithmetic + /// \return true if this is equal to the other, false otherwise + /// \details The operator tests for equality using this.m_modulus == rhs.m_modulus. + bool operator==(const ModularArithmetic &rhs) const + {return m_modulus == rhs.m_modulus;} + + static const RandomizationParameter DefaultRandomizationParameter; + +private: + // TODO: Clang on OS X needs a real operator=. + // Squash warning on missing assignment operator. + // ModularArithmetic& operator=(const ModularArithmetic &ma); + +protected: + Integer m_modulus; + mutable Integer m_result, m_result1; +}; + +// const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ; + +/// \brief Performs modular arithmetic in Montgomery representation for increased speed +/// \details The Montgomery representation represents each congruence class [a] as +/// a*r\%n, where r is a convenient power of 2. +/// \details const Element& returned by member functions are references to +/// internal data members. Since each object may have only one such data member for holding +/// results, the following code will produce incorrect results: +///
    abcd = group.Add(group.Add(a,b), group.Add(c,d));
+/// But this should be fine: +///
    abcd = group.Add(a, group.Add(b, group.Add(c,d));
+class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic +{ +public: + virtual ~MontgomeryRepresentation() {} + + /// \brief Construct a MontgomeryRepresentation + /// \param modulus congruence class modulus + /// \note The modulus must be odd. + MontgomeryRepresentation(const Integer &modulus); + + /// \brief Clone a MontgomeryRepresentation + /// \return pointer to a new MontgomeryRepresentation + /// \details Clone effectively copy constructs a new MontgomeryRepresentation. The caller is + /// responsible for deleting the pointer returned from this method. + virtual ModularArithmetic * Clone() const {return new MontgomeryRepresentation(*this);} + + bool IsMontgomeryRepresentation() const {return true;} + + Integer ConvertIn(const Integer &a) const + {return (a<<(WORD_BITS*m_modulus.reg.size()))%m_modulus;} + + Integer ConvertOut(const Integer &a) const; + + const Integer& MultiplicativeIdentity() const + {return m_result1 = Integer::Power2(WORD_BITS*m_modulus.reg.size())%m_modulus;} + + const Integer& Multiply(const Integer &a, const Integer &b) const; + + const Integer& Square(const Integer &a) const; + + const Integer& MultiplicativeInverse(const Integer &a) const; + + Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const + {return AbstractRing::CascadeExponentiate(x, e1, y, e2);} + + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const + {AbstractRing::SimultaneousExponentiate(results, base, exponents, exponentsCount);} + +private: + Integer m_u; + mutable IntegerSecBlock m_workspace; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/modes.cpp b/external/ours/library/crypto/src/shared/original/modes.cpp new file mode 100755 index 000000000..a95e7a952 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/modes.cpp @@ -0,0 +1,306 @@ +// modes.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "modes.h" +#include "misc.h" + +#if defined(CRYPTOPP_DEBUG) +#include "des.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void Modes_TestInstantiations() +{ + CFB_Mode::Encryption m0; + CFB_Mode::Decryption m1; + OFB_Mode::Encryption m2; + CTR_Mode::Encryption m3; + ECB_Mode::Encryption m4; + CBC_Mode::Encryption m5; +} +#endif + +void CipherModeBase::ResizeBuffers() +{ + m_register.New(m_cipher->BlockSize()); +} + +void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) +{ + CRYPTOPP_ASSERT(input); CRYPTOPP_ASSERT(output); + CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + CRYPTOPP_ASSERT(m_temp.size() == BlockSize()); + CRYPTOPP_ASSERT(iterationCount > 0); + + const unsigned int s = BlockSize(); + if (dir == ENCRYPTION) + { + m_cipher->ProcessAndXorBlock(m_register, input, output); + if (iterationCount > 1) + m_cipher->AdvancedProcessBlocks(output, PtrAdd(input,s), PtrAdd(output,s), (iterationCount-1)*s, 0); + memcpy(m_register, PtrAdd(output,(iterationCount-1)*s), s); + } + else + { + // make copy first in case of in-place decryption + memcpy(m_temp, PtrAdd(input,(iterationCount-1)*s), s); + if (iterationCount > 1) + m_cipher->AdvancedProcessBlocks(input, PtrAdd(input,s), PtrAdd(output,s), (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection); + m_cipher->ProcessAndXorBlock(m_register, input, output); + memcpy(m_register, m_temp, s); + } +} + +void CFB_ModePolicy::TransformRegister() +{ + CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + CRYPTOPP_ASSERT(m_temp.size() == BlockSize()); + + const ptrdiff_t updateSize = BlockSize()-m_feedbackSize; + m_cipher->ProcessBlock(m_register, m_temp); + memmove_s(m_register, m_register.size(), PtrAdd(m_register.begin(),m_feedbackSize), updateSize); + memcpy_s(PtrAdd(m_register.begin(),updateSize), m_register.size()-updateSize, m_temp, m_feedbackSize); +} + +void CFB_ModePolicy::CipherResynchronize(const byte *iv, size_t length) +{ + CRYPTOPP_ASSERT(length == BlockSize()); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + + CopyOrZero(m_register, m_register.size(), iv, length); + TransformRegister(); +} + +void CFB_ModePolicy::SetFeedbackSize(unsigned int feedbackSize) +{ + if (feedbackSize > BlockSize()) + throw InvalidArgument("CFB_Mode: invalid feedback size"); + m_feedbackSize = feedbackSize ? feedbackSize : BlockSize(); +} + +void CFB_ModePolicy::ResizeBuffers() +{ + CipherModeBase::ResizeBuffers(); + m_temp.New(BlockSize()); +} + +byte* CFB_ModePolicy::GetRegisterBegin() +{ + CRYPTOPP_ASSERT(!m_register.empty()); + CRYPTOPP_ASSERT(BlockSize() >= m_feedbackSize); + return PtrAdd(m_register.begin(), BlockSize() - m_feedbackSize); +} + +void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount) +{ + CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + CRYPTOPP_ASSERT(iterationCount > 0); + + const unsigned int s = BlockSize(); + m_cipher->ProcessBlock(m_register, keystreamBuffer); + if (iterationCount > 1) + m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULLPTR, PtrAdd(keystreamBuffer, s), s*(iterationCount-1), 0); + memcpy(m_register, PtrAdd(keystreamBuffer, (iterationCount-1)*s), s); +} + +void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + CRYPTOPP_ASSERT(length == BlockSize()); + + CopyOrZero(m_register, m_register.size(), iv, length); +} + +void CTR_ModePolicy::SeekToIteration(lword iterationCount) +{ + int carry=0; + for (int i=BlockSize()-1; i>=0; i--) + { + unsigned int sum = m_register[i] + (byte)iterationCount + carry; + m_counterArray[i] = byte(sum & 0xff); + carry = sum >> 8; + iterationCount >>= 8; + } +} + +void CTR_ModePolicy::IncrementCounterBy256() +{ + IncrementCounterByOne(m_counterArray, BlockSize()-1); +} + +void CTR_ModePolicy::OperateKeystream(KeystreamOperation /*operation*/, byte *output, const byte *input, size_t iterationCount) +{ + CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); + CRYPTOPP_ASSERT(m_counterArray.size() == BlockSize()); + + const unsigned int s = BlockSize(); + const unsigned int inputIncrement = input ? s : 0; + + while (iterationCount) + { + const byte lsb = m_counterArray[s-1]; + const size_t blocks = UnsignedMin(iterationCount, 256U-lsb); + + m_cipher->AdvancedProcessBlocks(m_counterArray, input, output, blocks*s, BlockTransformation::BT_InBlockIsCounter|BlockTransformation::BT_AllowParallel); + if ((m_counterArray[s-1] = byte(lsb + blocks)) == 0) + IncrementCounterBy256(); + + output = PtrAdd(output, blocks*s); + input = PtrAdd(input, blocks*inputIncrement); + iterationCount -= blocks; + } +} + +void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + CRYPTOPP_ASSERT(length == BlockSize()); + + CopyOrZero(m_register, m_register.size(), iv, length); + m_counterArray.Assign(m_register.begin(), m_register.size()); +} + +void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + m_cipher->SetKey(key, length, params); + ResizeBuffers(); + if (IsResynchronizable()) + { + size_t ivLength; + const byte *iv = GetIVAndThrowIfInvalid(params, ivLength); + Resynchronize(iv, (int)ivLength); + } +} + +void BlockOrientedCipherModeBase::ResizeBuffers() +{ + CipherModeBase::ResizeBuffers(); + m_buffer.New(BlockSize()); +} + +void ECB_OneWay::ProcessData(byte *outString, const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(length%BlockSize()==0); + m_cipher->AdvancedProcessBlocks(inString, NULLPTR, outString, length, BlockTransformation::BT_AllowParallel); +} + +void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(length%BlockSize()==0); + CRYPTOPP_ASSERT(m_register.size() == BlockSize()); + if (!length) return; + + const unsigned int blockSize = BlockSize(); + m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput); + if (length > blockSize) + m_cipher->AdvancedProcessBlocks(PtrAdd(inString,blockSize), outString, PtrAdd(outString,blockSize), length-blockSize, BlockTransformation::BT_XorInput); + memcpy(m_register, PtrAdd(outString, length - blockSize), blockSize); +} + +size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) +{ + CRYPTOPP_UNUSED(outLength); + const size_t used = inLength; + const unsigned int blockSize = BlockSize(); + + if (inLength <= blockSize) + { + if (!m_stolenIV) + throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing"); + + // steal from IV + memcpy(outString, m_register, inLength); + outString = m_stolenIV; + } + else + { + // steal from next to last block + xorbuf(m_register, inString, blockSize); + m_cipher->ProcessBlock(m_register); + inString = PtrAdd(inString, blockSize); + inLength -= blockSize; + memcpy(PtrAdd(outString, blockSize), m_register, inLength); + } + + // output last full ciphertext block + xorbuf(m_register, inString, inLength); + m_cipher->ProcessBlock(m_register); + memcpy(outString, m_register, blockSize); + + return used; +} + +void CBC_Decryption::ResizeBuffers() +{ + BlockOrientedCipherModeBase::ResizeBuffers(); + m_temp.New(BlockSize()); +} + +void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(length%BlockSize()==0); + if (!length) {return;} + + // save copy now in case of in-place decryption + const unsigned int blockSize = BlockSize(); + memcpy(m_temp, PtrAdd(inString, length-blockSize), blockSize); + if (length > blockSize) + m_cipher->AdvancedProcessBlocks(PtrAdd(inString,blockSize), inString, PtrAdd(outString,blockSize), length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel); + m_cipher->ProcessAndXorBlock(inString, m_register, outString); + m_register.swap(m_temp); +} + +size_t CBC_CTS_Decryption::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) +{ + CRYPTOPP_UNUSED(outLength); + const byte *pn1, *pn2; + const size_t used = inLength; + const bool stealIV = inLength <= BlockSize(); + const unsigned int blockSize = BlockSize(); + + if (stealIV) + { + pn1 = inString; + pn2 = m_register; + } + else + { + pn1 = PtrAdd(inString, blockSize); + pn2 = inString; + inLength -= blockSize; + } + + // decrypt last partial plaintext block + memcpy(m_temp, pn2, blockSize); + m_cipher->ProcessBlock(m_temp); + xorbuf(m_temp, pn1, inLength); + + if (stealIV) + { + memcpy(outString, m_temp, inLength); + } + else + { + memcpy(PtrAdd(outString, blockSize), m_temp, inLength); + // decrypt next to last plaintext block + memcpy(m_temp, pn1, inLength); + m_cipher->ProcessBlock(m_temp); + xorbuf(outString, m_temp, m_register, blockSize); + } + + return used; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/modes.h b/external/ours/library/crypto/src/shared/original/modes.h new file mode 100755 index 000000000..0bf1131d4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/modes.h @@ -0,0 +1,609 @@ +// modes.h - originally written and placed in the public domain by Wei Dai + +/// \file modes.h +/// \brief Classes for block cipher modes of operation + +#ifndef CRYPTOPP_MODES_H +#define CRYPTOPP_MODES_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" +#include "strciphr.h" +#include "argnames.h" +#include "algparam.h" + +// Issue 340 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6011 6386 28193) +# endif +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Block cipher mode of operation information +/// \details Each class derived from this one defines two types, Encryption and Decryption, +/// both of which implement the SymmetricCipher interface. +/// For each mode there are two classes, one of which is a template class, +/// and the other one has a name that ends in "_ExternalCipher". +/// The "external cipher" mode objects hold a reference to the underlying block cipher, +/// instead of holding an instance of it. The reference must be passed in to the constructor. +/// For the "cipher holder" classes, the CIPHER template parameter should be a class +/// derived from BlockCipherDocumentation, for example DES or AES. +/// \details See NIST SP 800-38A for definitions of these modes. See +/// AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes. +struct CipherModeDocumentation : public SymmetricCipherDocumentation +{ +}; + +/// \brief Block cipher mode of operation information +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher +{ +public: + virtual ~CipherModeBase() {} + + // Algorithm class + std::string AlgorithmProvider() const { + return m_cipher != NULLPTR ? m_cipher->AlgorithmProvider() : "C++"; + } + + /// \brief Returns smallest valid key length + /// \return the minimum key length, in bytes + size_t MinKeyLength() const {return m_cipher->MinKeyLength();} + + /// \brief Returns largest valid key length + /// \return the maximum key length, in bytes + size_t MaxKeyLength() const {return m_cipher->MaxKeyLength();} + + /// \brief Returns default key length + /// \return the default key length, in bytes + size_t DefaultKeyLength() const {return m_cipher->DefaultKeyLength();} + + /// \brief Returns a valid key length for the algorithm + /// \param keylength the size of the key, in bytes + /// \return the valid key length, in bytes + /// \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH, + /// then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, + /// then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE, + /// then keylength is returned. Otherwise, the function returns a \a lower multiple of + /// KEYLENGTH_MULTIPLE. + size_t GetValidKeyLength(size_t keylength) const {return m_cipher->GetValidKeyLength(keylength);} + + /// \brief Returns whether keylength is a valid key length + /// \param keylength the requested keylength + /// \return true if keylength is valid, false otherwise + /// \details Internally the function calls GetValidKeyLength() + bool IsValidKeyLength(size_t keylength) const {return m_cipher->IsValidKeyLength(keylength);} + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const {return m_cipher->OptimalDataAlignment();} + + /// \brief Returns length of the IV accepted by this object + /// \return the size of an IV, in bytes + /// \throw NotImplemented() if the object does not support resynchronization + /// \details The default implementation throws NotImplemented + unsigned int IVSize() const {return BlockSize();} + + /// \brief Minimal requirement for secure IVs + /// \return the secure IV requirement of the algorithm + virtual IV_Requirement IVRequirement() const =0; + + /// \brief Set external block cipher + /// \param cipher An external block cipher + /// \details The cipher should be keyed. + void SetCipher(BlockCipher &cipher) + { + this->ThrowIfResynchronizable(); + this->m_cipher = &cipher; + this->ResizeBuffers(); + } + + /// \brief Set external block cipher and IV + /// \param cipher An external block cipher + /// \param iv a byte array used to resynchronize the cipher + /// \param feedbackSize the feedback size, in bytes + /// \details The cipher should be keyed. + void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize = 0) + { + this->ThrowIfInvalidIV(iv); + this->m_cipher = &cipher; + this->ResizeBuffers(); + this->SetFeedbackSize(feedbackSize); + if (this->IsResynchronizable()) + this->Resynchronize(iv); + } + +protected: + CipherModeBase() : m_cipher(NULLPTR) {} + inline unsigned int BlockSize() const + { + CRYPTOPP_ASSERT(m_register.size() > 0); + return static_cast(m_register.size()); + } + virtual void SetFeedbackSize(unsigned int feedbackSize) + { + if (!(feedbackSize == 0 || feedbackSize == BlockSize())) + throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode"); + } + + virtual void ResizeBuffers(); + + BlockCipher *m_cipher; + SecByteBlock m_register; +}; + +/// \brief Block cipher mode of operation common operations +/// \tparam POLICY_INTERFACE common operations +template +class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE +{ + unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();} + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); +}; + +template +void ModePolicyCommonTemplate::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + m_cipher->SetKey(key, length, params); + ResizeBuffers(); + int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0); + SetFeedbackSize(feedbackSize); +} + +/// \brief CFB block cipher mode of operation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CFB";} + + virtual ~CFB_ModePolicy() {} + CFB_ModePolicy() : m_feedbackSize(0) {} + IV_Requirement IVRequirement() const {return RANDOM_IV;} + +protected: + unsigned int GetBytesPerIteration() const {return m_feedbackSize;} + bool CanIterate() const {return m_feedbackSize == BlockSize();} + void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount); + void TransformRegister(); + void CipherResynchronize(const byte *iv, size_t length); + void SetFeedbackSize(unsigned int feedbackSize); + void ResizeBuffers(); + byte * GetRegisterBegin(); + + SecByteBlock m_temp; + unsigned int m_feedbackSize; +}; + +/// \brief Initialize a block of memory +/// \param dest the destination block of memory +/// \param dsize the size of the destination block, in bytes +/// \param src the source block of memory +/// \param ssize the size of the source block, in bytes +/// \details CopyOrZero copies ssize bytes from source to destination if +/// src is not NULL. If src is NULL then dest is zero'd. Bounds are not +/// checked at runtime. Debug builds assert if ssize exceeds dsize. +inline void CopyOrZero(void *dest, size_t dsize, const void *src, size_t ssize) +{ + CRYPTOPP_ASSERT(dest); + CRYPTOPP_ASSERT(dsize >= ssize); + + if (src != NULLPTR) + memcpy_s(dest, dsize, src, ssize); + else + memset(dest, 0, dsize); +} + +/// \brief OFB block cipher mode of operation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTemplate +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "OFB";} + + bool CipherIsRandomAccess() const {return false;} + IV_Requirement IVRequirement() const {return UNIQUE_IV;} + +protected: + unsigned int GetBytesPerIteration() const {return BlockSize();} + unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();} + void WriteKeystream(byte *keystreamBuffer, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); +}; + +/// \brief CTR block cipher mode of operation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTemplate +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CTR";} + + virtual ~CTR_ModePolicy() {} + bool CipherIsRandomAccess() const {return true;} + IV_Requirement IVRequirement() const {return RANDOM_IV;} + +protected: + virtual void IncrementCounterBy256(); + unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();} + unsigned int GetBytesPerIteration() const {return BlockSize();} + unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();} + void WriteKeystream(byte *buffer, size_t iterationCount) + {OperateKeystream(WRITE_KEYSTREAM, buffer, NULLPTR, iterationCount);} + bool CanOperateKeystream() const {return true;} + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); + void SeekToIteration(lword iterationCount); + + // adv_simd.h increments the counter + mutable SecByteBlock m_counterArray; +}; + +/// \brief Block cipher mode of operation default implementation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public CipherModeBase +{ +public: + virtual ~BlockOrientedCipherModeBase() {} + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + unsigned int MandatoryBlockSize() const {return BlockSize();} + bool IsRandomAccess() const {return false;} + bool IsSelfInverting() const {return false;} + bool IsForwardTransformation() const + {return m_cipher->IsForwardTransformation();} + void Resynchronize(const byte *iv, int length=-1) + {memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));} + +protected: + bool RequireAlignedInput() const {return true;} + virtual void ResizeBuffers(); + + SecByteBlock m_buffer; +}; + +/// \brief ECB block cipher mode of operation default implementation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherModeBase +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECB";} + + void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs) + {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();} + IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;} + unsigned int OptimalBlockSize() const {return static_cast(BlockSize() * m_cipher->OptimalNumberOfParallelBlocks());} + void ProcessData(byte *outString, const byte *inString, size_t length); +}; + +/// \brief CBC block cipher mode of operation default implementation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CBC";} + + IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;} + bool RequireAlignedInput() const {return false;} + unsigned int MinLastBlockSize() const {return 0;} +}; + +/// \brief CBC block cipher mode of operation encryption operation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase +{ +public: + void ProcessData(byte *outString, const byte *inString, size_t length); +}; + +/// \brief CBC-CTS block cipher mode of operation encryption operation +/// \since Crypto++ 3.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";} + + void SetStolenIV(byte *iv) {m_stolenIV = iv;} + unsigned int MinLastBlockSize() const {return BlockSize()+1;} + size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); + +protected: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) + { + CBC_Encryption::UncheckedSetKey(key, length, params); + m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), static_cast(NULLPTR)); + } + + byte *m_stolenIV; +}; + +/// \brief CBC block cipher mode of operation decryption operation +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Decryption : public CBC_ModeBase +{ +public: + virtual ~CBC_Decryption() {} + void ProcessData(byte *outString, const byte *inString, size_t length); + +protected: + virtual void ResizeBuffers(); + + SecByteBlock m_temp; +}; + +/// \brief CBC-CTS block cipher mode of operation decryption operation +/// \since Crypto++ 3.0 +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Decryption : public CBC_Decryption +{ +public: + unsigned int MinLastBlockSize() const {return BlockSize()+1;} + size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); +}; + +/// \brief Block cipher mode of operation aggregate +template +class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder, public AlgorithmImpl > +{ +public: + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like \a AES or \a AES/GCM. Some algorithms + /// do not have standard names yet. For example, there is no standard algorithm name for + /// Shoup's ECIES. + static std::string CRYPTOPP_API StaticAlgorithmName() + {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();} + + /// \brief Construct a CipherModeFinalTemplate + CipherModeFinalTemplate_CipherHolder() + { + this->m_cipher = &this->m_object; + this->ResizeBuffers(); + } + + /// \brief Construct a CipherModeFinalTemplate + /// \param key a byte array used to key the cipher + /// \param length size of the key in bytes + /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls + /// SimpleKeyingInterface::SetKey. + CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length) + { + this->m_cipher = &this->m_object; + this->SetKey(key, length); + } + + /// \brief Construct a CipherModeFinalTemplate + /// \param key a byte array used to key the cipher + /// \param length size of the key in bytes + /// \param iv a byte array used to resynchronize the cipher + /// \details key must be at least DEFAULT_KEYLENGTH in length. iv must be IVSize() or + /// BLOCKSIZE in length. Internally, the function calls SimpleKeyingInterface::SetKey. + CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv) + { + this->m_cipher = &this->m_object; + this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))); + } + + /// \brief Construct a CipherModeFinalTemplate + /// \param key a byte array used to key the cipher + /// \param length size of the key in bytes + /// \param iv a byte array used to resynchronize the cipher + /// \param feedbackSize the feedback size, in bytes + /// \details key must be at least DEFAULT_KEYLENGTH in length. iv must be IVSize() or + /// BLOCKSIZE in length. Internally, the function calls SimpleKeyingInterface::SetKey. + CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv, int feedbackSize) + { + this->m_cipher = &this->m_object; + this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))(Name::FeedbackSize(), feedbackSize)); + } + + // Algorithm class + std::string AlgorithmProvider() const { + return this->m_cipher->AlgorithmProvider(); + } +}; + +/// \tparam BASE CipherModeFinalTemplate_CipherHolder base class +/// \details Base class for external mode cipher combinations +template +class CipherModeFinalTemplate_ExternalCipher : public BASE +{ +public: + /// \brief Construct a default CipherModeFinalTemplate + /// \details The cipher is not keyed. + CipherModeFinalTemplate_ExternalCipher() {} + + /// \brief Construct a CipherModeFinalTemplate + /// \param cipher An external block cipher + /// \details The cipher should be keyed. + CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher) + {this->SetCipher(cipher);} + + /// \brief Construct a CipherModeFinalTemplate + /// \param cipher An external block cipher + /// \param iv a byte array used to resynchronize the cipher + /// \param feedbackSize the feedback size, in bytes + /// \details The cipher should be keyed. + CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0) + {this->SetCipherWithIV(cipher, iv, feedbackSize);} + + /// \brief Provides the name of this algorithm + /// \return the standard algorithm name + /// \details The standard algorithm name can be a name like \a AES or \a AES/GCM. Some algorithms + /// do not have standard names yet. For example, there is no standard algorithm name for + /// Shoup's ECIES. + /// \note AlgorithmName is not universally implemented yet + std::string AlgorithmName() const + {return (this->m_cipher ? this->m_cipher->AlgorithmName() + "/" : std::string("")) + BASE::StaticAlgorithmName();} + + // Algorithm class + std::string AlgorithmProvider() const + {return this->m_cipher->AlgorithmProvider();} +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate >; + +/// \brief CFB block cipher mode of operation +/// \sa Modes of Operation +/// on the Crypto++ wiki. +template +struct CFB_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > Encryption; + typedef CipherModeFinalTemplate_CipherHolder > > > Decryption; +}; + +/// \brief CFB mode, external cipher. +/// \sa Modes of Operation +/// on the Crypto++ wiki. +struct CFB_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > Encryption; + typedef CipherModeFinalTemplate_ExternalCipher > > > Decryption; +}; + +/// \brief CFB block cipher mode of operation providing FIPS validated cryptography. +/// \details Requires full block plaintext according to FIPS 800-38A +/// \sa Modes of Operation +/// on the Crypto++ wiki. +template +struct CFB_FIPS_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > > Encryption; + typedef CipherModeFinalTemplate_CipherHolder > > > > Decryption; +}; + +/// \brief CFB mode, external cipher, providing FIPS validated cryptography. +/// \details Requires full block plaintext according to FIPS 800-38A +/// \sa Modes of Operation +/// on the Crypto++ wiki. +struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > > Encryption; + typedef CipherModeFinalTemplate_ExternalCipher > > > > Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate >; + +/// \brief OFB block cipher mode of operation +/// \sa Modes of Operation +/// on the Crypto++ wiki. +template +struct OFB_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > Encryption; + typedef Encryption Decryption; +}; + +/// \brief OFB mode, external cipher. +/// \sa Modes of Operation +/// on the Crypto++ wiki. +struct OFB_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > Encryption; + typedef Encryption Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher > > >; + +/// \brief CTR block cipher mode of operation +/// \sa Modes of Operation +/// on the Crypto++ wiki. +template +struct CTR_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > Encryption; + typedef Encryption Decryption; +}; + +/// \brief CTR mode, external cipher. +/// \sa Modes of Operation +/// on the Crypto++ wiki. +struct CTR_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > Encryption; + typedef Encryption Decryption; +}; + +/// \brief ECB block cipher mode of operation +/// \sa Modes of Operation +/// on the Crypto++ wiki. +template +struct ECB_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder Encryption; + typedef CipherModeFinalTemplate_CipherHolder Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; + +/// \brief ECB mode, external cipher. +/// \sa Modes of Operation +/// on the Crypto++ wiki. +struct ECB_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher Encryption; + typedef Encryption Decryption; +}; + +/// \brief CBC block cipher mode of operation +/// \sa Modes of Operation +/// on the Crypto++ wiki. +template +struct CBC_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder Encryption; + typedef CipherModeFinalTemplate_CipherHolder Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; + +/// \brief CBC mode, external cipher +/// \sa Modes of Operation +/// on the Crypto++ wiki. +struct CBC_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher Encryption; + typedef CipherModeFinalTemplate_ExternalCipher Decryption; +}; + +/// \brief CBC-CTS block cipher mode of operation +/// \sa Modes of Operation +/// on the Crypto++ wiki. +/// \since Crypto++ 3.0 +template +struct CBC_CTS_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder Encryption; + typedef CipherModeFinalTemplate_CipherHolder Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; + +/// \brief CBC mode with ciphertext stealing, external cipher +/// \sa Modes of Operation +/// on the Crypto++ wiki. +/// \since Crypto++ 3.0 +struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher Encryption; + typedef CipherModeFinalTemplate_ExternalCipher Decryption; +}; + +NAMESPACE_END + +// Issue 340 +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/modexppc.h b/external/ours/library/crypto/src/shared/original/modexppc.h new file mode 100755 index 000000000..5e8dd6760 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/modexppc.h @@ -0,0 +1,48 @@ +#ifndef CRYPTOPP_MODEXPPC_H +#define CRYPTOPP_MODEXPPC_H + +#include "cryptlib.h" +#include "modarith.h" +#include "integer.h" +#include "algebra.h" +#include "eprecomp.h" +#include "smartptr.h" +#include "pubkey.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl; + +class ModExpPrecomputation : public DL_GroupPrecomputation +{ +public: + virtual ~ModExpPrecomputation() {} + + // DL_GroupPrecomputation + bool NeedConversions() const {return true;} + Element ConvertIn(const Element &v) const {return m_mr->ConvertIn(v);} + virtual Element ConvertOut(const Element &v) const {return m_mr->ConvertOut(v);} + const AbstractGroup & GetGroup() const {return m_mr->MultiplicativeGroup();} + Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);} + + // non-inherited + void SetModulus(const Integer &v) {m_mr.reset(new MontgomeryRepresentation(v));} + const Integer & GetModulus() const {return m_mr->GetModulus();} + +private: + value_ptr m_mr; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/mqueue.cpp b/external/ours/library/crypto/src/shared/original/mqueue.cpp index 314d6f758..814c459d6 100755 --- a/external/ours/library/crypto/src/shared/original/mqueue.cpp +++ b/external/ours/library/crypto/src/shared/original/mqueue.cpp @@ -1,44 +1,175 @@ -// mqueue.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "mqueue.h" - -NAMESPACE_BEGIN(CryptoPP) - -MessageQueue::MessageQueue(unsigned int nodeSize) - : m_queue(nodeSize), m_lengths(1, 0) -{ -} - -bool MessageQueue::RetrieveNextMessage() -{ - if (NumberOfMessages() > 0 && !AnyRetrievable()) - { - m_lengths.pop_front(); - return true; - } - else - return false; -} - -unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const -{ - ByteQueue::Walker walker(m_queue); - std::deque::const_iterator it = m_lengths.begin(); - unsigned int i; - for (i=0; i= MaxRetrievable()) + return 0; + + return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking); +} + +size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + transferBytes = STDMIN(MaxRetrievable(), transferBytes); + size_t blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking); + m_lengths.front() -= transferBytes; + return blockedBytes; +} + +bool MessageQueue::GetNextMessage() +{ + if (NumberOfMessages() > 0 && !AnyRetrievable()) + { + m_lengths.pop_front(); + if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1) + m_messageCounts.pop_front(); + return true; + } + else + return false; +} + +unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const +{ + ByteQueue::Walker walker(m_queue); + std::deque::const_iterator it = m_lengths.begin(); + unsigned int i; + for (i=0; i 0 && q2.AnyRetrievable()) + { + size_t len = length; + const byte *data = q2.Spy(len); + len = STDMIN(len, length); + if (memcmp(inString, data, len) != 0) + goto mismatch; + inString += len; + length -= len; + q2.Skip(len); + } + + q1.Put(inString, length); + + if (messageEnd) + { + if (q2.AnyRetrievable()) + goto mismatch; + else if (q2.AnyMessages()) + q2.GetNextMessage(); + else if (q2.NumberOfMessageSeries() > 0) + goto mismatch; + else + q1.MessageEnd(); + } + + return 0; + +mismatch: + return HandleMismatchDetected(blocking); + } +} + +bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) +{ + unsigned int i = MapChannel(channel); + + if (i == 2) + { + OutputMessageSeriesEnd(4, propagation, blocking, channel); + return false; + } + else if (m_mismatchDetected) + return false; + else + { + MessageQueue &q1 = m_q[i], &q2 = m_q[1-i]; + + if (q2.AnyRetrievable() || q2.AnyMessages()) + goto mismatch; + else if (q2.NumberOfMessageSeries() > 0) + return Output(2, (const byte *)"\1", 1, 0, blocking) != 0; + else + q1.MessageSeriesEnd(); + + return false; + +mismatch: + return HandleMismatchDetected(blocking); + } +} + +bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking) +{ + m_mismatchDetected = true; + if (m_throwIfNotEqual) + throw MismatchDetected(); + const byte b[1] = {0}; + return Output(1, b, 1, 0, blocking) != 0; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/mqueue.h b/external/ours/library/crypto/src/shared/original/mqueue.h index 822df8003..a724286fe 100755 --- a/external/ours/library/crypto/src/shared/original/mqueue.h +++ b/external/ours/library/crypto/src/shared/original/mqueue.h @@ -1,61 +1,145 @@ -#ifndef CRYPTOPP_MQUEUE_H -#define CRYPTOPP_MQUEUE_H - -#include "queue.h" -#include "filters.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -//! Message Queue -class MessageQueue : public BufferedTransformationWithAutoSignal -{ -public: - MessageQueue(unsigned int nodeSize=256); - - void Put(byte inByte) - {m_queue.Put(inByte); m_lengths.back()++;} - void Put(const byte *inString, unsigned int length) - {m_queue.Put(inString, length); m_lengths.back()+=length;} - - unsigned long MaxRetrievable() const - {return m_lengths.front();} - bool AnyRetrievable() const - {return m_lengths.front() > 0;} - - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) - {return Got(m_queue.TransferTo(target, STDMIN(MaxRetrievable(), transferMax)));} - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const - {return m_queue.CopyTo(target, STDMIN(MaxRetrievable(), copyMax));} - - void MessageEnd(int=-1) - {m_lengths.push_back(0);} - - unsigned long TotalBytesRetrievable() const - {return m_queue.MaxRetrievable();} - unsigned int NumberOfMessages() const - {return m_lengths.size()-1;} - bool RetrieveNextMessage(); - - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; - - void swap(MessageQueue &rhs); - -private: - unsigned long Got(unsigned long length) - {assert(m_lengths.front() >= length); m_lengths.front() -= length; return length;} - - ByteQueue m_queue; - std::deque m_lengths; -}; - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) -{ - a.swap(b); -} -NAMESPACE_END - -#endif +// mqueue.h - originally written and placed in the public domain by Wei Dai + +/// \file +/// \brief Classes for an unlimited queue to store messages + +#ifndef CRYPTOPP_MQUEUE_H +#define CRYPTOPP_MQUEUE_H + +#include "cryptlib.h" +#include "queue.h" +#include "filters.h" +#include "misc.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Data structure used to store messages +/// \details The queue is implemented with a ByteQueue. +/// \sa MessageQueue +/// on the Crypto++ wiki. +/// \since Crypto++ 2.0 +class CRYPTOPP_DLL MessageQueue : public AutoSignaling +{ +public: + virtual ~MessageQueue() {} + + /// \brief Construct a MessageQueue + /// \param nodeSize the initial node size + MessageQueue(unsigned int nodeSize=256); + + // BufferedTransformation + void IsolatedInitialize(const NameValuePairs ¶meters) + {m_queue.IsolatedInitialize(parameters); m_lengths.assign(1, 0U); m_messageCounts.assign(1, 0U);} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + { + CRYPTOPP_UNUSED(blocking); + m_queue.Put(begin, length); + m_lengths.back() += length; + if (messageEnd) + { + m_lengths.push_back(0); + m_messageCounts.back()++; + } + return 0; + } + bool IsolatedFlush(bool hardFlush, bool blocking) + {CRYPTOPP_UNUSED(hardFlush), CRYPTOPP_UNUSED(blocking); return false;} + bool IsolatedMessageSeriesEnd(bool blocking) + {CRYPTOPP_UNUSED(blocking); m_messageCounts.push_back(0); return false;} + + lword MaxRetrievable() const + {return m_lengths.front();} + bool AnyRetrievable() const + {return m_lengths.front() > 0;} + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + + lword TotalBytesRetrievable() const + {return m_queue.MaxRetrievable();} + unsigned int NumberOfMessages() const + {return (unsigned int)m_lengths.size()-1;} + bool GetNextMessage(); + + unsigned int NumberOfMessagesInThisSeries() const + {return m_messageCounts[0];} + unsigned int NumberOfMessageSeries() const + {return (unsigned int)m_messageCounts.size()-1;} + + /// \brief Copy messages from this object to another BufferedTransformation. + /// \param target the destination BufferedTransformation + /// \param count the number of messages to copy + /// \param channel the channel on which the transfer should occur + /// \return the number of messages that remain in the copy (i.e., messages not copied) + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; + + /// \brief Peek data in the queue + /// \param contiguousSize the size of the data + /// \details Spy() peeks at data at the head of the queue. Spy() does + /// not remove data from the queue. + /// \details The data's size is returned in contiguousSize. + /// Spy() returns the size of the first message in the list. + const byte * Spy(size_t &contiguousSize) const; + + /// \brief Swap contents with another MessageQueue + /// \param rhs the other MessageQueue + void swap(MessageQueue &rhs); + +private: + ByteQueue m_queue; + std::deque m_lengths; + std::deque m_messageCounts; +}; + +/// \brief Filter that checks messages on two channels for equality +class CRYPTOPP_DLL EqualityComparisonFilter : public Unflushable > +{ +public: + /// \brief Different messages were detected + struct MismatchDetected : public Exception + { + /// \brief Construct a MismatchDetected exception + MismatchDetected() : Exception(DATA_INTEGRITY_CHECK_FAILED, "EqualityComparisonFilter: did not receive the same data on two channels") {} + }; + + /// \brief Construct an EqualityComparisonFilter + /// \param attachment an attached transformation + /// \param throwIfNotEqual flag indicating whether the objects throws + /// \param firstChannel string naming the first channel + /// \param secondChannel string naming the second channel + /// \throw MismatchDetected if throwIfNotEqual is true and not equal + /// \details If throwIfNotEqual is false, this filter will output a '\\0' + /// byte when it detects a mismatch, '\\1' otherwise. + EqualityComparisonFilter(BufferedTransformation *attachment=NULLPTR, bool throwIfNotEqual=true, const std::string &firstChannel="0", const std::string &secondChannel="1") + : m_throwIfNotEqual(throwIfNotEqual), m_mismatchDetected(false) + , m_firstChannel(firstChannel), m_secondChannel(secondChannel) + {Detach(attachment);} + + // BufferedTransformation + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); + +protected: + unsigned int MapChannel(const std::string &channel) const; + bool HandleMismatchDetected(bool blocking); + +private: + bool m_throwIfNotEqual, m_mismatchDetected; + std::string m_firstChannel, m_secondChannel; + MessageQueue m_q[2]; +}; + +NAMESPACE_END + +#ifndef __BORLANDC__ +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) +{ + a.swap(b); +} +NAMESPACE_END +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/mqv.cpp b/external/ours/library/crypto/src/shared/original/mqv.cpp new file mode 100755 index 000000000..ef886251e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/mqv.cpp @@ -0,0 +1,46 @@ +// mqv.cpp - originally written and placed in the public domain by Wei Dai +// HMQV provided by Jeffrey Walton, Ray Clayton and Uri Blumenthal. +// FHMQV provided by Uri Blumenthal. + +#include "pch.h" +#include "config.h" +#include "mqv.h" +#include "hmqv.h" +#include "fhmqv.h" +#include "eccrypto.h" + +// Squash MS LNK4221 and libtool warnings +extern const char MQV_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void TestInstantiations_MQV() +{ + MQV mqv; + ECMQV ecmqv; + + CRYPTOPP_UNUSED(mqv); + CRYPTOPP_UNUSED(ecmqv); +} + +void TestInstantiations_HMQV() +{ + HMQV hmqv; + ECHMQV echmqv; + + CRYPTOPP_UNUSED(hmqv); + CRYPTOPP_UNUSED(echmqv); +} + +void TestInstantiations_FHMQV() +{ + FHMQV fhmqv; + ECFHMQV ecfhmqv; + + CRYPTOPP_UNUSED(fhmqv); + CRYPTOPP_UNUSED(ecfhmqv); +} +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/mqv.h b/external/ours/library/crypto/src/shared/original/mqv.h new file mode 100755 index 000000000..7ab18e55b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/mqv.h @@ -0,0 +1,268 @@ +// mqv.h - originally written and placed in the public domain by Wei Dai + +/// \file mqv.h +/// \brief Classes for Menezes–Qu–Vanstone (MQV) key agreement +/// \since Crypto++ 3.0 + +#ifndef CRYPTOPP_MQV_H +#define CRYPTOPP_MQV_H + +#include "cryptlib.h" +#include "gfpcrypt.h" +#include "modarith.h" +#include "integer.h" +#include "algebra.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief MQV domain for performing authenticated key agreement +/// \tparam GROUP_PARAMETERS doamin parameters +/// \tparam COFACTOR_OPTION cofactor option +/// \details GROUP_PARAMETERS parameters include the curve coefcients and the base point. +/// Binary curves use a polynomial to represent its characteristic, while prime curves +/// use a prime number. +/// \sa MQV, HMQV, FHMQV, and AuthenticatedKeyAgreementDomain +/// \since Crypto++ 3.0 +template +class MQV_Domain : public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef MQV_Domain Domain; + + /// \brief Construct a MQV domain + MQV_Domain() {} + + /// \brief Construct a MQV domain + /// \param params group parameters and options + MQV_Domain(const GroupParameters ¶ms) + : m_groupParameters(params) {} + + /// \brief Construct a MQV domain + /// \param bt BufferedTransformation with group parameters and options + MQV_Domain(BufferedTransformation &bt) + {m_groupParameters.BERDecode(bt);} + + /// \brief Construct a MQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + template + MQV_Domain(T1 v1, T2 v2) + {m_groupParameters.Initialize(v1, v2);} + + /// \brief Construct a MQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. + template + MQV_Domain(T1 v1, T2 v2, T3 v3) + {m_groupParameters.Initialize(v1, v2, v3);} + + /// \brief Construct a MQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \tparam T3 template parameter used as a constructor parameter + /// \tparam T4 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param v4 third parameter + /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. + template + MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a const reference + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a non-const reference + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + /// \brief Retrieves the crypto parameters for this domain + /// \return the crypto parameters for this domain as a non-const reference + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + + /// \brief Provides the size of the agreed value + /// \return size of agreed value produced in this domain + /// \details The length is calculated using GetEncodedElementSize(false), + /// which means the element is encoded in a non-reversible format. A + /// non-reversible format means its a raw byte array, and it lacks presentation + /// format like an ASN.1 BIT_STRING or OCTET_STRING. + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + + /// \brief Provides the size of the static private key + /// \return size of static private keys in this domain + /// \details The length is calculated using the byte count of the subgroup order. + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + + /// \brief Provides the size of the static public key + /// \return size of static public keys in this domain + /// \details The length is calculated using GetEncodedElementSize(true), + /// which means the element is encoded in a reversible format. A reversible + /// format means it has a presentation format, and its an ANS.1 encoded element + /// or point. + unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + /// \brief Generate static private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \details The private key is a random scalar used as an exponent in the range + /// [1,MaxExponent()]. + /// \pre COUNTOF(privateKey) == PrivateStaticKeyLength() + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + /// \brief Generate a static public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details The public key is an element or point on the curve, and its stored + /// in a revrsible format. A reversible format means it has a presentation + /// format, and its an ANS.1 encoded element or point. + /// \pre COUNTOF(publicKey) == PublicStaticKeyLength() + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + /// \brief Provides the size of the ephemeral private key + /// \return size of ephemeral private keys in this domain + /// \details An ephemeral private key is a private key and public key. + /// The serialized size is different than a static private key. + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + + /// \brief Provides the size of the ephemeral public key + /// \return size of ephemeral public keys in this domain + /// \details An ephemeral public key is a public key. + /// The serialized size is the same as a static public key. + unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();} + + /// \brief Generate ephemeral private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \pre COUNTOF(privateKey) == EphemeralPrivateKeyLength() + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + /// \brief Generate ephemeral public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \pre COUNTOF(publicKey) == EphemeralPublicKeyLength() + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + /// \brief Derive agreed value or shared secret + /// \param agreedValue the shared secret + /// \param staticPrivateKey your long term private key + /// \param ephemeralPrivateKey your ephemeral private key + /// \param staticOtherPublicKey couterparty's long term public key + /// \param ephemeralOtherPublicKey couterparty's ephemeral public key + /// \param validateStaticOtherPublicKey flag indicating validation + /// \return true upon success, false in case of failure + /// \details Agree() performs the authenticated key agreement. Agree() + /// derives a shared secret from your private keys and couterparty's + /// public keys. Each instance or run of the protocol should use a new + /// ephemeral key pair. + /// \details The other's ephemeral public key will always be validated at + /// Level 1 to ensure it is a point on the curve. + /// validateStaticOtherPublicKey determines how thoroughly other's + /// static public key is validated. If you have previously validated the + /// couterparty's static public key, then use + /// validateStaticOtherPublicKey=false to save time. + /// \pre COUNTOF(agreedValue) == AgreedValueLength() + /// \pre COUNTOF(staticPrivateKey) == StaticPrivateKeyLength() + /// \pre COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength() + /// \pre COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength() + /// \pre COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength() + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey); + Element VV = params.DecodeElement(ephemeralOtherPublicKey, true); + + Integer s(staticPrivateKey, StaticPrivateKeyLength()); + Integer u(ephemeralPrivateKey, StaticPrivateKeyLength()); + Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false); + + const Integer &r = params.GetSubgroupOrder(); + Integer h2 = Integer::Power2((r.BitCount()+1)/2); + Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r; + Integer tt = h2 + params.ConvertElementToInteger(VV) % h2; + + if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION) + { + Element P = params.ExponentiateElement(WW, tt); + P = m_groupParameters.MultiplyElements(P, VV); + Element R[2]; + const Integer e2[2] = {r, e}; + params.SimultaneousExponentiate(R, P, e2, 2); + if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1])) + return false; + params.EncodeElement(false, R[1], agreedValue); + } + else + { + const Integer &k = params.GetCofactor(); + if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) + e = ModularArithmetic(r).Divide(e, k); + Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r)); + if (params.IsIdentity(P)) + return false; + params.EncodeElement(false, P, agreedValue); + } + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const {return m_groupParameters;} + + GroupParameters m_groupParameters; +}; + +/// Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV +/// \sa MQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain +/// \since Crypto++ 3.0 +typedef MQV_Domain MQV; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/naclite.h b/external/ours/library/crypto/src/shared/original/naclite.h new file mode 100755 index 000000000..586897209 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/naclite.h @@ -0,0 +1,438 @@ +// naclite.h - written and placed in the public domain by Jeffrey Walton +// based on public domain NaCl source code written by +// Daniel J. Bernstein, Bernard van Gastel, Wesley Janssen, +// Tanja Lange, Peter Schwabe and Sjaak Smetsers. + +// The Tweet API was added to the Crypto++ library to cross-validate results. +// We debated over putting it in the Test namespace, but settled for the NaCl +// namespace to segregate it from other parts of the library. + +/// \file naclite.h +/// \brief Crypto++ interface to TweetNaCl library (20140917) +/// \details TweetNaCl is a compact reimplementation of the NaCl library +/// by Daniel J. Bernstein, Bernard van Gastel, Wesley Janssen, Tanja +/// Lange, Peter Schwabe and Sjaak Smetsers. The library is less than +/// 20 KB in size and provides 25 of the NaCl library functions. +/// \details The compact library uses curve25519, XSalsa20, Poly1305 and +/// SHA-512 as default primitives, and includes both x25519 key exchange +/// and ed25519 signatures. The complete list of functions can be found +/// in TweetNaCl: +/// A crypto library in 100 tweets (20140917), Table 1, page 5. +/// \details Crypto++ rejects small order elements using libsodium's +/// blacklist. The TweetNaCl library allowed them but the library predated +/// the attack. If you wish to allow small elements then use the "unchecked" +/// versions of crypto_box_unchecked, crypto_box_open_unchecked and +/// crypto_box_beforenm_unchecked. +/// \details TweetNaCl is well written but not well optimzed. It runs about +/// 10x slower than optimized routines from libsodium. However, the library +/// is still 2x to 4x faster than the algorithms NaCl was designed to replace +/// and allows cross-checking results from an independent implementation. +/// \details The Crypto++ wrapper for TweetNaCl requires OS features. That is, +/// NO_OS_DEPENDENCE cannot be defined. It is due to TweetNaCl's +/// internal function randombytes. Crypto++ used +/// DefaultAutoSeededRNG within randombytes, so OS +/// integration must be enabled. You can use another generator like +/// RDRAND to avoid the restriction. +/// \sa The security +/// impact of a new cryptographic library, TweetNaCl: +/// A crypto library in 100 tweets (20140917), May the Fourth Be With You: +/// A Microarchitectural Side Channel Attack on Several Real-World +/// Applications of Curve25519, libsodium +/// commit afabd7e7386e1194 and RFC 7748, Elliptic Curves for +/// Security, Section 6. +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_NACL_H +#define CRYPTOPP_NACL_H + +#include "config.h" +#include "stdcpp.h" + +#if defined(NO_OS_DEPENDENCE) || !defined(OS_RNG_AVAILABLE) +# define CRYPTOPP_DISABLE_NACL 1 +#endif + +#ifndef CRYPTOPP_DISABLE_NACL + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(NaCl) + +/// \brief Hash size in bytes +/// \sa NaCl crypto_hash documentation +CRYPTOPP_CONSTANT(crypto_hash_BYTES = 64); + +/// \brief Key size in bytes +/// \sa NaCl crypto_stream documentation +CRYPTOPP_CONSTANT(crypto_stream_KEYBYTES = 32); +/// \brief Nonce size in bytes +/// \sa NaCl crypto_stream documentation +CRYPTOPP_CONSTANT(crypto_stream_NONCEBYTES = 24); + +/// \brief Key size in bytes +/// \sa NaCl crypto_auth documentation +CRYPTOPP_CONSTANT(crypto_auth_KEYBYTES = 32); +/// \brief Tag size in bytes +/// \sa NaCl crypto_auth documentation +CRYPTOPP_CONSTANT(crypto_auth_BYTES = 16); + +/// \brief Key size in bytes +/// \sa NaCl crypto_onetimeauth documentation +CRYPTOPP_CONSTANT(crypto_onetimeauth_KEYBYTES = 32); +/// \brief Tag size in bytes +/// \sa NaCl crypto_onetimeauth documentation +CRYPTOPP_CONSTANT(crypto_onetimeauth_BYTES = 16); + +/// \brief Key size in bytes +/// \sa NaCl crypto_secretbox documentation +CRYPTOPP_CONSTANT(crypto_secretbox_KEYBYTES = 32); +/// \brief Nonce size in bytes +/// \sa NaCl crypto_secretbox documentation +CRYPTOPP_CONSTANT(crypto_secretbox_NONCEBYTES = 24); +/// \brief Zero-padded message prefix in bytes +/// \sa NaCl crypto_secretbox documentation +CRYPTOPP_CONSTANT(crypto_secretbox_ZEROBYTES = 32); +/// \brief Zero-padded message prefix in bytes +/// \sa NaCl crypto_secretbox documentation +CRYPTOPP_CONSTANT(crypto_secretbox_BOXZEROBYTES = 16); + +/// \brief Private key size in bytes +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_SECRETKEYBYTES = 32); +/// \brief Public key size in bytes +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_PUBLICKEYBYTES = 32); +/// \brief Nonce size in bytes +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_NONCEBYTES = 24); +/// \brief Message 0-byte prefix in bytes +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_ZEROBYTES = 32); +/// \brief Open box 0-byte prefix in bytes +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_BOXZEROBYTES = 16); +/// \brief Precomputation 0-byte prefix in bytes in bytes +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_BEFORENMBYTES = 32); +/// \brief MAC size in bytes +/// \details crypto_box_MACBYTES was missing from tweetnacl.h. Its is defined as +/// crypto_box_curve25519xsalsa20poly1305_MACBYTES, which is defined as 16U. +/// \sa NaCl crypto_box documentation +CRYPTOPP_CONSTANT(crypto_box_MACBYTES = 16); + +/// \brief Private key size in bytes +/// \sa NaCl crypto_sign documentation +CRYPTOPP_CONSTANT(crypto_sign_SECRETKEYBYTES = 64); +/// \brief Public key size in bytes +/// \sa NaCl crypto_sign documentation +CRYPTOPP_CONSTANT(crypto_sign_PUBLICKEYBYTES = 32); +/// \brief Seed size in bytes +/// \sa NaCl crypto_sign documentation +CRYPTOPP_CONSTANT(crypto_sign_SEEDBYTES = 32); +/// \brief Signature size in bytes +/// \sa NaCl crypto_sign documentation +CRYPTOPP_CONSTANT(crypto_sign_BYTES = 64); + +/// \brief Group element size in bytes +/// \sa NaCl crypto_scalarmult documentation +CRYPTOPP_CONSTANT(crypto_scalarmult_BYTES = 32); +/// \brief Integer size in bytes +/// \sa NaCl crypto_scalarmult documentation +CRYPTOPP_CONSTANT(crypto_scalarmult_SCALARBYTES = 32); + +/// \brief Encrypt and authenticate a message +/// \param c output byte buffer +/// \param m input byte buffer +/// \param d size of the input byte buffer +/// \param n nonce byte buffer +/// \param y other's public key +/// \param x private key +/// \details crypto_box() uses crypto_box_curve25519xsalsa20poly1305 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_box documentation +/// \since Crypto++ 6.0 +int crypto_box(byte *c,const byte *m,word64 d,const byte *n,const byte *y,const byte *x); + +/// \brief Verify and decrypt a message +/// \param m output byte buffer +/// \param c input byte buffer +/// \param d size of the input byte buffer +/// \param n nonce byte buffer +/// \param y other's public key +/// \param x private key +/// \details crypto_box_open() uses crypto_box_curve25519xsalsa20poly1305 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_box documentation +/// \since Crypto++ 6.0 +int crypto_box_open(byte *m,const byte *c,word64 d,const byte *n,const byte *y,const byte *x); + +/// \brief Generate a keypair for encryption +/// \param y public key byte buffer +/// \param x private key byte buffer +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_box documentation +/// \since Crypto++ 6.0 +int crypto_box_keypair(byte *y,byte *x); + +/// \brief Encrypt and authenticate a message +/// \param k shared secret byte buffer +/// \param y other's public key +/// \param x private key +/// \details crypto_box_beforenm() performs message-independent precomputation to derive the key. +/// Once the key is derived multiple calls to crypto_box_afternm() can be made to process the message. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_box documentation +/// \since Crypto++ 6.0 +int crypto_box_beforenm(byte *k,const byte *y,const byte *x); + +/// \brief Encrypt and authenticate a message +/// \param m output byte buffer +/// \param c input byte buffer +/// \param d size of the input byte buffer +/// \param n nonce byte buffer +/// \param k shared secret byte buffer +/// \details crypto_box_afternm() performs message-dependent computation using the derived the key. +/// Once the key is derived using crypto_box_beforenm() multiple calls to crypto_box_afternm() +/// can be made to process the message. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_box documentation +/// \since Crypto++ 6.0 +int crypto_box_afternm(byte *c,const byte *m,word64 d,const byte *n,const byte *k); + +/// \brief Verify and decrypt a message +/// \param m output byte buffer +/// \param c input byte buffer +/// \param d size of the input byte buffer +/// \param n nonce byte buffer +/// \param k shared secret byte buffer +/// \details crypto_box_afternm() performs message-dependent computation using the derived the key. +/// Once the key is derived using crypto_box_beforenm() multiple calls to crypto_box_open_afternm() +/// can be made to process the message. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_box documentation +/// \since Crypto++ 6.0 +int crypto_box_open_afternm(byte *m,const byte *c,word64 d,const byte *n,const byte *k); + +/// \brief Encrypt and authenticate a message +/// \param c output byte buffer +/// \param m input byte buffer +/// \param d size of the input byte buffer +/// \param n nonce byte buffer +/// \param y other's public key +/// \param x private key +/// \details crypto_box() uses crypto_box_curve25519xsalsa20poly1305. +/// \details This version of crypto_box() does not check for small order elements. It can be unsafe +/// but it exists for backwards compatibility with downlevel clients. Without the compatibility +/// interop with early versions of NaCl, libsodium and other libraries does not exist. The +/// downlevel interop may also be needed of cryptocurrencies like Bitcoin, Ethereum, Monero +/// and Zcash. +/// \return 0 on success, non-0 otherwise +/// \warning This version of crypto_box() does not check for small order elements. It should not +/// be used in new software. +/// \sa NaCl crypto_box documentation, +/// May the Fourth Be With You: A Microarchitectural +/// Side Channel Attack on Several Real-World Applications of Curve25519, +/// libsodium commit +/// afabd7e7386e1194. +/// \since Crypto++ 6.0 +int crypto_box_unchecked(byte *c,const byte *m,word64 d,const byte *n,const byte *y,const byte *x); + +/// \brief Verify and decrypt a message +/// \param m output byte buffer +/// \param c input byte buffer +/// \param d size of the input byte buffer +/// \param n nonce byte buffer +/// \param y other's public key +/// \param x private key +/// \details crypto_box_open() uses crypto_box_curve25519xsalsa20poly1305. +/// \details This version of crypto_box_open() does not check for small order elements. It can be unsafe +/// but it exists for backwards compatibility with downlevel clients. Without the compatibility +/// interop with early versions of NaCl, libsodium and other libraries does not exist. The +/// downlevel interop may also be needed of cryptocurrencies like Bitcoin, Ethereum, Monero +/// and Zcash. +/// \return 0 on success, non-0 otherwise +/// \warning This version of crypto_box_open() does not check for small order elements. It should not +/// be used in new software. +/// \sa NaCl crypto_box documentation, +/// May the Fourth Be With You: A Microarchitectural +/// Side Channel Attack on Several Real-World Applications of Curve25519, +/// libsodium commit +/// afabd7e7386e1194. +/// \since Crypto++ 6.0 +int crypto_box_open_unchecked(byte *m,const byte *c,word64 d,const byte *n,const byte *y,const byte *x); + +/// \brief Encrypt and authenticate a message +/// \param k shared secret byte buffer +/// \param y other's public key +/// \param x private key +/// \details crypto_box_beforenm() performs message-independent precomputation to derive the key. +/// Once the key is derived multiple calls to crypto_box_afternm() can be made to process the message. +/// \details This version of crypto_box_beforenm() does not check for small order elements. It can be unsafe +/// but it exists for backwards compatibility with downlevel clients. Without the compatibility +/// interop with early versions of NaCl, libsodium and other libraries does not exist. The +/// downlevel interop may also be needed of cryptocurrencies like Bitcoin, Ethereum, Monero +/// and Zcash. +/// \return 0 on success, non-0 otherwise +/// \warning This version of crypto_box_beforenm() does not check for small order elements. It should not +/// be used in new software. +/// \sa NaCl crypto_box documentation, +/// May the Fourth Be With You: A Microarchitectural +/// Side Channel Attack on Several Real-World Applications of Curve25519, +/// libsodium commit +/// afabd7e7386e1194. +/// \since Crypto++ 6.0 +int crypto_box_beforenm_unchecked(byte *k,const byte *y,const byte *x); + +/// \brief TODO +int crypto_core_salsa20(byte *out,const byte *in,const byte *k,const byte *c); + +/// \brief TODO +/// \return 0 on success, non-0 otherwise +/// \since Crypto++ 6.0 +int crypto_core_hsalsa20(byte *out,const byte *in,const byte *k,const byte *c); + +/// \brief Hash multiple blocks +/// \details crypto_hashblocks() uses crypto_hashblocks_sha512. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_hash documentation +/// \since Crypto++ 6.0 +int crypto_hashblocks(byte *x,const byte *m,word64 n); + +/// \brief Hash a message +/// \details crypto_hash() uses crypto_hash_sha512. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_hash documentation +/// \since Crypto++ 6.0 +int crypto_hash(byte *out,const byte *m,word64 n); + +/// \brief Create an authentication tag for a message +/// \details crypto_onetimeauth() uses crypto_onetimeauth_poly1305. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_onetimeauth documentation +/// \since Crypto++ 6.0 +int crypto_onetimeauth(byte *out,const byte *m,word64 n,const byte *k); + +/// \brief Verify an authentication tag on a message +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_onetimeauth documentation +/// \since Crypto++ 6.0 +int crypto_onetimeauth_verify(const byte *h,const byte *m,word64 n,const byte *k); + +/// \brief Scalar multiplication of a point +/// \details crypto_scalarmult() uses crypto_scalarmult_curve25519 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_scalarmult documentation +/// \since Crypto++ 6.0 +int crypto_scalarmult(byte *q,const byte *n,const byte *p); + +/// \brief Scalar multiplication of base point +/// \details crypto_scalarmult_base() uses crypto_scalarmult_curve25519 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_scalarmult documentation +/// \since Crypto++ 6.0 +int crypto_scalarmult_base(byte *q,const byte *n); + +/// \brief Encrypt and authenticate a message +/// \details crypto_secretbox() uses a symmetric key to encrypt and authenticate a message. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_secretbox documentation +/// \since Crypto++ 6.0 +int crypto_secretbox(byte *c,const byte *m,word64 d,const byte *n,const byte *k); + +/// \brief Verify and decrypt a message +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_secretbox documentation +/// \since Crypto++ 6.0 +int crypto_secretbox_open(byte *m,const byte *c,word64 d,const byte *n,const byte *k); + +/// \brief Sign a message +/// \param sm output byte buffer +/// \param smlen size of the output byte buffer +/// \param m input byte buffer +/// \param n size of the input byte buffer +/// \param sk private key +/// \details crypto_sign() uses crypto_sign_ed25519. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_sign documentation +/// \since Crypto++ 6.0 +int crypto_sign(byte *sm,word64 *smlen,const byte *m,word64 n,const byte *sk); + +/// \brief Verify a message +/// \param m output byte buffer +/// \param mlen size of the output byte buffer +/// \param sm input byte buffer +/// \param n size of the input byte buffer +/// \param pk public key +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_sign documentation +/// \since Crypto++ 6.0 +int crypto_sign_open(byte *m,word64 *mlen,const byte *sm,word64 n,const byte *pk); + +/// \brief Generate a keypair for signing +/// \param pk public key byte buffer +/// \param sk private key byte buffer +/// \details crypto_sign_keypair() creates an ed25519 keypair. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_sign documentation +/// \since Crypto++ 6.0 +int crypto_sign_keypair(byte *pk, byte *sk); + +/// \brief Calculate a public key from a secret key +/// \param pk public key byte buffer +/// \param sk private key byte buffer +/// \details crypto_sign_sk2pk() creates an ed25519 public key from an existing +/// 32-byte secret key. The function does not backfill the tail bytes of the +/// secret key with the calculated public key. +/// \details crypto_sign_sk2pk() is not part of libsodium or Tweet API. It was +/// added for interop with some anonymous routing protocols. +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_sign documentation +/// \since Crypto++ 8.0 +int crypto_sign_sk2pk(byte *pk, const byte *sk); + +/// \brief Produce a keystream using XSalsa20 +/// \details crypto_stream() uses crypto_stream_xsalsa20 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_stream documentation +/// \since Crypto++ 6.0 +int crypto_stream(byte *c,word64 d,const byte *n,const byte *k); + +/// \brief Encrypt a message using XSalsa20 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_stream documentation +/// \since Crypto++ 6.0 +int crypto_stream_xor(byte *c,const byte *m,word64 d,const byte *n,const byte *k); + +/// \brief Produce a keystream using Salsa20 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_stream documentation +/// \since Crypto++ 6.0 +int crypto_stream_salsa20(byte *c,word64 d,const byte *n,const byte *k); + +/// \brief Encrypt a message using Salsa20 +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_stream documentation +/// \since Crypto++ 6.0 +int crypto_stream_salsa20_xor(byte *c,const byte *m,word64 b,const byte *n,const byte *k); + +/// \brief Compare 16-byte buffers +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_verify documentation +/// \since Crypto++ 6.0 +int crypto_verify_16(const byte *x,const byte *y); + +/// \brief Compare 32-byte buffers +/// \return 0 on success, non-0 otherwise +/// \sa NaCl crypto_verify documentation +/// \since Crypto++ 6.0 +int crypto_verify_32(const byte *x,const byte *y); + +NAMESPACE_END // CryptoPP +NAMESPACE_END // NaCl + +#endif // CRYPTOPP_DISABLE_NACL +#endif // CRYPTOPP_NACL_H diff --git a/external/ours/library/crypto/src/shared/original/nbtheory.cpp b/external/ours/library/crypto/src/shared/original/nbtheory.cpp new file mode 100755 index 000000000..a6087a0be --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/nbtheory.cpp @@ -0,0 +1,1141 @@ +// nbtheory.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "nbtheory.h" +#include "integer.h" +#include "modarith.h" +#include "algparam.h" +#include "smartptr.h" +#include "misc.h" +#include "stdcpp.h" + +#ifdef _OPENMP +# include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +const word s_lastSmallPrime = 32719; + +struct NewPrimeTable +{ + std::vector * operator()() const + { + const unsigned int maxPrimeTableSize = 3511; + + member_ptr > pPrimeTable(new std::vector); + std::vector &primeTable = *pPrimeTable; + primeTable.reserve(maxPrimeTableSize); + + primeTable.push_back(2); + unsigned int testEntriesEnd = 1; + + for (unsigned int p=3; p<=s_lastSmallPrime; p+=2) + { + unsigned int j; + for (j=1; j &primeTable = Singleton, NewPrimeTable>().Ref(); + size = (unsigned int)primeTable.size(); + return &primeTable[0]; +} + +bool IsSmallPrime(const Integer &p) +{ + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + if (p.IsPositive() && p <= primeTable[primeTableSize-1]) + return std::binary_search(primeTable, primeTable+primeTableSize, (word16)p.ConvertToLong()); + else + return false; +} + +bool TrialDivision(const Integer &p, unsigned bound) +{ + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + CRYPTOPP_ASSERT(primeTable[primeTableSize-1] >= bound); + + unsigned int i; + for (i = 0; primeTable[i]3 && b>1 && b3 && b>1 && b>a; + + Integer z = a_exp_b_mod_c(b, m, n); + if (z==1 || z==nminus1) + return true; + for (unsigned j=1; j3); + + Integer b; + for (unsigned int i=0; i2); + + Integer b=3; + unsigned int i=0; + int j; + + while ((j=Jacobi(b.Squared()-4, n)) == 1) + { + if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square + return false; + ++b; ++b; + } + + if (j==0) + return false; + else + return Lucas(n+1, b, n)==2; +} + +bool IsStrongLucasProbablePrime(const Integer &n) +{ + if (n <= 1) + return false; + + if (n.IsEven()) + return n==2; + + CRYPTOPP_ASSERT(n>2); + + Integer b=3; + unsigned int i=0; + int j; + + while ((j=Jacobi(b.Squared()-4, n)) == 1) + { + if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square + return false; + ++b; ++b; + } + + if (j==0) + return false; + + Integer n1 = n+1; + unsigned int a; + + // calculate a = largest power of 2 that divides n1 + for (a=0; ; a++) + if (n1.GetBit(a)) + break; + Integer m = n1>>a; + + Integer z = Lucas(m, b, n); + if (z==2 || z==n-2) + return true; + for (i=1; i().Ref()) + return SmallDivisorsTest(p); + else + return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p); +} + +bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level) +{ + bool pass = IsPrime(p) && RabinMillerTest(rng, p, 1); + if (level >= 1) + pass = pass && RabinMillerTest(rng, p, 10); + return pass; +} + +unsigned int PrimeSearchInterval(const Integer &max) +{ + return max.BitCount(); +} + +static inline bool FastProbablePrimeTest(const Integer &n) +{ + return IsStrongProbablePrime(n,2); +} + +AlgorithmParameters MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength) +{ + if (productBitLength < 16) + throw InvalidArgument("invalid bit length"); + + Integer minP, maxP; + + if (productBitLength%2==0) + { + minP = Integer(182) << (productBitLength/2-8); + maxP = Integer::Power2(productBitLength/2)-1; + } + else + { + minP = Integer::Power2((productBitLength-1)/2); + maxP = Integer(181) << ((productBitLength+1)/2-8); + } + + return MakeParameters("RandomNumberType", Integer::PRIME)("Min", minP)("Max", maxP); +} + +class PrimeSieve +{ +public: + // delta == 1 or -1 means double sieve with p = 2*q + delta + PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta=0); + bool NextCandidate(Integer &c); + + void DoSieve(); + static void SieveSingle(std::vector &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv); + + Integer m_first, m_last, m_step; + signed int m_delta; + word m_next; + std::vector m_sieve; +}; + +PrimeSieve::PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta) + : m_first(first), m_last(last), m_step(step), m_delta(delta), m_next(0) +{ + DoSieve(); +} + +bool PrimeSieve::NextCandidate(Integer &c) +{ + bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next); + CRYPTOPP_UNUSED(safe); CRYPTOPP_ASSERT(safe); + if (m_next == m_sieve.size()) + { + m_first += long(m_sieve.size())*m_step; + if (m_first > m_last) + return false; + else + { + m_next = 0; + DoSieve(); + return NextCandidate(c); + } + } + else + { + c = m_first + long(m_next)*m_step; + ++m_next; + return true; + } +} + +void PrimeSieve::SieveSingle(std::vector &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv) +{ + if (stepInv) + { + size_t sieveSize = sieve.size(); + size_t j = (word32(p-(first%p))*stepInv) % p; + // if the first multiple of p is p, skip it + if (first.WordCount() <= 1 && first + step*long(j) == p) + j += p; + for (; j < sieveSize; j += p) + sieve[j] = true; + } +} + +void PrimeSieve::DoSieve() +{ + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + const unsigned int maxSieveSize = 32768; + unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong(); + + m_sieve.clear(); + m_sieve.resize(sieveSize, false); + + if (m_delta == 0) + { + for (unsigned int i = 0; i < primeTableSize; ++i) + SieveSingle(m_sieve, primeTable[i], m_first, m_step, (word16)m_step.InverseMod(primeTable[i])); + } + else + { + CRYPTOPP_ASSERT(m_step%2==0); + Integer qFirst = (m_first-m_delta) >> 1; + Integer halfStep = m_step >> 1; + for (unsigned int i = 0; i < primeTableSize; ++i) + { + word16 p = primeTable[i]; + word16 stepInv = (word16)m_step.InverseMod(p); + SieveSingle(m_sieve, p, m_first, m_step, stepInv); + + word16 halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p; + SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv); + } + } +} + +bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector) +{ + CRYPTOPP_ASSERT(!equiv.IsNegative() && equiv < mod); + + Integer gcd = GCD(equiv, mod); + if (gcd != Integer::One()) + { + // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv) + if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd))) + { + p = gcd; + return true; + } + else + return false; + } + + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + if (p <= primeTable[primeTableSize-1]) + { + const word16 *pItr; + + --p; + if (p.IsPositive()) + pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong()); + else + pItr = primeTable; + + while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr)))) + ++pItr; + + if (pItr < primeTable+primeTableSize) + { + p = *pItr; + return p <= max; + } + + p = primeTable[primeTableSize-1]+1; + } + + CRYPTOPP_ASSERT(p > primeTable[primeTableSize-1]); + + if (mod.IsOdd()) + return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector); + + p += (equiv-p)%mod; + + if (p>max) + return false; + + PrimeSieve sieve(p, max, mod); + + while (sieve.NextCandidate(p)) + { + if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p)) + return true; + } + + return false; +} + +// the following two functions are based on code and comments provided by Preda Mihailescu +static bool ProvePrime(const Integer &p, const Integer &q) +{ + CRYPTOPP_ASSERT(p < q*q*q); + CRYPTOPP_ASSERT(p % q == 1); + +// this is the Quisquater test. Numbers p having passed the Lucas - Lehmer test +// for q and verifying p < q^3 can only be built up of two factors, both = 1 mod q, +// or be prime. The next two lines build the discriminant of a quadratic equation +// which holds iff p is built up of two factors (exercise ... ) + + Integer r = (p-1)/q; + if (((r%q).Squared()-4*(r/q)).IsSquare()) + return false; + + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + CRYPTOPP_ASSERT(primeTableSize >= 50); + for (int i=0; i<50; i++) + { + Integer b = a_exp_b_mod_c(primeTable[i], r, p); + if (b != 1) + return a_exp_b_mod_c(b, q, p) == 1; + } + return false; +} + +Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int pbits) +{ + Integer p; + Integer minP = Integer::Power2(pbits-1); + Integer maxP = Integer::Power2(pbits) - 1; + + if (maxP <= Integer(s_lastSmallPrime).Squared()) + { + // Randomize() will generate a prime provable by trial division + p.Randomize(rng, minP, maxP, Integer::PRIME); + return p; + } + + unsigned int qbits = (pbits+2)/3 + 1 + rng.GenerateWord32(0, pbits/36); + Integer q = MihailescuProvablePrime(rng, qbits); + Integer q2 = q<<1; + + while (true) + { + // this initializes the sieve to search in the arithmetic + // progression p = p_0 + \lambda * q2 = p_0 + 2 * \lambda * q, + // with q the recursively generated prime above. We will be able + // to use Lucas tets for proving primality. A trick of Quisquater + // allows taking q > cubic_root(p) rather than square_root: this + // decreases the recursion. + + p.Randomize(rng, minP, maxP, Integer::ANY, 1, q2); + PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*q2, maxP), q2); + + while (sieve.NextCandidate(p)) + { + if (FastProbablePrimeTest(p) && ProvePrime(p, q)) + return p; + } + } + + // not reached + return p; +} + +Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits) +{ + const unsigned smallPrimeBound = 29, c_opt=10; + Integer p; + + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + if (bits < smallPrimeBound) + { + do + p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2); + while (TrialDivision(p, 1 << ((bits+1)/2))); + } + else + { + const unsigned margin = bits > 50 ? 20 : (bits-10)/2; + double relativeSize; + do + relativeSize = std::pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1); + while (bits * relativeSize >= bits - margin); + + Integer a,b; + Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize)); + Integer I = Integer::Power2(bits-2)/q; + Integer I2 = I << 1; + unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt); + bool success = false; + while (!success) + { + p.Randomize(rng, I, I2, Integer::ANY); + p *= q; p <<= 1; ++p; + if (!TrialDivision(p, trialDivisorBound)) + { + a.Randomize(rng, 2, p-1, Integer::ANY); + b = a_exp_b_mod_c(a, (p-1)/q, p); + success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1); + } + } + } + return p; +} + +Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u) +{ + // isn't operator overloading great? + return p * (u * (xq-xp) % q) + xp; +/* + Integer t1 = xq-xp; + cout << hex << t1 << endl; + Integer t2 = u * t1; + cout << hex << t2 << endl; + Integer t3 = t2 % q; + cout << hex << t3 << endl; + Integer t4 = p * t3; + cout << hex << t4 << endl; + Integer t5 = t4 + xp; + cout << hex << t5 << endl; + return t5; +*/ +} + +Integer ModularSquareRoot(const Integer &a, const Integer &p) +{ + if (p%4 == 3) + return a_exp_b_mod_c(a, (p+1)/4, p); + + Integer q=p-1; + unsigned int r=0; + while (q.IsEven()) + { + r++; + q >>= 1; + } + + Integer n=2; + while (Jacobi(n, p) != -1) + ++n; + + Integer y = a_exp_b_mod_c(n, q, p); + Integer x = a_exp_b_mod_c(a, (q-1)/2, p); + Integer b = (x.Squared()%p)*a%p; + x = a*x%p; + Integer tempb, t; + + while (b != 1) + { + unsigned m=0; + tempb = b; + do + { + m++; + b = b.Squared()%p; + if (m==r) + return Integer::Zero(); + } + while (b != 1); + + t = y; + for (unsigned i=0; i>= 1; + b >>= 1; + k++; + } + + while (a[0]==0) + a >>= 1; + + while (b[0]==0) + b >>= 1; + + while (1) + { + switch (a.Compare(b)) + { + case -1: + b -= a; + while (b[0]==0) + b >>= 1; + break; + + case 0: + return (a <<= k); + + case 1: + a -= b; + while (a[0]==0) + a >>= 1; + break; + + default: + CRYPTOPP_ASSERT(false); + } + } +} + +Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) +{ + CRYPTOPP_ASSERT(b.Positive()); + + if (a.Negative()) + return EuclideanMultiplicativeInverse(a%b, b); + + if (b[0]==0) + { + if (!b || a[0]==0) + return Integer::Zero(); // no inverse + if (a==1) + return 1; + Integer u = EuclideanMultiplicativeInverse(b, a); + if (!u) + return Integer::Zero(); // no inverse + else + return (b*(a-u)+1)/a; + } + + Integer u=1, d=a, v1=b, v3=b, t1, t3, b2=(b+1)>>1; + + if (a[0]) + { + t1 = Integer::Zero(); + t3 = -b; + } + else + { + t1 = b2; + t3 = a>>1; + } + + while (!!t3) + { + while (t3[0]==0) + { + t3 >>= 1; + if (t1[0]==0) + t1 >>= 1; + else + { + t1 >>= 1; + t1 += b2; + } + } + if (t3.Positive()) + { + u = t1; + d = t3; + } + else + { + v1 = b-t1; + v3 = -t3; + } + t1 = u-v1; + t3 = d-v3; + if (t1.Negative()) + t1 += b; + } + if (d==1) + return u; + else + return Integer::Zero(); // no inverse +} +*/ + +int Jacobi(const Integer &aIn, const Integer &bIn) +{ + CRYPTOPP_ASSERT(bIn.IsOdd()); + + Integer b = bIn, a = aIn%bIn; + int result = 1; + + while (!!a) + { + unsigned i=0; + while (a.GetBit(i)==0) + i++; + a>>=i; + + if (i%2==1 && (b%8==3 || b%8==5)) + result = -result; + + if (a%4==3 && b%4==3) + result = -result; + + std::swap(a, b); + a %= b; + } + + return (b==1) ? result : 0; +} + +Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n) +{ + unsigned i = e.BitCount(); + if (i==0) + return Integer::Two(); + + MontgomeryRepresentation m(n); + Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(Integer::Two()); + Integer v=p, v1=m.Subtract(m.Square(p), two); + + i--; + while (i--) + { + if (e.GetBit(i)) + { + // v = (v*v1 - p) % m; + v = m.Subtract(m.Multiply(v,v1), p); + // v1 = (v1*v1 - 2) % m; + v1 = m.Subtract(m.Square(v1), two); + } + else + { + // v1 = (v*v1 - p) % m; + v1 = m.Subtract(m.Multiply(v,v1), p); + // v = (v*v - 2) % m; + v = m.Subtract(m.Square(v), two); + } + } + return m.ConvertOut(v); +} + +// This is Peter Montgomery's unpublished Lucas sequence evalutation algorithm. +// The total number of multiplies and squares used is less than the binary +// algorithm (see above). Unfortunately I can't get it to run as fast as +// the binary algorithm because of the extra overhead. +/* +Integer Lucas(const Integer &n, const Integer &P, const Integer &modulus) +{ + if (!n) + return 2; + +#define f(A, B, C) m.Subtract(m.Multiply(A, B), C) +#define X2(A) m.Subtract(m.Square(A), two) +#define X3(A) m.Multiply(A, m.Subtract(m.Square(A), three)) + + MontgomeryRepresentation m(modulus); + Integer two=m.ConvertIn(2), three=m.ConvertIn(3); + Integer A=m.ConvertIn(P), B, C, p, d=n, e, r, t, T, U; + + while (d!=1) + { + p = d; + unsigned int b = WORD_BITS * p.WordCount(); + Integer alpha = (Integer(5)<<(2*b-2)).SquareRoot() - Integer::Power2(b-1); + r = (p*alpha)>>b; + e = d-r; + B = A; + C = two; + d = r; + + while (d!=e) + { + if (d>2)) + if ((dm3+em3==0 || dm3+em3==3) && (t = e, t >>= 2, t += e, d <= t)) + { + // #1 +// t = (d+d-e)/3; +// t = d; t += d; t -= e; t /= 3; +// e = (e+e-d)/3; +// e += e; e -= d; e /= 3; +// d = t; + +// t = (d+e)/3 + t = d; t += e; t /= 3; + e -= t; + d -= t; + + T = f(A, B, C); + U = f(T, A, B); + B = f(T, B, A); + A = U; + continue; + } + +// if (dm6 == em6 && d <= e + (e>>2)) + if (dm3 == em3 && dm2 == em2 && (t = e, t >>= 2, t += e, d <= t)) + { + // #2 +// d = (d-e)>>1; + d -= e; d >>= 1; + B = f(A, B, C); + A = X2(A); + continue; + } + +// if (d <= (e<<2)) + if (d <= (t = e, t <<= 2)) + { + // #3 + d -= e; + C = f(A, B, C); + swap(B, C); + continue; + } + + if (dm2 == em2) + { + // #4 +// d = (d-e)>>1; + d -= e; d >>= 1; + B = f(A, B, C); + A = X2(A); + continue; + } + + if (dm2 == 0) + { + // #5 + d >>= 1; + C = f(A, C, B); + A = X2(A); + continue; + } + + if (dm3 == 0) + { + // #6 +// d = d/3 - e; + d /= 3; d -= e; + T = X2(A); + C = f(T, f(A, B, C), C); + swap(B, C); + A = f(T, A, A); + continue; + } + + if (dm3+em3==0 || dm3+em3==3) + { + // #7 +// d = (d-e-e)/3; + d -= e; d -= e; d /= 3; + T = f(A, B, C); + B = f(T, A, B); + A = X3(A); + continue; + } + + if (dm3 == em3) + { + // #8 +// d = (d-e)/3; + d -= e; d /= 3; + T = f(A, B, C); + C = f(A, C, B); + B = T; + A = X3(A); + continue; + } + + CRYPTOPP_ASSERT(em2 == 0); + // #9 + e >>= 1; + C = f(C, B, A); + B = X2(B); + } + + A = f(A, B, C); + } + +#undef f +#undef X2 +#undef X3 + + return m.ConvertOut(A); +} +*/ + +Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u) +{ + + // GCC warning bug, https://stackoverflow.com/q/12842306/608639 +#ifdef _OPENMP + Integer d = (m*m-4), p2, q2; + #pragma omp parallel + #pragma omp sections + { + #pragma omp section + { + p2 = p-Jacobi(d,p); + p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p); + } + #pragma omp section + { + q2 = q-Jacobi(d,q); + q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q); + } + } +#else + const Integer d = (m*m-4); + const Integer t1 = p-Jacobi(d,p); + const Integer p2 = Lucas(EuclideanMultiplicativeInverse(e,t1), m, p); + + const Integer t2 = q-Jacobi(d,q); + const Integer q2 = Lucas(EuclideanMultiplicativeInverse(e,t2), m, q); +#endif + + return CRT(p2, p, q2, q, u); +} + +unsigned int FactoringWorkFactor(unsigned int n) +{ + // extrapolated from the table in Odlyzko's "The Future of Integer Factorization" + // updated to reflect the factoring of RSA-130 + if (n<5) return 0; + else return (unsigned int)(2.4 * std::pow((double)n, 1.0/3.0) * std::pow(log(double(n)), 2.0/3.0) - 5); +} + +unsigned int DiscreteLogWorkFactor(unsigned int n) +{ + // assuming discrete log takes about the same time as factoring + if (n<5) return 0; + else return (unsigned int)(2.4 * std::pow((double)n, 1.0/3.0) * std::pow(log(double(n)), 2.0/3.0) - 5); +} + +// ******************************************************** + +void PrimeAndGenerator::Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) +{ + // no prime exists for delta = -1, qbits = 4, and pbits = 5 + CRYPTOPP_ASSERT(qbits > 4); + CRYPTOPP_ASSERT(pbits > qbits); + + if (qbits+1 == pbits) + { + Integer minP = Integer::Power2(pbits-1); + Integer maxP = Integer::Power2(pbits) - 1; + bool success = false; + + while (!success) + { + p.Randomize(rng, minP, maxP, Integer::ANY, 6+5*delta, 12); + PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*12, maxP), 12, delta); + + while (sieve.NextCandidate(p)) + { + CRYPTOPP_ASSERT(IsSmallPrime(p) || SmallDivisorsTest(p)); + q = (p-delta) >> 1; + CRYPTOPP_ASSERT(IsSmallPrime(q) || SmallDivisorsTest(q)); + if (FastProbablePrimeTest(q) && FastProbablePrimeTest(p) && IsPrime(q) && IsPrime(p)) + { + success = true; + break; + } + } + } + + if (delta == 1) + { + // find g such that g is a quadratic residue mod p, then g has order q + // g=4 always works, but this way we get the smallest quadratic residue (other than 1) + for (g=2; Jacobi(g, p) != 1; ++g) {} + // contributed by Walt Tuvell: g should be the following according to the Law of Quadratic Reciprocity + CRYPTOPP_ASSERT((p%8==1 || p%8==7) ? g==2 : (p%12==1 || p%12==11) ? g==3 : g==4); + } + else + { + CRYPTOPP_ASSERT(delta == -1); + // find g such that g*g-4 is a quadratic non-residue, + // and such that g has order q + for (g=3; ; ++g) + if (Jacobi(g*g-4, p)==-1 && Lucas(q, g, p)==2) + break; + } + } + else + { + Integer minQ = Integer::Power2(qbits-1); + Integer maxQ = Integer::Power2(qbits) - 1; + Integer minP = Integer::Power2(pbits-1); + Integer maxP = Integer::Power2(pbits) - 1; + + do + { + q.Randomize(rng, minQ, maxQ, Integer::PRIME); + } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, delta%q, q)); + + // find a random g of order q + if (delta==1) + { + do + { + Integer h(rng, 2, p-2, Integer::ANY); + g = a_exp_b_mod_c(h, (p-1)/q, p); + } while (g <= 1); + CRYPTOPP_ASSERT(a_exp_b_mod_c(g, q, p)==1); + } + else + { + CRYPTOPP_ASSERT(delta==-1); + do + { + Integer h(rng, 3, p-1, Integer::ANY); + if (Jacobi(h*h-4, p)==1) + continue; + g = Lucas((p+1)/q, h, p); + } while (g <= 2); + CRYPTOPP_ASSERT(Lucas(q, g, p) == 2); + } + } +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/nbtheory.h b/external/ours/library/crypto/src/shared/original/nbtheory.h new file mode 100755 index 000000000..a396ab462 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/nbtheory.h @@ -0,0 +1,317 @@ +// nbtheory.h - originally written and placed in the public domain by Wei Dai + +/// \file nbtheory.h +/// \brief Classes and functions for number theoretic operations + +#ifndef CRYPTOPP_NBTHEORY_H +#define CRYPTOPP_NBTHEORY_H + +#include "cryptlib.h" +#include "integer.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief The Small Prime table +/// \details GetPrimeTable obtains pointer to small prime table and provides the size of the table. +CRYPTOPP_DLL const word16 * CRYPTOPP_API GetPrimeTable(unsigned int &size); + +// ************ primality testing **************** + +/// \brief Generates a provable prime +/// \param rng a RandomNumberGenerator to produce random material +/// \param bits the number of bits in the prime number +/// \return Integer() meeting Maurer's tests for primality +CRYPTOPP_DLL Integer CRYPTOPP_API MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits); + +/// \brief Generates a provable prime +/// \param rng a RandomNumberGenerator to produce random material +/// \param bits the number of bits in the prime number +/// \return Integer() meeting Mihailescu's tests for primality +/// \details Mihailescu's methods performs a search using algorithmic progressions. +CRYPTOPP_DLL Integer CRYPTOPP_API MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits); + +/// \brief Tests whether a number is a small prime +/// \param p a candidate prime to test +/// \return true if p is a small prime, false otherwise +/// \details Internally, the library maintains a table of the first 32719 prime numbers +/// in sorted order. IsSmallPrime searches the table and returns true if p is +/// in the table. +CRYPTOPP_DLL bool CRYPTOPP_API IsSmallPrime(const Integer &p); + +/// \brief Tests whether a number is divisible by a small prime +/// \return true if p is divisible by some prime less than bound. +/// \details TrialDivision() returns true if p is divisible by some prime less +/// than bound. bound should not be greater than the largest entry in the +/// prime table, which is 32719. +CRYPTOPP_DLL bool CRYPTOPP_API TrialDivision(const Integer &p, unsigned bound); + +/// \brief Tests whether a number is divisible by a small prime +/// \return true if p is NOT divisible by small primes. +/// \details SmallDivisorsTest() returns true if p is NOT divisible by some +/// prime less than 32719. +CRYPTOPP_DLL bool CRYPTOPP_API SmallDivisorsTest(const Integer &p); + +/// \brief Determine if a number is probably prime +/// \param n the number to test +/// \param b the base to exponentiate +/// \return true if the number n is probably prime, false otherwise. +/// \details IsFermatProbablePrime raises b to the n-1 power and checks if +/// the result is congruent to 1 modulo n. +/// \details These is no reason to use IsFermatProbablePrime, use IsStrongProbablePrime or +/// IsStrongLucasProbablePrime instead. +/// \sa IsStrongProbablePrime, IsStrongLucasProbablePrime +CRYPTOPP_DLL bool CRYPTOPP_API IsFermatProbablePrime(const Integer &n, const Integer &b); + +/// \brief Determine if a number is probably prime +/// \param n the number to test +/// \return true if the number n is probably prime, false otherwise. +/// \details These is no reason to use IsLucasProbablePrime, use IsStrongProbablePrime or +/// IsStrongLucasProbablePrime instead. +/// \sa IsStrongProbablePrime, IsStrongLucasProbablePrime +CRYPTOPP_DLL bool CRYPTOPP_API IsLucasProbablePrime(const Integer &n); + +/// \brief Determine if a number is probably prime +/// \param n the number to test +/// \param b the base to exponentiate +/// \return true if the number n is probably prime, false otherwise. +CRYPTOPP_DLL bool CRYPTOPP_API IsStrongProbablePrime(const Integer &n, const Integer &b); + +/// \brief Determine if a number is probably prime +/// \param n the number to test +/// \return true if the number n is probably prime, false otherwise. +CRYPTOPP_DLL bool CRYPTOPP_API IsStrongLucasProbablePrime(const Integer &n); + +/// \brief Determine if a number is probably prime +/// \param rng a RandomNumberGenerator to produce random material +/// \param n the number to test +/// \param rounds the number of tests to perform +/// \details This is the Rabin-Miller primality test, i.e. repeating the strong probable prime +/// test for several rounds with random bases +/// \sa Trial divisions before +/// Miller-Rabin checks? on Crypto Stack Exchange +CRYPTOPP_DLL bool CRYPTOPP_API RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds); + +/// \brief Verifies a number is probably prime +/// \param p a candidate prime to test +/// \return true if p is a probable prime, false otherwise +/// \details IsPrime() is suitable for testing candidate primes when creating them. Internally, +/// IsPrime() utilizes SmallDivisorsTest(), IsStrongProbablePrime() and IsStrongLucasProbablePrime(). +CRYPTOPP_DLL bool CRYPTOPP_API IsPrime(const Integer &p); + +/// \brief Verifies a number is probably prime +/// \param rng a RandomNumberGenerator for randomized testing +/// \param p a candidate prime to test +/// \param level the level of thoroughness of testing +/// \return true if p is a strong probable prime, false otherwise +/// \details VerifyPrime() is suitable for testing candidate primes created by others. Internally, +/// VerifyPrime() utilizes IsPrime() and one-round RabinMillerTest(). If the candidate passes and +/// level is greater than 1, then 10 round RabinMillerTest() primality testing is performed. +CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1); + +/// \brief Application callback to signal suitability of a cabdidate prime +class CRYPTOPP_DLL PrimeSelector +{ +public: + virtual ~PrimeSelector() {} + const PrimeSelector *GetSelectorPointer() const {return this;} + virtual bool IsAcceptable(const Integer &candidate) const =0; +}; + +/// \brief Finds a random prime of special form +/// \param p an Integer reference to receive the prime +/// \param max the maximum value +/// \param equiv the equivalence class based on the parameter mod +/// \param mod the modulus used to reduce the equivalence class +/// \param pSelector pointer to a PrimeSelector function for the application to signal suitability +/// \return true if and only if FirstPrime() finds a prime and returns the prime through p. If FirstPrime() +/// returns false, then no such prime exists and the value of p is undefined +/// \details FirstPrime() uses a fast sieve to find the first probable prime +/// in {x | p<=x<=max and x%mod==equiv} +CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector); + +CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max); + +CRYPTOPP_DLL AlgorithmParameters CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); + +// ********** other number theoretic functions ************ + +/// \brief Calculate the greatest common divisor +/// \param a the first term +/// \param b the second term +/// \return the greatest common divisor if one exists, 0 otherwise. +inline Integer GCD(const Integer &a, const Integer &b) + {return Integer::Gcd(a,b);} + +/// \brief Determine relative primality +/// \param a the first term +/// \param b the second term +/// \return true if a and b are relatively prime, false otherwise. +inline bool RelativelyPrime(const Integer &a, const Integer &b) + {return Integer::Gcd(a,b) == Integer::One();} + +/// \brief Calculate the least common multiple +/// \param a the first term +/// \param b the second term +/// \return the least common multiple of a and b. +inline Integer LCM(const Integer &a, const Integer &b) + {return a/Integer::Gcd(a,b)*b;} + +/// \brief Calculate multiplicative inverse +/// \param a the number to test +/// \param b the modulus +/// \return an Integer (a ^ -1) % n or 0 if none exists. +/// \details EuclideanMultiplicativeInverse returns the multiplicative inverse of the Integer +/// *a modulo the Integer b. If no Integer exists then Integer 0 is returned. +inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) + {return a.InverseMod(b);} + + +/// \brief Chinese Remainder Theorem +/// \param xp the first number, mod p +/// \param p the first prime modulus +/// \param xq the second number, mod q +/// \param q the second prime modulus +/// \param u inverse of p mod q +/// \return the CRT value of the parameters +/// \details CRT uses the Chinese Remainder Theorem to calculate x given +/// x mod p and x mod q, and u the inverse of p mod q. +CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u); + +/// \brief Calculate the Jacobi symbol +/// \param a the first term +/// \param b the second term +/// \return the Jacobi symbol. +/// \details Jacobi symbols are calculated using the following rules: +/// -# if b is prime, then Jacobi(a, b), then return 0 +/// -# if a%b==0 AND a is quadratic residue mod b, then return 1 +/// -# return -1 otherwise +/// \details Refer to a number theory book for what Jacobi symbol means when b is not prime. +CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b); + +/// \brief Calculate the Lucas value +/// \return the Lucas value +/// \details Lucas() calculates the Lucas function V_e(p, 1) mod n. +CRYPTOPP_DLL Integer CRYPTOPP_API Lucas(const Integer &e, const Integer &p, const Integer &n); + +/// \brief Calculate the inverse Lucas value +/// \return the inverse Lucas value +/// \details InverseLucas() calculates x such that m==Lucas(e, x, p*q), +/// p q primes, u is inverse of p mod q. +CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u); + +/// \brief Modular multiplication +/// \param x the first term +/// \param y the second term +/// \param m the modulus +/// \return an Integer (x * y) % m. +inline Integer ModularMultiplication(const Integer &x, const Integer &y, const Integer &m) + {return a_times_b_mod_c(x, y, m);} + +/// \brief Modular exponentiation +/// \param x the base +/// \param e the exponent +/// \param m the modulus +/// \return an Integer (a ^ b) % m. +inline Integer ModularExponentiation(const Integer &x, const Integer &e, const Integer &m) + {return a_exp_b_mod_c(x, e, m);} + +/// \brief Extract a modular square root +/// \param a the number to extract square root +/// \param p the prime modulus +/// \return the modular square root if it exists +/// \details ModularSquareRoot returns x such that x*x%p == a, p prime +CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p); + +/// \brief Extract a modular root +/// \return a modular root if it exists +/// \details ModularRoot returns x such that a==ModularExponentiation(x, e, p*q), +/// p q primes, and e relatively prime to (p-1)*(q-1), +/// dp=d%(p-1), dq=d%(q-1), (d is inverse of e mod (p-1)*(q-1)) +/// and u=inverse of p mod q. +CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u); + +/// \brief Solve a Modular Quadratic Equation +/// \param r1 the first residue +/// \param r2 the second residue +/// \param a the first coefficient +/// \param b the second coefficient +/// \param c the third constant +/// \param p the prime modulus +/// \return true if solutions exist +/// \details SolveModularQuadraticEquation() finds r1 and r2 such that ax^2 + +/// bx + c == 0 (mod p) for x in {r1, r2}, p prime. +CRYPTOPP_DLL bool CRYPTOPP_API SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p); + +/// \brief Estimate work factor +/// \param bitlength the size of the number, in bits +/// \return the estimated work factor, in operations +/// \details DiscreteLogWorkFactor returns log base 2 of estimated number of operations to +/// calculate discrete log or factor a number. +CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength); + +/// \brief Estimate work factor +/// \param bitlength the size of the number, in bits +/// \return the estimated work factor, in operations +/// \details FactoringWorkFactor returns log base 2 of estimated number of operations to +/// calculate discrete log or factor a number. +CRYPTOPP_DLL unsigned int CRYPTOPP_API FactoringWorkFactor(unsigned int bitlength); + +// ******************************************************** + +/// \brief Generator of prime numbers of special forms +class CRYPTOPP_DLL PrimeAndGenerator +{ +public: + /// \brief Construct a PrimeAndGenerator + PrimeAndGenerator() {} + + /// \brief Construct a PrimeAndGenerator + /// \param delta +1 or -1 + /// \param rng a RandomNumberGenerator derived class + /// \param pbits the number of bits in the prime p + /// \details PrimeAndGenerator() generates a random prime p of the form 2*q+delta, where delta is 1 or -1 and q is + /// also prime. Internally the constructor calls Generate(delta, rng, pbits, pbits-1). + /// \pre pbits > 5 + /// \warning This PrimeAndGenerator() is slow because primes of this form are harder to find. + PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits) + {Generate(delta, rng, pbits, pbits-1);} + + /// \brief Construct a PrimeAndGenerator + /// \param delta +1 or -1 + /// \param rng a RandomNumberGenerator derived class + /// \param pbits the number of bits in the prime p + /// \param qbits the number of bits in the prime q + /// \details PrimeAndGenerator() generates a random prime p of the form 2*r*q+delta, where q is also prime. + /// Internally the constructor calls Generate(delta, rng, pbits, qbits). + /// \pre qbits > 4 && pbits > qbits + PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits) + {Generate(delta, rng, pbits, qbits);} + + /// \brief Generate a Prime and Generator + /// \param delta +1 or -1 + /// \param rng a RandomNumberGenerator derived class + /// \param pbits the number of bits in the prime p + /// \param qbits the number of bits in the prime q + /// \details Generate() generates a random prime p of the form 2*r*q+delta, where q is also prime. + void Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits); + + /// \brief Retrieve first prime + /// \return Prime() returns the prime p. + const Integer& Prime() const {return p;} + + /// \brief Retrieve second prime + /// \return SubPrime() returns the prime q. + const Integer& SubPrime() const {return q;} + + /// \brief Retrieve the generator + /// \return Generator() returns the generator g. + const Integer& Generator() const {return g;} + +private: + Integer p, q, g; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/neon_simd.cpp b/external/ours/library/crypto/src/shared/original/neon_simd.cpp new file mode 100755 index 000000000..602ba0e97 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/neon_simd.cpp @@ -0,0 +1,197 @@ + +// crc_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics to gain access to ARMv7a and +// ARMv8a NEON instructions. A separate source file is needed +// because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. +// For Linux and Unix additional flags are not required. + +#include "pch.h" +#include "config.h" +#include "stdcpp.h" + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char NEON_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +bool CPU_ProbeARMv7() +{ +#if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) + return false; +#elif defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif CRYPTOPP_ARM_NEON_AVAILABLE +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + // Modern MS hardware is ARMv7 + result = true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +# else + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + +#if 0 + // ARMv7 added movt and movw + int a; + asm volatile("movw %0,%1 \n" + "movt %0,%1 \n" + : "=r"(a) : "i"(0x1234)); + +00000010 <_Z5test2v>: // ARM + 10: e3010234 movw r0, #4660 ; 0x1234 + 14: e3410234 movt r0, #4660 ; 0x1234 + 18: e12fff1e bx lr + +0000001c <_Z5test3v>: // Thumb + 1c: f241 2034 movw r0, #4660 ; 0x1234 + 20: f2c1 2034 movt r0, #4660 ; 0x1234 + 24: e12fff1e bx lr +#endif + + unsigned int a; + asm volatile ( +#if defined(__thumb__) + ".inst.n 0xf241, 0x2034 \n\t" // movw r0, 0x1234 + ".inst.n 0xf2c1, 0x2034 \n\t" // movt r0, 0x1234 + "mov %0, r0 \n\t" // mov [a], r0 +#else + ".inst 0xe3010234 \n\t" // movw r0, 0x1234 + ".inst 0xe3410234 \n\t" // movt r0, 0x1234 + "mov %0, r0 \n\t" // mov [a], r0 +#endif + : "=r" (a) : : "r0"); + + result = (a == 0x12341234); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_NEON_AVAILABLE +} + +bool CPU_ProbeNEON() +{ +#if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) + return true; +#elif defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif CRYPTOPP_ARM_NEON_AVAILABLE +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + uint32x4_t x = vdupq_n_u32(1); + uint32x4_t y = vshlq_n_u32(x, 4); + + word32 z[4]; vst1q_u32(z, y); + return (z[0] & z[1] & z[2] & z[3]) == 16; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +# else + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + // This is risky... When we hand encode the instructions + // for vmov.u32 and vshl.u32 we get a SIGILL. Apparently + // we need more than just the instructions. Using + // intrinsics introduces the risk because the whole + // file gets built with ISA options, and the higher ISA + // may escape the try block with the SIGILL guard. + uint32x4_t x = vdupq_n_u32(1); + uint32x4_t y = vshlq_n_u32(x, 4); + + word32 z[4]; vst1q_u32(z, y); + result = (z[0] & z[1] & z[2] & z[3]) == 16; + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_NEON_AVAILABLE +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/nr.h b/external/ours/library/crypto/src/shared/original/nr.h new file mode 100755 index 000000000..101f9106e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/nr.h @@ -0,0 +1,11 @@ +// nr.h - originally written and placed in the public domain by Wei Dai + +/// \file nr.h +/// \brief Classes for Nyberg-Rueppel signature scheme + +#ifndef CRYPTOPP_NR_H +#define CRYPTOPP_NR_H + +#include "gfpcrypt.h" + +#endif diff --git a/external/ours/library/crypto/src/shared/original/oaep.cpp b/external/ours/library/crypto/src/shared/original/oaep.cpp new file mode 100755 index 000000000..fb9e31a0c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/oaep.cpp @@ -0,0 +1,98 @@ +// oaep.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "oaep.h" +#include "stdcpp.h" +#include "smartptr.h" + +NAMESPACE_BEGIN(CryptoPP) + +// ******************************************************** + +size_t OAEP_Base::MaxUnpaddedLength(size_t paddedLength) const +{ + return SaturatingSubtract(paddedLength/8, 1+2*DigestSize()); +} + +void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLength, byte *oaepBlock, size_t oaepBlockLen, const NameValuePairs ¶meters) const +{ + CRYPTOPP_ASSERT (inputLength <= MaxUnpaddedLength(oaepBlockLen)); + + // convert from bit length to byte length + if (oaepBlockLen % 8 != 0) + { + oaepBlock[0] = 0; + oaepBlock++; + } + oaepBlockLen /= 8; + + member_ptr pHash(NewHash()); + const size_t hLen = pHash->DigestSize(); + const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; + byte *const maskedSeed = oaepBlock; + byte *const maskedDB = oaepBlock+seedLen; + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + // DB = pHash || 00 ... || 01 || M + pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()); + memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1); + maskedDB[dbLen-inputLength-1] = 0x01; + memcpy(maskedDB+dbLen-inputLength, input, inputLength); + + rng.GenerateBlock(maskedSeed, seedLen); + member_ptr pMGF(NewMGF()); + pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); + pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); +} + +DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, size_t oaepBlockLen, byte *output, const NameValuePairs ¶meters) const +{ + bool invalid = false; + + // convert from bit length to byte length + if (oaepBlockLen % 8 != 0) + { + invalid = (oaepBlock[0] != 0) || invalid; + oaepBlock++; + } + oaepBlockLen /= 8; + + member_ptr pHash(NewHash()); + const size_t hLen = pHash->DigestSize(); + const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; + + invalid = (oaepBlockLen < 2*hLen+1) || invalid; + + SecByteBlock t(oaepBlock, oaepBlockLen); + byte *const maskedSeed = t; + byte *const maskedDB = t+seedLen; + + member_ptr pMGF(NewMGF()); + pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); + pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + // DB = pHash' || 00 ... || 01 || M + byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01); + invalid = (M == maskedDB+dbLen) || invalid; + invalid = (FindIfNot(maskedDB+hLen, M, byte(0)) != M) || invalid; + invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid; + + if (invalid) + return DecodingResult(); + + M++; + memcpy(output, M, maskedDB+dbLen-M); + return DecodingResult(maskedDB+dbLen-M); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/oaep.h b/external/ours/library/crypto/src/shared/original/oaep.h new file mode 100755 index 000000000..76be7f244 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/oaep.h @@ -0,0 +1,54 @@ +// oaep.h - originally written and placed in the public domain by Wei Dai + +/// \file oaep.h +/// \brief Classes for optimal asymmetric encryption padding +/// \since Crypto++ 2.1 + +#ifndef CRYPTOPP_OAEP_H +#define CRYPTOPP_OAEP_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief OAEP padding base class +/// \since Crypto++ 2.1 +class CRYPTOPP_DLL OAEP_Base : public PK_EncryptionMessageEncodingMethod +{ +public: + bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} + size_t MaxUnpaddedLength(size_t paddedLength) const; + void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedLength, const NameValuePairs ¶meters) const; + DecodingResult Unpad(const byte *padded, size_t paddedLength, byte *raw, const NameValuePairs ¶meters) const; + +protected: + virtual unsigned int DigestSize() const =0; + virtual HashTransformation * NewHash() const =0; + virtual MaskGeneratingFunction * NewMGF() const =0; +}; + +/// \brief OAEP padding +/// \tparam H HashTransformation derived class +/// \tparam MGF MaskGeneratingFunction derived class +/// \sa EME-OAEP, for use with classes derived from TF_ES +/// \since Crypto++ 2.1 +template +class OAEP : public OAEP_Base, public EncryptionStandard +{ +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("OAEP-") + MGF::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} + typedef OAEP EncryptionMessageEncodingMethod; + +protected: + unsigned int DigestSize() const {return H::DIGESTSIZE;} + HashTransformation * NewHash() const {return new H;} + MaskGeneratingFunction * NewMGF() const {return new MGF;} +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS OAEP; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/oids.h b/external/ours/library/crypto/src/shared/original/oids.h new file mode 100755 index 000000000..016d218ac --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/oids.h @@ -0,0 +1,197 @@ +// oids.h - originally written and placed in the public domain by Wei Dai + +/// \file oids.h +/// \brief ASN.1 object identifiers for algorthms and schemes +/// \details Most OIDs can be found at http://www.oid-info.com/. The Chinese OIDs +/// are assigned in GM/T 0006-2012, Cryptographic Application Identifier Criterion +/// Specification. A reproduction can be found at http://gmssl.org/docs/oid.html. +/// There seems to be some confusion between the text of GmSSL's oid.html web page +/// and the actual OID used in the code. We used the same OIDs that were detailed in +/// http://github.com/guanzhi/GmSSL/blob/master/crypto/objects/objects.txt. + +#ifndef CRYPTOPP_OIDS_H +#define CRYPTOPP_OIDS_H + +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +NAMESPACE_BEGIN(ASN1) + +#define DEFINE_OID(value, name) inline OID name() {return value;} + +DEFINE_OID(1, iso) + DEFINE_OID(iso()+2, member_body) + DEFINE_OID(member_body()+156, iso_cn) + DEFINE_OID(iso_cn()+10197, oscca) + DEFINE_OID(oscca()+1, sm_scheme) + DEFINE_OID(sm_scheme()+104, sms4) + DEFINE_OID(sm_scheme()+301, sm2p256v1) + DEFINE_OID(sm2p256v1()+1, sm2sign) + DEFINE_OID(sm2p256v1()+2, sm2exchange) + DEFINE_OID(sm2p256v1()+3, sm2encrypt) + DEFINE_OID(sm2encrypt()+1, sm2encrypt_recommendedParameters) + DEFINE_OID(sm2encrypt()+2, sm2encrypt_specifiedParameters) + DEFINE_OID(member_body()+840, iso_us) + DEFINE_OID(iso_us()+10040, ansi_x9_57) + DEFINE_OID(ansi_x9_57()+4, ansi_x9cm) + DEFINE_OID(ansi_x9cm()+1, id_dsa) + DEFINE_OID(iso_us()+10045, ansi_x9_62) + DEFINE_OID(ansi_x9_62()+1, id_fieldType) + DEFINE_OID(id_fieldType()+1, prime_field) + DEFINE_OID(id_fieldType()+2, characteristic_two_field) + DEFINE_OID(characteristic_two_field()+3, id_characteristic_two_basis) + DEFINE_OID(id_characteristic_two_basis()+1, gnBasis) + DEFINE_OID(id_characteristic_two_basis()+2, tpBasis) + DEFINE_OID(id_characteristic_two_basis()+3, ppBasis) + DEFINE_OID(ansi_x9_62()+2, id_publicKeyType) + DEFINE_OID(id_publicKeyType()+1, id_ecPublicKey) + DEFINE_OID(ansi_x9_62()+3, ansi_x9_62_curves) + DEFINE_OID(ansi_x9_62_curves()+1, ansi_x9_62_curves_prime) + // ANSI X9.62 + DEFINE_OID(ansi_x9_62_curves_prime()+1, secp192r1) // secp192v1 + //DEFINE_OID(ansi_x9_62_curves_prime()+2, secp192v2) + //DEFINE_OID(ansi_x9_62_curves_prime()+3, secp192v3) + //DEFINE_OID(ansi_x9_62_curves_prime()+4, secp239v1) + //DEFINE_OID(ansi_x9_62_curves_prime()+5, secp239v2) + //DEFINE_OID(ansi_x9_62_curves_prime()+6, secp239v3) + DEFINE_OID(ansi_x9_62_curves_prime()+7, secp256r1) // secp256v1 + DEFINE_OID(ansi_x9_62()+4, ansi_signatures) + DEFINE_OID(ansi_signatures()+3, ecdsa_with_sha2) + DEFINE_OID(ecdsa_with_sha2()+1, ecdsa_with_sha224) + DEFINE_OID(ecdsa_with_sha2()+2, ecdsa_with_sha256) + DEFINE_OID(ecdsa_with_sha2()+3, ecdsa_with_sha384) + DEFINE_OID(ecdsa_with_sha2()+4, ecdsa_with_sha512) + DEFINE_OID(iso_us()+113549, rsadsi) + DEFINE_OID(rsadsi()+1, pkcs) + DEFINE_OID(pkcs()+1, pkcs_1) + // Arc from PKCS #1 and RFC 2459 + DEFINE_OID(pkcs_1()+1, rsaEncryption) + DEFINE_OID(pkcs_1()+2, md2WithRSAEncryption) + DEFINE_OID(pkcs_1()+3, md4withRSAEncryption) + DEFINE_OID(pkcs_1()+4, md5WithRSAEncryption) + DEFINE_OID(pkcs_1()+5, sha1WithRSAEncryption) + DEFINE_OID(pkcs_1()+10, rsassa_pss) + DEFINE_OID(pkcs_1()+11, sha256WithRSAEncryption) + DEFINE_OID(pkcs_1()+12, sha384WithRSAEncryption) + DEFINE_OID(pkcs_1()+13, sha512WithRSAEncryption) + DEFINE_OID(pkcs_1()+14, sha224WithRSAEncryption) + DEFINE_OID(pkcs_1()+15, sha512_224WithRSAEncryption) + DEFINE_OID(pkcs_1()+16, sha512_256WithRSAEncryption) + DEFINE_OID(rsadsi()+2, rsadsi_digestAlgorithm) + DEFINE_OID(rsadsi_digestAlgorithm()+2, id_md2) + DEFINE_OID(rsadsi_digestAlgorithm()+5, id_md5) + DEFINE_OID(iso()+3, identified_organization) + // Arc from http://tools.ietf.org/html/draft-josefsson-pkix-newcurves + // GNU and OpenPGP uses 1.3.6.1.4.1.11591.15.1 for Ed25519. See + // https://www.gnu.org/prep/standards/html_node/OID-Allocations.html, + // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-rfc4880bis + DEFINE_OID(identified_organization()+6, dod) + DEFINE_OID(dod()+1, internet) + DEFINE_OID(internet()+4, internet_private) + DEFINE_OID(internet_private()+1, enterprise) + DEFINE_OID(enterprise()+11591,gnu) + DEFINE_OID(gnu()+15,ellipticCurve) + DEFINE_OID(ellipticCurve()+1,curve25519) + DEFINE_OID(ellipticCurve()+2,curve448) + DEFINE_OID(ellipticCurve()+3,curve25519ph) + DEFINE_OID(ellipticCurve()+4,curve448ph) + DEFINE_OID(identified_organization()+14, oiw) + DEFINE_OID(oiw()+3, oiw_secsig) + DEFINE_OID(oiw_secsig()+2, oiw_secsig_algorithms) + DEFINE_OID(oiw_secsig_algorithms()+26, id_sha1) + DEFINE_OID(oiw()+7, dssig) + DEFINE_OID(dssig()+2, algorithm) + DEFINE_OID(algorithm()+1, encryptionAlgorithm) + DEFINE_OID(encryptionAlgorithm()+1, elGamal) + DEFINE_OID(identified_organization()+36, teletrust) + DEFINE_OID(teletrust()+3, teletrust_algorithm) + DEFINE_OID(teletrust_algorithm()+2+1, id_ripemd160) + DEFINE_OID(teletrust_algorithm()+3+2+8+1, teletrust_ellipticCurve) + DEFINE_OID(teletrust_ellipticCurve()+1+1, brainpoolP160r1) + DEFINE_OID(teletrust_ellipticCurve()+1+3, brainpoolP192r1) + DEFINE_OID(teletrust_ellipticCurve()+1+5, brainpoolP224r1) + DEFINE_OID(teletrust_ellipticCurve()+1+7, brainpoolP256r1) + DEFINE_OID(teletrust_ellipticCurve()+1+9, brainpoolP320r1) + DEFINE_OID(teletrust_ellipticCurve()+1+11, brainpoolP384r1) + DEFINE_OID(teletrust_ellipticCurve()+1+13, brainpoolP512r1) + // https://tools.ietf.org/html/draft-ietf-curdle-pkix-07 + DEFINE_OID(identified_organization()+101, thawte) + DEFINE_OID(thawte()+110, X25519) + DEFINE_OID(thawte()+111, X448) + DEFINE_OID(thawte()+112, Ed25519) + DEFINE_OID(thawte()+113, Ed448) + DEFINE_OID(identified_organization()+132, certicom) + DEFINE_OID(certicom()+0, certicom_ellipticCurve) + // these are sorted by curve type and then by OID + // first curves based on GF(p) + DEFINE_OID(certicom_ellipticCurve()+6, secp112r1) + DEFINE_OID(certicom_ellipticCurve()+7, secp112r2) + DEFINE_OID(certicom_ellipticCurve()+8, secp160r1) + DEFINE_OID(certicom_ellipticCurve()+9, secp160k1) + DEFINE_OID(certicom_ellipticCurve()+10, secp256k1) + DEFINE_OID(certicom_ellipticCurve()+28, secp128r1) + DEFINE_OID(certicom_ellipticCurve()+29, secp128r2) + DEFINE_OID(certicom_ellipticCurve()+30, secp160r2) + DEFINE_OID(certicom_ellipticCurve()+31, secp192k1) + DEFINE_OID(certicom_ellipticCurve()+32, secp224k1) + DEFINE_OID(certicom_ellipticCurve()+33, secp224r1) + DEFINE_OID(certicom_ellipticCurve()+34, secp384r1) + DEFINE_OID(certicom_ellipticCurve()+35, secp521r1) + // then curves based on GF(2^n) + DEFINE_OID(certicom_ellipticCurve()+1, sect163k1) + DEFINE_OID(certicom_ellipticCurve()+2, sect163r1) + DEFINE_OID(certicom_ellipticCurve()+3, sect239k1) + DEFINE_OID(certicom_ellipticCurve()+4, sect113r1) + DEFINE_OID(certicom_ellipticCurve()+5, sect113r2) + DEFINE_OID(certicom_ellipticCurve()+15, sect163r2) + DEFINE_OID(certicom_ellipticCurve()+16, sect283k1) + DEFINE_OID(certicom_ellipticCurve()+17, sect283r1) + DEFINE_OID(certicom_ellipticCurve()+22, sect131r1) + DEFINE_OID(certicom_ellipticCurve()+23, sect131r2) + DEFINE_OID(certicom_ellipticCurve()+24, sect193r1) + DEFINE_OID(certicom_ellipticCurve()+25, sect193r2) + DEFINE_OID(certicom_ellipticCurve()+26, sect233k1) + DEFINE_OID(certicom_ellipticCurve()+27, sect233r1) + DEFINE_OID(certicom_ellipticCurve()+36, sect409k1) + DEFINE_OID(certicom_ellipticCurve()+37, sect409r1) + DEFINE_OID(certicom_ellipticCurve()+38, sect571k1) + DEFINE_OID(certicom_ellipticCurve()+39, sect571r1) +DEFINE_OID(2, joint_iso_ccitt) + DEFINE_OID(joint_iso_ccitt()+16, country) + DEFINE_OID(country()+840, joint_iso_ccitt_us) + DEFINE_OID(joint_iso_ccitt_us()+1, us_organization) + DEFINE_OID(us_organization()+101, us_gov) + DEFINE_OID(us_gov()+3, csor) + DEFINE_OID(csor()+4, nistalgorithms) + DEFINE_OID(nistalgorithms()+1, aes) + DEFINE_OID(aes()+1, id_aes128_ECB) + DEFINE_OID(aes()+2, id_aes128_cbc) + DEFINE_OID(aes()+3, id_aes128_ofb) + DEFINE_OID(aes()+4, id_aes128_cfb) + DEFINE_OID(aes()+21, id_aes192_ECB) + DEFINE_OID(aes()+22, id_aes192_cbc) + DEFINE_OID(aes()+23, id_aes192_ofb) + DEFINE_OID(aes()+24, id_aes192_cfb) + DEFINE_OID(aes()+41, id_aes256_ECB) + DEFINE_OID(aes()+42, id_aes256_cbc) + DEFINE_OID(aes()+43, id_aes256_ofb) + DEFINE_OID(aes()+44, id_aes256_cfb) + DEFINE_OID(nistalgorithms()+2, nist_hashalgs) + DEFINE_OID(nist_hashalgs()+1, id_sha256) + DEFINE_OID(nist_hashalgs()+2, id_sha384) + DEFINE_OID(nist_hashalgs()+3, id_sha512) + DEFINE_OID(nist_hashalgs()+4, id_sha224) + DEFINE_OID(nist_hashalgs()+7, id_sha3_224) + DEFINE_OID(nist_hashalgs()+8, id_sha3_256) + DEFINE_OID(nist_hashalgs()+9, id_sha3_384) + DEFINE_OID(nist_hashalgs()+10, id_sha3_512) + DEFINE_OID(joint_iso_ccitt_us()+10046, ansi_x942) + DEFINE_OID(ansi_x942()+2, number_type) + DEFINE_OID(number_type()+1, dhpublicnumber) + +NAMESPACE_END + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/osrng.cpp b/external/ours/library/crypto/src/shared/original/osrng.cpp new file mode 100755 index 000000000..5121ac1ed --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/osrng.cpp @@ -0,0 +1,300 @@ +// osrng.cpp - originally written and placed in the public domain by Wei Dai + +// Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool. + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +// Win32 has CryptoAPI and . Windows 10 and Windows Store 10 have CNG and . +// There's a hole for Windows Phone 8 and Windows Store 8. There is no userland RNG available. +// Also see http://www.drdobbs.com/windows/using-c-and-com-with-winrt/240168150 and +// http://stackoverflow.com/questions/36974545/random-numbers-for-windows-phone-8-and-windows-store-8 and +// https://social.msdn.microsoft.com/Forums/vstudio/en-US/25b83e13-c85f-4aa1-a057-88a279ea3fd6/what-crypto-random-generator-c-code-could-use-on-wp81 +#if defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(OS_RNG_AVAILABLE) +# pragma message("WARNING: Compiling for Windows but an OS RNG is not available. This is likely a Windows Phone 8 or Windows Store 8 app.") +#endif + +#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE) + +#include "osrng.h" +#include "rng.h" + +#ifdef CRYPTOPP_WIN32_AVAILABLE +#define WIN32_LEAN_AND_MEAN +#include +#ifndef ERROR_INCORRECT_SIZE +# define ERROR_INCORRECT_SIZE 0x000005B6 +#endif +#if defined(USE_MS_CRYPTOAPI) +#include +#ifndef CRYPT_NEWKEYSET +# define CRYPT_NEWKEYSET 0x00000008 +#endif +#ifndef CRYPT_MACHINE_KEYSET +# define CRYPT_MACHINE_KEYSET 0x00000020 +#endif +#elif defined(USE_MS_CNGAPI) +#include +#ifndef BCRYPT_SUCCESS +# define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif +#ifndef STATUS_INVALID_PARAMETER +# define STATUS_INVALID_PARAMETER 0xC000000D +#endif +#ifndef STATUS_INVALID_HANDLE +# define STATUS_INVALID_HANDLE 0xC0000008 +#endif +#endif +#endif // Win32 + +#ifdef CRYPTOPP_UNIX_AVAILABLE +#include +#include +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE) +OS_RNG_Err::OS_RNG_Err(const std::string &operation) + : Exception(OTHER_ERROR, "OS_Rng: " + operation + " operation failed with error " + +#ifdef CRYPTOPP_WIN32_AVAILABLE + "0x" + IntToString(GetLastError(), 16) +#else + IntToString(errno) +#endif + ) +{ +} +#endif + +#ifdef NONBLOCKING_RNG_AVAILABLE + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +#if defined(USE_MS_CNGAPI) +inline DWORD NtStatusToErrorCode(NTSTATUS status) +{ + if (status == STATUS_INVALID_PARAMETER) + return ERROR_INVALID_PARAMETER; + else if (status == STATUS_INVALID_HANDLE) + return ERROR_INVALID_HANDLE; + else + return (DWORD)status; +} +#endif + +#if defined(UNICODE) || defined(_UNICODE) +# define CRYPTOPP_CONTAINER L"Crypto++ RNG" +#else +# define CRYPTOPP_CONTAINER "Crypto++ RNG" +#endif + +MicrosoftCryptoProvider::MicrosoftCryptoProvider() : m_hProvider(0) +{ +#if defined(USE_MS_CRYPTOAPI) + // See http://support.microsoft.com/en-us/kb/238187 for CRYPT_NEWKEYSET fallback strategy + if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + const DWORD firstErr = GetLastError(); + if (!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET /*user*/) && + !CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET)) + { + // Set original error with original code + SetLastError(firstErr); + throw OS_RNG_Err("CryptAcquireContext"); + } + } +#elif defined(USE_MS_CNGAPI) + NTSTATUS ret = BCryptOpenAlgorithmProvider(&m_hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + if (!(BCRYPT_SUCCESS(ret))) + { + // Hack... OS_RNG_Err calls GetLastError() + SetLastError(NtStatusToErrorCode(ret)); + throw OS_RNG_Err("BCryptOpenAlgorithmProvider"); + } +#endif +} + +MicrosoftCryptoProvider::~MicrosoftCryptoProvider() +{ +#if defined(USE_MS_CRYPTOAPI) + if (m_hProvider) + CryptReleaseContext(m_hProvider, 0); +#elif defined(USE_MS_CNGAPI) + if (m_hProvider) + BCryptCloseAlgorithmProvider(m_hProvider, 0); +#endif +} + +#endif // CRYPTOPP_WIN32_AVAILABLE + +NonblockingRng::NonblockingRng() +{ +#ifndef CRYPTOPP_WIN32_AVAILABLE + m_fd = open("/dev/urandom",O_RDONLY); + if (m_fd == -1) + throw OS_RNG_Err("open /dev/urandom"); + + // Do some OSes return -NNN instead of -1? + CRYPTOPP_ASSERT(m_fd >= 0); +#endif +} + +NonblockingRng::~NonblockingRng() +{ +#ifndef CRYPTOPP_WIN32_AVAILABLE + close(m_fd); +#endif +} + +void NonblockingRng::GenerateBlock(byte *output, size_t size) +{ +#ifdef CRYPTOPP_WIN32_AVAILABLE + // Acquiring a provider is expensive. Do it once and retain the reference. +# if defined(CRYPTOPP_CXX11_STATIC_INIT) + static const MicrosoftCryptoProvider hProvider = MicrosoftCryptoProvider(); +# else + const MicrosoftCryptoProvider &hProvider = Singleton().Ref(); +# endif +# if defined(USE_MS_CRYPTOAPI) + DWORD dwSize; + CRYPTOPP_ASSERT(SafeConvert(size, dwSize)); + if (!SafeConvert(size, dwSize)) + { + SetLastError(ERROR_INCORRECT_SIZE); + throw OS_RNG_Err("GenerateBlock size"); + } + BOOL ret = CryptGenRandom(hProvider.GetProviderHandle(), dwSize, output); + CRYPTOPP_ASSERT(ret != FALSE); + if (ret == FALSE) + throw OS_RNG_Err("CryptGenRandom"); +# elif defined(USE_MS_CNGAPI) + ULONG ulSize; + CRYPTOPP_ASSERT(SafeConvert(size, ulSize)); + if (!SafeConvert(size, ulSize)) + { + SetLastError(ERROR_INCORRECT_SIZE); + throw OS_RNG_Err("GenerateBlock size"); + } + NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, ulSize, 0); + CRYPTOPP_ASSERT(BCRYPT_SUCCESS(ret)); + if (!(BCRYPT_SUCCESS(ret))) + { + // Hack... OS_RNG_Err calls GetLastError() + SetLastError(NtStatusToErrorCode(ret)); + throw OS_RNG_Err("BCryptGenRandom"); + } +# endif +#else + while (size) + { + ssize_t len = read(m_fd, output, size); + if (len < 0) + { + // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) + if (errno != EINTR && errno != EAGAIN) + throw OS_RNG_Err("read /dev/urandom"); + + continue; + } + + output += len; + size -= len; + } +#endif // CRYPTOPP_WIN32_AVAILABLE +} + +#endif // NONBLOCKING_RNG_AVAILABLE + +// ************************************************************* + +#ifdef BLOCKING_RNG_AVAILABLE + +#ifndef CRYPTOPP_BLOCKING_RNG_FILENAME +#ifdef __OpenBSD__ +#define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/srandom" +#else +#define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/random" +#endif +#endif + +BlockingRng::BlockingRng() +{ + m_fd = open(CRYPTOPP_BLOCKING_RNG_FILENAME,O_RDONLY); + if (m_fd == -1) + throw OS_RNG_Err("open " CRYPTOPP_BLOCKING_RNG_FILENAME); + + // Do some OSes return -NNN instead of -1? + CRYPTOPP_ASSERT(m_fd >= 0); +} + +BlockingRng::~BlockingRng() +{ + close(m_fd); +} + +void BlockingRng::GenerateBlock(byte *output, size_t size) +{ + while (size) + { + // on some systems /dev/random will block until all bytes + // are available, on others it returns immediately + ssize_t len = read(m_fd, output, size); + if (len < 0) + { + // /dev/random reads CAN give EAGAIN errors! (maybe EINTR as well) + if (errno != EINTR && errno != EAGAIN) + throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); + + continue; + } + + size -= len; + output += len; + if (size) + sleep(1); + } +} + +#endif // BLOCKING_RNG_AVAILABLE + +// ************************************************************* + +void OS_GenerateRandomBlock(bool blocking, byte *output, size_t size) +{ +#ifdef NONBLOCKING_RNG_AVAILABLE + if (blocking) +#endif + { +#ifdef BLOCKING_RNG_AVAILABLE + BlockingRng rng; + rng.GenerateBlock(output, size); +#endif + } + +#ifdef BLOCKING_RNG_AVAILABLE + if (!blocking) +#endif + { +#ifdef NONBLOCKING_RNG_AVAILABLE + NonblockingRng rng; + rng.GenerateBlock(output, size); +#endif + } +} + +void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize) +{ + SecByteBlock seed(seedSize); + OS_GenerateRandomBlock(blocking, seed, seedSize); + IncorporateEntropy(seed, seedSize); +} + +NAMESPACE_END + +#endif // OS_RNG_AVAILABLE + +#endif // CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/osrng.h b/external/ours/library/crypto/src/shared/original/osrng.h new file mode 100755 index 000000000..bd534d585 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/osrng.h @@ -0,0 +1,304 @@ +// osrng.h - originally written and placed in the public domain by Wei Dai + +/// \file osrng.h +/// \brief Classes for access to the operating system's random number generators + +#ifndef CRYPTOPP_OSRNG_H +#define CRYPTOPP_OSRNG_H + +#include "config.h" + +#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE) + +#include "cryptlib.h" +#include "randpool.h" +#include "smartptr.h" +#include "fips140.h" +#include "hkdf.h" +#include "rng.h" +#include "aes.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Exception thrown when an operating system error is encountered +class CRYPTOPP_DLL OS_RNG_Err : public Exception +{ +public: + /// \brief Constructs an OS_RNG_Err + /// \param operation the operation or API call when the error occurs + OS_RNG_Err(const std::string &operation); +}; + +#ifdef NONBLOCKING_RNG_AVAILABLE + +#ifdef CRYPTOPP_WIN32_AVAILABLE +/// \brief Wrapper for Microsoft crypto service provider +/// \sa \def USE_MS_CRYPTOAPI, \def USE_MS_CNGAPI +class CRYPTOPP_DLL MicrosoftCryptoProvider +{ +public: + /// \brief Construct a MicrosoftCryptoProvider + MicrosoftCryptoProvider(); + ~MicrosoftCryptoProvider(); + +// type HCRYPTPROV and BCRYPT_ALG_HANDLE, avoid #include +#if defined(USE_MS_CRYPTOAPI) +# if defined(__CYGWIN__) && defined(__x86_64__) + typedef unsigned long long ProviderHandle; +# elif defined(WIN64) || defined(_WIN64) + typedef unsigned __int64 ProviderHandle; +# else + typedef unsigned long ProviderHandle; +# endif +#elif defined(USE_MS_CNGAPI) + typedef void *PVOID; + typedef PVOID ProviderHandle; +#endif // USE_MS_CRYPTOAPI or USE_MS_CNGAPI + + /// \brief Retrieves the provider handle + /// \return CryptoAPI provider handle + /// \details If USE_MS_CRYPTOAPI is in effect, then CryptAcquireContext() + /// acquires then handle and CryptReleaseContext() releases the handle + /// upon destruction. If USE_MS_CNGAPI is in effect, then + /// BCryptOpenAlgorithmProvider() acquires then handle and + /// BCryptCloseAlgorithmProvider() releases the handle upon destruction. + ProviderHandle GetProviderHandle() const {return m_hProvider;} + +private: + ProviderHandle m_hProvider; +}; + +#if defined(_MSC_VER) && defined(USE_MS_CRYPTOAPI) +# pragma comment(lib, "advapi32.lib") +#endif + +#if defined(_MSC_VER) && defined(USE_MS_CNGAPI) +# pragma comment(lib, "bcrypt.lib") +#endif + +#endif // CRYPTOPP_WIN32_AVAILABLE + +/// \brief Wrapper class for /dev/random and /dev/srandom +/// \details Encapsulates CryptoAPI's CryptGenRandom() or CryptoNG's BCryptGenRandom() +/// on Windows, or /dev/urandom on Unix and compatibles. +class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "NonblockingRng"; } + + ~NonblockingRng(); + + /// \brief Construct a NonblockingRng + NonblockingRng(); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock(). + void GenerateBlock(byte *output, size_t size); + +protected: +#ifdef CRYPTOPP_WIN32_AVAILABLE + MicrosoftCryptoProvider m_Provider; +#else + int m_fd; +#endif +}; + +#endif + +#if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \brief Wrapper class for /dev/random and /dev/srandom +/// \details Encapsulates /dev/random on Linux, OS X and Unix; and /dev/srandom on the BSDs. +/// \note On Linux the /dev/random interface is effectively deprecated. According to the +/// Kernel Crypto developers, /dev/urandom or getrandom(2) should be used instead. Also +/// see [RFC PATCH v12 3/4] Linux Random +/// Number Generator on the kernel-crypto mailing list. +class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; } + + ~BlockingRng(); + + /// \brief Construct a BlockingRng + BlockingRng(); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock(). + void GenerateBlock(byte *output, size_t size); + +protected: + int m_fd; +}; + +#endif + +/// OS_GenerateRandomBlock +/// \brief Generate random array of bytes +/// \param blocking specifies whether a blocking or non-blocking generator should be used +/// \param output the byte buffer +/// \param size the length of the buffer, in bytes +/// \details OS_GenerateRandomBlock() uses the underlying operating system's +/// random number generator. On Windows, CryptGenRandom() is called using NonblockingRng. +/// \details On Unix and compatibles, /dev/urandom is called if blocking is false using +/// NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used +/// by way of BlockingRng, if available. +CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size); + +/// \brief Automatically Seeded Randomness Pool +/// \details This class seeds itself using an operating system provided RNG. +/// AutoSeededRandomPool was suggested by Leonard Janke. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "AutoSeededRandomPool"; } + + ~AutoSeededRandomPool() {} + + /// \brief Construct an AutoSeededRandomPool + /// \param blocking controls seeding with BlockingRng or NonblockingRng + /// \param seedSize the size of the seed, in bytes + /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng. + /// The parameter is ignored if only one of these is available. + explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32) + {Reseed(blocking, seedSize);} + + /// \brief Reseed an AutoSeededRandomPool + /// \param blocking controls seeding with BlockingRng or NonblockingRng + /// \param seedSize the size of the seed, in bytes + void Reseed(bool blocking = false, unsigned int seedSize = 32); +}; + +/// \tparam BLOCK_CIPHER a block cipher +/// \brief Automatically Seeded X9.17 RNG +/// \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG. +/// If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is +/// used, then its a X9.31 conforming generator. +/// \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER +/// can be any BlockTransformation derived class. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa X917RNG, DefaultAutoSeededRNG +template +class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable +{ +public: + static std::string StaticAlgorithmName() { + return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")"); + } + + ~AutoSeededX917RNG() {} + + /// \brief Construct an AutoSeededX917RNG + /// \param blocking controls seeding with BlockingRng or NonblockingRng + /// \param autoSeed controls auto seeding of the generator + /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng. + /// The parameter is ignored if only one of these is available. + /// \sa X917RNG + explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true) + {if (autoSeed) Reseed(blocking);} + + /// \brief Reseed an AutoSeededX917RNG + /// \param blocking controls seeding with BlockingRng or NonblockingRng + /// \param input additional entropy to add to the generator + /// \param length the size of the additional entropy, in bytes + /// \details Internally, the generator uses SHA256 to extract the entropy from + /// from the seed and then stretch the material for the block cipher's key + /// and initialization vector. + void Reseed(bool blocking = false, const byte *input = NULLPTR, size_t length = 0); + + /// \brief Deterministically reseed an AutoSeededX917RNG for testing + /// \param key the key to use for the deterministic reseeding + /// \param keylength the size of the key, in bytes + /// \param seed the seed to use for the deterministic reseeding + /// \param timeVector a time vector to use for deterministic reseeding + /// \details This is a testing interface for testing purposes, and should \a NOT + /// be used in production. + void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector); + + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);} + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) + {m_rng->GenerateIntoBufferedTransformation(target, channel, length);} + + std::string AlgorithmProvider() const; + +private: + member_ptr m_rng; +}; + +template +void AutoSeededX917RNG::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector) +{ + m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector)); +} + +template +void AutoSeededX917RNG::Reseed(bool blocking, const byte *input, size_t length) +{ + enum {BlockSize=BLOCK_CIPHER::BLOCKSIZE}; + enum {KeyLength=BLOCK_CIPHER::DEFAULT_KEYLENGTH}; + enum {SeedSize=EnumToInt(BlockSize)+EnumToInt(KeyLength)}; + + SecByteBlock seed(SeedSize), temp(SeedSize); + const byte label[] = "X9.17 key generation"; + const byte *key=NULLPTR; + + do + { + OS_GenerateRandomBlock(blocking, temp, temp.size()); + + HKDF hkdf; + hkdf.DeriveKey( + seed, seed.size(), // derived secret + temp, temp.size(), // instance secret + input, length, // user secret + label, 20 // unique label + ); + + key = seed + BlockSize; + } // check that seed and key don't have same value + while (memcmp(key, seed, STDMIN((size_t)BlockSize, (size_t)KeyLength)) == 0); + + Reseed(key, KeyLength, seed, NULLPTR); +} + +template +std::string AutoSeededX917RNG::AlgorithmProvider() const +{ + // Hack for now... We need to instantiate one + typename BLOCK_CIPHER::Encryption bc; + return bc.AlgorithmProvider(); +} + +CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG; + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief A typedef providing a default generator +/// \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG or AutoSeededRandomPool. +/// If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is +/// AutoSeededX917RNG. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +class DefaultAutoSeededRNG {} +#else +// AutoSeededX917RNG in FIPS mode, otherwise it's AutoSeededRandomPool +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +typedef AutoSeededX917RNG DefaultAutoSeededRNG; +#else +typedef AutoSeededRandomPool DefaultAutoSeededRNG; +#endif +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +NAMESPACE_END + +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ossig.h b/external/ours/library/crypto/src/shared/original/ossig.h new file mode 100755 index 000000000..ce9789b7d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ossig.h @@ -0,0 +1,128 @@ +// ossig.h - written and placed in the public domain by Jeffrey Walton +// +/// \file ossig.h +/// \brief Utility class for trapping OS signals. +/// \since Crypto++ 5.6.5 + +#ifndef CRYPTOPP_OS_SIGNAL_H +#define CRYPTOPP_OS_SIGNAL_H + +#include "config.h" + +#if defined(UNIX_SIGNALS_AVAILABLE) +# include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// ************** Unix and Linux compatibles *************** + +#if defined(UNIX_SIGNALS_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \brief Signal handler function pointer +/// \details SignalHandlerFn is provided as a stand alone function pointer with external "C" linkage +/// \sa SignalHandler, NullSignalHandler +extern "C" { + typedef void (*SignalHandlerFn) (int); +} + +/// \brief Null signal handler function +/// \param unused the signal number +/// \details NullSignalHandler is provided as a stand alone function with external "C" linkage +/// and not a static member function due to the member function's implicit +/// external "C++" linkage. +/// \sa SignalHandler, SignalHandlerFn +extern "C" { + inline void NullSignalHandler(int unused) {CRYPTOPP_UNUSED(unused);} +} + +/// Signal handler for Linux and Unix compatibles +/// \tparam S Signal number +/// \tparam O Flag indicating if an existing handler should be overwritten +/// \details SignalHandler() can be used to install a signal handler with the signature +/// void handler_fn(int). If SignalHandlerFn is not NULL, then +/// the sigaction is set to the function and the sigaction flags is set to the flags. +/// If SignalHandlerFn is NULL, then a default handler is installed +/// using sigaction flags set to 0. The default handler only returns from the call. +/// \details Upon destruction the previous signal handler is restored if the former signal handler +/// was replaced. +/// \details On Cygwin systems using Newlib, you should define _XOPEN_SOURCE=700 or +/// _GNU_SOURCE; or use -std=gnu++03, -std=gnu++11, or similar. If +/// you compile with -std=c++03, -std=c++11 or similar, then define +/// _XOPEN_SOURCE=700. +/// \warning Do not use SignalHandler in a code block that uses setjmp or longjmp +/// because the destructor may not run. +/// \since Crypto++ 5.6.5 +/// \sa NullSignalHandler, SignalHandlerFn, \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", DebugTrapHandler +template +struct SignalHandler +{ + /// \brief Construct a signal handler + /// \param pfn Pointer to a signal handler function + /// \param flags Flags to use with the signal handler + /// \details SignalHandler() installs a signal handler with the signature + /// void handler_fn(int). If SignalHandlerFn is not NULL, then + /// the sigaction is set to the function and the sigaction flags is set to the flags. + /// If SignalHandlerFn is NULL, then a default handler is installed + /// using sigaction flags set to 0. The default handler only returns from the call. + /// \details Upon destruction the previous signal handler is restored if the former signal handler + /// was overwritten. + /// \details On Cygwin systems using Newlib, you should define _XOPEN_SOURCE=700 or + /// _GNU_SOURCE; or use -std=gnu++03, -std=gnu++11, or similar. If + /// you compile with -std=c++03, -std=c++11 or similar, then define + /// _XOPEN_SOURCE=700. + /// \warning Do not use SignalHandler in a code block that uses setjmp or longjmp + /// because the destructor may not run. setjmp is why cpu.cpp does not use SignalHandler + /// during CPU feature testing. + /// \since Crypto++ 5.6.5 + SignalHandler(SignalHandlerFn pfn = NULLPTR, int flags = 0) : m_installed(false) + { + // http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html + struct sigaction new_handler; + + do + { + int ret = 0; + + ret = sigaction (S, 0, &m_old); + if (ret != 0) break; // Failed + + // Don't step on another's handler if Overwrite=false + if (m_old.sa_handler != 0 && !O) break; + + // Cygwin/Newlib requires -D_XOPEN_SOURCE=700 + ret = sigemptyset (&new_handler.sa_mask); + if (ret != 0) break; // Failed + + new_handler.sa_handler = (pfn ? pfn : &NullSignalHandler); + new_handler.sa_flags = (pfn ? flags : 0); + + // Install it + ret = sigaction (S, &new_handler, 0); + if (ret != 0) break; // Failed + + m_installed = true; + + } while(0); + } + + ~SignalHandler() + { + if (m_installed) + sigaction (S, &m_old, 0); + } + +private: + struct sigaction m_old; + bool m_installed; + +private: + // Not copyable + SignalHandler(const SignalHandler &); + void operator=(const SignalHandler &); +}; +#endif + +NAMESPACE_END + +#endif // CRYPTOPP_OS_SIGNAL_H diff --git a/external/ours/library/crypto/src/shared/original/padlkrng.cpp b/external/ours/library/crypto/src/shared/original/padlkrng.cpp new file mode 100755 index 000000000..2c776c539 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/padlkrng.cpp @@ -0,0 +1,105 @@ +// via-rng.cpp - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. + +#include "pch.h" +#include "config.h" +#include "cryptlib.h" +#include "secblock.h" +#include "padlkrng.h" +#include "cpu.h" + +// The Padlock Security Engine RNG has a few items to be aware of. You can +// find copies of the Programmer's manual, Cryptography Research Inc audit +// report, and other goodies at http://www.cryptopp.com/wiki/VIA_Padlock. + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4702) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +std::string PadlockRNG::AlgorithmProvider() const +{ + return "Padlock"; +} + +PadlockRNG::PadlockRNG(word32 divisor) + : m_divisor(DivisorHelper(divisor)), m_msr(0) +{ +#if defined(CRYPTOPP_X86_ASM_AVAILABLE) + if (!HasPadlockRNG()) +#endif + throw PadlockRNG_Err("PadlockRNG", "PadlockRNG generator not available"); +} + +void PadlockRNG::GenerateBlock(byte *output, size_t size) +{ + CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size); +#if defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__GNUC__) + while (size) + { + __asm__ __volatile__ + ( +#if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + "mov %1, %%rdi ;\n" + "movl %2, %%edx ;\n" +#else + "mov %1, %%edi ;\n" + "movl %2, %%edx ;\n" +#endif + + // xstore-rng + ".byte 0x0f, 0xa7, 0xc0 ;\n" + "movl %%eax, %0 ;\n" + + : "=g" (m_msr) : "g" (m_buffer.data()), "g" (m_divisor) +#if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + : "rax", "rdx", "rdi", "cc" +#else + : "eax", "edx", "edi", "cc" +#endif + ); + + const size_t ret = m_msr & 0x1f; + const size_t rem = STDMIN(ret, STDMIN(size, 16U /*buffer size*/)); + std::memcpy(output, m_buffer, rem); + size -= rem; output += rem; + } +#elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(_MSC_VER) && defined(_M_IX86) + while (size) + { + word32 result, divisor = m_divisor; + byte *buffer = reinterpret_cast(m_buffer.data()); + __asm { + mov edi, buffer + mov edx, divisor + _emit 0x0f + _emit 0xa7 + _emit 0xc0 + mov result, eax + } + + const size_t ret = (m_msr = result) & 0x1f; + const size_t rem = STDMIN(ret, STDMIN(size, 16U /*buffer size*/)); + std::memcpy(output, buffer, rem); + size -= rem; output += rem; + } +#else + throw PadlockRNG_Err("GenerateBlock", "PadlockRNG generator not available"); +#endif // CRYPTOPP_X86_ASM_AVAILABLE +} + +void PadlockRNG::DiscardBytes(size_t n) +{ + FixedSizeSecBlock discard; + n = RoundUpToMultipleOf(n, sizeof(word32)); + + size_t count = STDMIN(n, discard.SizeInBytes()); + while (count) + { + GenerateBlock(discard.BytePtr(), count); + n -= count; + count = STDMIN(n, discard.SizeInBytes()); + } +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/padlkrng.h b/external/ours/library/crypto/src/shared/original/padlkrng.h new file mode 100755 index 000000000..fda1d66b2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/padlkrng.h @@ -0,0 +1,138 @@ +// via-rng.h - written and placed in public domain by Jeffrey Walton + +/// \file padlkrng.h +/// \brief Classes for VIA Padlock RNG +/// \since Crypto++ 6.0 +/// \sa VIA +/// Padlock on the Crypto++ wiki + +#ifndef CRYPTOPP_PADLOCK_RNG_H +#define CRYPTOPP_PADLOCK_RNG_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Exception thrown when a PadlockRNG generator encounters +/// a generator related error. +/// \since Crypto++ 6.0 +class PadlockRNG_Err : public Exception +{ +public: + PadlockRNG_Err(const std::string &operation) + : Exception(OTHER_ERROR, "PadlockRNG: " + operation + " operation failed") {} + PadlockRNG_Err(const std::string &component, const std::string &message) + : Exception(OTHER_ERROR, component + ": " + message) {} +}; + +/// \brief Hardware generated random numbers using VIA XSTORE +/// \details Some VIA processors provide a Security Engine called Padlock. The Padlock +/// Security Engine provides AES, SHA and a RNG. The PadlockRNG class provides access +/// to the RNG. +/// \details The VIA generator uses an 8 byte FIFO buffer for random numbers. The +/// generator can be configured to discard bits from the buffer to resist analysis. +/// The divisor controls the number of bytes discarded. The formula for +/// the discard amount is 2**divisor - 1. When divisor=0 no bits +/// are discarded and the entire 8 byte buffer is read. If divisor=3 then +/// 7 bytes are discarded and 1 byte is read. TheVIA SDK samples use divisor=1. +/// \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine +/// in 2003. CRI provided recommendations to operate the generator for secure and +/// non-secure applications. Additionally, the Programmers Guide and SDK provided a +/// different configuration in the sample code. +/// \details You can operate the generator according to CRI recommendations by setting +/// divisor, reading one word (or partial word) at a time from the FIFO, and +/// then inspecting the MSR after each read. +/// \details The audit report with recommendations is available on the Crypto++ wiki +/// at VIA Padlock. +/// \sa MaurerRandomnessTest() for random bit generators +/// \since Crypto++ 6.0 +class PadlockRNG : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "PadlockRNG"; } + + virtual ~PadlockRNG() {} + + /// \brief Construct a PadlockRNG generator + /// \param divisor the XSTORE divisor + /// \details Some VIA processors provide a Security Engine called Padlock. The Padlock + /// Security Engine provides AES, SHA and a RNG. The PadlockRNG class provides access + /// to the RNG. + /// \details The VIA generator uses an 8 byte FIFO buffer for random numbers. The + /// generator can be configured to discard bits from the buffer to resist analysis. + /// The divisor controls the number of bytes discarded. The formula for + /// the discard amount is 2**divisor - 1. When divisor=0 no bits + /// are discarded and the entire 8 byte buffer is read. If divisor=3 then + /// 7 bytes are discarded and 1 byte is read. VIA SDK samples use divisor=1. + /// \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine + /// in 2003. CRI provided recommendations to operate the generator for secure and + /// non-secure applications. Additionally, the Programmers SDK provided a different + /// configuration in the sample code. + /// \details The audit report with recommendations is available on the Crypto++ wiki + /// at VIA Padlock. + /// \sa SetDivisor, GetDivisor + PadlockRNG(word32 divisor=1); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + virtual void GenerateBlock(byte *output, size_t size); + + /// \brief Generate and discard n bytes + /// \param n the number of bytes to generate and discard + /// \details the Padlock generator discards words, not bytes. If n is + /// not a multiple of a 32-bit word, then it is rounded up to + /// that size. + virtual void DiscardBytes(size_t n); + + /// \brief Update RNG state with additional unpredictable values + /// \param input unused + /// \param length unused + /// \details The operation is a nop for this generator. + virtual void IncorporateEntropy(const byte *input, size_t length) + { + // Override to avoid the base class' throw. + CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); + } + + std::string AlgorithmProvider() const; + + /// \brief Set the XSTORE divisor + /// \param divisor the XSTORE divisor + /// \return the old XSTORE divisor + word32 SetDivisor(word32 divisor) + { + word32 old = m_divisor; + m_divisor = DivisorHelper(divisor); + return old; + } + + /// \brief Get the XSTORE divisor + /// \return the current XSTORE divisor + word32 GetDivisor() const + { + return m_divisor; + } + + /// \brief Get the MSR for the last operation + /// \return the MSR for the last read operation + word32 GetMSR() const + { + return m_msr; + } + +protected: + inline word32 DivisorHelper(word32 divisor) + { + return divisor > 3 ? 3 : divisor; + } + +private: + FixedSizeAlignedSecBlock m_buffer; + word32 m_divisor, m_msr; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_PADLOCK_RNG_H diff --git a/external/ours/library/crypto/src/shared/original/panama.cpp b/external/ours/library/crypto/src/shared/original/panama.cpp new file mode 100755 index 000000000..b6d6a0b63 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/panama.cpp @@ -0,0 +1,533 @@ +// panama.cpp - originally written and placed in the public domain by Wei Dai + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM panama.cpp" to generate MASM code + +#include "pch.h" + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "panama.h" +#include "secblock.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4731) +#endif + +template +std::string Panama::AlgorithmProvider() const +{ +#ifndef CRYPTOPP_DISABLE_PANAMA_ASM +# if CRYPTOPP_SSSE3_ASM_AVAILABLE + if(HasSSSE3()) + return "SSSE3"; +# elif CRYPTOPP_SSE2_ASM_AVAILABLE + if(HasSSE2()) + return "SSE2"; +# endif +#endif + return "C++"; +} + +template +void Panama::Reset() +{ + memset(m_state, 0, m_state.SizeInBytes()); +#if CRYPTOPP_SSSE3_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_PANAMA_ASM) + m_state[17] = HasSSSE3(); +#endif +} + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y); +} +#elif CRYPTOPP_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_PANAMA_ASM) + +#ifdef CRYPTOPP_GENERATE_X64_MASM + Panama_SSE2_Pull PROC FRAME + rex_push_reg rdi + alloc_stack(2*16) + save_xmm128 xmm6, 0h + save_xmm128 xmm7, 10h + .endprolog +#else +void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y) +{ +#if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + asm __volatile__ + ( + INTEL_NOPREFIX + AS_PUSH_IF86( bx) +#else + AS2( mov AS_REG_1, count) + AS2( mov AS_REG_2, state) + AS2( mov AS_REG_3, z) + AS2( mov AS_REG_4, y) +#endif +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#if CRYPTOPP_BOOL_X86 + #define REG_loopEnd [esp] +#elif defined(CRYPTOPP_GENERATE_X64_MASM) + #define REG_loopEnd rdi +#else + #define REG_loopEnd r8 +#endif + + AS2( shl AS_REG_1, 5) + ASJ( jz, 5, f) + AS2( mov AS_REG_6d, [AS_REG_2+4*17]) + AS2( add AS_REG_1, AS_REG_6) + + #if CRYPTOPP_BOOL_X64 + AS2( mov REG_loopEnd, AS_REG_1) + #else + AS_PUSH_IF86( bp) + AS1( push AS_REG_1) + #endif + + AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+0*16]) + AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_2+1*16]) + AS2( movdqa xmm2, XMMWORD_PTR [AS_REG_2+2*16]) + AS2( movdqa xmm3, XMMWORD_PTR [AS_REG_2+3*16]) + AS2( mov eax, dword ptr [AS_REG_2+4*16]) + + ASL(4) + // gamma and pi +#if CRYPTOPP_SSSE3_ASM_AVAILABLE + AS2( test AS_REG_6, 1) + ASJ( jnz, 6, f) +#endif + AS2( movdqa xmm6, xmm2) + AS2( movss xmm6, xmm3) + ASS( pshufd xmm5, xmm6, 0, 3, 2, 1) + AS2( movd xmm6, eax) + AS2( movdqa xmm7, xmm3) + AS2( movss xmm7, xmm6) + ASS( pshufd xmm6, xmm7, 0, 3, 2, 1) +#if CRYPTOPP_SSSE3_ASM_AVAILABLE + ASJ( jmp, 7, f) + ASL(6) + AS2( movdqa xmm5, xmm3) + AS3( palignr xmm5, xmm2, 4) + AS2( movd xmm6, eax) + AS3( palignr xmm6, xmm3, 4) + ASL(7) +#endif + + AS2( movd AS_REG_1d, xmm2) + AS1( not AS_REG_1d) + AS2( movd AS_REG_7d, xmm3) + AS2( or AS_REG_1d, AS_REG_7d) + AS2( xor eax, AS_REG_1d) + +#define SSE2_Index(i) ASM_MOD(((i)*13+16), 17) + +#define pi(i) \ + AS2( movd AS_REG_1d, xmm7)\ + AS2( rol AS_REG_1d, ASM_MOD((ASM_MOD(5*i,17)*(ASM_MOD(5*i,17)+1)/2), 32))\ + AS2( mov [AS_REG_2+SSE2_Index(ASM_MOD(5*(i), 17))*4], AS_REG_1d) + +#define pi4(x, y, z, a, b, c, d) \ + AS2( pcmpeqb xmm7, xmm7)\ + AS2( pxor xmm7, x)\ + AS2( por xmm7, y)\ + AS2( pxor xmm7, z)\ + pi(a)\ + ASS( pshuflw xmm7, xmm7, 1, 0, 3, 2)\ + pi(b)\ + AS2( punpckhqdq xmm7, xmm7)\ + pi(c)\ + ASS( pshuflw xmm7, xmm7, 1, 0, 3, 2)\ + pi(d) + + pi4(xmm1, xmm2, xmm3, 1, 5, 9, 13) + pi4(xmm0, xmm1, xmm2, 2, 6, 10, 14) + pi4(xmm6, xmm0, xmm1, 3, 7, 11, 15) + pi4(xmm5, xmm6, xmm0, 4, 8, 12, 16) + + // output keystream and update buffer here to hide partial memory stalls between pi and theta + AS2( movdqa xmm4, xmm3) + AS2( punpcklqdq xmm3, xmm2) // 1 5 2 6 + AS2( punpckhdq xmm4, xmm2) // 9 10 13 14 + AS2( movdqa xmm2, xmm1) + AS2( punpcklqdq xmm1, xmm0) // 3 7 4 8 + AS2( punpckhdq xmm2, xmm0) // 11 12 15 16 + + // keystream + AS2( test AS_REG_3, AS_REG_3) + ASJ( jz, 0, f) + AS2( movdqa xmm6, xmm4) + AS2( punpcklqdq xmm4, xmm2) + AS2( punpckhqdq xmm6, xmm2) + AS2( test AS_REG_4, 15) + ASJ( jnz, 2, f) + AS2( test AS_REG_4, AS_REG_4) + ASJ( jz, 1, f) + AS2( pxor xmm4, [AS_REG_4]) + AS2( pxor xmm6, [AS_REG_4+16]) + AS2( add AS_REG_4, 32) + ASJ( jmp, 1, f) + ASL(2) + AS2( movdqu xmm0, [AS_REG_4]) + AS2( movdqu xmm2, [AS_REG_4+16]) + AS2( pxor xmm4, xmm0) + AS2( pxor xmm6, xmm2) + AS2( add AS_REG_4, 32) + ASL(1) + AS2( test AS_REG_3, 15) + ASJ( jnz, 3, f) + AS2( movdqa XMMWORD_PTR [AS_REG_3], xmm4) + AS2( movdqa XMMWORD_PTR [AS_REG_3+16], xmm6) + AS2( add AS_REG_3, 32) + ASJ( jmp, 0, f) + ASL(3) + AS2( movdqu XMMWORD_PTR [AS_REG_3], xmm4) + AS2( movdqu XMMWORD_PTR [AS_REG_3+16], xmm6) + AS2( add AS_REG_3, 32) + ASL(0) + + // buffer update + AS2( lea AS_REG_1, [AS_REG_6 + 32]) + AS2( and AS_REG_1, 31*32) + AS2( lea AS_REG_7, [AS_REG_6 + (32-24)*32]) + AS2( and AS_REG_7, 31*32) + + AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*8]) + AS2( pxor xmm3, xmm0) + ASS( pshufd xmm0, xmm0, 2, 3, 0, 1) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*8], xmm3) + AS2( pxor xmm0, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+2*8]) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+2*8], xmm0) + + AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+2*8]) + AS2( pxor xmm1, xmm4) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+2*8], xmm1) + AS2( pxor xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*8]) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*8], xmm4) + + // theta + AS2( movdqa xmm3, XMMWORD_PTR [AS_REG_2+3*16]) + AS2( movdqa xmm2, XMMWORD_PTR [AS_REG_2+2*16]) + AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_2+1*16]) + AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+0*16]) + +#if CRYPTOPP_SSSE3_ASM_AVAILABLE + AS2( test AS_REG_6, 1) + ASJ( jnz, 8, f) +#endif + AS2( movd xmm6, eax) + AS2( movdqa xmm7, xmm3) + AS2( movss xmm7, xmm6) + AS2( movdqa xmm6, xmm2) + AS2( movss xmm6, xmm3) + AS2( movdqa xmm5, xmm1) + AS2( movss xmm5, xmm2) + AS2( movdqa xmm4, xmm0) + AS2( movss xmm4, xmm1) + ASS( pshufd xmm7, xmm7, 0, 3, 2, 1) + ASS( pshufd xmm6, xmm6, 0, 3, 2, 1) + ASS( pshufd xmm5, xmm5, 0, 3, 2, 1) + ASS( pshufd xmm4, xmm4, 0, 3, 2, 1) +#if CRYPTOPP_SSSE3_ASM_AVAILABLE + ASJ( jmp, 9, f) + ASL(8) + AS2( movd xmm7, eax) + AS3( palignr xmm7, xmm3, 4) + AS2( movq xmm6, xmm3) + AS3( palignr xmm6, xmm2, 4) + AS2( movq xmm5, xmm2) + AS3( palignr xmm5, xmm1, 4) + AS2( movq xmm4, xmm1) + AS3( palignr xmm4, xmm0, 4) + ASL(9) +#endif + + AS2( xor eax, 1) + AS2( movd AS_REG_1d, xmm0) + AS2( xor eax, AS_REG_1d) + AS2( movd AS_REG_1d, xmm3) + AS2( xor eax, AS_REG_1d) + + AS2( pxor xmm3, xmm2) + AS2( pxor xmm2, xmm1) + AS2( pxor xmm1, xmm0) + AS2( pxor xmm0, xmm7) + AS2( pxor xmm3, xmm7) + AS2( pxor xmm2, xmm6) + AS2( pxor xmm1, xmm5) + AS2( pxor xmm0, xmm4) + + // sigma + AS2( lea AS_REG_1, [AS_REG_6 + (32-4)*32]) + AS2( and AS_REG_1, 31*32) + AS2( lea AS_REG_7, [AS_REG_6 + 16*32]) + AS2( and AS_REG_7, 31*32) + + AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*16]) + AS2( movdqa xmm5, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*16]) + AS2( movdqa xmm6, xmm4) + AS2( punpcklqdq xmm4, xmm5) + AS2( punpckhqdq xmm6, xmm5) + AS2( pxor xmm3, xmm4) + AS2( pxor xmm2, xmm6) + + AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+1*16]) + AS2( movdqa xmm5, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+1*16]) + AS2( movdqa xmm6, xmm4) + AS2( punpcklqdq xmm4, xmm5) + AS2( punpckhqdq xmm6, xmm5) + AS2( pxor xmm1, xmm4) + AS2( pxor xmm0, xmm6) + + // loop + AS2( add AS_REG_6, 32) + AS2( cmp AS_REG_6, REG_loopEnd) + ASJ( jne, 4, b) + + // save state + AS2( mov [AS_REG_2+4*16], eax) + AS2( movdqa XMMWORD_PTR [AS_REG_2+3*16], xmm3) + AS2( movdqa XMMWORD_PTR [AS_REG_2+2*16], xmm2) + AS2( movdqa XMMWORD_PTR [AS_REG_2+1*16], xmm1) + AS2( movdqa XMMWORD_PTR [AS_REG_2+0*16], xmm0) + + #if CRYPTOPP_BOOL_X86 + AS2( add esp, 4) + AS_POP_IF86( bp) + #endif + ASL(5) + +#if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + AS_POP_IF86( bx) + ATT_PREFIX + : + #if CRYPTOPP_BOOL_X64 + : "D" (count), "S" (state), "d" (z), "c" (y) + : "%r8", "%r9", "r10", "%eax", "memory", "cc", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" + #else + : "c" (count), "d" (state), "S" (z), "D" (y) + : "%eax", "memory", "cc" + #endif + ); +#endif + +#ifdef CRYPTOPP_GENERATE_X64_MASM + movdqa xmm6, [rsp + 0h] + movdqa xmm7, [rsp + 10h] + add rsp, 2*16 + pop rdi + ret + Panama_SSE2_Pull ENDP +#else +} +#endif +#endif // CRYPTOPP_SSE2_ASM_AVAILABLE + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +template +void Panama::Iterate(size_t count, const word32 *p, byte *output, const byte *input, KeystreamOperation operation) +{ + word32 bstart = m_state[17]; + word32 *const aPtr = m_state; + word32 cPtr[17]; + +#define bPtr ((byte *)(aPtr+20)) + +// reorder the state for SSE2 +// a and c: 4 8 12 16 | 3 7 11 15 | 2 6 10 14 | 1 5 9 13 | 0 | +// xmm0 xmm1 xmm2 xmm3 eax +#define a(i) aPtr[((i)*13+16) % 17] // 13 is inverse of 4 mod 17 +#define c(i) cPtr[((i)*13+16) % 17] +// b: 0 4 | 1 5 | 2 6 | 3 7 +#define b(i, j) b##i[(j)*2%8 + (j)/4] + +// buffer update +#define US(i) {word32 t=b(0,i); b(0,i)=ConditionalByteReverse(B::ToEnum(), p[i])^t; b(25,(i+6)%8)^=t;} +#define UL(i) {word32 t=b(0,i); b(0,i)=a(i+1)^t; b(25,(i+6)%8)^=t;} +// gamma and pi +#define GP(i) c(5*i%17) = rotlFixed(a(i) ^ (a((i+1)%17) | ~a((i+2)%17)), ((5*i%17)*((5*i%17)+1)/2)%32) +// theta and sigma +#define T(i,x) a(i) = c(i) ^ c((i+1)%17) ^ c((i+4)%17) ^ x +#define TS1S(i) T(i+1, ConditionalByteReverse(B::ToEnum(), p[i])) +#define TS1L(i) T(i+1, b(4,i)) +#define TS2(i) T(i+9, b(16,i)) + + while (count--) + { + if (output) + { +#define PANAMA_OUTPUT(x) \ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, a(0+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, a(1+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, a(2+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a(3+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 4, a(4+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 5, a(5+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 6, a(6+9));\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 7, a(7+9)); + + typedef word32 WordType; + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(PANAMA_OUTPUT, 4*8); + } + + word32 *const b16 = (word32 *)(void *)(bPtr+((bstart+16*32) & 31*32)); + word32 *const b4 = (word32 *)(void *)(bPtr+((bstart+(32-4)*32) & 31*32)); + bstart += 32; + word32 *const b0 = (word32 *)(void *)(bPtr+((bstart) & 31*32)); + word32 *const b25 = (word32 *)(void *)(bPtr+((bstart+(32-25)*32) & 31*32)); + + if (p) + { + US(0); US(1); US(2); US(3); US(4); US(5); US(6); US(7); + } + else + { + UL(0); UL(1); UL(2); UL(3); UL(4); UL(5); UL(6); UL(7); + } + + GP(0); + GP(1); + GP(2); + GP(3); + GP(4); + GP(5); + GP(6); + GP(7); + GP(8); + GP(9); + GP(10); + GP(11); + GP(12); + GP(13); + GP(14); + GP(15); + GP(16); + + T(0,1); + + if (p) + { + TS1S(0); TS1S(1); TS1S(2); TS1S(3); TS1S(4); TS1S(5); TS1S(6); TS1S(7); + p += 8; + } + else + { + TS1L(0); TS1L(1); TS1L(2); TS1L(3); TS1L(4); TS1L(5); TS1L(6); TS1L(7); + } + + TS2(0); TS2(1); TS2(2); TS2(3); TS2(4); TS2(5); TS2(6); TS2(7); + } + m_state[17] = bstart; +} + +NAMESPACE_BEGIN(Weak) +template +size_t PanamaHash::HashMultipleBlocks(const word32 *input, size_t length) +{ + this->Iterate(length / this->BLOCKSIZE, input); + return length % this->BLOCKSIZE; +} + +template +void PanamaHash::TruncatedFinal(byte *hash, size_t size) +{ + this->ThrowIfInvalidTruncatedSize(size); + + this->PadLastBlock(this->BLOCKSIZE, 0x01); + + this->HashEndianCorrectedBlock(this->m_data); + + this->Iterate(32); // pull + + this->Iterate(1, NULLPTR, m_buf.BytePtr(), NULLPTR); + + memcpy(hash, m_buf, size); + + this->Restart(); // reinit for next use +} +NAMESPACE_END + +template +void PanamaCipherPolicy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==32); + memcpy(m_key, key, 32); +} + +template +void PanamaCipherPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); + CRYPTOPP_UNUSED(length); CRYPTOPP_ASSERT(length==32); + + this->Reset(); + this->Iterate(1, m_key); + if (iv && IsAligned(iv)) + this->Iterate(1, reinterpret_cast(iv)); + else + { + if (iv) + memcpy(m_buf, iv, 32); + else + memset(m_buf, 0, 32); + this->Iterate(1, m_buf); + } + +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_PANAMA_ASM) + if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2() && !IsP4()) // SSE2 code is slower on P4 Prescott + Panama_SSE2_Pull(32, this->m_state, NULLPTR, NULLPTR); + else +#endif + this->Iterate(32); +} + +template +std::string PanamaCipherPolicy::AlgorithmProvider() const +{ + return Panama::AlgorithmProvider(); +} + +template +unsigned int PanamaCipherPolicy::GetAlignment() const +{ +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_PANAMA_ASM) + if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2()) + return 16; + else +#endif + return 1; +} + +template +void PanamaCipherPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_PANAMA_ASM) + if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2()) + Panama_SSE2_Pull(iterationCount, this->m_state, + reinterpret_cast(output), reinterpret_cast(input)); + else +#endif + this->Iterate(iterationCount, NULLPTR, output, input, operation); +} + +template class Panama; +template class Panama; + +template class Weak::PanamaHash; +template class Weak::PanamaHash; + +template class PanamaCipherPolicy; +template class PanamaCipherPolicy; + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM diff --git a/external/ours/library/crypto/src/shared/original/panama.h b/external/ours/library/crypto/src/shared/original/panama.h new file mode 100755 index 000000000..b3d50a044 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/panama.h @@ -0,0 +1,169 @@ +// panama.h - originally written and placed in the public domain by Wei Dai + +/// \file panama.h +/// \brief Classes for Panama hash and stream cipher + +#ifndef CRYPTOPP_PANAMA_H +#define CRYPTOPP_PANAMA_H + +#include "strciphr.h" +#include "iterhash.h" +#include "secblock.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler error with .intel_syntax +//#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +//# define CRYPTOPP_DISABLE_PANAMA_ASM +//#endif + +// https://github.com/weidai11/cryptopp/issues/758 +#define CRYPTOPP_DISABLE_PANAMA_ASM 1 + +NAMESPACE_BEGIN(CryptoPP) + +// Base class, do not use directly +template +class CRYPTOPP_NO_VTABLE Panama +{ +public: + virtual ~Panama() {} + std::string AlgorithmProvider() const; + void Reset(); + void Iterate(size_t count, const word32 *p=NULLPTR, byte *output=NULLPTR, const byte *input=NULLPTR, KeystreamOperation operation=WRITE_KEYSTREAM); + +protected: + typedef word32 Stage[8]; + CRYPTOPP_CONSTANT(STAGES = 32); + + FixedSizeAlignedSecBlock m_state; +}; + +namespace Weak { +/// \brief Panama hash +/// \sa Panama Hash +template +class PanamaHash : protected Panama, public AlgorithmImpl, PanamaHash > +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 32); + virtual ~PanamaHash() {} + PanamaHash() {Panama::Reset();} + unsigned int DigestSize() const {return DIGESTSIZE;} + void TruncatedFinal(byte *hash, size_t size); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";} + std::string AlgorithmProvider() const {return Panama::AlgorithmProvider();} // Fix https://github.com/weidai11/cryptopp/issues/801 + +protected: + void Init() {Panama::Reset();} + void HashEndianCorrectedBlock(const word32 *data) {this->Iterate(1, data);} // push + size_t HashMultipleBlocks(const word32 *input, size_t length); + word32* StateBuf() {return NULLPTR;} + + FixedSizeSecBlock m_buf; +}; +} + +/// \brief MAC construction using a hermetic hash function +template +class HermeticHashFunctionMAC : public AlgorithmImpl > >, T_Info> +{ +public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) + { + CRYPTOPP_UNUSED(params); + + m_key.Assign(key, length); + Restart(); + } + + void Restart() + { + m_hash.Restart(); + m_keyed = false; + } + + void Update(const byte *input, size_t length) + { + if (!m_keyed) + KeyHash(); + m_hash.Update(input, length); + } + + void TruncatedFinal(byte *digest, size_t digestSize) + { + if (!m_keyed) + KeyHash(); + m_hash.TruncatedFinal(digest, digestSize); + m_keyed = false; + } + + unsigned int DigestSize() const + {return m_hash.DigestSize();} + unsigned int BlockSize() const + {return m_hash.BlockSize();} + unsigned int OptimalBlockSize() const + {return m_hash.OptimalBlockSize();} + unsigned int OptimalDataAlignment() const + {return m_hash.OptimalDataAlignment();} + +protected: + void KeyHash() + { + m_hash.Update(m_key, m_key.size()); + m_keyed = true; + } + + T_Hash m_hash; + bool m_keyed; + SecByteBlock m_key; +}; + +namespace Weak { +/// \brief Panama message authentication code +template +class PanamaMAC : public HermeticHashFunctionMAC > +{ +public: + PanamaMAC() {} + PanamaMAC(const byte *key, unsigned int length) + {this->SetKey(key, length);} +}; +} + +/// \brief Panama stream cipher information +template +struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 32> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";} +}; + +/// \brief Panama stream cipher operation +template +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, + public PanamaCipherInfo, + protected Panama +{ +protected: + virtual ~PanamaCipherPolicy() {} + std::string AlgorithmProvider() const; + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + bool CipherIsRandomAccess() const {return false;} + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); + unsigned int GetAlignment() const; + + FixedSizeSecBlock m_key; + FixedSizeSecBlock m_buf; +}; + +/// \brief Panama stream cipher +/// \sa Panama Stream Cipher +template +struct PanamaCipher : public PanamaCipherInfo, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, PanamaCipherInfo > Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/pch.cpp b/external/ours/library/crypto/src/shared/original/pch.cpp new file mode 100755 index 000000000..9e6b2e073 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/external/ours/library/crypto/src/shared/original/pch.h b/external/ours/library/crypto/src/shared/original/pch.h new file mode 100755 index 000000000..f158399c5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pch.h @@ -0,0 +1,31 @@ +// pch.h - originally written and placed in the public domain by Wei Dai + +/// \file pch.h +/// \brief Precompiled header file +/// \details The precompiled header files are used Windows. + +#ifndef CRYPTOPP_PCH_H +#define CRYPTOPP_PCH_H + +# ifdef CRYPTOPP_GENERATE_X64_MASM + #include "cpu.h" + +# else + #include "config.h" + + #ifdef USE_PRECOMPILED_HEADERS + #include "simple.h" + #include "secblock.h" + #include "misc.h" + #include "smartptr.h" + #include "stdcpp.h" + #endif +# endif + +// Enable file and line numbers, if available. +// #if defined(_MSC_VER) && defined(_DEBUG) && defined(USE_PRECOMPILED_HEADERS) +// # define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) +// # define new DEBUG_NEW +// #endif + +#endif // CRYPTOPP_PCH_H diff --git a/external/ours/library/crypto/src/shared/original/pkcspad.cpp b/external/ours/library/crypto/src/shared/original/pkcspad.cpp new file mode 100755 index 000000000..5192c1094 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pkcspad.cpp @@ -0,0 +1,160 @@ +// pkcspad.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_PKCSPAD_CPP // SunCC workaround: compiler could cause this file to be included twice +#define CRYPTOPP_PKCSPAD_CPP + +#include "pkcspad.h" +#include "emsa2.h" +#include "hashfwd.h" +#include "misc.h" +#include "trap.h" + +NAMESPACE_BEGIN(CryptoPP) + +// Typedef/cast change due to Clang, http://github.com/weidai11/cryptopp/issues/300 +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x29,0x30,0x0D,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x0C,0x02,0x05,0x00,0x04,0x18}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +// Inclusion based on DLL due to Clang, http://github.com/weidai11/cryptopp/issues/300 +#ifndef CRYPTOPP_IS_DLL +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x03,0x05, 0x00,0x04,0x40}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +// http://github.com/weidai11/cryptopp/issues/517. OIDs and encoded prefixes found at +// http://www.ietf.org/archive/id/draft-jivsov-openpgp-sha3-01.txt +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x08,0x05, 0x00,0x04,0x20}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x09,0x05, 0x00,0x04,0x30}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d, 0x06,0x09,0x60,0x86, 0x48,0x01,0x65,0x03, 0x04,0x02,0x0a,0x05, 0x00,0x04,0x40}; +template<> const unsigned int PKCS_DigestDecoration::length = (unsigned int)sizeof(PKCS_DigestDecoration::decoration); +#endif + +size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const +{ + return SaturatingSubtract(paddedLength/8, 10U); +} + +void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator& rng, const byte *input, size_t inputLen, byte *pkcsBlock, size_t pkcsBlockLen, const NameValuePairs& parameters) const +{ + CRYPTOPP_UNUSED(parameters); + CRYPTOPP_ASSERT (inputLen <= MaxUnpaddedLength(pkcsBlockLen)); // this should be checked by caller + + // convert from bit length to byte length + if (pkcsBlockLen % 8 != 0) + { + pkcsBlock[0] = 0; + pkcsBlock++; + } + pkcsBlockLen /= 8; + + pkcsBlock[0] = 2; // block type 2 + + // pad with non-zero random bytes + for (unsigned i = 1; i < pkcsBlockLen-inputLen-1; i++) + pkcsBlock[i] = (byte)rng.GenerateWord32(1, 0xff); + + pkcsBlock[pkcsBlockLen-inputLen-1] = 0; // separator + memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); +} + +DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, size_t pkcsBlockLen, byte *output, const NameValuePairs& parameters) const +{ + CRYPTOPP_UNUSED(parameters); + bool invalid = false; + size_t maxOutputLen = MaxUnpaddedLength(pkcsBlockLen); + + // convert from bit length to byte length + if (pkcsBlockLen % 8 != 0) + { + invalid = (pkcsBlock[0] != 0) || invalid; + pkcsBlock++; + } + pkcsBlockLen /= 8; + + // Require block type 2. + invalid = (pkcsBlock[0] != 2) || invalid; + + // skip past the padding until we find the separator + size_t i=1; + while (i maxOutputLen) || invalid; + + if (invalid) + return DecodingResult(); + + memcpy (output, pkcsBlock+i, outputLen); + return DecodingResult(outputLen); +} + +// ******************************************************** + +#ifndef CRYPTOPP_IMPORTS + +void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength); + CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier); + CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + size_t pkcsBlockLen = representativeBitLength; + // convert from bit length to byte length + if (pkcsBlockLen % 8 != 0) + { + representative[0] = 0; + representative++; + } + pkcsBlockLen /= 8; + + representative[0] = 1; // block type 1 + + unsigned int digestSize = hash.DigestSize(); + byte *pPadding = representative + 1; + byte *pDigest = representative + pkcsBlockLen - digestSize; + byte *pHashId = pDigest - hashIdentifier.second; + byte *pSeparator = pHashId - 1; + + // pad with 0xff + memset(pPadding, 0xff, pSeparator-pPadding); + *pSeparator = 0; + memcpy(pHashId, hashIdentifier.first, hashIdentifier.second); + hash.Final(pDigest); +} + +#endif + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/pkcspad.h b/external/ours/library/crypto/src/shared/original/pkcspad.h new file mode 100755 index 000000000..88d9d7358 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pkcspad.h @@ -0,0 +1,123 @@ +// pkcspad.h - originally written and placed in the public domain by Wei Dai + +/// \file pkcspad.h +/// \brief Classes for PKCS padding schemes +/// \details PKCS #1 v1.5, v2.0 and P1363a allow MD2, MD5, SHA1, SHA224, SHA256, SHA384, +/// SHA512, Tiger and RipeMd-160 to be instantiated. + +#ifndef CRYPTOPP_PKCSPAD_H +#define CRYPTOPP_PKCSPAD_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "hashfwd.h" + +#ifdef CRYPTOPP_IS_DLL +#include "sha.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief PKCS #1 v1.5 Encryption Padding Scheme +/// \sa EME-PKCS1-v1_5 +class PKCS_EncryptionPaddingScheme : public PK_EncryptionMessageEncodingMethod +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "EME-PKCS1-v1_5";} + + size_t MaxUnpaddedLength(size_t paddedLength) const; + void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedLength, const NameValuePairs ¶meters) const; + DecodingResult Unpad(const byte *padded, size_t paddedLength, byte *raw, const NameValuePairs ¶meters) const; +}; + +/// \brief PKCS #1 decoration data structure +template class PKCS_DigestDecoration +{ +public: + static const byte decoration[]; + static const unsigned int length; +}; + +// PKCS_DigestDecoration can be instantiated with the following +// classes as specified in PKCS #1 v2.0 and P1363a +// SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, RIPEMD160, MD2, MD5 + +#if defined(CRYPTOPP_IS_DLL) +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +// http://github.com/weidai11/cryptopp/issues/517 +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +#endif + +// https://github.com/weidai11/cryptopp/issues/300 and +// https://github.com/weidai11/cryptopp/issues/533 +#if defined(__clang__) +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; + +// http://github.com/weidai11/cryptopp/issues/517 +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; + +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +template<> const byte PKCS_DigestDecoration::decoration[]; +template<> const unsigned int PKCS_DigestDecoration::length; +#endif + +/// \brief PKCS #1 v1.5 Signature Encoding Scheme +/// \sa EMSA-PKCS1-v1_5 +class CRYPTOPP_DLL PKCS1v15_SignatureMessageEncodingMethod : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "EMSA-PKCS1-v1_5";} + + size_t MinRepresentativeBitLength(size_t hashIdentifierSize, size_t digestSize) const + {return 8 * (digestSize + hashIdentifierSize + 10);} + + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; + + struct HashIdentifierLookup + { + template struct HashIdentifierLookup2 + { + static HashIdentifier Lookup() + { + return HashIdentifier(PKCS_DigestDecoration::decoration, PKCS_DigestDecoration::length); + } + }; + }; +}; + +/// \brief PKCS #1 version 1.5, for use with RSAES and RSASS +/// \dontinclude pkcspad.h + +struct PKCS1v15 : public SignatureStandard, public EncryptionStandard +{ + typedef PKCS_EncryptionPaddingScheme EncryptionMessageEncodingMethod; + typedef PKCS1v15_SignatureMessageEncodingMethod SignatureMessageEncodingMethod; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/poly1305.cpp b/external/ours/library/crypto/src/shared/original/poly1305.cpp new file mode 100755 index 000000000..354d76c42 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/poly1305.cpp @@ -0,0 +1,403 @@ +// poly1305.cpp - written and placed in the public domain by Jeffrey Walton and Jean-Pierre Munch +// Based on Andy Polyakov's Base-2^26 scalar multiplication implementation. +// For more information, see https://www.openssl.org/~appro/cryptogams/. + +// Copyright (c) 2006-2017, CRYPTOGAMS by +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain copyright notices, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials +// provided with the distribution. +// * Neither the name of the CRYPTOGAMS nor the names of its copyright +// holder and contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. + +#include "pch.h" +#include "cryptlib.h" +#include "poly1305.h" +#include "aes.h" +#include "cpu.h" + +////////////////////////////// Common Poly1305 ////////////////////////////// + +ANONYMOUS_NAMESPACE_BEGIN + +using namespace CryptoPP; + +inline word32 CONSTANT_TIME_CARRY(word32 a, word32 b) +{ + return ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1)); +} + +void Poly1305_HashBlocks(word32 h[5], word32 r[4], const byte *input, size_t length, word32 padbit) +{ + word32 r0, r1, r2, r3; + word32 s1, s2, s3; + word32 h0, h1, h2, h3, h4, c; + word64 d0, d1, d2, d3; + + r0 = r[0]; r1 = r[1]; + r2 = r[2]; r3 = r[3]; + + s1 = r1 + (r1 >> 2); + s2 = r2 + (r2 >> 2); + s3 = r3 + (r3 >> 2); + + h0 = h[0]; h1 = h[1]; h2 = h[2]; + h3 = h[3]; h4 = h[4]; + + while (length >= 16) + { + // h += m[i] + h0 = (word32)(d0 = (word64)h0 + GetWord(false, LITTLE_ENDIAN_ORDER, input + 0)); + h1 = (word32)(d1 = (word64)h1 + (d0 >> 32) + GetWord(false, LITTLE_ENDIAN_ORDER, input + 4)); + h2 = (word32)(d2 = (word64)h2 + (d1 >> 32) + GetWord(false, LITTLE_ENDIAN_ORDER, input + 8)); + h3 = (word32)(d3 = (word64)h3 + (d2 >> 32) + GetWord(false, LITTLE_ENDIAN_ORDER, input + 12)); + h4 += (word32)(d3 >> 32) + padbit; + + // h *= r "%" p + d0 = ((word64)h0 * r0) + + ((word64)h1 * s3) + + ((word64)h2 * s2) + + ((word64)h3 * s1); + d1 = ((word64)h0 * r1) + + ((word64)h1 * r0) + + ((word64)h2 * s3) + + ((word64)h3 * s2) + + (h4 * s1); + d2 = ((word64)h0 * r2) + + ((word64)h1 * r1) + + ((word64)h2 * r0) + + ((word64)h3 * s3) + + (h4 * s2); + d3 = ((word64)h0 * r3) + + ((word64)h1 * r2) + + ((word64)h2 * r1) + + ((word64)h3 * r0) + + (h4 * s3); + h4 = (h4 * r0); + + // a) h4:h0 = h4<<128 + d3<<96 + d2<<64 + d1<<32 + d0 + h0 = (word32)d0; + h1 = (word32)(d1 += d0 >> 32); + h2 = (word32)(d2 += d1 >> 32); + h3 = (word32)(d3 += d2 >> 32); + h4 += (word32)(d3 >> 32); + + // b) (h4:h0 += (h4:h0>>130) * 5) %= 2^130 + c = (h4 >> 2) + (h4 & ~3U); + h4 &= 3; + h0 += c; + h1 += (c = CONSTANT_TIME_CARRY(h0,c)); + h2 += (c = CONSTANT_TIME_CARRY(h1,c)); + h3 += (c = CONSTANT_TIME_CARRY(h2,c)); + h4 += CONSTANT_TIME_CARRY(h3,c); + + input += 16; + length -= 16; + } + + h[0] = h0; h[1] = h1; h[2] = h2; + h[3] = h3; h[4] = h4; +} + +void Poly1305_HashFinal(word32 h[5], word32 n[4], byte *mac, size_t size) +{ + word32 h0, h1, h2, h3, h4; + word32 g0, g1, g2, g3, g4; + word32 mask; + word64 t; + + h0 = h[0]; + h1 = h[1]; + h2 = h[2]; + h3 = h[3]; + h4 = h[4]; + + // compare to modulus by computing h + -p + g0 = (word32)(t = (word64)h0 + 5); + g1 = (word32)(t = (word64)h1 + (t >> 32)); + g2 = (word32)(t = (word64)h2 + (t >> 32)); + g3 = (word32)(t = (word64)h3 + (t >> 32)); + g4 = h4 + (word32)(t >> 32); + + // if there was carry into 131st bit, h3:h0 = g3:g0 + mask = 0 - (g4 >> 2); + g0 &= mask; g1 &= mask; + g2 &= mask; g3 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; h3 = (h3 & mask) | g3; + + // mac = (h + nonce) % (2^128) + h0 = (word32)(t = (word64)h0 + n[0]); + h1 = (word32)(t = (word64)h1 + (t >> 32) + n[1]); + h2 = (word32)(t = (word64)h2 + (t >> 32) + n[2]); + h3 = (word32)(t = (word64)h3 + (t >> 32) + n[3]); + + if (size >= 16) + { + PutWord(false, LITTLE_ENDIAN_ORDER, mac + 0, h0); + PutWord(false, LITTLE_ENDIAN_ORDER, mac + 4, h1); + PutWord(false, LITTLE_ENDIAN_ORDER, mac + 8, h2); + PutWord(false, LITTLE_ENDIAN_ORDER, mac + 12, h3); + } + else + { + FixedSizeAlignedSecBlock m; + PutWord(false, LITTLE_ENDIAN_ORDER, m + 0, h0); + PutWord(false, LITTLE_ENDIAN_ORDER, m + 4, h1); + PutWord(false, LITTLE_ENDIAN_ORDER, m + 8, h2); + PutWord(false, LITTLE_ENDIAN_ORDER, m + 12, h3); + std::memcpy(mac, m, size); + } +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +////////////////////////////// Bernstein Poly1305 ////////////////////////////// + +// TODO: No longer needed. Remove at next major version bump +template +void Poly1305_Base::HashBlocks(const byte *input, size_t length, word32 padbit) { + CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(padbit); + CRYPTOPP_ASSERT(0); +} + +// TODO: No longer needed. Remove at next major version bump +template +void Poly1305_Base::HashFinal(byte *mac, size_t length) { + CRYPTOPP_UNUSED(mac); CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(0); +} + +template +std::string Poly1305_Base::AlgorithmProvider() const +{ + return m_cipher.AlgorithmProvider(); +} + +template +void Poly1305_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(key && length >= 32); + + // key is {k,r} pair. k is AES key, r is the additional key that gets clamped + length = SaturatingSubtract(length, (unsigned)BLOCKSIZE); + m_cipher.SetKey(key, length); + key += length; + + // Rbar is clamped and little endian + m_r[0] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 0) & 0x0fffffff; + m_r[1] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 4) & 0x0ffffffc; + m_r[2] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 8) & 0x0ffffffc; + m_r[3] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 12) & 0x0ffffffc; + + // Mark the nonce as dirty, meaning we need a new one + m_used = true; + + ConstByteArrayParameter t; + if (params.GetValue(Name::IV(), t) && t.begin() && t.size()) + { + CRYPTOPP_ASSERT(t.size() == m_nk.size()); + Resynchronize(t.begin(), (int)t.size()); + } + + Restart(); +} + +template +void Poly1305_Base::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT((input && length) || !length); + if (!length) return; + + size_t rem, num = m_idx; + if (num) + { + rem = BLOCKSIZE - num; + if (length >= rem) + { + // Process + memcpy_s(m_acc + num, BLOCKSIZE - num, input, rem); + Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 1); + input += rem; length -= rem; + } + else + { + // Accumulate + memcpy_s(m_acc + num, BLOCKSIZE - num, input, length); + m_idx = num + length; + return; + } + } + + rem = length % BLOCKSIZE; + length -= rem; + + if (length >= BLOCKSIZE) { + Poly1305_HashBlocks(m_h, m_r, input, length, 1); + input += length; + } + + if (rem) + memcpy(m_acc, input, rem); + + m_idx = rem; +} + +template +void Poly1305_Base::TruncatedFinal(byte *mac, size_t size) +{ + CRYPTOPP_ASSERT(mac); // Pointer is valid + CRYPTOPP_ASSERT(!m_used); // Nonce is fresh + + ThrowIfInvalidTruncatedSize(size); + + size_t num = m_idx; + if (num) + { + m_acc[num++] = 1; /* pad bit */ + while (num < BLOCKSIZE) + m_acc[num++] = 0; + Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 0); + } + + Poly1305_HashFinal(m_h, m_n, mac, size); + + // Restart + m_used = true; + Restart(); +} + +template +void Poly1305_Base::Resynchronize(const byte *nonce, int nonceLength) +{ + CRYPTOPP_ASSERT(nonceLength == -1 || nonceLength == (int)BLOCKSIZE); + if (nonceLength == -1) { nonceLength = BLOCKSIZE; } + + // Encrypt the nonce, stash in m_nk + m_cipher.ProcessBlock(nonce, m_nk.begin()); + + m_n[0] = GetWord(false, LITTLE_ENDIAN_ORDER, m_nk + 0); + m_n[1] = GetWord(false, LITTLE_ENDIAN_ORDER, m_nk + 4); + m_n[2] = GetWord(false, LITTLE_ENDIAN_ORDER, m_nk + 8); + m_n[3] = GetWord(false, LITTLE_ENDIAN_ORDER, m_nk + 12); + + // Mark nonce as unused, meaning it is fresh + m_used = false; +} + +template +void Poly1305_Base::GetNextIV(RandomNumberGenerator &rng, byte *iv) +{ + rng.GenerateBlock(iv, BLOCKSIZE); +} + +template +void Poly1305_Base::Restart() +{ + m_h[0] = m_h[1] = m_h[2] = m_h[3] = m_h[4] = 0; + m_idx = 0; +} + +////////////////////////////// IETF Poly1305 ////////////////////////////// + +void Poly1305TLS_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(key && length >= 32); + + // key is {r,s} pair. r is the additional key that gets clamped, s is the nonce. + m_r[0] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 0) & 0x0fffffff; + m_r[1] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 4) & 0x0ffffffc; + m_r[2] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 8) & 0x0ffffffc; + m_r[3] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 12) & 0x0ffffffc; + + key += 16; + m_n[0] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 0); + m_n[1] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 4); + m_n[2] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 8); + m_n[3] = GetWord(false, LITTLE_ENDIAN_ORDER, key + 12); + + Restart(); +} + +void Poly1305TLS_Base::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT((input && length) || !length); + if (!length) return; + + size_t rem, num = m_idx; + if (num) + { + rem = BLOCKSIZE - num; + if (length >= rem) + { + // Process + memcpy_s(m_acc + num, BLOCKSIZE - num, input, rem); + Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 1); + input += rem; length -= rem; + } + else + { + // Accumulate + memcpy_s(m_acc + num, BLOCKSIZE - num, input, length); + m_idx = num + length; + return; + } + } + + rem = length % BLOCKSIZE; + length -= rem; + + if (length >= BLOCKSIZE) { + Poly1305_HashBlocks(m_h, m_r, input, length, 1); + input += length; + } + + if (rem) + memcpy(m_acc, input, rem); + + m_idx = rem; +} + +void Poly1305TLS_Base::TruncatedFinal(byte *mac, size_t size) +{ + CRYPTOPP_ASSERT(mac); // Pointer is valid + + ThrowIfInvalidTruncatedSize(size); + + size_t num = m_idx; + if (num) + { + m_acc[num++] = 1; /* pad bit */ + while (num < BLOCKSIZE) + m_acc[num++] = 0; + Poly1305_HashBlocks(m_h, m_r, m_acc, BLOCKSIZE, 0); + } + + Poly1305_HashFinal(m_h, m_n, mac, size); + + Restart(); +} + +void Poly1305TLS_Base::Restart() +{ + m_h[0] = m_h[1] = m_h[2] = m_h[3] = m_h[4] = 0; + m_idx = 0; +} + +template class Poly1305_Base; +template class Poly1305; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/poly1305.h b/external/ours/library/crypto/src/shared/original/poly1305.h new file mode 100755 index 000000000..0745d9352 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/poly1305.h @@ -0,0 +1,241 @@ +// poly1305.h - written and placed in the public domain by Jeffrey Walton and Jean-Pierre Munch +// Based on Andy Polyakov's Base-2^26 scalar multiplication implementation. +// For more information, see https://www.openssl.org/~appro/cryptogams/. + +// The library added Bernstein's Poly1305 classses at Crypto++ 6.0. The IETF +// uses a slightly different implementation than Bernstein, and the IETF +// classes were added at Crypto++ 8.1. We wanted to maintain ABI compatibility +// at the 8.1 release so the original Poly1305 classes were not disturbed. +// Instead new classes were added for IETF Poly1305. The back-end implementation +// shares code as expected, however. + +/// \file poly1305.h +/// \brief Classes for Poly1305 message authentication code +/// \details Poly1305-AES is a state-of-the-art message-authentication code suitable for a wide +/// variety of applications. Poly1305-AES computes a 16-byte authenticator of a variable-length +/// message, using a 16-byte AES key, a 16-byte additional key, and a 16-byte nonce. +/// \details Crypto++ also supplies the IETF's version of Poly1305. It is a slightly different +/// algorithm than Bernstein's version. +/// \sa Daniel J. Bernstein The Poly1305-AES +/// Message-Authentication Code (20050329), RFC +/// 8439, ChaCha20 and Poly1305 for IETF Protocols and Andy Polyakov Poly1305 Revised +/// \since Poly1305 since Crypto++ 6.0, Poly1305TLS since Crypto++ 8.1 + +#ifndef CRYPTOPP_POLY1305_H +#define CRYPTOPP_POLY1305_H + +#include "cryptlib.h" +#include "seckey.h" +#include "secblock.h" +#include "argnames.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +////////////////////////////// Bernstein Poly1305 ////////////////////////////// + +/// \brief Poly1305 message authentication code base class +/// \tparam T BlockCipherDocumentation derived class with 16-byte key and 16-byte blocksize +/// \details Poly1305_Base is the base class of Bernstein's Poly1305 algorithm. +/// \since Crypto++ 6.0 +template +class CRYPTOPP_NO_VTABLE Poly1305_Base : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 16>, public MessageAuthenticationCode +{ + CRYPTOPP_COMPILE_ASSERT(T::DEFAULT_KEYLENGTH == 16); + CRYPTOPP_COMPILE_ASSERT(T::BLOCKSIZE == 16); + +public: + static std::string StaticAlgorithmName() {return std::string("Poly1305(") + T::StaticAlgorithmName() + ")";} + + CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE); + CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE); + + virtual ~Poly1305_Base() {} + Poly1305_Base() : m_idx(0), m_used(true) {} + + void Resynchronize (const byte *iv, int ivLength=-1); + void GetNextIV (RandomNumberGenerator &rng, byte *iv); + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + void Restart(); + + unsigned int BlockSize() const {return BLOCKSIZE;} + unsigned int DigestSize() const {return DIGESTSIZE;} + + std::string AlgorithmProvider() const; + +protected: + // TODO: No longer needed. Remove at next major version bump + void HashBlocks(const byte *input, size_t length, word32 padbit); + void HashFinal(byte *mac, size_t length); + + typename T::Encryption m_cipher; + + // Accumulated hash, clamped r-key, and encrypted nonce + FixedSizeAlignedSecBlock m_h; + FixedSizeAlignedSecBlock m_r; + FixedSizeAlignedSecBlock m_n; + + // Accumulated message bytes and index + FixedSizeAlignedSecBlock m_acc, m_nk; + size_t m_idx; + + // Track nonce reuse; assert in debug but continue + bool m_used; +}; + +/// \brief Poly1305 message authentication code +/// \tparam T class derived from BlockCipherDocumentation with 16-byte key and 16-byte blocksize +/// \details Poly1305-AES is a state-of-the-art message-authentication code suitable for a wide +/// variety of applications. Poly1305-AES computes a 16-byte authenticator of a variable-length +/// message, using a 16-byte AES key, a 16-byte additional key, and a 16-byte nonce. +/// \details The key is 32 bytes and a concatenation key = {k,s}, where +/// k is the AES key and r is additional key that gets clamped. +/// The key is clamped internally so there is no need to perform the operation +/// before setting the key. +/// \details Each message must have a unique security context, which means either the key or nonce +/// must be changed after each message. It can be accomplished in one of two ways. First, you +/// can create a new Poly1305 object each time its needed. +///
  SecByteBlock key(32), nonce(16);
+///   prng.GenerateBlock(key, key.size());
+///   prng.GenerateBlock(nonce, nonce.size());
+///
+///   Poly1305 poly1305(key, key.size(), nonce, nonce.size());
+///   poly1305.Update(...);
+///   poly1305.Final(...);
+/// +/// \details Second, you can create a Poly1305 object, reuse the key, and set a fresh nonce +/// for each message. The second and subsequent nonces can be generated using GetNextIV(). +///
  SecByteBlock key(32), nonce(16);
+///   prng.GenerateBlock(key, key.size());
+///   prng.GenerateBlock(nonce, nonce.size());
+///
+///   // First message
+///   Poly1305 poly1305(key, key.size());
+///   poly1305.Resynchronize(nonce);
+///   poly1305.Update(...);
+///   poly1305.Final(...);
+///
+///   // Second message
+///   poly1305.GetNextIV(prng, nonce);
+///   poly1305.Resynchronize(nonce);
+///   poly1305.Update(...);
+///   poly1305.Final(...);
+///   ...
+/// \warning Each message must have a unique security context. The Poly1305 class does not +/// enforce a fresh key or nonce for each message. The source code will assert in debug +/// builds to alert of nonce reuse. No action is taken in release builds. +/// \sa Daniel J. Bernstein The Poly1305-AES +/// Message-Authentication Code (20050329) and Andy Polyakov Poly1305 Revised +/// \since Crypto++ 6.0 +template +class Poly1305 : public MessageAuthenticationCodeFinal > +{ +public: + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=Poly1305_Base::DEFAULT_KEYLENGTH); + + /// \brief Construct a Poly1305 + Poly1305() {} + + /// \brief Construct a Poly1305 + /// \param key a byte array used to key the cipher + /// \param keyLength the size of the byte array, in bytes + /// \param nonce a byte array used to key the cipher + /// \param nonceLength the size of the byte array, in bytes + /// \details The key is 32 bytes and a concatenation key = {k,s}, where + /// k is the AES key and r is additional key that gets clamped. + /// The key is clamped internally so there is no need to perform the operation + /// before setting the key. + /// \details Each message requires a unique security context. You can use GetNextIV() + /// and Resynchronize() to set a new nonce under a key for a message. + Poly1305(const byte *key, size_t keyLength=DEFAULT_KEYLENGTH, const byte *nonce=NULLPTR, size_t nonceLength=0) + {this->SetKey(key, keyLength, MakeParameters(Name::IV(), ConstByteArrayParameter(nonce, nonceLength)));} +}; + +////////////////////////////// IETF Poly1305 ////////////////////////////// + +/// \brief Poly1305-TLS message authentication code base class +/// \details Poly1305TLS_Base is the base class of the IETF's Poly1305 algorithm. +/// \since Crypto++ 8.1 +class Poly1305TLS_Base : public FixedKeyLength<32>, public MessageAuthenticationCode +{ +public: + static std::string StaticAlgorithmName() {return std::string("Poly1305TLS");} + CRYPTOPP_CONSTANT(DIGESTSIZE=16); + CRYPTOPP_CONSTANT(BLOCKSIZE=16); + + virtual ~Poly1305TLS_Base() {} + Poly1305TLS_Base() {} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + void Restart(); + + unsigned int BlockSize() const {return BLOCKSIZE;} + unsigned int DigestSize() const {return DIGESTSIZE;} + +protected: + // Accumulated hash, clamped r-key, and encrypted nonce + FixedSizeAlignedSecBlock m_h; + FixedSizeAlignedSecBlock m_r; + FixedSizeAlignedSecBlock m_n; + + // Accumulated message bytes and index + FixedSizeAlignedSecBlock m_acc; + size_t m_idx; +}; + +/// \brief Poly1305-TLS message authentication code +/// \details This is the IETF's variant of Bernstein's Poly1305 from RFC 8439. +/// IETF Poly1305 is called Poly1305TLS in the Crypto++ library. It is +/// _slightly_ different from the Bernstein implementation. Poly1305-TLS +/// can be used for cipher suites +/// TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, +/// TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, and +/// TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256. +/// \details The key is 32 bytes and a concatenation key = {r,s}, where +/// r is additional key that gets clamped and s is the nonce. +/// The key is clamped internally so there is no need to perform the operation +/// before setting the key. +/// \details Each message must have a unique security context, which means the key +/// must be changed after each message. It can be accomplished in one of two ways. +/// First, you can create a new Poly1305 object with a new key each time its needed. +///
  SecByteBlock key(32);
+///   prng.GenerateBlock(key, key.size());
+///
+///   Poly1305TLS poly1305(key, key.size());
+///   poly1305.Update(...);
+///   poly1305.Final(...);
+/// +/// \details Second, you can create a Poly1305 object, and use a new key for each +/// message. The keys can be generated directly using a RandomNumberGenerator() +/// derived class. +///
  SecByteBlock key(32);
+///   prng.GenerateBlock(key, key.size());
+///
+///   // First message
+///   Poly1305TLS poly1305(key, key.size());
+///   poly1305.Update(...);
+///   poly1305.Final(...);
+///
+///   // Second message
+///   prng.GenerateBlock(key, key.size());
+///   poly1305.SetKey(key, key.size());
+///   poly1305.Update(...);
+///   poly1305.Final(...);
+///   ...
+/// \warning Each message must have a unique security context. The Poly1305-TLS class +/// does not enforce a fresh key or nonce for each message. +/// \since Crypto++ 8.1 +/// \sa MessageAuthenticationCode(), RFC +/// 8439, ChaCha20 and Poly1305 for IETF Protocols +DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal, Poly1305TLS); + +NAMESPACE_END + +#endif // CRYPTOPP_POLY1305_H diff --git a/external/ours/library/crypto/src/shared/original/polynomi.cpp b/external/ours/library/crypto/src/shared/original/polynomi.cpp new file mode 100755 index 000000000..2305f80ae --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/polynomi.cpp @@ -0,0 +1,577 @@ +// polynomi.cpp - originally written and placed in the public domain by Wei Dai + +// Part of the code for polynomial evaluation and interpolation +// originally came from Hal Finney's public domain secsplit.c. + +#include "pch.h" +#include "polynomi.h" +#include "secblock.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +template +void PolynomialOver::Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring) +{ + m_coefficients.resize(parameter.m_coefficientCount); + for (unsigned int i=0; i +void PolynomialOver::FromStr(const char *str, const Ring &ring) +{ + std::istringstream in((char *)str); + bool positive = true; + CoefficientType coef; + unsigned int power; + + while (in) + { + std::ws(in); + if (in.peek() == 'x') + coef = ring.MultiplicativeIdentity(); + else + in >> coef; + + std::ws(in); + if (in.peek() == 'x') + { + in.get(); + std::ws(in); + if (in.peek() == '^') + { + in.get(); + in >> power; + } + else + power = 1; + } + else + power = 0; + + if (!positive) + coef = ring.Inverse(coef); + + SetCoefficient(power, coef, ring); + + std::ws(in); + switch (in.get()) + { + case '+': + positive = true; + break; + case '-': + positive = false; + break; + default: + return; // something's wrong with the input string + } + } +} + +template +unsigned int PolynomialOver::CoefficientCount(const Ring &ring) const +{ + unsigned count = m_coefficients.size(); + while (count && ring.Equal(m_coefficients[count-1], ring.Identity())) + count--; + const_cast &>(m_coefficients).resize(count); + return count; +} + +template +typename PolynomialOver::CoefficientType PolynomialOver::GetCoefficient(unsigned int i, const Ring &ring) const +{ + return (i < m_coefficients.size()) ? m_coefficients[i] : ring.Identity(); +} + +template +PolynomialOver& PolynomialOver::operator=(const PolynomialOver& t) +{ + if (this != &t) + { + m_coefficients.resize(t.m_coefficients.size()); + for (unsigned int i=0; i +PolynomialOver& PolynomialOver::Accumulate(const PolynomialOver& t, const Ring &ring) +{ + unsigned int count = t.CoefficientCount(ring); + + if (count > CoefficientCount(ring)) + m_coefficients.resize(count, ring.Identity()); + + for (unsigned int i=0; i +PolynomialOver& PolynomialOver::Reduce(const PolynomialOver& t, const Ring &ring) +{ + unsigned int count = t.CoefficientCount(ring); + + if (count > CoefficientCount(ring)) + m_coefficients.resize(count, ring.Identity()); + + for (unsigned int i=0; i +typename PolynomialOver::CoefficientType PolynomialOver::EvaluateAt(const CoefficientType &x, const Ring &ring) const +{ + int degree = Degree(ring); + + if (degree < 0) + return ring.Identity(); + + CoefficientType result = m_coefficients[degree]; + for (int j=degree-1; j>=0; j--) + { + result = ring.Multiply(result, x); + ring.Accumulate(result, m_coefficients[j]); + } + return result; +} + +template +PolynomialOver& PolynomialOver::ShiftLeft(unsigned int n, const Ring &ring) +{ + unsigned int i = CoefficientCount(ring) + n; + m_coefficients.resize(i, ring.Identity()); + while (i > n) + { + i--; + m_coefficients[i] = m_coefficients[i-n]; + } + while (i) + { + i--; + m_coefficients[i] = ring.Identity(); + } + return *this; +} + +template +PolynomialOver& PolynomialOver::ShiftRight(unsigned int n, const Ring &ring) +{ + unsigned int count = CoefficientCount(ring); + if (count > n) + { + for (unsigned int i=0; i +void PolynomialOver::SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring) +{ + if (i >= m_coefficients.size()) + m_coefficients.resize(i+1, ring.Identity()); + m_coefficients[i] = value; +} + +template +void PolynomialOver::Negate(const Ring &ring) +{ + unsigned int count = CoefficientCount(ring); + for (unsigned int i=0; i +void PolynomialOver::swap(PolynomialOver &t) +{ + m_coefficients.swap(t.m_coefficients); +} + +template +bool PolynomialOver::Equals(const PolynomialOver& t, const Ring &ring) const +{ + unsigned int count = CoefficientCount(ring); + + if (count != t.CoefficientCount(ring)) + return false; + + for (unsigned int i=0; i +PolynomialOver PolynomialOver::Plus(const PolynomialOver& t, const Ring &ring) const +{ + unsigned int i; + unsigned int count = CoefficientCount(ring); + unsigned int tCount = t.CoefficientCount(ring); + + if (count > tCount) + { + PolynomialOver result(ring, count); + + for (i=0; i result(ring, tCount); + + for (i=0; i +PolynomialOver PolynomialOver::Minus(const PolynomialOver& t, const Ring &ring) const +{ + unsigned int i; + unsigned int count = CoefficientCount(ring); + unsigned int tCount = t.CoefficientCount(ring); + + if (count > tCount) + { + PolynomialOver result(ring, count); + + for (i=0; i result(ring, tCount); + + for (i=0; i +PolynomialOver PolynomialOver::Inverse(const Ring &ring) const +{ + unsigned int count = CoefficientCount(ring); + PolynomialOver result(ring, count); + + for (unsigned int i=0; i +PolynomialOver PolynomialOver::Times(const PolynomialOver& t, const Ring &ring) const +{ + if (IsZero(ring) || t.IsZero(ring)) + return PolynomialOver(); + + unsigned int count1 = CoefficientCount(ring), count2 = t.CoefficientCount(ring); + PolynomialOver result(ring, count1 + count2 - 1); + + for (unsigned int i=0; i +PolynomialOver PolynomialOver::DividedBy(const PolynomialOver& t, const Ring &ring) const +{ + PolynomialOver remainder, quotient; + Divide(remainder, quotient, *this, t, ring); + return quotient; +} + +template +PolynomialOver PolynomialOver::Modulo(const PolynomialOver& t, const Ring &ring) const +{ + PolynomialOver remainder, quotient; + Divide(remainder, quotient, *this, t, ring); + return remainder; +} + +template +PolynomialOver PolynomialOver::MultiplicativeInverse(const Ring &ring) const +{ + return Degree(ring)==0 ? ring.MultiplicativeInverse(m_coefficients[0]) : ring.Identity(); +} + +template +bool PolynomialOver::IsUnit(const Ring &ring) const +{ + return Degree(ring)==0 && ring.IsUnit(m_coefficients[0]); +} + +template +std::istream& PolynomialOver::Input(std::istream &in, const Ring &ring) +{ + char c; + unsigned int length = 0; + SecBlock str(length + 16); + bool paren = false; + + std::ws(in); + + if (in.peek() == '(') + { + paren = true; + in.get(); + } + + do + { + in.read(&c, 1); + str[length++] = c; + if (length >= str.size()) + str.Grow(length + 16); + } + // if we started with a left paren, then read until we find a right paren, + // otherwise read until the end of the line + while (in && ((paren && c != ')') || (!paren && c != '\n'))); + + str[length-1] = '\0'; + *this = PolynomialOver(str, ring); + + return in; +} + +template +std::ostream& PolynomialOver::Output(std::ostream &out, const Ring &ring) const +{ + unsigned int i = CoefficientCount(ring); + if (i) + { + bool firstTerm = true; + + while (i--) + { + if (m_coefficients[i] != ring.Identity()) + { + if (firstTerm) + { + firstTerm = false; + if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity())) + out << m_coefficients[i]; + } + else + { + CoefficientType inverse = ring.Inverse(m_coefficients[i]); + std::ostringstream pstr, nstr; + + pstr << m_coefficients[i]; + nstr << inverse; + + if (pstr.str().size() <= nstr.str().size()) + { + out << " + "; + if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity())) + out << m_coefficients[i]; + } + else + { + out << " - "; + if (!i || !ring.Equal(inverse, ring.MultiplicativeIdentity())) + out << inverse; + } + } + + switch (i) + { + case 0: + break; + case 1: + out << "x"; + break; + default: + out << "x^" << i; + } + } + } + } + else + { + out << ring.Identity(); + } + return out; +} + +template +void PolynomialOver::Divide(PolynomialOver &r, PolynomialOver &q, const PolynomialOver &a, const PolynomialOver &d, const Ring &ring) +{ + unsigned int i = a.CoefficientCount(ring); + const int dDegree = d.Degree(ring); + + if (dDegree < 0) + throw DivideByZero(); + + r = a; + q.m_coefficients.resize(STDMAX(0, int(i - dDegree))); + + while (i > (unsigned int)dDegree) + { + --i; + q.m_coefficients[i-dDegree] = ring.Divide(r.m_coefficients[i], d.m_coefficients[dDegree]); + for (int j=0; j<=dDegree; j++) + ring.Reduce(r.m_coefficients[i-dDegree+j], ring.Multiply(q.m_coefficients[i-dDegree], d.m_coefficients[j])); + } + + r.CoefficientCount(ring); // resize r.m_coefficients +} + +// ******************************************************** + +// helper function for Interpolate() and InterpolateAt() +template +void RingOfPolynomialsOver::CalculateAlpha(std::vector &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const +{ + for (unsigned int j=0; j=k; --j) + { + m_ring.Reduce(alpha[j], alpha[j-1]); + + CoefficientType d = m_ring.Subtract(x[j], x[j-k]); + if (!m_ring.IsUnit(d)) + throw InterpolationFailed(); + alpha[j] = m_ring.Divide(alpha[j], d); + } + } +} + +template +typename RingOfPolynomialsOver::Element RingOfPolynomialsOver::Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const +{ + CRYPTOPP_ASSERT(n > 0); + + std::vector alpha(n); + CalculateAlpha(alpha, x, y, n); + + std::vector coefficients((size_t)n, m_ring.Identity()); + coefficients[0] = alpha[n-1]; + + for (int j=n-2; j>=0; --j) + { + for (unsigned int i=n-j-1; i>0; i--) + coefficients[i] = m_ring.Subtract(coefficients[i-1], m_ring.Multiply(coefficients[i], x[j])); + + coefficients[0] = m_ring.Subtract(alpha[j], m_ring.Multiply(coefficients[0], x[j])); + } + + return PolynomialOver(coefficients.begin(), coefficients.end()); +} + +template +typename RingOfPolynomialsOver::CoefficientType RingOfPolynomialsOver::InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const +{ + CRYPTOPP_ASSERT(n > 0); + + std::vector alpha(n); + CalculateAlpha(alpha, x, y, n); + + CoefficientType result = alpha[n-1]; + for (int j=n-2; j>=0; --j) + { + result = m_ring.Multiply(result, m_ring.Subtract(position, x[j])); + m_ring.Accumulate(result, alpha[j]); + } + return result; +} + +template +void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n) +{ + for (unsigned int i=0; i +void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n) +{ + CRYPTOPP_ASSERT(n > 0); + + std::vector a(2*n-1); + unsigned int i; + + for (i=0; i1; i--) + a[i-1] = ring.Multiply(a[2*i], a[2*i-1]); + + a[0] = ring.MultiplicativeIdentity(); + + for (i=0; i +Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n) +{ + Element result = ring.Identity(); + for (unsigned int i=0; i +const PolynomialOverFixedRing &PolynomialOverFixedRing::Zero() +{ + return Singleton().Ref(); +} + +template +const PolynomialOverFixedRing &PolynomialOverFixedRing::One() +{ + return Singleton().Ref(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/polynomi.h b/external/ours/library/crypto/src/shared/original/polynomi.h new file mode 100755 index 000000000..025ee67bc --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/polynomi.h @@ -0,0 +1,463 @@ +// polynomi.h - originally written and placed in the public domain by Wei Dai + +/// \file polynomi.h +/// \brief Classes for polynomial basis and operations + +#ifndef CRYPTOPP_POLYNOMI_H +#define CRYPTOPP_POLYNOMI_H + +#include "cryptlib.h" +#include "secblock.h" +#include "algebra.h" +#include "misc.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// represents single-variable polynomials over arbitrary rings +/*! \nosubgrouping */ +template class PolynomialOver +{ +public: + /// \name ENUMS, EXCEPTIONS, and TYPEDEFS + //@{ + /// division by zero exception + class DivideByZero : public Exception + { + public: + DivideByZero() : Exception(OTHER_ERROR, "PolynomialOver: division by zero") {} + }; + + /// specify the distribution for randomization functions + class RandomizationParameter + { + public: + RandomizationParameter(unsigned int coefficientCount, const typename T::RandomizationParameter &coefficientParameter ) + : m_coefficientCount(coefficientCount), m_coefficientParameter(coefficientParameter) {} + + private: + unsigned int m_coefficientCount; + typename T::RandomizationParameter m_coefficientParameter; + friend class PolynomialOver; + }; + + typedef T Ring; + typedef typename T::Element CoefficientType; + //@} + + /// \name CREATORS + //@{ + /// creates the zero polynomial + PolynomialOver() {} + + /// + PolynomialOver(const Ring &ring, unsigned int count) + : m_coefficients((size_t)count, ring.Identity()) {} + + /// copy constructor + PolynomialOver(const PolynomialOver &t) + : m_coefficients(t.m_coefficients.size()) {*this = t;} + + /// construct constant polynomial + PolynomialOver(const CoefficientType &element) + : m_coefficients(1, element) {} + + /// construct polynomial with specified coefficients, starting from coefficient of x^0 + template PolynomialOver(Iterator begin, Iterator end) + : m_coefficients(begin, end) {} + + /// convert from string + PolynomialOver(const char *str, const Ring &ring) {FromStr(str, ring);} + + /// convert from big-endian byte array + PolynomialOver(const byte *encodedPolynomialOver, unsigned int byteCount); + + /// convert from Basic Encoding Rules encoded byte array + explicit PolynomialOver(const byte *BEREncodedPolynomialOver); + + /// convert from BER encoded byte array stored in a BufferedTransformation object + explicit PolynomialOver(BufferedTransformation &bt); + + /// create a random PolynomialOver + PolynomialOver(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring) + {Randomize(rng, parameter, ring);} + //@} + + /// \name ACCESSORS + //@{ + /// the zero polynomial will return a degree of -1 + int Degree(const Ring &ring) const {return int(CoefficientCount(ring))-1;} + /// + unsigned int CoefficientCount(const Ring &ring) const; + /// return coefficient for x^i + CoefficientType GetCoefficient(unsigned int i, const Ring &ring) const; + //@} + + /// \name MANIPULATORS + //@{ + /// + PolynomialOver& operator=(const PolynomialOver& t); + + /// + void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring); + + /// set the coefficient for x^i to value + void SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring); + + /// + void Negate(const Ring &ring); + + /// + void swap(PolynomialOver &t); + //@} + + + /// \name BASIC ARITHMETIC ON POLYNOMIALS + //@{ + bool Equals(const PolynomialOver &t, const Ring &ring) const; + bool IsZero(const Ring &ring) const {return CoefficientCount(ring)==0;} + + PolynomialOver Plus(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver Minus(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver Inverse(const Ring &ring) const; + + PolynomialOver Times(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver DividedBy(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver Modulo(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver MultiplicativeInverse(const Ring &ring) const; + bool IsUnit(const Ring &ring) const; + + PolynomialOver& Accumulate(const PolynomialOver& t, const Ring &ring); + PolynomialOver& Reduce(const PolynomialOver& t, const Ring &ring); + + /// + PolynomialOver Doubled(const Ring &ring) const {return Plus(*this, ring);} + /// + PolynomialOver Squared(const Ring &ring) const {return Times(*this, ring);} + + CoefficientType EvaluateAt(const CoefficientType &x, const Ring &ring) const; + + PolynomialOver& ShiftLeft(unsigned int n, const Ring &ring); + PolynomialOver& ShiftRight(unsigned int n, const Ring &ring); + + /// calculate r and q such that (a == d*q + r) && (0 <= degree of r < degree of d) + static void Divide(PolynomialOver &r, PolynomialOver &q, const PolynomialOver &a, const PolynomialOver &d, const Ring &ring); + //@} + + /// \name INPUT/OUTPUT + //@{ + std::istream& Input(std::istream &in, const Ring &ring); + std::ostream& Output(std::ostream &out, const Ring &ring) const; + //@} + +private: + void FromStr(const char *str, const Ring &ring); + + std::vector m_coefficients; +}; + +/// Polynomials over a fixed ring +/*! Having a fixed ring allows overloaded operators */ +template class PolynomialOverFixedRing : private PolynomialOver +{ + typedef PolynomialOver B; + typedef PolynomialOverFixedRing ThisType; + +public: + typedef T Ring; + typedef typename T::Element CoefficientType; + typedef typename B::DivideByZero DivideByZero; + typedef typename B::RandomizationParameter RandomizationParameter; + + /// \name CREATORS + //@{ + /// creates the zero polynomial + PolynomialOverFixedRing(unsigned int count = 0) : B(ms_fixedRing, count) {} + + /// copy constructor + PolynomialOverFixedRing(const ThisType &t) : B(t) {} + + explicit PolynomialOverFixedRing(const B &t) : B(t) {} + + /// construct constant polynomial + PolynomialOverFixedRing(const CoefficientType &element) : B(element) {} + + /// construct polynomial with specified coefficients, starting from coefficient of x^0 + template PolynomialOverFixedRing(Iterator first, Iterator last) + : B(first, last) {} + + /// convert from string + explicit PolynomialOverFixedRing(const char *str) : B(str, ms_fixedRing) {} + + /// convert from big-endian byte array + PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {} + + /// convert from Basic Encoding Rules encoded byte array + explicit PolynomialOverFixedRing(const byte *BEREncodedPoly) : B(BEREncodedPoly) {} + + /// convert from BER encoded byte array stored in a BufferedTransformation object + explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {} + + /// create a random PolynomialOverFixedRing + PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) : B(rng, parameter, ms_fixedRing) {} + + static const ThisType &Zero(); + static const ThisType &One(); + //@} + + /// \name ACCESSORS + //@{ + /// the zero polynomial will return a degree of -1 + int Degree() const {return B::Degree(ms_fixedRing);} + /// degree + 1 + unsigned int CoefficientCount() const {return B::CoefficientCount(ms_fixedRing);} + /// return coefficient for x^i + CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);} + /// return coefficient for x^i + CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);} + //@} + + /// \name MANIPULATORS + //@{ + /// + ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;} + /// + ThisType& operator+=(const ThisType& t) {Accumulate(t, ms_fixedRing); return *this;} + /// + ThisType& operator-=(const ThisType& t) {Reduce(t, ms_fixedRing); return *this;} + /// + ThisType& operator*=(const ThisType& t) {return *this = *this*t;} + /// + ThisType& operator/=(const ThisType& t) {return *this = *this/t;} + /// + ThisType& operator%=(const ThisType& t) {return *this = *this%t;} + + /// + ThisType& operator<<=(unsigned int n) {ShiftLeft(n, ms_fixedRing); return *this;} + /// + ThisType& operator>>=(unsigned int n) {ShiftRight(n, ms_fixedRing); return *this;} + + /// set the coefficient for x^i to value + void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, ms_fixedRing);} + + /// + void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) {B::Randomize(rng, parameter, ms_fixedRing);} + + /// + void Negate() {B::Negate(ms_fixedRing);} + + void swap(ThisType &t) {B::swap(t);} + //@} + + /// \name UNARY OPERATORS + //@{ + /// + bool operator!() const {return CoefficientCount()==0;} + /// + ThisType operator+() const {return *this;} + /// + ThisType operator-() const {return ThisType(Inverse(ms_fixedRing));} + //@} + + /// \name BINARY OPERATORS + //@{ + /// + friend ThisType operator>>(ThisType a, unsigned int n) {return ThisType(a>>=n);} + /// + friend ThisType operator<<(ThisType a, unsigned int n) {return ThisType(a<<=n);} + //@} + + /// \name OTHER ARITHMETIC FUNCTIONS + //@{ + /// + ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(ms_fixedRing));} + /// + bool IsUnit() const {return B::IsUnit(ms_fixedRing);} + + /// + ThisType Doubled() const {return ThisType(B::Doubled(ms_fixedRing));} + /// + ThisType Squared() const {return ThisType(B::Squared(ms_fixedRing));} + + CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, ms_fixedRing);} + + /// calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) + static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d) + {B::Divide(r, q, a, d, ms_fixedRing);} + //@} + + /// \name INPUT/OUTPUT + //@{ + /// + friend std::istream& operator>>(std::istream& in, ThisType &a) + {return a.Input(in, ms_fixedRing);} + /// + friend std::ostream& operator<<(std::ostream& out, const ThisType &a) + {return a.Output(out, ms_fixedRing);} + //@} + +private: + struct NewOnePolynomial + { + ThisType * operator()() const + { + return new ThisType(ms_fixedRing.MultiplicativeIdentity()); + } + }; + + static const Ring ms_fixedRing; +}; + +/// Ring of polynomials over another ring +template class RingOfPolynomialsOver : public AbstractEuclideanDomain > +{ +public: + typedef T CoefficientRing; + typedef PolynomialOver Element; + typedef typename Element::CoefficientType CoefficientType; + typedef typename Element::RandomizationParameter RandomizationParameter; + + RingOfPolynomialsOver(const CoefficientRing &ring) : m_ring(ring) {} + + Element RandomElement(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) + {return Element(rng, parameter, m_ring);} + + bool Equal(const Element &a, const Element &b) const + {return a.Equals(b, m_ring);} + + const Element& Identity() const + {return this->result = m_ring.Identity();} + + const Element& Add(const Element &a, const Element &b) const + {return this->result = a.Plus(b, m_ring);} + + Element& Accumulate(Element &a, const Element &b) const + {a.Accumulate(b, m_ring); return a;} + + const Element& Inverse(const Element &a) const + {return this->result = a.Inverse(m_ring);} + + const Element& Subtract(const Element &a, const Element &b) const + {return this->result = a.Minus(b, m_ring);} + + Element& Reduce(Element &a, const Element &b) const + {return a.Reduce(b, m_ring);} + + const Element& Double(const Element &a) const + {return this->result = a.Doubled(m_ring);} + + const Element& MultiplicativeIdentity() const + {return this->result = m_ring.MultiplicativeIdentity();} + + const Element& Multiply(const Element &a, const Element &b) const + {return this->result = a.Times(b, m_ring);} + + const Element& Square(const Element &a) const + {return this->result = a.Squared(m_ring);} + + bool IsUnit(const Element &a) const + {return a.IsUnit(m_ring);} + + const Element& MultiplicativeInverse(const Element &a) const + {return this->result = a.MultiplicativeInverse(m_ring);} + + const Element& Divide(const Element &a, const Element &b) const + {return this->result = a.DividedBy(b, m_ring);} + + const Element& Mod(const Element &a, const Element &b) const + {return this->result = a.Modulo(b, m_ring);} + + void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const + {Element::Divide(r, q, a, d, m_ring);} + + class InterpolationFailed : public Exception + { + public: + InterpolationFailed() : Exception(OTHER_ERROR, "RingOfPolynomialsOver: interpolation failed") {} + }; + + Element Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const; + + // a faster version of Interpolate(x, y, n).EvaluateAt(position) + CoefficientType InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const; +/* + void PrepareBulkInterpolation(CoefficientType *w, const CoefficientType x[], unsigned int n) const; + void PrepareBulkInterpolationAt(CoefficientType *v, const CoefficientType &position, const CoefficientType x[], const CoefficientType w[], unsigned int n) const; + CoefficientType BulkInterpolateAt(const CoefficientType y[], const CoefficientType v[], unsigned int n) const; +*/ +protected: + void CalculateAlpha(std::vector &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const; + + CoefficientRing m_ring; +}; + +template +void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n); +template +void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n); +template +Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n); + +/// +template +inline bool operator==(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Equals(b, a.ms_fixedRing);} +/// +template +inline bool operator!=(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return !(a==b);} + +/// +template +inline bool operator> (const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() > b.Degree();} +/// +template +inline bool operator>=(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() >= b.Degree();} +/// +template +inline bool operator< (const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() < b.Degree();} +/// +template +inline bool operator<=(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() <= b.Degree();} + +/// +template +inline CryptoPP::PolynomialOverFixedRing operator+(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Plus(b, a.ms_fixedRing));} +/// +template +inline CryptoPP::PolynomialOverFixedRing operator-(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Minus(b, a.ms_fixedRing));} +/// +template +inline CryptoPP::PolynomialOverFixedRing operator*(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Times(b, a.ms_fixedRing));} +/// +template +inline CryptoPP::PolynomialOverFixedRing operator/(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.DividedBy(b, a.ms_fixedRing));} +/// +template +inline CryptoPP::PolynomialOverFixedRing operator%(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Modulo(b, a.ms_fixedRing));} + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template inline void swap(CryptoPP::PolynomialOver &a, CryptoPP::PolynomialOver &b) +{ + a.swap(b); +} +template inline void swap(CryptoPP::PolynomialOverFixedRing &a, CryptoPP::PolynomialOverFixedRing &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ppc_power7.cpp b/external/ours/library/crypto/src/shared/original/ppc_power7.cpp new file mode 100755 index 000000000..84a7275a5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ppc_power7.cpp @@ -0,0 +1,93 @@ +// ppc_power7.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics and built-ins to gain access to +// Power7 instructions. A separate source file is needed because +// additional CXXFLAGS are required to enable the appropriate +// instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#if defined(__ALTIVEC__) || defined(_ARCH_PWR7) +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char PPC_POWER7_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// ************************* Feature Probes ************************* // + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) +bool CPU_ProbePower7() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif defined(CRYPTOPP_POWER7_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile int result = false; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + // POWER7 added unaligned loads and store operations + byte b1[19] = {255, 255, 255, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, b2[17]; + + // See comments in ppc_simd.h for some of these defines. + #if defined(_AIX) && defined(_ARCH_PWR7) && ((__xlC__ & 0xff00) == 0x0c00) + vec_xstw4(vec_xlw4(0, (unsigned int*)(b1+3)), 0, (unsigned int*)(b2+1)); + result = (0 == std::memcmp(b1+3, b2+1, 16)); + #elif defined(_ARCH_PWR7) && defined(__VSX__) + vec_xst(vec_xl(0, (unsigned int*)(b1+3)), 0, (unsigned int*)(b2+1)); + result = (0 == std::memcmp(b1+3, b2+1, 16)); + #else + result = false; + #endif + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // _ARCH_PWR7 +} + +#endif // PPC32 or PPC64 + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ppc_power8.cpp b/external/ours/library/crypto/src/shared/original/ppc_power8.cpp new file mode 100755 index 000000000..7e287ee58 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ppc_power8.cpp @@ -0,0 +1,246 @@ +// ppc_power8.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics and built-ins to gain access to +// Power8 instructions. A separate source file is needed because +// additional CXXFLAGS are required to enable the appropriate +// instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#if defined(_ARCH_PWR8) || defined(__CRYPTO__) +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char PPC_POWER8_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// ************************* Feature Probes ************************* // + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + +bool CPU_ProbePower8() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (_ARCH_PWR8) && defined(CRYPTOPP_POWER8_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile int result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + // POWER8 added 64-bit SIMD operations + const word64 x = W64LIT(0xffffffffffffffff); + word64 w1[2] = {x, x}, w2[2] = {4, 6}, w3[2]; + + // Specifically call the VSX loads and stores with 64-bit types + #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) || defined(__clang__) + const uint64x2_p v1 = vec_xl(0, (unsigned long long*)w1); + const uint64x2_p v2 = vec_xl(0, (unsigned long long*)w2); + const uint64x2_p v3 = vec_add(v1, v2); // 64-bit add + vec_xst(v3, 0, (unsigned long long*)w3); + #else + const uint64x2_p v1 = (uint64x2_p)vec_vsx_ld(0, (const byte*)w1); + const uint64x2_p v2 = (uint64x2_p)vec_vsx_ld(0, (const byte*)w2); + const uint64x2_p v3 = vec_add(v1, v2); // 64-bit add + vec_vsx_st((uint8x16_p)v3, 0, (byte*)w3); + #endif + + // Relies on integer wrap + result = (w3[0] == 3 && w3[1] == 5); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // _ARCH_PWR8 +} + +bool CPU_ProbeAES() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (__CRYPTO__) && defined(CRYPTOPP_POWER8_AES_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile int result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + byte key[16] = {0xA0, 0xFA, 0xFE, 0x17, 0x88, 0x54, 0x2c, 0xb1, + 0x23, 0xa3, 0x39, 0x39, 0x2a, 0x6c, 0x76, 0x05}; + byte state[16] = {0x19, 0x3d, 0xe3, 0xb3, 0xa0, 0xf4, 0xe2, 0x2b, + 0x9a, 0xc6, 0x8d, 0x2a, 0xe9, 0xf8, 0x48, 0x08}; + byte r[16] = {255}, z[16] = {}; + + uint8x16_p k = (uint8x16_p)VecLoad(0, key); + uint8x16_p s = (uint8x16_p)VecLoad(0, state); + s = VecEncrypt(s, k); + s = VecEncryptLast(s, k); + s = VecDecrypt(s, k); + s = VecDecryptLast(s, k); + VecStore(s, r); + + result = (0 != std::memcmp(r, z, 16)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // __CRYPTO__ +} + +bool CPU_ProbeSHA256() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (__CRYPTO__) && defined(CRYPTOPP_POWER8_SHA_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile int result = false; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + byte r[16], z[16] = {0}; + uint8x16_p x = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + x = VecSHA256<0,0>(x); + x = VecSHA256<0,0xf>(x); + x = VecSHA256<1,0>(x); + x = VecSHA256<1,0xf>(x); + VecStore(x, r); + + result = (0 == std::memcmp(r, z, 16)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ALTIVEC_AVAILABLE +} + +bool CPU_ProbeSHA512() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (__CRYPTO__) && defined(CRYPTOPP_POWER8_SHA_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile int result = false; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + byte r[16], z[16] = {0}; + uint8x16_p x = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + x = VecSHA512<0,0>(x); + x = VecSHA512<0,0xf>(x); + x = VecSHA512<1,0>(x); + x = VecSHA512<1,0xf>(x); + VecStore(x, r); + + result = (0 == std::memcmp(r, z, 16)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_POWER8_AVAILABLE +} + +#endif // PPC32 or PPC64 + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ppc_power9.cpp b/external/ours/library/crypto/src/shared/original/ppc_power9.cpp new file mode 100755 index 000000000..b7288f7c4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ppc_power9.cpp @@ -0,0 +1,136 @@ +// ppc_power9.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics and built-ins to gain access to +// Power9 instructions. A separate source file is needed because +// additional CXXFLAGS are required to enable the appropriate +// instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#if defined(_ARCH_PWR9) +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char PPC_POWER9_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// ************************* Feature Probes ************************* // + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + +bool CPU_ProbePower9() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif defined(CRYPTOPP_POWER9_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721954 + volatile int result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + // This is "darn r3, 0" from POWER9. We cannot use __builtin_darn + // and friends because Clang and IBM XL C/C++ does not offer them. +#if CRYPTOPP_BIG_ENDIAN + __asm__ __volatile__ (".byte 0x7c, 0x60, 0x05, 0xe6 \n" : : : "r3"); +#else + __asm__ __volatile__ (".byte 0xe6, 0x05, 0x60, 0x7c \n" : : : "r3"); +#endif + result = true; + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // _ARCH_PWR9 +} + +// The DARN probe is not guarded with a preprocessor macro at the moment. We +// don't use CRYPTOPP_POWER9_AVAILABLE because old compilers, like GCC 4.8 on +// CentOS 7, will report NO even though we can produce the random numbers. +// Other Power9 implementations which use builtins will use the preprocessor +// macro guard. This strategy also gets into a situation where Power9 is not +// available but DARN is. +bool CPU_ProbeDARN() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#else +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721954 + volatile int result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + // This is "darn r3, 0" from POWER9. We cannot use __builtin_darn + // and friends because Clang and IBM XL C/C++ does not offer them. +#if CRYPTOPP_BIG_ENDIAN + __asm__ __volatile__ (".byte 0x7c, 0x60, 0x05, 0xe6 \n" : : : "r3"); +#else + __asm__ __volatile__ (".byte 0xe6, 0x05, 0x60, 0x7c \n" : : : "r3"); +#endif + result = true; + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#endif // DARN +} + +#endif // PPC32 or PPC64 + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ppc_simd.cpp b/external/ours/library/crypto/src/shared/original/ppc_simd.cpp new file mode 100755 index 000000000..081d05150 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ppc_simd.cpp @@ -0,0 +1,96 @@ +// ppc_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics to gain access to AltiVec, +// Power8 and in-core crypto instructions. A separate source file +// is needed because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "stdcpp.h" + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# include "ppc_simd.h" +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char PPC_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) +bool CPU_ProbeAltivec() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (_ARCH_PWR3) && (CRYPTOPP_ALTIVEC_AVAILABLE) +# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile int result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + CRYPTOPP_ALIGN_DATA(16) + const byte b1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + CRYPTOPP_ALIGN_DATA(16) + const byte b2[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + CRYPTOPP_ALIGN_DATA(16) byte b3[16]; + + // Specifically call the Altivec loads and stores + const uint8x16_p v1 = (uint8x16_p)vec_ld(0, (byte*)b1); + const uint8x16_p v2 = (uint8x16_p)vec_ld(0, (byte*)b2); + const uint8x16_p v3 = (uint8x16_p)VecXor(v1, v2); + vec_st(v3, 0, b3); + + result = (0 == std::memcmp(b2, b3, 16)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ALTIVEC_AVAILABLE +} + +# endif // CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ppc_simd.h b/external/ours/library/crypto/src/shared/original/ppc_simd.h new file mode 100755 index 000000000..1ed0b5601 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ppc_simd.h @@ -0,0 +1,2764 @@ +// ppc_simd.h - written and placed in public domain by Jeffrey Walton + +/// \file ppc_simd.h +/// \brief Support functions for PowerPC and vector operations +/// \details This header provides an agnostic interface into Clang, GCC +/// and IBM XL C/C++ compilers modulo their different built-in functions +/// for accessing vector intructions. +/// \details The abstractions are necesssary to support back to GCC 4.8 and +/// XLC 11 and 12. GCC 4.8 and 4.9 are still popular, and they are the +/// default compiler for GCC112, GCC119 and others on the compile farm. +/// Older IBM XL C/C++ compilers also have the need due to lack of +/// vec_xl and vec_xst support on some platforms. Modern +/// compilers provide best support and don't need many of the hacks +/// below. +/// \details The library is tested with the following PowerPC machines and +/// compilers. GCC110, GCC111, GCC112, GCC119 and GCC135 are provided by +/// the GCC Compile Farm +/// - PowerMac G5, OSX 10.5, POWER4, Apple GCC 4.0 +/// - PowerMac G5, OSX 10.5, POWER4, Macports GCC 5.0 +/// - GCC110, Linux, POWER7, GCC 4.8.5 +/// - GCC110, Linux, POWER7, XLC 12.01 +/// - GCC111, AIX, POWER7, GCC 4.8.1 +/// - GCC111, AIX, POWER7, XLC 12.01 +/// - GCC112, Linux, POWER8, GCC 4.8.5 +/// - GCC112, Linux, POWER8, XLC 13.01 +/// - GCC112, Linux, POWER8, Clang 7.0 +/// - GCC119, AIX, POWER8, GCC 7.2.0 +/// - GCC119, AIX, POWER8, XLC 13.01 +/// - GCC135, Linux, POWER9, GCC 7.0 +/// \details 12 machines are used for testing because the three compilers form +/// five or six profiles. The profiles are listed below. +/// - GCC (Linux GCC, Macports GCC, etc. Consistent across machines) +/// - XLC 13.0 and earlier (all IBM components) +/// - XLC 13.1 and later on Linux (LLVM front-end, no compatibility macros) +/// - XLC 13.1 and later on Linux (LLVM front-end, -qxlcompatmacros option) +/// - early LLVM Clang (traditional Clang compiler) +/// - late LLVM Clang (traditional Clang compiler) +/// \details The LLVM front-end makes it tricky to write portable code because +/// LLVM pretends to be other compilers but cannot consume other compiler's +/// builtins. When using XLC with -qxlcompatmacros the compiler pretends to +/// be GCC, Clang and XLC all at once but it can only consume it's variety +/// of builtins. +/// \details At Crypto++ 8.0 the various Vector{FuncName} were +/// renamed to Vec{FuncName}. For example, VectorAnd was +/// changed to VecAnd. The name change helped consolidate two +/// slightly different implementations. +/// \details At Crypto++ 8.3 the library added select 64-bit functions for +/// 32-bit Altivec. For example, VecAdd64 and VecSub64 +/// take 32-bit vectors and adds or subtracts them as if there were vectors +/// with two 64-bit elements. The functions dramtically improve performance +/// for some algorithms on some platforms, like SIMON128 and SPECK128 on +/// Power6 and earlier. For example, SPECK128 improved from 70 cpb to +/// 10 cpb on an old PowerMac. Use the functions like shown below. +///
+///    \#if defined(_ARCH_PWR8)
+///    \#  define speck128_t uint64x2_p
+///    \#else
+///    \#  define speck128_t uint32x4_p
+///    \#endif
+///
+///    speck128_t rk, x1, x2, y1, y2;
+///    rk = (speck128_t)VecLoadAligned(ptr);
+///    x1 = VecRotateRight64<8>(x1);
+///    x1 = VecAdd64(x1, y1);
+///    ...
+/// \since Crypto++ 6.0, LLVM Clang compiler support since Crypto++ 8.0 + +// Use __ALTIVEC__, _ARCH_PWR7, __VSX__, and _ARCH_PWR8 when detecting +// actual availaibility of the feature for the source file being compiled. +// The preprocessor macros depend on compiler options like -maltivec; and +// not compiler versions. + +// For GCC see https://gcc.gnu.org/onlinedocs/gcc/Basic-PowerPC-Built-in-Functions.html +// For XLC see the Compiler Reference manual. For Clang you have to experiment. +// Clang does not document the compiler options, does not reject options it does +// not understand, and pretends to be other compilers even though it cannot +// process the builtins and intrinsics. Clang will waste hours of your time. + +// DO NOT USE this pattern in VecLoad and VecStore. We have to use the +// code paths guarded by preprocessor macros because XLC 12 generates +// bad code in some places. To verify the bad code generation test on +// GCC111 with XLC 12.01 installed. XLC 13.01 on GCC112 and GCC119 are OK. +// +// inline uint32x4_p VecLoad(const byte src[16]) +// { +// #if defined(__VSX__) || defined(_ARCH_PWR8) +// return (uint32x4_p) *(uint8x16_p*)((byte*)src); +// #else +// return VecLoad_ALTIVEC(src); +// #endif +// } + +// We should be able to perform the load using inline asm on Power7 with +// VSX or Power8. The inline asm will avoid C undefined behavior due to +// casting from byte* to word32*. We are safe because our byte* are +// 16-byte aligned for Altivec. Below is the big endian load. Little +// endian would need to follow with xxpermdi for the reversal. +// +// __asm__ ("lxvw4x %x0, %1, %2" : "=wa"(v) : "r"(0), "r"(src) : ); + +// GCC and XLC use integer math for the address (D-form or byte-offset +// in the ISA manual). LLVM uses pointer math for the address (DS-form +// or indexed in the ISA manual). To keep them consistent we calculate +// the address from the offset and pass to a load or store function +// using a 0 offset. + +#ifndef CRYPTOPP_PPC_CRYPTO_H +#define CRYPTOPP_PPC_CRYPTO_H + +#include "config.h" +#include "misc.h" + +#if defined(__ALTIVEC__) +# include +# undef vector +# undef pixel +# undef bool +#endif + +// XL C++ on AIX does not define VSX and does not +// provide an option to set it. We have to set it +// for the code below. This define must stay in +// sync with the define in test_ppc_power7.cpp. +#ifndef CRYPTOPP_DISABLE_POWER7 +# if defined(_AIX) && defined(_ARCH_PWR7) && defined(__xlC__) +# define __VSX__ 1 +# endif +#endif + +// XL C++ on AIX does not define CRYPTO and does not +// provide an option to set it. We have to set it +// for the code below. This define must stay in +// sync with the define in test_ppc_power8.cpp +#ifndef CRYPTOPP_DISABLE_POWER8 +# if defined(_AIX) && defined(_ARCH_PWR8) && defined(__xlC__) +# define __CRYPTO__ 1 +# endif +#endif + +/// \brief Cast array to vector pointer +/// \details CONST_V8_CAST casts a const array to a vector +/// pointer for a byte array. The Power ABI says source arrays +/// are non-const, so this define removes the const. XLC++ will +/// fail the compile if the source array is const. +#define CONST_V8_CAST(x) ((unsigned char*)(x)) +/// \brief Cast array to vector pointer +/// \details CONST_V32_CAST casts a const array to a vector +/// pointer for a word array. The Power ABI says source arrays +/// are non-const, so this define removes the const. XLC++ will +/// fail the compile if the source array is const. +#define CONST_V32_CAST(x) ((unsigned int*)(x)) +/// \brief Cast array to vector pointer +/// \details CONST_V64_CAST casts a const array to a vector +/// pointer for a double word array. The Power ABI says source arrays +/// are non-const, so this define removes the const. XLC++ will +/// fail the compile if the source array is const. +#define CONST_V64_CAST(x) ((unsigned long long*)(x)) +/// \brief Cast array to vector pointer +/// \details NCONST_V8_CAST casts an array to a vector +/// pointer for a byte array. The Power ABI says source arrays +/// are non-const, so this define removes the const. XLC++ will +/// fail the compile if the source array is const. +#define NCONST_V8_CAST(x) ((unsigned char*)(x)) +/// \brief Cast array to vector pointer +/// \details NCONST_V32_CAST casts an array to a vector +/// pointer for a word array. The Power ABI says source arrays +/// are non-const, so this define removes the const. XLC++ will +/// fail the compile if the source array is const. +#define NCONST_V32_CAST(x) ((unsigned int*)(x)) +/// \brief Cast array to vector pointer +/// \details NCONST_V64_CAST casts an array to a vector +/// pointer for a double word array. The Power ABI says source arrays +/// are non-const, so this define removes the const. XLC++ will +/// fail the compile if the source array is const. +#define NCONST_V64_CAST(x) ((unsigned long long*)(x)) + +// VecLoad_ALTIVEC and VecStore_ALTIVEC are +// too noisy on modern compilers +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(__ALTIVEC__) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \brief Vector of 8-bit elements +/// \par Wraps +/// __vector unsigned char +/// \since Crypto++ 6.0 +typedef __vector unsigned char uint8x16_p; +/// \brief Vector of 16-bit elements +/// \par Wraps +/// __vector unsigned short +/// \since Crypto++ 6.0 +typedef __vector unsigned short uint16x8_p; +/// \brief Vector of 32-bit elements +/// \par Wraps +/// __vector unsigned int +/// \since Crypto++ 6.0 +typedef __vector unsigned int uint32x4_p; + +#if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Vector of 64-bit elements +/// \details uint64x2_p is available on POWER7 with VSX and above. Most +/// supporting functions, like 64-bit vec_add (vaddudm) +/// and vec_sub (vsubudm), did not arrive until POWER8. +/// \par Wraps +/// __vector unsigned long long +/// \since Crypto++ 6.0 +typedef __vector unsigned long long uint64x2_p; +#endif // VSX or ARCH_PWR8 + +/// \brief The 0 vector +/// \return a 32-bit vector of 0's +/// \since Crypto++ 8.0 +inline uint32x4_p VecZero() +{ + const uint32x4_p v = {0,0,0,0}; + return v; +} + +/// \brief The 1 vector +/// \return a 32-bit vector of 1's +/// \since Crypto++ 8.0 +inline uint32x4_p VecOne() +{ + const uint32x4_p v = {1,1,1,1}; + return v; +} + +/// \brief Reverse bytes in a vector +/// \tparam T vector type +/// \param data the vector +/// \return vector +/// \details VecReverse() reverses the bytes in a vector +/// \par Wraps +/// vec_perm +/// \since Crypto++ 6.0 +template +inline T VecReverse(const T data) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + return (T)vec_perm(data, data, mask); +#else + const uint8x16_p mask = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}; + return (T)vec_perm(data, data, mask); +#endif +} + +/// \brief Reverse bytes in a vector +/// \tparam T vector type +/// \param data the vector +/// \return vector +/// \details VecReverseLE() reverses the bytes in a vector on +/// little-endian systems. +/// \par Wraps +/// vec_perm +/// \since Crypto++ 6.0 +template +inline T VecReverseLE(const T data) +{ +#if defined(CRYPTOPP_LITTLE_ENDIAN) + const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + return (T)vec_perm(data, data, mask); +#else + return data; +#endif +} + +/// \brief Reverse bytes in a vector +/// \tparam T vector type +/// \param data the vector +/// \return vector +/// \details VecReverseBE() reverses the bytes in a vector on +/// big-endian systems. +/// \par Wraps +/// vec_perm +/// \since Crypto++ 6.0 +template +inline T VecReverseBE(const T data) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + return (T)vec_perm(data, data, mask); +#else + return data; +#endif +} + +/// \name LOAD OPERATIONS +//@{ + +/// \brief Loads a vector from a byte array +/// \param src the byte array +/// \details Loads a vector in native endian format from a byte array. +/// \details VecLoad_ALTIVEC() uses vec_ld if the effective address +/// of src is aligned. If unaligned it uses vec_lvsl, +/// vec_ld, vec_perm and src. The fixups using +/// vec_lvsl and vec_perm are relatively expensive so +/// you should provide aligned memory adresses. +/// \par Wraps +/// vec_ld, vec_lvsl, vec_perm +/// \sa VecLoad, VecLoadAligned +/// \since Crypto++ 6.0 +inline uint32x4_p VecLoad_ALTIVEC(const byte src[16]) +{ + // Avoid IsAlignedOn for convenience. + const uintptr_t addr = reinterpret_cast(src); + if (addr % 16 == 0) + { + return (uint32x4_p)vec_ld(0, CONST_V8_CAST(addr)); + } + else + { + // http://www.nxp.com/docs/en/reference-manual/ALTIVECPEM.pdf + const uint8x16_p perm = vec_lvsl(0, CONST_V8_CAST(addr)); + const uint8x16_p low = vec_ld(0, CONST_V8_CAST(addr)); + const uint8x16_p high = vec_ld(15, CONST_V8_CAST(addr)); + return (uint32x4_p)vec_perm(low, high, perm); + } +} + +/// \brief Loads a vector from a byte array +/// \param src the byte array +/// \param off offset into the src byte array +/// \details Loads a vector in native endian format from a byte array. +/// \details VecLoad_ALTIVEC() uses vec_ld if the effective address +/// of src is aligned. If unaligned it uses vec_lvsl, +/// vec_ld, vec_perm and src. +/// \details The fixups using vec_lvsl and vec_perm are +/// relatively expensive so you should provide aligned memory adresses. +/// \par Wraps +/// vec_ld, vec_lvsl, vec_perm +/// \sa VecLoad, VecLoadAligned +/// \since Crypto++ 6.0 +inline uint32x4_p VecLoad_ALTIVEC(int off, const byte src[16]) +{ + // Avoid IsAlignedOn for convenience. + const uintptr_t addr = reinterpret_cast(src)+off; + if (addr % 16 == 0) + { + return (uint32x4_p)vec_ld(0, CONST_V8_CAST(addr)); + } + else + { + // http://www.nxp.com/docs/en/reference-manual/ALTIVECPEM.pdf + const uint8x16_p perm = vec_lvsl(0, CONST_V8_CAST(addr)); + const uint8x16_p low = vec_ld(0, CONST_V8_CAST(addr)); + const uint8x16_p high = vec_ld(15, CONST_V8_CAST(addr)); + return (uint32x4_p)vec_perm(low, high, perm); + } +} + +/// \brief Loads a vector from a byte array +/// \param src the byte array +/// \details VecLoad() loads a vector from a byte array. +/// \details VecLoad() uses POWER9's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER9 is not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xl on POWER9 and above, Altivec load on POWER8 and below +/// \sa VecLoad_ALTIVEC, VecLoadAligned +/// \since Crypto++ 6.0 +inline uint32x4_p VecLoad(const byte src[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(0, CONST_V8_CAST(src)); +#else + return (uint32x4_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#endif +} + +/// \brief Loads a vector from a byte array +/// \param src the byte array +/// \param off offset into the src byte array +/// \details VecLoad() loads a vector from a byte array. +/// \details VecLoad() uses POWER9's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER9 is not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xl on POWER9 and above, Altivec load on POWER8 and below +/// \sa VecLoad_ALTIVEC, VecLoadAligned +/// \since Crypto++ 6.0 +inline uint32x4_p VecLoad(int off, const byte src[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(off, CONST_V8_CAST(src)); +#else + return (uint32x4_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#endif +} + +/// \brief Loads a vector from a word array +/// \param src the word array +/// \details VecLoad() loads a vector from a word array. +/// \details VecLoad() uses POWER7's and VSX's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER7 is not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, Altivec load on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoadAligned +/// \since Crypto++ 8.0 +inline uint32x4_p VecLoad(const word32 src[4]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(0, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + return (uint32x4_p)vec_xl(0, CONST_V32_CAST(addr)); +#else + return (uint32x4_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#endif +} + +/// \brief Loads a vector from a word array +/// \param src the word array +/// \param off offset into the word array +/// \details VecLoad() loads a vector from a word array. +/// \details VecLoad() uses POWER7's and VSX's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER7 is not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, Altivec load on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoadAligned +/// \since Crypto++ 8.0 +inline uint32x4_p VecLoad(int off, const word32 src[4]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(off, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + return (uint32x4_p)vec_xl(0, CONST_V32_CAST(addr)); +#else + return (uint32x4_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#endif +} + +#if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \brief Loads a vector from a double word array +/// \param src the double word array +/// \details VecLoad() loads a vector from a double word array. +/// \details VecLoad() uses POWER7's and VSX's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER7 and VSX are not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \details VecLoad() with 64-bit elements is available on POWER7 and above. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, Altivec load on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoadAligned +/// \since Crypto++ 8.0 +inline uint64x2_p VecLoad(const word64 src[2]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint64x2_p)vec_xl(0, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + // The 32-bit cast is not a typo. Compiler workaround. + return (uint64x2_p)vec_xl(0, CONST_V32_CAST(addr)); +#else + return (uint64x2_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#endif +} + +/// \brief Loads a vector from a double word array +/// \param src the double word array +/// \param off offset into the double word array +/// \details VecLoad() loads a vector from a double word array. +/// \details VecLoad() uses POWER7's and VSX's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER7 and VSX are not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \details VecLoad() with 64-bit elements is available on POWER8 and above. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, Altivec load on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoadAligned +/// \since Crypto++ 8.0 +inline uint64x2_p VecLoad(int off, const word64 src[2]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint64x2_p)vec_xl(off, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + // The 32-bit cast is not a typo. Compiler workaround. + return (uint64x2_p)vec_xl(0, CONST_V32_CAST(addr)); +#else + return (uint64x2_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#endif +} + +#endif // VSX or ARCH_PWR8 + +/// \brief Loads a vector from an aligned byte array +/// \param src the byte array +/// \details VecLoadAligned() loads a vector from an aligned byte array. +/// \details VecLoadAligned() uses POWER9's vec_xl if available. +/// vec_ld is used if POWER9 is not available. The effective +/// address of src must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xl on POWER9, vec_ld on POWER8 and below +/// \sa VecLoad_ALTIVEC, VecLoad +/// \since Crypto++ 8.0 +inline uint32x4_p VecLoadAligned(const byte src[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + CRYPTOPP_ASSERT(addr % 16 == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(0, CONST_V8_CAST(src)); +#else + return (uint32x4_p)vec_ld(0, CONST_V8_CAST(src)); +#endif +} + +/// \brief Loads a vector from an aligned byte array +/// \param src the byte array +/// \param off offset into the src byte array +/// \details VecLoadAligned() loads a vector from an aligned byte array. +/// \details VecLoadAligned() uses POWER9's vec_xl if available. +/// vec_ld is used if POWER9 is not available. The effective +/// address of src must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xl on POWER9, vec_ld on POWER8 and below +/// \sa VecLoad_ALTIVEC, VecLoad +/// \since Crypto++ 8.0 +inline uint32x4_p VecLoadAligned(int off, const byte src[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + CRYPTOPP_ASSERT(addr % 16 == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(off, CONST_V8_CAST(src)); +#else + return (uint32x4_p)vec_ld(off, CONST_V8_CAST(src)); +#endif +} + +/// \brief Loads a vector from an aligned word array +/// \param src the word array +/// \details VecLoadAligned() loads a vector from an aligned word array. +/// \details VecLoadAligned() uses POWER7's and VSX's vec_xl if +/// available. vec_ld is used if POWER7 or VSX are not available. +/// The effective address of src must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, vec_ld on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoad +/// \since Crypto++ 8.0 +inline uint32x4_p VecLoadAligned(const word32 src[4]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + CRYPTOPP_ASSERT(addr % 16 == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(0, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + return (uint32x4_p)vec_xl(0, CONST_V32_CAST(src)); +#else + return (uint32x4_p)vec_ld(0, CONST_V8_CAST(src)); +#endif +} + +/// \brief Loads a vector from an aligned word array +/// \param src the word array +/// \param off offset into the src word array +/// \details VecLoadAligned() loads a vector from an aligned word array. +/// \details VecLoadAligned() uses POWER7's and VSX's vec_xl if +/// available. vec_ld is used if POWER7 or VSX are not available. +/// The effective address of src must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, vec_ld on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoad +/// \since Crypto++ 8.0 +inline uint32x4_p VecLoadAligned(int off, const word32 src[4]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + CRYPTOPP_ASSERT(addr % 16 == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint32x4_p)vec_xl(off, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + return (uint32x4_p)vec_xl(0, CONST_V32_CAST(addr)); +#else + return (uint32x4_p)vec_ld(off, CONST_V8_CAST(src)); +#endif +} + +#if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \brief Loads a vector from an aligned double word array +/// \param src the double word array +/// \details VecLoadAligned() loads a vector from an aligned double word array. +/// \details VecLoadAligned() uses POWER7's and VSX's vec_xl if +/// available. vec_ld is used if POWER7 or VSX are not available. +/// The effective address of src must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, vec_ld on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoad +/// \since Crypto++ 8.0 +inline uint64x2_p VecLoadAligned(const word64 src[4]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + CRYPTOPP_ASSERT(addr % 16 == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint64x2_p)vec_xl(0, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + // The 32-bit cast is not a typo. Compiler workaround. + return (uint64x2_p)vec_xl(0, CONST_V32_CAST(src)); +#else + return (uint64x2_p)vec_ld(0, CONST_V8_CAST(src)); +#endif +} + +/// \brief Loads a vector from an aligned double word array +/// \param src the double word array +/// \param off offset into the src double word array +/// \details VecLoadAligned() loads a vector from an aligned double word array. +/// \details VecLoadAligned() uses POWER7's and VSX's vec_xl if +/// available. vec_ld is used if POWER7 or VSX are not available. +/// The effective address of src must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xl on VSX or POWER8 and above, vec_ld on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoad +/// \since Crypto++ 8.0 +inline uint64x2_p VecLoadAligned(int off, const word64 src[4]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + CRYPTOPP_ASSERT(addr % 16 == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + return (uint64x2_p)vec_xl(off, CONST_V8_CAST(src)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + // The 32-bit cast is not a typo. Compiler workaround. + return (uint64x2_p)vec_xl(0, CONST_V32_CAST(addr)); +#else + return (uint64x2_p)vec_ld(off, CONST_V8_CAST(src)); +#endif +} + +#endif + +/// \brief Loads a vector from a byte array +/// \param src the byte array +/// \details VecLoadBE() loads a vector from a byte array. VecLoadBE +/// will reverse all bytes in the array on a little endian system. +/// \details VecLoadBE() uses POWER7's and VSX's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER7 or VSX are not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xl on POWER8, Altivec load on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoad, VecLoadAligned +/// \since Crypto++ 6.0 +inline uint32x4_p VecLoadBE(const byte src[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src); + // CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + return (uint32x4_p)vec_xl_be(0, CONST_V8_CAST(src)); +#elif defined(CRYPTOPP_BIG_ENDIAN) + return (uint32x4_p)VecLoad_ALTIVEC(0, CONST_V8_CAST(src)); +#else + return (uint32x4_p)VecReverseLE(VecLoad_ALTIVEC(CONST_V8_CAST(src))); +#endif +} + +/// \brief Loads a vector from a byte array +/// \param src the byte array +/// \param off offset into the src byte array +/// \details VecLoadBE() loads a vector from a byte array. VecLoadBE +/// will reverse all bytes in the array on a little endian system. +/// \details VecLoadBE() uses POWER7's and VSX's vec_xl if available. +/// The instruction does not require aligned effective memory addresses. +/// VecLoad_ALTIVEC() is used if POWER7 is not available. +/// VecLoad_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xl on POWER8, Altivec load on POWER7 and below +/// \sa VecLoad_ALTIVEC, VecLoad, VecLoadAligned +/// \since Crypto++ 6.0 +inline uint32x4_p VecLoadBE(int off, const byte src[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(src)+off; + // CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + return (uint32x4_p)vec_xl_be(off, CONST_V8_CAST(src)); +#elif defined(CRYPTOPP_BIG_ENDIAN) + return (uint32x4_p)VecLoad_ALTIVEC(CONST_V8_CAST(addr)); +#else + return (uint32x4_p)VecReverseLE(VecLoad_ALTIVEC(CONST_V8_CAST(addr))); +#endif +} + +//@} + +/// \name STORE OPERATIONS +//@{ + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param dest the byte array +/// \details VecStore_ALTIVEC() stores a vector to a byte array. +/// \details VecStore_ALTIVEC() uses vec_st if the effective address +/// of dest is aligned, and uses vec_ste otherwise. +/// vec_ste is relatively expensive so you should provide aligned +/// memory adresses. +/// \details VecStore_ALTIVEC() is used when POWER7 or above +/// and unaligned loads is not available. +/// \par Wraps +/// vec_st, vec_ste, vec_lvsr, vec_perm +/// \sa VecStore, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStore_ALTIVEC(const T data, byte dest[16]) +{ + // Avoid IsAlignedOn for convenience. + uintptr_t addr = reinterpret_cast(dest); + if (addr % 16 == 0) + { + vec_st((uint8x16_p)data, 0, NCONST_V8_CAST(addr)); + } + else + { + // http://www.nxp.com/docs/en/reference-manual/ALTIVECPEM.pdf + uint8x16_p perm = (uint8x16_p)vec_perm(data, data, vec_lvsr(0, NCONST_V8_CAST(addr))); + vec_ste((uint8x16_p) perm, 0, (unsigned char*) NCONST_V8_CAST(addr)); + vec_ste((uint16x8_p) perm, 1, (unsigned short*)NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 3, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 4, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 8, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 12, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint16x8_p) perm, 14, (unsigned short*)NCONST_V8_CAST(addr)); + vec_ste((uint8x16_p) perm, 15, (unsigned char*) NCONST_V8_CAST(addr)); + } +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest byte array +/// \param dest the byte array +/// \details VecStore_ALTIVEC() stores a vector to a byte array. +/// \details VecStore_ALTIVEC() uses vec_st if the effective address +/// of dest is aligned, and uses vec_ste otherwise. +/// vec_ste is relatively expensive so you should provide aligned +/// memory adresses. +/// \details VecStore_ALTIVEC() is used when POWER7 or above +/// and unaligned loads is not available. +/// \par Wraps +/// vec_st, vec_ste, vec_lvsr, vec_perm +/// \sa VecStore, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStore_ALTIVEC(const T data, int off, byte dest[16]) +{ + // Avoid IsAlignedOn for convenience. + uintptr_t addr = reinterpret_cast(dest)+off; + if (addr % 16 == 0) + { + vec_st((uint8x16_p)data, 0, NCONST_V8_CAST(addr)); + } + else + { + // http://www.nxp.com/docs/en/reference-manual/ALTIVECPEM.pdf + uint8x16_p perm = (uint8x16_p)vec_perm(data, data, vec_lvsr(0, NCONST_V8_CAST(addr))); + vec_ste((uint8x16_p) perm, 0, (unsigned char*) NCONST_V8_CAST(addr)); + vec_ste((uint16x8_p) perm, 1, (unsigned short*)NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 3, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 4, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 8, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint32x4_p) perm, 12, (unsigned int*) NCONST_V8_CAST(addr)); + vec_ste((uint16x8_p) perm, 14, (unsigned short*)NCONST_V8_CAST(addr)); + vec_ste((uint8x16_p) perm, 15, (unsigned char*) NCONST_V8_CAST(addr)); + } +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param dest the byte array +/// \details VecStore() stores a vector to a byte array. +/// \details VecStore() uses POWER9's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER9 is not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on POWER9 and above, Altivec store on POWER8 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 6.0 +template +inline void VecStore(const T data, byte dest[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#else + VecStore_ALTIVEC((uint8x16_p)data, NCONST_V8_CAST(dest)); +#endif +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest byte array +/// \param dest the byte array +/// \details VecStore() stores a vector to a byte array. +/// \details VecStore() uses POWER9's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER9 is not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on POWER9 and above, Altivec store on POWER8 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 6.0 +template +inline void VecStore(const T data, int off, byte dest[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#else + VecStore_ALTIVEC((uint8x16_p)data, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param dest the word array +/// \details VecStore() stores a vector to a word array. +/// \details VecStore() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 or VSX are not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, Altivec store on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStore(const T data, word32 dest[4]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + vec_xst((uint32x4_p)data, 0, NCONST_V32_CAST(addr)); +#else + VecStore_ALTIVEC((uint8x16_p)data, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest word array +/// \param dest the word array +/// \details VecStore() stores a vector to a word array. +/// \details VecStore() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 or VSX are not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, Altivec store on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStore(const T data, int off, word32 dest[4]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + vec_xst((uint32x4_p)data, 0, NCONST_V32_CAST(addr)); +#else + VecStore_ALTIVEC((uint8x16_p)data, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param dest the word array +/// \details VecStore() stores a vector to a word array. +/// \details VecStore() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 or VSX are not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \details VecStore() with 64-bit elements is available on POWER8 and above. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, Altivec store on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStore(const T data, word64 dest[2]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + // 32-bit cast is not a typo. Compiler workaround. + vec_xst((uint32x4_p)data, 0, NCONST_V32_CAST(addr)); +#else + VecStore_ALTIVEC((uint8x16_p)data, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest word array +/// \param dest the word array +/// \details VecStore() stores a vector to a word array. +/// \details VecStore() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 or VSX are not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \details VecStore() with 64-bit elements is available on POWER8 and above. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, Altivec store on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStore(const T data, int off, word64 dest[2]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + // 32-bit cast is not a typo. Compiler workaround. + vec_xst((uint32x4_p)data, 0, NCONST_V32_CAST(addr)); +#else + VecStore_ALTIVEC((uint8x16_p)data, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param dest the byte array +/// \details VecStoreAligned() stores a vector from an aligned byte array. +/// \details VecStoreAligned() uses POWER9's vec_xl if available. +/// vec_st is used if POWER9 is not available. The effective +/// address of dest must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xst on POWER9 or above, vec_st on POWER8 and below +/// \sa VecStore_ALTIVEC, VecStore +/// \since Crypto++ 8.0 +template +inline void VecStoreAligned(const T data, byte dest[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#else + vec_st((uint8x16_p)data, 0, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest byte array +/// \param dest the byte array +/// \details VecStoreAligned() stores a vector from an aligned byte array. +/// \details VecStoreAligned() uses POWER9's vec_xl if available. +/// vec_st is used if POWER9 is not available. The effective +/// address of dest must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xst on POWER9 or above, vec_st on POWER8 and below +/// \sa VecStore_ALTIVEC, VecStore +/// \since Crypto++ 8.0 +template +inline void VecStoreAligned(const T data, int off, byte dest[16]) +{ + // Power7/ISA 2.06 provides vec_xl, but only for 32-bit and 64-bit + // word pointers. The ISA lacks loads for short* and char*. + // Power9/ISA 3.0 provides vec_xl for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#else + vec_st((uint8x16_p)data, 0, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param dest the word array +/// \details VecStoreAligned() stores a vector from an aligned word array. +/// \details VecStoreAligned() uses POWER9's vec_xl if available. +/// POWER7 vec_xst is used if POWER9 is not available. vec_st +/// is used if POWER7 is not available. The effective address of dest +/// must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, vec_st on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStore +/// \since Crypto++ 8.0 +template +inline void VecStoreAligned(const T data, word32 dest[4]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + vec_xst((uint32x4_p)data, 0, NCONST_V32_CAST(addr)); +#else + vec_st((uint8x16_p)data, 0, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest word array +/// \param dest the word array +/// \details VecStoreAligned() stores a vector from an aligned word array. +/// \details VecStoreAligned() uses POWER9's vec_xl if available. +/// POWER7 vec_xst is used if POWER9 is not available. vec_st +/// is used if POWER7 is not available. The effective address of dest +/// must be 16-byte aligned for Altivec. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, vec_st on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStore +/// \since Crypto++ 8.0 +template +inline void VecStoreAligned(const T data, int off, word32 dest[4]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#elif defined(__VSX__) || defined(_ARCH_PWR8) + vec_xst((uint32x4_p)data, 0, NCONST_V32_CAST(addr)); +#else + vec_st((uint8x16_p)data, 0, NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param dest the byte array +/// \details VecStoreBE() stores a vector to a byte array. VecStoreBE +/// will reverse all bytes in the array on a little endian system. +/// \details VecStoreBE() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 is not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, vec_st on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 6.0 +template +inline void VecStoreBE(const T data, byte dest[16]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst_be((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#elif defined(CRYPTOPP_BIG_ENDIAN) + VecStore((uint8x16_p)data, NCONST_V8_CAST(addr)); +#else + VecStore((uint8x16_p)VecReverseLE(data), NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a byte array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest byte array +/// \param dest the byte array +/// \details VecStoreBE() stores a vector to a byte array. VecStoreBE +/// will reverse all bytes in the array on a little endian system. +/// \details VecStoreBE() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 is not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, vec_st on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 6.0 +template +inline void VecStoreBE(const T data, int off, byte dest[16]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst_be((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#elif defined(CRYPTOPP_BIG_ENDIAN) + VecStore((uint8x16_p)data, NCONST_V8_CAST(addr)); +#else + VecStore((uint8x16_p)VecReverseLE(data), NCONST_V8_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param dest the word array +/// \details VecStoreBE() stores a vector to a word array. VecStoreBE +/// will reverse all bytes in the array on a little endian system. +/// \details VecStoreBE() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 is not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, vec_st on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStoreBE(const T data, word32 dest[4]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest); + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst_be((uint8x16_p)data, 0, NCONST_V8_CAST(dest)); +#elif defined(CRYPTOPP_BIG_ENDIAN) + VecStore((uint32x4_p)data, NCONST_V32_CAST(addr)); +#else + VecStore((uint32x4_p)VecReverseLE(data), NCONST_V32_CAST(addr)); +#endif +} + +/// \brief Stores a vector to a word array +/// \tparam T vector type +/// \param data the vector +/// \param off offset into the dest word array +/// \param dest the word array +/// \details VecStoreBE() stores a vector to a word array. VecStoreBE +/// will reverse all words in the array on a little endian system. +/// \details VecStoreBE() uses POWER7's and VSX's vec_xst if available. +/// The instruction does not require aligned effective memory addresses. +/// VecStore_ALTIVEC() is used if POWER7 is not available. +/// VecStore_ALTIVEC() can be relatively expensive if extra instructions +/// are required to fix up unaligned memory addresses. +/// \par Wraps +/// vec_xst on VSX or POWER8 and above, vec_st on POWER7 and below +/// \sa VecStore_ALTIVEC, VecStoreAligned +/// \since Crypto++ 8.0 +template +inline void VecStoreBE(const T data, int off, word32 dest[4]) +{ + // Power7/ISA 2.06 provides vec_xst, but only for 32-bit and 64-bit + // word pointers. The ISA lacks stores for short* and char*. + // Power9/ISA 3.0 provides vec_xst for all datatypes. + + const uintptr_t addr = reinterpret_cast(dest)+off; + CRYPTOPP_ASSERT(addr % GetAlignmentOf() == 0); + CRYPTOPP_UNUSED(addr); + +#if defined(_ARCH_PWR9) + vec_xst_be((uint8x16_p)data, off, NCONST_V8_CAST(dest)); +#elif defined(CRYPTOPP_BIG_ENDIAN) + VecStore((uint32x4_p)data, NCONST_V32_CAST(addr)); +#else + VecStore((uint32x4_p)VecReverseLE(data), NCONST_V32_CAST(addr)); +#endif +} + +//@} + +/// \name LOGICAL OPERATIONS +//@{ + +/// \brief AND two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecAnd() performs vec1 & vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \par Wraps +/// vec_and +/// \sa VecAnd64 +/// \since Crypto++ 6.0 +template +inline T1 VecAnd(const T1 vec1, const T2 vec2) +{ + return (T1)vec_and(vec1, (T1)vec2); +} + +/// \brief OR two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecOr() performs vec1 | vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \par Wraps +/// vec_or +/// \sa VecOr64 +/// \since Crypto++ 6.0 +template +inline T1 VecOr(const T1 vec1, const T2 vec2) +{ + return (T1)vec_or(vec1, (T1)vec2); +} + +/// \brief XOR two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecXor() performs vec1 ^ vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \par Wraps +/// vec_xor +/// \sa VecXor64 +/// \since Crypto++ 6.0 +template +inline T1 VecXor(const T1 vec1, const T2 vec2) +{ + return (T1)vec_xor(vec1, (T1)vec2); +} + +//@} + +/// \name ARITHMETIC OPERATIONS +//@{ + +/// \brief Add two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecAdd() performs vec1 + vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \par Wraps +/// vec_add +/// \sa VecAdd64 +/// \since Crypto++ 6.0 +template +inline T1 VecAdd(const T1 vec1, const T2 vec2) +{ + return (T1)vec_add(vec1, (T1)vec2); +} + +/// \brief Subtract two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \details VecSub() performs vec1 - vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \par Wraps +/// vec_sub +/// \sa VecSub64 +/// \since Crypto++ 6.0 +template +inline T1 VecSub(const T1 vec1, const T2 vec2) +{ + return (T1)vec_sub(vec1, (T1)vec2); +} + +//@} + +/// \name PERMUTE OPERATIONS +//@{ + +/// \brief Permutes a vector +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec the vector +/// \param mask vector mask +/// \return vector +/// \details VecPermute() creates a new vector from vec according to mask. +/// mask is an uint8x16_p vector. The return vector is the same type as vec. +/// \par Wraps +/// vec_perm +/// \since Crypto++ 6.0 +template +inline T1 VecPermute(const T1 vec, const T2 mask) +{ + return (T1)vec_perm(vec, vec, (uint8x16_p)mask); +} + +/// \brief Permutes two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \param mask vector mask +/// \return vector +/// \details VecPermute() creates a new vector from vec1 and vec2 according to mask. +/// mask is an uint8x16_p vector. The return vector is the same type as vec. +/// \par Wraps +/// vec_perm +/// \since Crypto++ 6.0 +template +inline T1 VecPermute(const T1 vec1, const T1 vec2, const T2 mask) +{ + return (T1)vec_perm(vec1, (T1)vec2, (uint8x16_p)mask); +} + +//@} + +/// \name SHIFT AND ROTATE OPERATIONS +//@{ + +/// \brief Shift a vector left +/// \tparam C shift byte count +/// \tparam T vector type +/// \param vec the vector +/// \return vector +/// \details VecShiftLeftOctet() returns a new vector after shifting the +/// concatenation of the zero vector and the source vector by the specified +/// number of bytes. The return vector is the same type as vec. +/// \details On big endian machines VecShiftLeftOctet() is vec_sld(a, z, +/// c). On little endian machines VecShiftLeftOctet() is translated to +/// vec_sld(z, a, 16-c). You should always call the function as +/// if on a big endian machine as shown below. +///
+///   uint8x16_p x = VecLoad(ptr);
+///   uint8x16_p y = VecShiftLeftOctet<12>(x);
+/// 
+/// \par Wraps +/// vec_sld +/// \sa Is vec_sld +/// endian sensitive? on Stack Overflow +/// \since Crypto++ 6.0 +template +inline T VecShiftLeftOctet(const T vec) +{ + const T zero = {0}; + if (C >= 16) + { + // Out of range + return zero; + } + else if (C == 0) + { + // Noop + return vec; + } + else + { +#if defined(CRYPTOPP_BIG_ENDIAN) + enum { R=C&0xf }; + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)zero, R); +#else + enum { R=(16-C)&0xf }; // Linux xlC 13.1 workaround in Debug builds + return (T)vec_sld((uint8x16_p)zero, (uint8x16_p)vec, R); +#endif + } +} + +/// \brief Shift a vector right +/// \tparam C shift byte count +/// \tparam T vector type +/// \param vec the vector +/// \return vector +/// \details VecShiftRightOctet() returns a new vector after shifting the +/// concatenation of the zero vector and the source vector by the specified +/// number of bytes. The return vector is the same type as vec. +/// \details On big endian machines VecShiftRightOctet() is vec_sld(a, z, +/// c). On little endian machines VecShiftRightOctet() is translated to +/// vec_sld(z, a, 16-c). You should always call the function as +/// if on a big endian machine as shown below. +///
+///   uint8x16_p x = VecLoad(ptr);
+///   uint8x16_p y = VecShiftRightOctet<12>(y);
+/// 
+/// \par Wraps +/// vec_sld +/// \sa Is vec_sld +/// endian sensitive? on Stack Overflow +/// \since Crypto++ 6.0 +template +inline T VecShiftRightOctet(const T vec) +{ + const T zero = {0}; + if (C >= 16) + { + // Out of range + return zero; + } + else if (C == 0) + { + // Noop + return vec; + } + else + { +#if defined(CRYPTOPP_BIG_ENDIAN) + enum { R=(16-C)&0xf }; // Linux xlC 13.1 workaround in Debug builds + return (T)vec_sld((uint8x16_p)zero, (uint8x16_p)vec, R); +#else + enum { R=C&0xf }; + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)zero, R); +#endif + } +} + +/// \brief Rotate a vector left +/// \tparam C shift byte count +/// \tparam T vector type +/// \param vec the vector +/// \return vector +/// \details VecRotateLeftOctet() returns a new vector after rotating the +/// concatenation of the source vector with itself by the specified +/// number of bytes. The return vector is the same type as vec. +/// \par Wraps +/// vec_sld +/// \sa Is vec_sld +/// endian sensitive? on Stack Overflow +/// \since Crypto++ 6.0 +template +inline T VecRotateLeftOctet(const T vec) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + enum { R = C&0xf }; + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)vec, R); +#else + enum { R=(16-C)&0xf }; // Linux xlC 13.1 workaround in Debug builds + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)vec, R); +#endif +} + +/// \brief Rotate a vector right +/// \tparam C shift byte count +/// \tparam T vector type +/// \param vec the vector +/// \return vector +/// \details VecRotateRightOctet() returns a new vector after rotating the +/// concatenation of the source vector with itself by the specified +/// number of bytes. The return vector is the same type as vec. +/// \par Wraps +/// vec_sld +/// \sa Is vec_sld +/// endian sensitive? on Stack Overflow +/// \since Crypto++ 6.0 +template +inline T VecRotateRightOctet(const T vec) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + enum { R=(16-C)&0xf }; // Linux xlC 13.1 workaround in Debug builds + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)vec, R); +#else + enum { R = C&0xf }; + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)vec, R); +#endif +} + +/// \brief Rotate a vector left +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateLeft() rotates each element in a vector by +/// bit count. The return vector is the same type as vec. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 7.0 +template +inline uint32x4_p VecRotateLeft(const uint32x4_p vec) +{ + const uint32x4_p m = {C, C, C, C}; + return vec_rl(vec, m); +} + +/// \brief Rotate a vector right +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateRight() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 7.0 +template +inline uint32x4_p VecRotateRight(const uint32x4_p vec) +{ + const uint32x4_p m = {32-C, 32-C, 32-C, 32-C}; + return vec_rl(vec, m); +} + +/// \brief Shift a vector left +/// \tparam C shift bit count +/// \param vec the vector +/// \return vector +/// \details VecShiftLeft() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \par Wraps +/// vec_sl +/// \since Crypto++ 8.1 +template +inline uint32x4_p VecShiftLeft(const uint32x4_p vec) +{ + const uint32x4_p m = {C, C, C, C}; + return vec_sl(vec, m); +} + +/// \brief Shift a vector right +/// \tparam C shift bit count +/// \param vec the vector +/// \return vector +/// \details VecShiftRight() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.1 +template +inline uint32x4_p VecShiftRight(const uint32x4_p vec) +{ + const uint32x4_p m = {C, C, C, C}; + return vec_sr(vec, m); +} + +// 64-bit elements available at POWER7 with VSX, but vec_rl and vec_sl require POWER8 +#if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \brief Rotate a vector left +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateLeft() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \details VecRotateLeft() with 64-bit elements is available on +/// POWER8 and above. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.0 +template +inline uint64x2_p VecRotateLeft(const uint64x2_p vec) +{ + const uint64x2_p m = {C, C}; + return vec_rl(vec, m); +} + +/// \brief Shift a vector left +/// \tparam C shift bit count +/// \param vec the vector +/// \return vector +/// \details VecShiftLeft() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \details VecShiftLeft() with 64-bit elements is available on +/// POWER8 and above. +/// \par Wraps +/// vec_sl +/// \since Crypto++ 8.1 +template +inline uint64x2_p VecShiftLeft(const uint64x2_p vec) +{ + const uint64x2_p m = {C, C}; + return vec_sl(vec, m); +} + +/// \brief Rotate a vector right +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateRight() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \details VecRotateRight() with 64-bit elements is available on +/// POWER8 and above. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.0 +template +inline uint64x2_p VecRotateRight(const uint64x2_p vec) +{ + const uint64x2_p m = {64-C, 64-C}; + return vec_rl(vec, m); +} + +/// \brief Shift a vector right +/// \tparam C shift bit count +/// \param vec the vector +/// \return vector +/// \details VecShiftRight() rotates each element in a vector +/// by bit count. The return vector is the same type as vec. +/// \details VecShiftRight() with 64-bit elements is available on +/// POWER8 and above. +/// \par Wraps +/// vec_sr +/// \since Crypto++ 8.1 +template +inline uint64x2_p VecShiftRight(const uint64x2_p vec) +{ + const uint64x2_p m = {C, C}; + return vec_sr(vec, m); +} + +#endif // ARCH_PWR8 + +//@} + +/// \name OTHER OPERATIONS +//@{ + +/// \brief Merge two vectors +/// \tparam T vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \par Wraps +/// vec_mergel +/// \since Crypto++ 8.1 +template +inline T VecMergeLow(const T vec1, const T vec2) +{ + return vec_mergel(vec1, vec2); +} + +/// \brief Merge two vectors +/// \tparam T vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \par Wraps +/// vec_mergeh +/// \since Crypto++ 8.1 +template +inline T VecMergeHigh(const T vec1, const T vec2) +{ + return vec_mergeh(vec1, vec2); +} + +/// \brief Broadcast 32-bit word to a vector +/// \param val the 32-bit value +/// \return vector +/// \par Wraps +/// vec_splats +/// \since Crypto++ 8.3 +inline uint32x4_p VecSplatWord(word32 val) +{ + // Fix spurious GCC warning??? + CRYPTOPP_UNUSED(val); + + // Apple Altivec and XL C++ do not offer vec_splats. + // GCC offers vec_splats back to -mcpu=power4. +#if defined(_ARCH_PWR4) && defined(__GNUC__) + return vec_splats(val); +#else + //const word32 x[4] = {val,val,val,val}; + //return VecLoad(x); + const word32 x[4] = {val}; + return vec_splat(VecLoad(x),0); +#endif +} + +/// \brief Broadcast 32-bit element to a vector +/// \tparam the element number +/// \param val the 32-bit value +/// \return vector +/// \par Wraps +/// vec_splat +/// \since Crypto++ 8.3 +template +inline uint32x4_p VecSplatElement(const uint32x4_p val) +{ + return vec_splat(val, N); +} + +#if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Broadcast 64-bit double word to a vector +/// \param val the 64-bit value +/// \return vector +/// \par Wraps +/// vec_splats +/// \since Crypto++ 8.3 +inline uint64x2_p VecSplatWord(word64 val) +{ + // The PPC64 ABI says so. + return vec_splats((unsigned long long)val); +} + +/// \brief Broadcast 64-bit element to a vector +/// \tparam the element number +/// \param val the 64-bit value +/// \return vector +/// \par Wraps +/// vec_splat +/// \since Crypto++ 8.3 +template +inline uint64x2_p VecSplatElement(const uint64x2_p val) +{ +#if defined(__VSX__) || defined(_ARCH_PWR8) + return vec_splat(val, N); +#else + enum {E=N&1}; + if (E == 0) + { + const uint8x16_p m = {0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7}; + return vec_perm(val, val, m); + } + else // (E == 1) + { + const uint8x16_p m = {8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15}; + return vec_perm(val, val, m); + } +#endif +} +#endif + +/// \brief Extract a dword from a vector +/// \tparam T vector type +/// \param val the vector +/// \return vector created from low dword +/// \details VecGetLow() extracts the low dword from a vector. The low dword +/// is composed of the least significant bits and occupies bytes 8 through 15 +/// when viewed as a big endian array. The return vector is the same type as +/// the original vector and padded with 0's in the most significant bit positions. +/// \par Wraps +/// vec_sld +/// \since Crypto++ 7.0 +template +inline T VecGetLow(const T val) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) && (defined(__VSX__) || defined(_ARCH_PWR8)) + const T zero = {0}; + return (T)VecMergeLow((uint64x2_p)zero, (uint64x2_p)val); +#else + return VecShiftRightOctet<8>(VecShiftLeftOctet<8>(val)); +#endif +} + +/// \brief Extract a dword from a vector +/// \tparam T vector type +/// \param val the vector +/// \return vector created from high dword +/// \details VecGetHigh() extracts the high dword from a vector. The high dword +/// is composed of the most significant bits and occupies bytes 0 through 7 +/// when viewed as a big endian array. The return vector is the same type as +/// the original vector and padded with 0's in the most significant bit positions. +/// \par Wraps +/// vec_sld +/// \since Crypto++ 7.0 +template +inline T VecGetHigh(const T val) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) && (defined(__VSX__) || defined(_ARCH_PWR8)) + const T zero = {0}; + return (T)VecMergeHigh((uint64x2_p)zero, (uint64x2_p)val); +#else + return VecShiftRightOctet<8>(val); +#endif +} + +/// \brief Exchange high and low double words +/// \tparam T vector type +/// \param vec the vector +/// \return vector +/// \par Wraps +/// vec_sld +/// \since Crypto++ 7.0 +template +inline T VecSwapWords(const T vec) +{ + return (T)vec_sld((uint8x16_p)vec, (uint8x16_p)vec, 8); +} + +//@} + +/// \name COMPARISON +//@{ + +/// \brief Compare two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return true if vec1 equals vec2, false otherwise +/// \details VecEqual() performs a bitwise compare. The vector element types do +/// not matter. +/// \par Wraps +/// vec_all_eq +/// \since Crypto++ 8.0 +template +inline bool VecEqual(const T1 vec1, const T2 vec2) +{ + return 1 == vec_all_eq((uint32x4_p)vec1, (uint32x4_p)vec2); +} + +/// \brief Compare two vectors +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return true if vec1 does not equal vec2, false otherwise +/// \details VecNotEqual() performs a bitwise compare. The vector element types do +/// not matter. +/// \par Wraps +/// vec_all_eq +/// \since Crypto++ 8.0 +template +inline bool VecNotEqual(const T1 vec1, const T2 vec2) +{ + return 0 == vec_all_eq((uint32x4_p)vec1, (uint32x4_p)vec2); +} + +//@} + +////////////////// 32-bit Altivec ///////////////// + +/// \name 32-BIT ALTIVEC +//@{ + +/// \brief Add two vectors as if uint64x2_p +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecAdd64() performs vec1 + vec2. VecAdd64() performs as +/// if adding two uint64x2_p vectors. On POWER7 and below VecAdd64() manages +/// the carries from the elements. +/// \par Wraps +/// vec_add for POWER8, vec_addc, vec_perm, vec_add for Altivec +/// \since Crypto++ 8.3 +inline uint32x4_p VecAdd64(const uint32x4_p& vec1, const uint32x4_p& vec2) +{ + // 64-bit elements available at POWER7 with VSX, but addudm requires POWER8 +#if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG) + return (uint32x4_p)vec_add((uint64x2_p)vec1, (uint64x2_p)vec2); +#else + // The carry mask selects carrys for elements 1 and 3 and sets + // remaining elements to 0. The results is then shifted so the + // carried values are added to elements 0 and 2. +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint32x4_p zero = {0, 0, 0, 0}; + const uint32x4_p mask = {0, 1, 0, 1}; +#else + const uint32x4_p zero = {0, 0, 0, 0}; + const uint32x4_p mask = {1, 0, 1, 0}; +#endif + + uint32x4_p cy = vec_addc(vec1, vec2); + uint32x4_p res = vec_add(vec1, vec2); + cy = vec_and(mask, cy); + cy = vec_sld (cy, zero, 4); + return vec_add(res, cy); +#endif +} + +#if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Add two vectors as if uint64x2_p +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecAdd64() performs vec1 + vec2. VecAdd64() performs as +/// if adding two uint64x2_p vectors. On POWER7 and below VecAdd64() manages +/// the carries from the elements. +/// \par Wraps +/// vec_add for POWER8 +/// \since Crypto++ 8.3 +inline uint64x2_p VecAdd64(const uint64x2_p& vec1, const uint64x2_p& vec2) +{ + // 64-bit elements available at POWER7 with VSX, but addudm requires POWER8 + const uint64x2_p res = vec_add(vec1, vec2); + +#if defined(CRYPTOPP_DEBUG) + // Test 32-bit add in debug builds while we are here. + const uint32x4_p x = (uint32x4_p)vec1; + const uint32x4_p y = (uint32x4_p)vec2; + const uint32x4_p r = VecAdd64(x, y); + + CRYPTOPP_ASSERT(vec_all_eq((uint32x4_p)res, r) == 1); +#endif + + return res; +} +#endif + +/// \brief Subtract two vectors as if uint64x2_p +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \details VecSub64() performs vec1 - vec2. VecSub64() performs as +/// if subtracting two uint64x2_p vectors. On POWER7 and below VecSub64() +/// manages the borrows from the elements. +/// \par Wraps +/// vec_sub for POWER8, vec_subc, vec_andc, vec_perm, vec_sub for Altivec +/// \since Crypto++ 8.3 +inline uint32x4_p VecSub64(const uint32x4_p& vec1, const uint32x4_p& vec2) +{ +#if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG) + // 64-bit elements available at POWER7 with VSX, but subudm requires POWER8 + return (uint32x4_p)vec_sub((uint64x2_p)vec1, (uint64x2_p)vec2); +#else + // The borrow mask selects borrows for elements 1 and 3 and sets + // remaining elements to 0. The results is then shifted so the + // borrowed values are subtracted from elements 0 and 2. +#if defined(CRYPTOPP_BIG_ENDIAN) + const uint32x4_p zero = {0, 0, 0, 0}; + const uint32x4_p mask = {0, 1, 0, 1}; +#else + const uint32x4_p zero = {0, 0, 0, 0}; + const uint32x4_p mask = {1, 0, 1, 0}; +#endif + + // subc sets the complement of borrow, so we have to + // un-complement it using andc. + uint32x4_p bw = vec_subc(vec1, vec2); + uint32x4_p res = vec_sub(vec1, vec2); + bw = vec_andc(mask, bw); + bw = vec_sld (bw, zero, 4); + return vec_sub(res, bw); +#endif +} + +#if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Subtract two vectors as if uint64x2_p +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \details VecSub64() performs vec1 - vec2. VecSub64() performs as +/// if subtracting two uint64x2_p vectors. On POWER7 and below VecSub64() +/// manages the borrows from the elements. +/// \par Wraps +/// vec_sub for POWER8 +/// \since Crypto++ 8.3 +inline uint64x2_p VecSub64(const uint64x2_p& vec1, const uint64x2_p& vec2) +{ + // 64-bit elements available at POWER7 with VSX, but subudm requires POWER8 + const uint64x2_p res = vec_sub(vec1, vec2); + +#if defined(CRYPTOPP_DEBUG) + // Test 32-bit sub in debug builds while we are here. + const uint32x4_p x = (uint32x4_p)vec1; + const uint32x4_p y = (uint32x4_p)vec2; + const uint32x4_p r = VecSub64(x, y); + + CRYPTOPP_ASSERT(vec_all_eq((uint32x4_p)res, r) == 1); +#endif + + return res; +} +#endif + +/// \brief Rotate a vector left as if uint64x2_p +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateLeft() rotates each element in a vector by bit count. +/// vec is rotated as if uint64x2_p. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.3 +template +inline uint32x4_p VecRotateLeft64(const uint32x4_p vec) +{ +#if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG) + // 64-bit elements available at POWER7 with VSX, but vec_rl and vec_sl require POWER8 + return (uint32x4_p)VecRotateLeft((uint64x2_p)vec); +#else + // C=0, 32, or 64 needs special handling. That is S32 and S64 below. + enum {S64=C&63, S32=C&31, BR=(S64>=32)}; + + // Get the low bits, shift them to high bits + uint32x4_p t1 = VecShiftLeft(vec); + // Get the high bits, shift them to low bits + uint32x4_p t2 = VecShiftRight<32-S32>(vec); + + if (S64 == 0) + { + const uint8x16_p m = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}; + return VecPermute(vec, m); + } + else if (S64 == 32) + { + const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + return VecPermute(vec, m); + } + else if (BR) // Big rotate amount? + { + const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + t1 = VecPermute(t1, m); + } + else + { + const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + t2 = VecPermute(t2, m); + } + + return vec_or(t1, t2); +#endif +} + +/// \brief Rotate a vector left as if uint64x2_p +/// \param vec the vector +/// \return vector +/// \details VecRotateLeft<8>() rotates each element in a vector +/// by 8-bits. vec is rotated as if uint64x2_p. This specialization +/// is used by algorithms like Speck128. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.3 +template<> +inline uint32x4_p VecRotateLeft64<8>(const uint32x4_p vec) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 }; + return VecPermute(vec, m); +#else + const uint8x16_p m = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 }; + return VecPermute(vec, m); +#endif +} + +#if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Rotate a vector left as if uint64x2_p +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateLeft64() rotates each element in a vector by +/// bit count. vec is rotated as if uint64x2_p. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.3 +template +inline uint64x2_p VecRotateLeft64(const uint64x2_p vec) +{ + // 64-bit elements available at POWER7 with VSX, but vec_rl and vec_sl require POWER8 + const uint64x2_p res = VecRotateLeft(vec); + +#if defined(CRYPTOPP_DEBUG) + // Test 32-bit rotate in debug builds while we are here. + const uint32x4_p x = (uint32x4_p)vec; + const uint32x4_p r = VecRotateLeft64(x); + + CRYPTOPP_ASSERT(vec_all_eq((uint32x4_p)res, r) == 1); +#endif + + return res; +} +#endif + +/// \brief Rotate a vector right as if uint64x2_p +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateRight64() rotates each element in a vector by +/// bit count. vec is rotated as if uint64x2_p. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.3 +template +inline uint32x4_p VecRotateRight64(const uint32x4_p vec) +{ +#if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG) + // 64-bit elements available at POWER7 with VSX, but vec_rl and vec_sl require POWER8 + return (uint32x4_p)VecRotateRight((uint64x2_p)vec); +#else + // C=0, 32, or 64 needs special handling. That is S32 and S64 below. + enum {S64=C&63, S32=C&31, BR=(S64>=32)}; + + // Get the low bits, shift them to high bits + uint32x4_p t1 = VecShiftRight(vec); + // Get the high bits, shift them to low bits + uint32x4_p t2 = VecShiftLeft<32-S32>(vec); + + if (S64 == 0) + { + const uint8x16_p m = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}; + return VecPermute(vec, m); + } + else if (S64 == 32) + { + const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + return VecPermute(vec, m); + } + else if (BR) // Big rotate amount? + { + const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + t1 = VecPermute(t1, m); + } + else + { + const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + t2 = VecPermute(t2, m); + } + + return vec_or(t1, t2); +#endif +} + +/// \brief Rotate a vector right as if uint64x2_p +/// \param vec the vector +/// \return vector +/// \details VecRotateRight64<8>() rotates each element in a vector +/// by 8-bits. vec is rotated as if uint64x2_p. This specialization +/// is used by algorithms like Speck128. +/// \details vec is rotated as if uint64x2_p. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.3 +template<> +inline uint32x4_p VecRotateRight64<8>(const uint32x4_p vec) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 }; + return VecPermute(vec, m); +#else + const uint8x16_p m = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 }; + return VecPermute(vec, m); +#endif +} + +#if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Rotate a vector right as if uint64x2_p +/// \tparam C rotate bit count +/// \param vec the vector +/// \return vector +/// \details VecRotateRight64() rotates each element in a vector by +/// bit count. vec is rotated as if uint64x2_p. +/// \par Wraps +/// vec_rl +/// \since Crypto++ 8.3 +template +inline uint64x2_p VecRotateRight64(const uint64x2_p vec) +{ + // 64-bit elements available at POWER7 with VSX, but vec_rl and vec_sl require POWER8 + const uint64x2_p res = VecRotateRight(vec); + +#if defined(CRYPTOPP_DEBUG) + // Test 32-bit rotate in debug builds while we are here. + const uint32x4_p x = (uint32x4_p)vec; + const uint32x4_p r = VecRotateRight64(x); + + CRYPTOPP_ASSERT(vec_all_eq((uint32x4_p)res, r) == 1); +#endif + + return res; +} +#endif + +/// \brief AND two vectors as if uint64x2_p +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecAnd64() performs vec1 & vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \details VecAnd64() is a convenience function that simply performs a VecAnd(). +/// \par Wraps +/// vec_and +/// \since Crypto++ 8.3 +template +inline T1 VecAnd64(const T1 vec1, const T2 vec2) +{ + return (T1)vec_and(vec1, (T1)vec2); +} + +/// \brief OR two vectors as if uint64x2_p +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecOr64() performs vec1 | vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \details VecOr64() is a convenience function that simply performs a VecOr(). +/// \par Wraps +/// vec_or +/// \since Crypto++ 8.3 +template +inline T1 VecOr64(const T1 vec1, const T2 vec2) +{ + return (T1)vec_or(vec1, (T1)vec2); +} + +/// \brief XOR two vectors as if uint64x2_p +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param vec1 the first vector +/// \param vec2 the second vector +/// \return vector +/// \details VecXor64() performs vec1 ^ vec2. +/// vec2 is cast to the same type as vec1. The return vector +/// is the same type as vec1. +/// \details VecXor64() is a convenience function that simply performs a VecXor(). +/// \par Wraps +/// vec_xor +/// \since Crypto++ 8.3 +template +inline T1 VecXor64(const T1 vec1, const T2 vec2) +{ + return (T1)vec_xor(vec1, (T1)vec2); +} + +/// \brief Broadcast 64-bit double word to a vector +/// \param val the 64-bit value +/// \return vector +/// \par Wraps +/// vec_splats +/// \since Crypto++ 8.3 +inline uint32x4_p VecSplatWord64(word64 val) +{ +#if defined(_ARCH_PWR8) + // The PPC64 ABI says so. + return (uint32x4_p)vec_splats((unsigned long long)val); +#else + const word64 x[2] = {val,val}; + return (uint32x4_p)VecLoad((const word32*)x); +#endif +} + +/// \brief Broadcast 64-bit element to a vector as if uint64x2_p +/// \tparam the element number +/// \param val the 64-bit value +/// \return vector +/// \par Wraps +/// vec_splat +/// \since Crypto++ 8.3 +template +inline uint32x4_p VecSplatElement64(const uint32x4_p val) +{ +#if defined(__VSX__) || defined(_ARCH_PWR8) + return (uint32x4_p)vec_splat((uint64x2_p)val, N); +#else + enum {E=N&1}; + if (E == 0) + { + const uint8x16_p m = {0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7}; + return (uint32x4_p)vec_perm(val, val, m); + } + else // (E == 1) + { + const uint8x16_p m = {8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15}; + return (uint32x4_p)vec_perm(val, val, m); + } +#endif +} + +#if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Broadcast 64-bit element to a vector +/// \tparam the element number +/// \param val the 64-bit value +/// \return vector +/// \since Crypto++ 8.3 +template +inline uint64x2_p VecSplatElement64(const uint64x2_p val) +{ + return vec_splat(val, N); +} +#endif + +//@} + +//////////////////////// Power8 Crypto //////////////////////// + +// __CRYPTO__ alone is not enough. Clang will define __CRYPTO__ +// when it is not available, like with Power7. Sigh... +#if (defined(_ARCH_PWR8) && defined(__CRYPTO__)) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + +/// \name POLYNOMIAL MULTIPLICATION +//@{ + +/// \brief Polynomial multiplication +/// \param a the first term +/// \param b the second term +/// \return vector product +/// \details VecPolyMultiply() performs polynomial multiplication. POWER8 +/// polynomial multiplication multiplies the high and low terms, and then +/// XOR's the high and low products. That is, the result is ah*bh XOR +/// al*bl. It is different behavior than Intel polynomial +/// multiplication. To obtain a single product without the XOR, then set +/// one of the high or low terms to 0. For example, setting ah=0 +/// results in 0*bh XOR al*bl = al*bl. +/// \par Wraps +/// __vpmsumw, __builtin_altivec_crypto_vpmsumw and __builtin_crypto_vpmsumw. +/// \since Crypto++ 8.1 +inline uint32x4_p VecPolyMultiply(const uint32x4_p& a, const uint32x4_p& b) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return __vpmsumw (a, b); +#elif defined(__clang__) + return __builtin_altivec_crypto_vpmsumw (a, b); +#else + return __builtin_crypto_vpmsumw (a, b); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first term +/// \param b the second term +/// \return vector product +/// \details VecPolyMultiply() performs polynomial multiplication. POWER8 +/// polynomial multiplication multiplies the high and low terms, and then +/// XOR's the high and low products. That is, the result is ah*bh XOR +/// al*bl. It is different behavior than Intel polynomial +/// multiplication. To obtain a single product without the XOR, then set +/// one of the high or low terms to 0. For example, setting ah=0 +/// results in 0*bh XOR al*bl = al*bl. +/// \par Wraps +/// __vpmsumd, __builtin_altivec_crypto_vpmsumd and __builtin_crypto_vpmsumd. +/// \since Crypto++ 8.1 +inline uint64x2_p VecPolyMultiply(const uint64x2_p& a, const uint64x2_p& b) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return __vpmsumd (a, b); +#elif defined(__clang__) + return __builtin_altivec_crypto_vpmsumd (a, b); +#else + return __builtin_crypto_vpmsumd (a, b); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first term +/// \param b the second term +/// \return vector product +/// \details VecIntelMultiply00() performs polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x00). +/// The 0x00 indicates the low 64-bits of a and b +/// are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and numbered 0. +/// \par Wraps +/// __vpmsumd, __builtin_altivec_crypto_vpmsumd and __builtin_crypto_vpmsumd. +/// \since Crypto++ 8.0 +inline uint64x2_p VecIntelMultiply00(const uint64x2_p& a, const uint64x2_p& b) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + return VecSwapWords(VecPolyMultiply(VecGetHigh(a), VecGetHigh(b))); +#else + return VecPolyMultiply(VecGetHigh(a), VecGetHigh(b)); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first term +/// \param b the second term +/// \return vector product +/// \details VecIntelMultiply01 performs() polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x01). +/// The 0x01 indicates the low 64-bits of a and high +/// 64-bits of b are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and numbered 0. +/// \par Wraps +/// __vpmsumd, __builtin_altivec_crypto_vpmsumd and __builtin_crypto_vpmsumd. +/// \since Crypto++ 8.0 +inline uint64x2_p VecIntelMultiply01(const uint64x2_p& a, const uint64x2_p& b) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + return VecSwapWords(VecPolyMultiply(a, VecGetHigh(b))); +#else + return VecPolyMultiply(a, VecGetHigh(b)); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first term +/// \param b the second term +/// \return vector product +/// \details VecIntelMultiply10() performs polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x10). +/// The 0x10 indicates the high 64-bits of a and low +/// 64-bits of b are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and numbered 0. +/// \par Wraps +/// __vpmsumd, __builtin_altivec_crypto_vpmsumd and __builtin_crypto_vpmsumd. +/// \since Crypto++ 8.0 +inline uint64x2_p VecIntelMultiply10(const uint64x2_p& a, const uint64x2_p& b) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + return VecSwapWords(VecPolyMultiply(VecGetHigh(a), b)); +#else + return VecPolyMultiply(VecGetHigh(a), b); +#endif +} + +/// \brief Polynomial multiplication +/// \param a the first term +/// \param b the second term +/// \return vector product +/// \details VecIntelMultiply11() performs polynomial multiplication and presents +/// the result like Intel's c = _mm_clmulepi64_si128(a, b, 0x11). +/// The 0x11 indicates the high 64-bits of a and b +/// are multiplied. +/// \note An Intel XMM register is composed of 128-bits. The leftmost bit +/// is MSB and numbered 127, while the rightmost bit is LSB and numbered 0. +/// \par Wraps +/// __vpmsumd, __builtin_altivec_crypto_vpmsumd and __builtin_crypto_vpmsumd. +/// \since Crypto++ 8.0 +inline uint64x2_p VecIntelMultiply11(const uint64x2_p& a, const uint64x2_p& b) +{ +#if defined(CRYPTOPP_BIG_ENDIAN) + return VecSwapWords(VecPolyMultiply(VecGetLow(a), b)); +#else + return VecPolyMultiply(VecGetLow(a), b); +#endif +} + +//@} + +/// \name AES ENCRYPTION +//@{ + +/// \brief One round of AES encryption +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param state the state vector +/// \param key the subkey vector +/// \details VecEncrypt() performs one round of AES encryption of state +/// using subkey key. The return vector is the same type as state. +/// \details VecEncrypt() is available on POWER8 and above. +/// \par Wraps +/// __vcipher, __builtin_altivec_crypto_vcipher, __builtin_crypto_vcipher +/// \since GCC and XLC since Crypto++ 6.0, LLVM Clang since Crypto++ 8.0 +template +inline T1 VecEncrypt(const T1 state, const T2 key) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return (T1)__vcipher((uint8x16_p)state, (uint8x16_p)key); +#elif defined(__clang__) + return (T1)__builtin_altivec_crypto_vcipher((uint64x2_p)state, (uint64x2_p)key); +#elif defined(__GNUC__) + return (T1)__builtin_crypto_vcipher((uint64x2_p)state, (uint64x2_p)key); +#else + CRYPTOPP_ASSERT(0); +#endif +} + +/// \brief Final round of AES encryption +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param state the state vector +/// \param key the subkey vector +/// \details VecEncryptLast() performs the final round of AES encryption +/// of state using subkey key. The return vector is the same type as state. +/// \details VecEncryptLast() is available on POWER8 and above. +/// \par Wraps +/// __vcipherlast, __builtin_altivec_crypto_vcipherlast, __builtin_crypto_vcipherlast +/// \since GCC and XLC since Crypto++ 6.0, LLVM Clang since Crypto++ 8.0 +template +inline T1 VecEncryptLast(const T1 state, const T2 key) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return (T1)__vcipherlast((uint8x16_p)state, (uint8x16_p)key); +#elif defined(__clang__) + return (T1)__builtin_altivec_crypto_vcipherlast((uint64x2_p)state, (uint64x2_p)key); +#elif defined(__GNUC__) + return (T1)__builtin_crypto_vcipherlast((uint64x2_p)state, (uint64x2_p)key); +#else + CRYPTOPP_ASSERT(0); +#endif +} + +/// \brief One round of AES decryption +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param state the state vector +/// \param key the subkey vector +/// \details VecDecrypt() performs one round of AES decryption of state +/// using subkey key. The return vector is the same type as state. +/// \details VecDecrypt() is available on POWER8 and above. +/// \par Wraps +/// __vncipher, __builtin_altivec_crypto_vncipher, __builtin_crypto_vncipher +/// \since GCC and XLC since Crypto++ 6.0, LLVM Clang since Crypto++ 8.0 +template +inline T1 VecDecrypt(const T1 state, const T2 key) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return (T1)__vncipher((uint8x16_p)state, (uint8x16_p)key); +#elif defined(__clang__) + return (T1)__builtin_altivec_crypto_vncipher((uint64x2_p)state, (uint64x2_p)key); +#elif defined(__GNUC__) + return (T1)__builtin_crypto_vncipher((uint64x2_p)state, (uint64x2_p)key); +#else + CRYPTOPP_ASSERT(0); +#endif +} + +/// \brief Final round of AES decryption +/// \tparam T1 vector type +/// \tparam T2 vector type +/// \param state the state vector +/// \param key the subkey vector +/// \details VecDecryptLast() performs the final round of AES decryption +/// of state using subkey key. The return vector is the same type as state. +/// \details VecDecryptLast() is available on POWER8 and above. +/// \par Wraps +/// __vncipherlast, __builtin_altivec_crypto_vncipherlast, __builtin_crypto_vncipherlast +/// \since GCC and XLC since Crypto++ 6.0, LLVM Clang since Crypto++ 8.0 +template +inline T1 VecDecryptLast(const T1 state, const T2 key) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return (T1)__vncipherlast((uint8x16_p)state, (uint8x16_p)key); +#elif defined(__clang__) + return (T1)__builtin_altivec_crypto_vncipherlast((uint64x2_p)state, (uint64x2_p)key); +#elif defined(__GNUC__) + return (T1)__builtin_crypto_vncipherlast((uint64x2_p)state, (uint64x2_p)key); +#else + CRYPTOPP_ASSERT(0); +#endif +} + +//@} + +/// \name SHA DIGESTS +//@{ + +/// \brief SHA256 Sigma functions +/// \tparam func function +/// \tparam fmask function mask +/// \tparam T vector type +/// \param data the block to transform +/// \details VecSHA256() selects sigma0, sigma1, Sigma0, Sigma1 based on +/// func and fmask. The return vector is the same type as data. +/// \details VecSHA256() is available on POWER8 and above. +/// \par Wraps +/// __vshasigmaw, __builtin_altivec_crypto_vshasigmaw, __builtin_crypto_vshasigmaw +/// \since GCC and XLC since Crypto++ 6.0, LLVM Clang since Crypto++ 8.0 +template +inline T VecSHA256(const T data) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return (T)__vshasigmaw((uint32x4_p)data, func, fmask); +#elif defined(__clang__) + return (T)__builtin_altivec_crypto_vshasigmaw((uint32x4_p)data, func, fmask); +#elif defined(__GNUC__) + return (T)__builtin_crypto_vshasigmaw((uint32x4_p)data, func, fmask); +#else + CRYPTOPP_ASSERT(0); +#endif +} + +/// \brief SHA512 Sigma functions +/// \tparam func function +/// \tparam fmask function mask +/// \tparam T vector type +/// \param data the block to transform +/// \details VecSHA512() selects sigma0, sigma1, Sigma0, Sigma1 based on +/// func and fmask. The return vector is the same type as data. +/// \details VecSHA512() is available on POWER8 and above. +/// \par Wraps +/// __vshasigmad, __builtin_altivec_crypto_vshasigmad, __builtin_crypto_vshasigmad +/// \since GCC and XLC since Crypto++ 6.0, LLVM Clang since Crypto++ 8.0 +template +inline T VecSHA512(const T data) +{ +#if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__)) + return (T)__vshasigmad((uint64x2_p)data, func, fmask); +#elif defined(__clang__) + return (T)__builtin_altivec_crypto_vshasigmad((uint64x2_p)data, func, fmask); +#elif defined(__GNUC__) + return (T)__builtin_crypto_vshasigmad((uint64x2_p)data, func, fmask); +#else + CRYPTOPP_ASSERT(0); +#endif +} + +//@} + +#endif // __CRYPTO__ + +#endif // _ALTIVEC_ + +NAMESPACE_END + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#endif // CRYPTOPP_PPC_CRYPTO_H diff --git a/external/ours/library/crypto/src/shared/original/pssr.cpp b/external/ours/library/crypto/src/shared/original/pssr.cpp new file mode 100755 index 000000000..753797ba4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pssr.cpp @@ -0,0 +1,163 @@ +// pssr.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "pssr.h" +#include "emsa2.h" +#include "ripemd.h" +#include "whrlpool.h" +#include "misc.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +template<> const byte EMSA2HashId::id = 0x31; +template<> const byte EMSA2HashId::id = 0x32; +template<> const byte EMSA2HashId::id = 0x37; + +#ifndef CRYPTOPP_IMPORTS + +size_t PSSR_MEM_Base::MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const +{ + size_t saltLen = SaltLen(digestLength); + size_t minPadLen = MinPadLen(digestLength); + return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength); +} + +size_t PSSR_MEM_Base::MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const +{ + if (AllowRecovery()) + return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8; + return 0; +} + +bool PSSR_MEM_Base::IsProbabilistic() const +{ + return SaltLen(1) > 0; +} + +bool PSSR_MEM_Base::AllowNonrecoverablePart() const +{ + return true; +} + +bool PSSR_MEM_Base::RecoverablePartFirst() const +{ + return false; +} + +void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength); + CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier); + CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + const size_t u = hashIdentifier.second + 1; + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t saltSize = SaltLen(digestSize); + byte *const h = representative + representativeByteLength - u - digestSize; + + SecByteBlock digest(digestSize), salt(saltSize); + hash.Final(digest); + rng.GenerateBlock(salt, saltSize); + + // compute H = hash of M' + byte c[8]; + PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); + PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); + hash.Update(c, 8); + hash.Update(recoverableMessage, recoverableMessageLength); + hash.Update(digest, digestSize); + hash.Update(salt, saltSize); + hash.Final(h); + + // compute representative + GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false); + byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1; + xorStart[0] ^= 1; + if (recoverableMessage && recoverableMessageLength) + xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength); + xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size()); + if (hashIdentifier.first && hashIdentifier.second) + { + memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second); + representative[representativeByteLength - 1] = 0xcc; + } + else + { + representative[representativeByteLength - 1] = 0xbc; + } + if (representativeBitLength % 8 != 0) + representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); +} + +DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength, + byte *recoverableMessage) const +{ + CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier); + CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + const size_t u = hashIdentifier.second + 1; + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t saltSize = SaltLen(digestSize); + const byte *const h = representative + representativeByteLength - u - digestSize; + + SecByteBlock digest(digestSize); + hash.Final(digest); + + DecodingResult result(0); + bool &valid = result.isValidCoding; + size_t &recoverableMessageLength = result.messageLength; + + valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid; + + if (hashIdentifier.first && hashIdentifier.second) + valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid; + + GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize); + if (representativeBitLength % 8 != 0) + representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); + + // extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt + byte *salt = representative + representativeByteLength - u - digestSize - saltSize; + byte *M = FindIfNot(representative, salt-1, byte(0)); + recoverableMessageLength = salt-M-1; + if (*M == 0x01 && + (size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) && + recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize)) + { + if (recoverableMessage) + memcpy(recoverableMessage, M+1, recoverableMessageLength); + } + else + { + recoverableMessageLength = 0; + valid = false; + } + + // verify H = hash of M' + byte c[8]; + PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); + PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); + hash.Update(c, 8); + hash.Update(recoverableMessage, recoverableMessageLength); + hash.Update(digest, digestSize); + hash.Update(salt, saltSize); + valid = hash.Verify(h) && valid; + + if (!AllowRecovery() && valid && recoverableMessageLength != 0) + {throw NotImplemented("PSSR_MEM: message recovery disabled");} + + return result; +} + +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/pssr.h b/external/ours/library/crypto/src/shared/original/pssr.h new file mode 100755 index 000000000..e192aaf3a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pssr.h @@ -0,0 +1,105 @@ +// pssr.h - originally written and placed in the public domain by Wei Dai + +/// \file pssr.h +/// \brief Classes for probabilistic signature schemes +/// \since Crypto++ 2.1 + +#ifndef CRYPTOPP_PSSR_H +#define CRYPTOPP_PSSR_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "emsa2.h" + +#ifdef CRYPTOPP_IS_DLL +#include "sha.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief PSSR Message Encoding Method interface +/// \since Crypto++ 2.1 +class CRYPTOPP_DLL PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncodingMethod +{ +public: + virtual ~PSSR_MEM_Base() {} + +protected: + virtual bool AllowRecovery() const =0; + virtual size_t SaltLen(size_t hashLen) const =0; + virtual size_t MinPadLen(size_t hashLen) const =0; + virtual const MaskGeneratingFunction & GetMGF() const =0; + +private: + size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const; + size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const; + bool IsProbabilistic() const; + bool AllowNonrecoverablePart() const; + bool RecoverablePartFirst() const; + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; + DecodingResult RecoverMessageFromRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength, + byte *recoverableMessage) const; +}; + +/// \brief PSSR Message Encoding Method with Hash Identifier +/// \tparam USE_HASH_ID flag indicating whether the HashId is used +/// \since Crypto++ 2.1 +template class PSSR_MEM_BaseWithHashId; + +/// \brief PSSR Message Encoding Method with Hash Identifier +/// \details If USE_HASH_ID is true, then EMSA2HashIdLookup is used for the base class +template<> class PSSR_MEM_BaseWithHashId : public EMSA2HashIdLookup {}; + +/// \brief PSSR Message Encoding Method without Hash Identifier +/// \details If USE_HASH_ID is false, then PSSR_MEM_Base is used for the base class +/// \since Crypto++ 2.1 +template<> class PSSR_MEM_BaseWithHashId : public PSSR_MEM_Base {}; + +/// \brief PSSR Message Encoding Method +/// \tparam ALLOW_RECOVERY flag indicating whether the scheme provides message recovery +/// \tparam MGF mask generation function +/// \tparam SALT_LEN length of the salt +/// \tparam MIN_PAD_LEN minimum length of the pad +/// \tparam USE_HASH_ID flag indicating whether the HashId is used +/// \details If ALLOW_RECOVERY is true, the signature scheme provides message recovery. If +/// ALLOW_RECOVERY is false, the signature scheme is appendix, and the message must be +/// provided during verification. +/// \since Crypto++ 2.1 +template +class PSSR_MEM : public PSSR_MEM_BaseWithHashId +{ + virtual bool AllowRecovery() const {return ALLOW_RECOVERY;} + virtual size_t SaltLen(size_t hashLen) const {return SALT_LEN < 0 ? hashLen : SALT_LEN;} + virtual size_t MinPadLen(size_t hashLen) const {return MIN_PAD_LEN < 0 ? hashLen : MIN_PAD_LEN;} + virtual const MaskGeneratingFunction & GetMGF() const {static MGF mgf; return mgf;} + +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(ALLOW_RECOVERY ? "PSSR-" : "PSS-") + MGF::StaticAlgorithmName();} +}; + +/// \brief Probabilistic Signature Scheme with Recovery +/// \details Signature Schemes with Recovery encode the message with the signature. +/// \sa PSSR-MGF1 +/// \since Crypto++ 2.1 +struct PSSR : public SignatureStandard +{ + typedef PSSR_MEM SignatureMessageEncodingMethod; +}; + +/// \brief Probabilistic Signature Scheme with Appendix +/// \details Signature Schemes with Appendix require the message to be provided during verification. +/// \sa PSS-MGF1 +/// \since Crypto++ 2.1 +struct PSS : public SignatureStandard +{ + typedef PSSR_MEM SignatureMessageEncodingMethod; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/pubkey.cpp b/external/ours/library/crypto/src/shared/original/pubkey.cpp new file mode 100755 index 000000000..3a6009063 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pubkey.cpp @@ -0,0 +1,170 @@ +// pubkey.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "pubkey.h" +#include "integer.h" +#include "filters.h" + +NAMESPACE_BEGIN(CryptoPP) + +void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart) +{ + ArraySink *sink; + HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength)); + word32 counter = counterStart; + while (sink->AvailableSize() > 0) + { + filter.Put(input, inputLength); + filter.PutWord32(counter++); + filter.Put(derivationParams, derivationParamsLength); + filter.MessageEnd(); + } +} + +bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength)); + ComputeMessageRepresentative(NullRNG(), NULLPTR, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength); + return VerifyBufsEqual(representative, computedRepresentative, computedRepresentative.size()); +} + +bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + SecByteBlock recoveredMessage(MaxRecoverableLength(representativeBitLength, hashIdentifier.second, hash.DigestSize())); + DecodingResult result = RecoverMessageFromRepresentative( + hash, hashIdentifier, messageEmpty, representative, representativeBitLength, recoveredMessage); + return result.isValidCoding && result.messageLength == 0; +} + +void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + size_t maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize()); + + if (maxRecoverableLength == 0) + {throw NotImplemented("TF_SignerBase: this algorithm does not support message recovery or the key is too short");} + if (recoverableMessageLength > maxRecoverableLength) + throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm"); + + ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); + encoding.ProcessRecoverableMessage( + ma.AccessHash(), + recoverableMessage, recoverableMessageLength, + NULLPTR, 0, ma.m_semisignature); +} + +size_t TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const +{ + CRYPTOPP_UNUSED(restart); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + SecByteBlock representative(MessageRepresentativeLength()); + encoding.ComputeMessageRepresentative(rng, + ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), id, ma.m_empty, + representative, MessageRepresentativeBitLength()); + ma.m_empty = true; + + Integer r(representative, representative.size()); + size_t signatureLength = SignatureLength(); + GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength); + return signatureLength; +} + +void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + ma.m_representative.New(MessageRepresentativeLength()); + Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength)); + if (x.BitCount() > MessageRepresentativeBitLength()) + x = Integer::Zero(); // don't return false here to prevent timing attack + x.Encode(ma.m_representative, ma.m_representative.size()); +} + +bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + bool result = encoding.VerifyMessageRepresentative( + ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength()); + ma.m_empty = true; + return result; +} + +DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + DecodingResult result = encoding.RecoverMessageFromRepresentative( + ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage); + ma.m_empty = true; + return result; +} + +DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const +{ + if (ciphertextLength != FixedCiphertextLength()) + throw InvalidArgument(AlgorithmName() + ": ciphertext length of " + IntToString(ciphertextLength) + " doesn't match the required length of " + IntToString(FixedCiphertextLength()) + " for this key"); + + SecByteBlock paddedBlock(PaddedBlockByteLength()); + Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, ciphertextLength)); + if (x.ByteCount() > paddedBlock.size()) + x = Integer::Zero(); // don't return false here to prevent timing attack + x.Encode(paddedBlock, paddedBlock.size()); + return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters); +} + +void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const +{ + if (plaintextLength > FixedMaxPlaintextLength()) + { + if (FixedMaxPlaintextLength() < 1) + throw InvalidArgument(AlgorithmName() + ": this key is too short to encrypt any messages"); + else + throw InvalidArgument(AlgorithmName() + ": message length of " + IntToString(plaintextLength) + " exceeds the maximum of " + IntToString(FixedMaxPlaintextLength()) + " for this public key"); + } + + SecByteBlock paddedBlock(PaddedBlockByteLength()); + GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters); + GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength()); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/pubkey.h b/external/ours/library/crypto/src/shared/original/pubkey.h new file mode 100755 index 000000000..efa607b68 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pubkey.h @@ -0,0 +1,2378 @@ +// pubkey.h - originally written and placed in the public domain by Wei Dai + +/// \file pubkey.h +/// \brief This file contains helper classes/functions for implementing public key algorithms. +/// \details The class hierachies in this header file tend to look like this: +/// +///
+///                   x1
+///                  +--+
+///                  |  |
+///                 y1  z1
+///                  |  |
+///             x2  x2
+///                  |  |
+///                 y2  z2
+///                  |  |
+///             x3  x3
+///                  |  |
+///                 y3  z3
+/// 
+/// +///
    +///
  • x1, y1, z1 are abstract interface classes defined in cryptlib.h +///
  • x2, y2, z2 are implementations of the interfaces using "abstract policies", which +/// are pure virtual functions that should return interfaces to interchangeable algorithms. +/// These classes have Base suffixes. +///
  • x3, y3, z3 hold actual algorithms and implement those virtual functions. +/// These classes have Impl suffixes. +///
+/// +/// \details The TF_ prefix means an implementation using trapdoor functions on integers. +/// \details The DL_ prefix means an implementation using group operations in groups where discrete log is hard. + +#ifndef CRYPTOPP_PUBKEY_H +#define CRYPTOPP_PUBKEY_H + +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4702) +#endif + +#include "cryptlib.h" +#include "integer.h" +#include "algebra.h" +#include "modarith.h" +#include "filters.h" +#include "eprecomp.h" +#include "fips140.h" +#include "argnames.h" +#include "smartptr.h" +#include "stdcpp.h" + +#if defined(__SUNPRO_CC) +# define MAYBE_RETURN(x) return x +#else +# define MAYBE_RETURN(x) CRYPTOPP_UNUSED(x) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Provides range for plaintext and ciphertext lengths +/// \details A trapdoor function is a function that is easy to compute in one direction, +/// but difficult to compute in the opposite direction without special knowledge. +/// The special knowledge is usually the private key. +/// \details Trapdoor functions only handle messages of a limited length or size. +/// MaxPreimage is the plaintext's maximum length, and MaxImage is the +/// ciphertext's maximum length. +/// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(), +/// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds +{ +public: + virtual ~TrapdoorFunctionBounds() {} + + /// \brief Returns the maximum size of a message before the trapdoor function is applied + /// \return the maximum size of a message before the trapdoor function is applied + /// \details Derived classes must implement PreimageBound(). + virtual Integer PreimageBound() const =0; + /// \brief Returns the maximum size of a message after the trapdoor function is applied + /// \return the maximum size of a message after the trapdoor function is applied + /// \details Derived classes must implement ImageBound(). + virtual Integer ImageBound() const =0; + /// \brief Returns the maximum size of a message before the trapdoor function is applied bound to a public key + /// \return the maximum size of a message before the trapdoor function is applied bound to a public key + /// \details The default implementation returns PreimageBound() - 1. + virtual Integer MaxPreimage() const {return --PreimageBound();} + /// \brief Returns the maximum size of a message after the trapdoor function is applied bound to a public key + /// \return the maximum size of a message after the trapdoor function is applied bound to a public key + /// \details The default implementation returns ImageBound() - 1. + virtual Integer MaxImage() const {return --ImageBound();} +}; + +/// \brief Applies the trapdoor function, using random data if required +/// \details ApplyFunction() is the foundation for encrypting a message under a public key. +/// Derived classes will override it at some point. +/// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(), +/// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds +{ +public: + virtual ~RandomizedTrapdoorFunction() {} + + /// \brief Applies the trapdoor function, using random data if required + /// \param rng a RandomNumberGenerator derived class + /// \param x the message on which the encryption function is applied + /// \return the message x encrypted under the public key + /// \details ApplyRandomizedFunction is a generalization of encryption under a public key + /// cryptosystem. The RandomNumberGenerator may (or may not) be required. + /// Derived classes must implement it. + virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0; + + /// \brief Determines if the encryption algorithm is randomized + /// \return true if the encryption algorithm is randomized, false otherwise + /// \details If IsRandomized() returns false, then NullRNG() can be used. + virtual bool IsRandomized() const {return true;} +}; + +/// \brief Applies the trapdoor function +/// \details ApplyFunction() is the foundation for encrypting a message under a public key. +/// Derived classes will override it at some point. +/// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(), +/// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction +{ +public: + virtual ~TrapdoorFunction() {} + + /// \brief Applies the trapdoor function + /// \param rng a RandomNumberGenerator derived class + /// \param x the message on which the encryption function is applied + /// \details ApplyRandomizedFunction is a generalization of encryption under a public key + /// cryptosystem. The RandomNumberGenerator may (or may not) be required. + /// \details Internally, ApplyRandomizedFunction() calls ApplyFunction() \a + /// without the RandomNumberGenerator. + Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const + {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);} + bool IsRandomized() const {return false;} + + /// \brief Applies the trapdoor + /// \param x the message on which the encryption function is applied + /// \return the message x encrypted under the public key + /// \details ApplyFunction is a generalization of encryption under a public key + /// cryptosystem. Derived classes must implement it. + virtual Integer ApplyFunction(const Integer &x) const =0; +}; + +/// \brief Applies the inverse of the trapdoor function, using random data if required +/// \details CalculateInverse() is the foundation for decrypting a message under a private key +/// in a public key cryptosystem. Derived classes will override it at some point. +/// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(), +/// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse +{ +public: + virtual ~RandomizedTrapdoorFunctionInverse() {} + + /// \brief Applies the inverse of the trapdoor function, using random data if required + /// \param rng a RandomNumberGenerator derived class + /// \param x the message on which the decryption function is applied + /// \return the message x decrypted under the private key + /// \details CalculateRandomizedInverse is a generalization of decryption using the private key + /// The RandomNumberGenerator may (or may not) be required. Derived classes must implement it. + virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0; + + /// \brief Determines if the decryption algorithm is randomized + /// \return true if the decryption algorithm is randomized, false otherwise + /// \details If IsRandomized() returns false, then NullRNG() can be used. + virtual bool IsRandomized() const {return true;} +}; + +/// \brief Applies the inverse of the trapdoor function +/// \details CalculateInverse() is the foundation for decrypting a message under a private key +/// in a public key cryptosystem. Derived classes will override it at some point. +/// \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(), +/// RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse() +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse +{ +public: + virtual ~TrapdoorFunctionInverse() {} + + /// \brief Applies the inverse of the trapdoor function + /// \param rng a RandomNumberGenerator derived class + /// \param x the message on which the decryption function is applied + /// \return the message x decrypted under the private key + /// \details CalculateRandomizedInverse is a generalization of decryption using the private key + /// \details Internally, CalculateRandomizedInverse() calls CalculateInverse() \a + /// without the RandomNumberGenerator. + Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const + {return CalculateInverse(rng, x);} + + /// \brief Determines if the decryption algorithm is randomized + /// \return true if the decryption algorithm is randomized, false otherwise + /// \details If IsRandomized() returns false, then NullRNG() can be used. + bool IsRandomized() const {return false;} + + /// \brief Calculates the inverse of an element + /// \param rng a RandomNumberGenerator derived class + /// \param x the element + /// \return the inverse of the element in the group + virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0; +}; + +// ******************************************************** + +/// \brief Message encoding method for public key encryption +class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod +{ +public: + virtual ~PK_EncryptionMessageEncodingMethod() {} + + virtual bool ParameterSupported(const char *name) const + {CRYPTOPP_UNUSED(name); return false;} + + /// max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus) + virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0; + + virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs ¶meters) const =0; + + virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs ¶meters) const =0; +}; + +// ******************************************************** + +/// \brief The base for trapdoor based cryptosystems +/// \tparam TFI trapdoor function interface derived class +/// \tparam MEI message encoding interface derived class +template +class CRYPTOPP_NO_VTABLE TF_Base +{ +protected: + virtual ~TF_Base() {} + + virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0; + + typedef TFI TrapdoorFunctionInterface; + virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0; + + typedef MEI MessageEncodingInterface; + virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0; +}; + +// ******************************************************** + +/// \brief Public key trapdoor function default implementation +/// \tparam BASE public key cryptosystem with a fixed length +template +class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE +{ +public: + virtual ~PK_FixedLengthCryptoSystemImpl() {} + + size_t MaxPlaintextLength(size_t ciphertextLength) const + {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;} + size_t CiphertextLength(size_t plaintextLength) const + {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;} + + virtual size_t FixedMaxPlaintextLength() const =0; + virtual size_t FixedCiphertextLength() const =0; +}; + +/// \brief Trapdoor function cryptosystem base class +/// \tparam INTFACE public key cryptosystem base interface +/// \tparam BASE public key cryptosystem implementation base +template +class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl, protected BASE +{ +public: + virtual ~TF_CryptoSystemBase() {} + + bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);} + size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());} + size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();} + +protected: + size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());} + // Coverity finding on potential overflow/underflow. + size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);} +}; + +/// \brief Trapdoor function cryptosystems decryption base class +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase > +{ +public: + virtual ~TF_DecryptorBase() {} + + DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const; +}; + +/// \brief Trapdoor function cryptosystems encryption base class +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase > +{ +public: + virtual ~TF_EncryptorBase() {} + + void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const; +}; + +// ******************************************************** + +// Typedef change due to Clang, http://github.com/weidai11/cryptopp/issues/300 +typedef std::pair HashIdentifier; + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details PK_SignatureMessageEncodingMethod provides interfaces for message +/// encoding method for public key signature schemes. The methods support both +/// trapdoor functions (TF_*) and discrete logarithm (DL_*) +/// based schemes. +class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod +{ +public: + virtual ~PK_SignatureMessageEncodingMethod() {} + + virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const + {CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;} + virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const + {CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;} + + /// \brief Determines whether an encoding method requires a random number generator + /// \return true if the encoding method requires a RandomNumberGenerator() + /// \details if IsProbabilistic() returns false, then NullRNG() can be passed to functions that take + /// RandomNumberGenerator(). + /// \sa Bellare and RogawayPSS: + /// Provably Secure Encoding Method for Digital Signatures + bool IsProbabilistic() const + {return true;} + bool AllowNonrecoverablePart() const + {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + virtual bool RecoverablePartFirst() const + {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + + // for verification, DL + virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const + {CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength);} + + // for signature + virtual void ProcessRecoverableMessage(HashTransformation &hash, + const byte *recoverableMessage, size_t recoverableMessageLength, + const byte *presignature, size_t presignatureLength, + SecByteBlock &semisignature) const + { + CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength); + CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); CRYPTOPP_UNUSED(semisignature); + if (RecoverablePartFirst()) + CRYPTOPP_ASSERT(!"ProcessRecoverableMessage() not implemented"); + } + + virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const =0; + + virtual bool VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const =0; + + virtual DecodingResult RecoverMessageFromRepresentative( // for TF + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength, + byte *recoveredMessage) const + {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty); + CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(recoveredMessage); + throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + + virtual DecodingResult RecoverMessageFromSemisignature( // for DL + HashTransformation &hash, HashIdentifier hashIdentifier, + const byte *presignature, size_t presignatureLength, + const byte *semisignature, size_t semisignatureLength, + byte *recoveredMessage) const + {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); + CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength); CRYPTOPP_UNUSED(recoveredMessage); + throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + + // VC60 workaround + struct HashIdentifierLookup + { + template struct HashIdentifierLookup2 + { + static HashIdentifier CRYPTOPP_API Lookup() + { + return HashIdentifier(static_cast(NULLPTR), 0); + } + }; + }; +}; + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details PK_DeterministicSignatureMessageEncodingMethod provides interfaces +/// for message encoding method for public key signature schemes. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod +{ +public: + bool VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details PK_RecoverableSignatureMessageEncodingMethod provides interfaces +/// for message encoding method for public key signature schemes. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod +{ +public: + bool VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details DL_SignatureMessageEncodingMethod_DSA provides interfaces +/// for message encoding method for DSA. +class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details DL_SignatureMessageEncodingMethod_NR provides interfaces +/// for message encoding method for Nyberg-Rueppel. +class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +#if 0 +/// \brief Interface for message encoding method for public key signature schemes. +/// \details DL_SignatureMessageEncodingMethod_SM2 provides interfaces +/// for message encoding method for SM2. +class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_SM2 : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; +#endif + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details PK_MessageAccumulatorBase provides interfaces +/// for message encoding method. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator +{ +public: + PK_MessageAccumulatorBase() : m_empty(true) {} + + virtual HashTransformation & AccessHash() =0; + + void Update(const byte *input, size_t length) + { + AccessHash().Update(input, length); + m_empty = m_empty && length == 0; + } + + SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature; + Integer m_k, m_s; + bool m_empty; +}; + +/// \brief Interface for message encoding method for public key signature schemes. +/// \details PK_MessageAccumulatorBase provides interfaces +/// for message encoding method. +template +class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder +{ +public: + HashTransformation & AccessHash() {return this->m_object;} +}; + +/// \brief Trapdoor Function (TF) Signature Scheme base class +/// \tparam INTFACE interface +/// \tparam BASE base class +template +class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTFACE, protected BASE +{ +public: + virtual ~TF_SignatureSchemeBase() {} + + size_t SignatureLength() const + {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();} + size_t MaxRecoverableLength() const + {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());} + size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const + {CRYPTOPP_UNUSED(signatureLength); return this->MaxRecoverableLength();} + + bool IsProbabilistic() const + {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();} + bool AllowNonrecoverablePart() const + {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();} + bool RecoverablePartFirst() const + {return this->GetMessageEncodingInterface().RecoverablePartFirst();} + +protected: + size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} + // Coverity finding on potential overflow/underflow. + size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);} + virtual HashIdentifier GetHashIdentifier() const =0; + virtual size_t GetDigestSize() const =0; +}; + +/// \brief Trapdoor Function (TF) Signer base class +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase > +{ +public: + virtual ~TF_SignerBase() {} + + void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const; + size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const; +}; + +/// \brief Trapdoor Function (TF) Verifier base class +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase > +{ +public: + virtual ~TF_VerifierBase() {} + + void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const; + bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const; + DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const; +}; + +// ******************************************************** + +/// \brief Trapdoor Function (TF) scheme options +/// \tparam T1 algorithm info class +/// \tparam T2 keys class with public and private key +/// \tparam T3 message encoding class +template +struct TF_CryptoSchemeOptions +{ + typedef T1 AlgorithmInfo; + typedef T2 Keys; + typedef typename Keys::PrivateKey PrivateKey; + typedef typename Keys::PublicKey PublicKey; + typedef T3 MessageEncodingMethod; +}; + +/// \brief Trapdoor Function (TF) signature scheme options +/// \tparam T1 algorithm info class +/// \tparam T2 keys class with public and private key +/// \tparam T3 message encoding class +/// \tparam T4 HashTransformation class +template +struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions +{ + typedef T4 HashFunction; +}; + +/// \brief Trapdoor Function (TF) base implementation +/// \tparam BASE base class +/// \tparam SCHEME_OPTIONS scheme options class +/// \tparam KEY_CLASS key class +template +class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl +{ +public: + typedef SCHEME_OPTIONS SchemeOptions; + typedef KEY_CLASS KeyClass; + + virtual ~TF_ObjectImplBase() {} + + PublicKey & AccessPublicKey() {return AccessKey();} + const PublicKey & GetPublicKey() const {return GetKey();} + + PrivateKey & AccessPrivateKey() {return AccessKey();} + const PrivateKey & GetPrivateKey() const {return GetKey();} + + virtual const KeyClass & GetKey() const =0; + virtual KeyClass & AccessKey() =0; + + const KeyClass & GetTrapdoorFunction() const {return GetKey();} + + PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const + { + CRYPTOPP_UNUSED(rng); + return new PK_MessageAccumulatorImpl; + } + PK_MessageAccumulator * NewVerificationAccumulator() const + { + return new PK_MessageAccumulatorImpl; + } + +protected: + const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const + {return Singleton().Ref();} + const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const + {return GetKey();} + const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const + {return GetKey();} + + // for signature scheme + HashIdentifier GetHashIdentifier() const + { + typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2 L; + return L::Lookup(); + } + size_t GetDigestSize() const + { + typedef typename SchemeOptions::HashFunction H; + return H::DIGESTSIZE; + } +}; + +/// \brief Trapdoor Function (TF) signature with external reference +/// \tparam BASE base class +/// \tparam SCHEME_OPTIONS scheme options class +/// \tparam KEY key class +/// \details TF_ObjectImplExtRef() holds a pointer to an external key structure +template +class TF_ObjectImplExtRef : public TF_ObjectImplBase +{ +public: + virtual ~TF_ObjectImplExtRef() {} + + TF_ObjectImplExtRef(const KEY *pKey = NULLPTR) : m_pKey(pKey) {} + void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;} + + const KEY & GetKey() const {return *m_pKey;} + KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");} + +private: + const KEY * m_pKey; +}; + +/// \brief Trapdoor Function (TF) signature scheme options +/// \tparam BASE base class +/// \tparam SCHEME_OPTIONS scheme options class +/// \tparam KEY_CLASS key class +/// \details TF_ObjectImpl() holds a reference to a trapdoor function +template +class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase +{ +public: + typedef KEY_CLASS KeyClass; + + virtual ~TF_ObjectImpl() {} + + const KeyClass & GetKey() const {return m_trapdoorFunction;} + KeyClass & AccessKey() {return m_trapdoorFunction;} + +private: + KeyClass m_trapdoorFunction; +}; + +/// \brief Trapdoor Function (TF) decryptor options +/// \tparam SCHEME_OPTIONS scheme options class +template +class TF_DecryptorImpl : public TF_ObjectImpl +{ +}; + +/// \brief Trapdoor Function (TF) encryptor options +/// \tparam SCHEME_OPTIONS scheme options class +template +class TF_EncryptorImpl : public TF_ObjectImpl +{ +}; + +/// \brief Trapdoor Function (TF) encryptor options +/// \tparam SCHEME_OPTIONS scheme options class +template +class TF_SignerImpl : public TF_ObjectImpl +{ +}; + +/// \brief Trapdoor Function (TF) encryptor options +/// \tparam SCHEME_OPTIONS scheme options class +template +class TF_VerifierImpl : public TF_ObjectImpl +{ +}; + +// ******************************************************** + +/// \brief Mask generation function interface +/// \sa P1363_KDF2, P1363_MGF1 +/// \since Crypto++ 2.0 +class CRYPTOPP_NO_VTABLE MaskGeneratingFunction +{ +public: + virtual ~MaskGeneratingFunction() {} + + /// \brief Generate and apply mask + /// \param hash HashTransformation derived class + /// \param output the destination byte array + /// \param outputLength the size of the destination byte array + /// \param input the message to hash + /// \param inputLength the size of the message + /// \param mask flag indicating whether to apply the mask + virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0; +}; + +/// \fn P1363_MGF1KDF2_Common +/// \brief P1363 mask generation function +/// \param hash HashTransformation derived class +/// \param output the destination byte array +/// \param outputLength the size of the destination byte array +/// \param input the message to hash +/// \param inputLength the size of the message +/// \param derivationParams additional derivation parameters +/// \param derivationParamsLength the size of the additional derivation parameters +/// \param mask flag indicating whether to apply the mask +/// \param counterStart starting counter value used in generation function +CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart); + +/// \brief P1363 mask generation function +/// \sa P1363_KDF2, MaskGeneratingFunction +/// \since Crypto++ 2.0 +class P1363_MGF1 : public MaskGeneratingFunction +{ +public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "MGF1";} + + /// \brief P1363 mask generation function + /// \param hash HashTransformation derived class + /// \param output the destination byte array + /// \param outputLength the size of the destination byte array + /// \param input the message to hash + /// \param inputLength the size of the message + /// \param mask flag indicating whether to apply the mask + void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const + { + P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULLPTR, 0, mask, 0); + } +}; + +// ******************************************************** + +/// \brief P1363 key derivation function +/// \tparam H hash function used in the derivation +/// \sa P1363_MGF1, KeyDerivationFunction, P1363_KDF2 +/// on the Crypto++ wiki +/// \since Crypto++ 2.0 +template +class P1363_KDF2 +{ +public: + /// \brief P1363 key derivation function + /// \param output the destination byte array + /// \param outputLength the size of the destination byte array + /// \param input the message to hash + /// \param inputLength the size of the message + /// \param derivationParams additional derivation parameters + /// \param derivationParamsLength the size of the additional derivation parameters + /// \details DeriveKey calls P1363_MGF1KDF2_Common + static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength) + { + H h; + P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1); + } +}; + +// ******************************************************** + +/// \brief Exception thrown when an invalid group element is encountered +/// \details Thrown by DecodeElement and AgreeWithStaticPrivateKey +class DL_BadElement : public InvalidDataFormat +{ +public: + DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {} +}; + +/// \brief Interface for Discrete Log (DL) group parameters +/// \tparam T element in the group +/// \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point" +template +class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters +{ + typedef DL_GroupParameters ThisClass; + +public: + typedef T Element; + + virtual ~DL_GroupParameters() {} + + DL_GroupParameters() : m_validationLevel(0) {} + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + if (!GetBasePrecomputation().IsInitialized()) + return false; + + if (m_validationLevel > level) + return true; + + CRYPTOPP_ASSERT(ValidateGroup(rng, level)); + bool pass = ValidateGroup(rng, level); + CRYPTOPP_ASSERT(ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation())); + pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()); + + m_validationLevel = pass ? level+1 : 0; + + return pass; + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) + ; + } + + /// \brief Determines whether the object supports precomputation + /// \return true if the object supports precomputation, false otherwise + /// \sa Precompute() + bool SupportsPrecomputation() const {return true;} + + /// \brief Perform precomputation + /// \param precomputationStorage the suggested number of objects for the precompute table + /// \throw NotImplemented + /// \details The exact semantics of Precompute() varies, but it typically means calculate + /// a table of n objects that can be used later to speed up computation. + /// \details If a derived class does not override Precompute(), then the base class throws + /// NotImplemented. + /// \sa SupportsPrecomputation(), LoadPrecomputation(), SavePrecomputation() + void Precompute(unsigned int precomputationStorage=16) + { + AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage); + } + + /// \brief Retrieve previously saved precomputation + /// \param storedPrecomputation BufferedTransformation with the saved precomputation + /// \throw NotImplemented + /// \sa SupportsPrecomputation(), Precompute() + void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + { + AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation); + m_validationLevel = 0; + } + + /// \brief Save precomputation for later use + /// \param storedPrecomputation BufferedTransformation to write the precomputation + /// \throw NotImplemented + /// \sa SupportsPrecomputation(), Precompute() + void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + { + GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation); + } + + /// \brief Retrieves the subgroup generator + /// \return the subgroup generator + /// \details The subgroup generator is retrieved from the base precomputation + virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());} + + /// \brief Sets the subgroup generator + /// \param base the new subgroup generator + /// \details The subgroup generator is set in the base precomputation + virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);} + + /// \brief Exponentiates the base + /// \return the element after exponentiation + /// \details ExponentiateBase() calls GetBasePrecomputation() and then exponentiates. + virtual Element ExponentiateBase(const Integer &exponent) const + { + return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent); + } + + /// \brief Exponentiates an element + /// \param base the base elemenet + /// \param exponent the exponent to raise the base + /// \return the result of the exponentiation + /// \details Internally, ExponentiateElement() calls SimultaneousExponentiate(). + virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const + { + Element result; + SimultaneousExponentiate(&result, base, &exponent, 1); + return result; + } + + /// \brief Retrieves the group precomputation + /// \return a const reference to the group precomputation + virtual const DL_GroupPrecomputation & GetGroupPrecomputation() const =0; + + /// \brief Retrieves the group precomputation + /// \return a const reference to the group precomputation using a fixed base + virtual const DL_FixedBasePrecomputation & GetBasePrecomputation() const =0; + + /// \brief Retrieves the group precomputation + /// \return a non-const reference to the group precomputation using a fixed base + virtual DL_FixedBasePrecomputation & AccessBasePrecomputation() =0; + + /// \brief Retrieves the subgroup order + /// \return the order of subgroup generated by the base element + virtual const Integer & GetSubgroupOrder() const =0; + + /// \brief Retrieves the maximum exponent for the group + /// \return the maximum exponent for the group + virtual Integer GetMaxExponent() const =0; + + /// \brief Retrieves the order of the group + /// \return the order of the group + /// \details Either GetGroupOrder() or GetCofactor() must be overridden in a derived class. + virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} + + /// \brief Retrieves the cofactor + /// \return the cofactor + /// \details Either GetGroupOrder() or GetCofactor() must be overridden in a derived class. + virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();} + + /// \brief Retrieves the encoded element's size + /// \param reversible flag indicating the encoding format + /// \return encoded element's size, in bytes + /// \details The format of the encoded element varies by the underlying type of the element and the + /// reversible flag. GetEncodedElementSize() must be implemented in a derived class. + /// \sa GetEncodedElementSize(), EncodeElement(), DecodeElement() + virtual unsigned int GetEncodedElementSize(bool reversible) const =0; + + /// \brief Encodes the element + /// \param reversible flag indicating the encoding format + /// \param element reference to the element to encode + /// \param encoded destination byte array for the encoded element + /// \details EncodeElement() must be implemented in a derived class. + /// \pre COUNTOF(encoded) == GetEncodedElementSize() + virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0; + + /// \brief Decodes the element + /// \param encoded byte array with the encoded element + /// \param checkForGroupMembership flag indicating if the element should be validated + /// \return Element after decoding + /// \details DecodeElement() must be implemented in a derived class. + /// \pre COUNTOF(encoded) == GetEncodedElementSize() + virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0; + + /// \brief Converts an element to an Integer + /// \param element the element to convert to an Integer + /// \return Element after converting to an Integer + /// \details ConvertElementToInteger() must be implemented in a derived class. + virtual Integer ConvertElementToInteger(const Element &element) const =0; + + /// \brief Check the group for errors + /// \param rng RandomNumberGenerator for objects which use randomized testing + /// \param level level of thoroughness + /// \return true if the tests succeed, false otherwise + /// \details There are four levels of thoroughness: + ///
    + ///
  • 0 - using this object won't cause a crash or exception + ///
  • 1 - this object will probably function, and encrypt, sign, other operations correctly + ///
  • 2 - ensure this object will function correctly, and perform reasonable security checks + ///
  • 3 - perform reasonable security checks, and do checks that may take a long time + ///
+ /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0. + /// Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended. + /// \details ValidateGroup() must be implemented in a derived class. + virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0; + + /// \brief Check the element for errors + /// \param level level of thoroughness + /// \param element element to check + /// \param precomp optional pointer to DL_FixedBasePrecomputation + /// \return true if the tests succeed, false otherwise + /// \details There are four levels of thoroughness: + ///
    + ///
  • 0 - using this object won't cause a crash or exception + ///
  • 1 - this object will probably function, and encrypt, sign, other operations correctly + ///
  • 2 - ensure this object will function correctly, and perform reasonable security checks + ///
  • 3 - perform reasonable security checks, and do checks that may take a long time + ///
+ /// \details Level 0 performs group membership checks. Level 1 may not check for weak keys and such. + /// Levels 2 and 3 are recommended. + /// \details ValidateElement() must be implemented in a derived class. + virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation *precomp) const =0; + + virtual bool FastSubgroupCheckAvailable() const =0; + + /// \brief Determines if an element is an identity + /// \param element element to check + /// \return true if the element is an identity, false otherwise + /// \details The identity element or or neutral element is a special element in a group that leaves + /// other elements unchanged when combined with it. + /// \details IsIdentity() must be implemented in a derived class. + virtual bool IsIdentity(const Element &element) const =0; + + /// \brief Exponentiates a base to multiple exponents + /// \param results an array of Elements + /// \param base the base to raise to the exponents + /// \param exponents an array of exponents + /// \param exponentsCount the number of exponents in the array + /// \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the + /// result at the respective position in the results array. + /// \details SimultaneousExponentiate() must be implemented in a derived class. + /// \pre COUNTOF(results) == exponentsCount + /// \pre COUNTOF(exponents) == exponentsCount + virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0; + +protected: + void ParametersChanged() {m_validationLevel = 0;} + +private: + mutable unsigned int m_validationLevel; +}; + +/// \brief Base implementation of Discrete Log (DL) group parameters +/// \tparam GROUP_PRECOMP group precomputation class +/// \tparam BASE_PRECOMP fixed base precomputation class +/// \tparam BASE class or type of an element +template , class BASE = DL_GroupParameters > +class DL_GroupParametersImpl : public BASE +{ +public: + typedef GROUP_PRECOMP GroupPrecomputation; + typedef typename GROUP_PRECOMP::Element Element; + typedef BASE_PRECOMP BasePrecomputation; + + virtual ~DL_GroupParametersImpl() {} + + /// \brief Retrieves the group precomputation + /// \return a const reference to the group precomputation + const DL_GroupPrecomputation & GetGroupPrecomputation() const {return m_groupPrecomputation;} + + /// \brief Retrieves the group precomputation + /// \return a const reference to the group precomputation using a fixed base + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return m_gpc;} + + /// \brief Retrieves the group precomputation + /// \return a non-const reference to the group precomputation using a fixed base + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return m_gpc;} + +protected: + GROUP_PRECOMP m_groupPrecomputation; + BASE_PRECOMP m_gpc; +}; + +/// \brief Base class for a Discrete Log (DL) key +/// \tparam T class or type of an element +/// \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point" +template +class CRYPTOPP_NO_VTABLE DL_Key +{ +public: + virtual ~DL_Key() {} + + /// \brief Retrieves abstract group parameters + /// \return a const reference to the group parameters + virtual const DL_GroupParameters & GetAbstractGroupParameters() const =0; + /// \brief Retrieves abstract group parameters + /// \return a non-const reference to the group parameters + virtual DL_GroupParameters & AccessAbstractGroupParameters() =0; +}; + +/// \brief Interface for Discrete Log (DL) public keys +template +class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key +{ + typedef DL_PublicKey ThisClass; + +public: + typedef T Element; + + virtual ~DL_PublicKey(); + + /// \brief Get a named value + /// \param name the name of the object or value to retrieve + /// \param valueType reference to a variable that receives the value + /// \param pValue void pointer to a variable that receives the value + /// \return true if the value was retrieved, false otherwise + /// \details GetVoidValue() retrieves the value of name if it exists. + /// \note GetVoidValue() is an internal function and should be implemented + /// by derived classes. Users should use one of the other functions instead. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters()) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement); + } + + /// \brief Initialize or reinitialize this key + /// \param source NameValuePairs to assign + void AssignFrom(const NameValuePairs &source); + + /// \brief Retrieves the public element + /// \return the public element + virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());} + + /// \brief Sets the public element + /// \param y the public element + virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);} + + /// \brief Exponentiates this element + /// \param exponent the exponent to raise the base + /// \return the public element raised to the exponent + virtual Element ExponentiatePublicElement(const Integer &exponent) const + { + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent); + } + + /// \brief Exponentiates an element + /// \param baseExp the first exponent + /// \param publicExp the second exponent + /// \return the public element raised to the exponent + /// \details CascadeExponentiateBaseAndPublicElement raises the public element to + /// the base element and precomputation. + virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const + { + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp); + } + + /// \brief Accesses the public precomputation + /// \details GetPublicPrecomputation returns a const reference, while + /// AccessPublicPrecomputation returns a non-const reference. Must be + /// overridden in derived classes. + virtual const DL_FixedBasePrecomputation & GetPublicPrecomputation() const =0; + + /// \brief Accesses the public precomputation + /// \details GetPublicPrecomputation returns a const reference, while + /// AccessPublicPrecomputation returns a non-const reference. Must be + /// overridden in derived classes. + virtual DL_FixedBasePrecomputation & AccessPublicPrecomputation() =0; +}; + +// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499 +template +DL_PublicKey::~DL_PublicKey() {} + +/// \brief Interface for Discrete Log (DL) private keys +template +class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key +{ + typedef DL_PrivateKey ThisClass; + +public: + typedef T Element; + + virtual ~DL_PrivateKey(); + + /// \brief Initializes a public key from this key + /// \param pub reference to a public key + void MakePublicKey(DL_PublicKey &pub) const + { + pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters()); + pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent())); + } + + /// \brief Get a named value + /// \param name the name of the object or value to retrieve + /// \param valueType reference to a variable that receives the value + /// \param pValue void pointer to a variable that receives the value + /// \return true if the value was retrieved, false otherwise + /// \details GetVoidValue() retrieves the value of name if it exists. + /// \note GetVoidValue() is an internal function and should be implemented + /// by derived classes. Users should use one of the other functions instead. + /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(), + /// GetRequiredParameter() and GetRequiredIntParameter() + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters()) + CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent); + } + + /// \brief Initialize or reinitialize this key + /// \param source NameValuePairs to assign + void AssignFrom(const NameValuePairs &source) + { + this->AccessAbstractGroupParameters().AssignFrom(source); + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent); + } + + /// \brief Retrieves the private exponent + /// \return the private exponent + /// \details Must be overridden in derived classes. + virtual const Integer & GetPrivateExponent() const =0; + /// \brief Sets the private exponent + /// \param x the private exponent + /// \details Must be overridden in derived classes. + virtual void SetPrivateExponent(const Integer &x) =0; +}; + +// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499 +template +DL_PrivateKey::~DL_PrivateKey() {} + +template +void DL_PublicKey::AssignFrom(const NameValuePairs &source) +{ + DL_PrivateKey *pPrivateKey = NULLPTR; + if (source.GetThisPointer(pPrivateKey)) + pPrivateKey->MakePublicKey(*this); + else + { + this->AccessAbstractGroupParameters().AssignFrom(source); + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement); + } +} + +class OID; + +/// \brief Discrete Log (DL) key base implementation +/// \tparam PK Key class +/// \tparam GP GroupParameters class +/// \tparam O OID class +template +class DL_KeyImpl : public PK +{ +public: + typedef GP GroupParameters; + + virtual ~DL_KeyImpl() {} + + O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();} + bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) + {AccessGroupParameters().BERDecode(bt); return true;} + bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const + {GetGroupParameters().DEREncode(bt); return true;} + + const GP & GetGroupParameters() const {return m_groupParameters;} + GP & AccessGroupParameters() {return m_groupParameters;} + +private: + GP m_groupParameters; +}; + +class X509PublicKey; +class PKCS8PrivateKey; + +/// \brief Discrete Log (DL) private key base implementation +/// \tparam GP GroupParameters class +template +class DL_PrivateKeyImpl : public DL_PrivateKey, public DL_KeyImpl +{ +public: + typedef typename GP::Element Element; + + virtual ~DL_PrivateKeyImpl() {} + + // GeneratableCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + CRYPTOPP_ASSERT(GetAbstractGroupParameters().Validate(rng, level)); + bool pass = GetAbstractGroupParameters().Validate(rng, level); + + const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder(); + const Integer &x = GetPrivateExponent(); + + CRYPTOPP_ASSERT(x.IsPositive()); + CRYPTOPP_ASSERT(x < q); + pass = pass && x.IsPositive() && x < q; + + if (level >= 1) + { + CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One()); + pass = pass && Integer::Gcd(x, q) == Integer::One(); + } + return pass; + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper >(this, name, valueType, pValue).Assignable(); + } + + void AssignFrom(const NameValuePairs &source) + { + AssignFromHelper >(this, source); + } + + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) + { + if (!params.GetThisObject(this->AccessGroupParameters())) + this->AccessGroupParameters().GenerateRandom(rng, params); + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + SetPrivateExponent(x); + } + + bool SupportsPrecomputation() const {return true;} + + void Precompute(unsigned int precomputationStorage=16) + {AccessAbstractGroupParameters().Precompute(precomputationStorage);} + + void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);} + + void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);} + + // DL_Key + const DL_GroupParameters & GetAbstractGroupParameters() const {return this->GetGroupParameters();} + DL_GroupParameters & AccessAbstractGroupParameters() {return this->AccessGroupParameters();} + + // DL_PrivateKey + const Integer & GetPrivateExponent() const {return m_x;} + void SetPrivateExponent(const Integer &x) {m_x = x;} + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) + {m_x.BERDecode(bt);} + void DEREncodePrivateKey(BufferedTransformation &bt) const + {m_x.DEREncode(bt);} + +private: + Integer m_x; +}; + +template +class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE +{ +public: + virtual ~DL_PrivateKey_WithSignaturePairwiseConsistencyTest() {} + + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) + { + BASE::GenerateRandom(rng, params); + + if (FIPS_140_2_ComplianceEnabled()) + { + typename SIGNATURE_SCHEME::Signer signer(*this); + typename SIGNATURE_SCHEME::Verifier verifier(signer); + SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); + } + } +}; + +/// \brief Discrete Log (DL) public key base implementation +/// \tparam GP GroupParameters class +template +class DL_PublicKeyImpl : public DL_PublicKey, public DL_KeyImpl +{ +public: + typedef typename GP::Element Element; + + virtual ~DL_PublicKeyImpl(); + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + CRYPTOPP_ASSERT(GetAbstractGroupParameters().Validate(rng, level)); + bool pass = GetAbstractGroupParameters().Validate(rng, level); + CRYPTOPP_ASSERT(GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation())); + pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation()); + return pass; + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper >(this, name, valueType, pValue).Assignable(); + } + + void AssignFrom(const NameValuePairs &source) + { + AssignFromHelper >(this, source); + } + + bool SupportsPrecomputation() const {return true;} + + void Precompute(unsigned int precomputationStorage=16) + { + AccessAbstractGroupParameters().Precompute(precomputationStorage); + AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage); + } + + void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + { + AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation); + AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); + } + + void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + { + GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation); + GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); + } + + // DL_Key + const DL_GroupParameters & GetAbstractGroupParameters() const {return this->GetGroupParameters();} + DL_GroupParameters & AccessAbstractGroupParameters() {return this->AccessGroupParameters();} + + // DL_PublicKey + const DL_FixedBasePrecomputation & GetPublicPrecomputation() const {return m_ypc;} + DL_FixedBasePrecomputation & AccessPublicPrecomputation() {return m_ypc;} + + // non-inherited + bool operator==(const DL_PublicKeyImpl &rhs) const + {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();} + +private: + typename GP::BasePrecomputation m_ypc; +}; + +// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499 +template +DL_PublicKeyImpl::~DL_PublicKeyImpl() {} + +/// \brief Interface for Elgamal-like signature algorithms +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +template +class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm +{ +public: + virtual ~DL_ElgamalLikeSignatureAlgorithm() {} + + /// \brief Sign a message using a private key + /// \param params GroupParameters + /// \param privateKey private key + /// \param k signing exponent + /// \param e encoded message + /// \param r r part of signature + /// \param s s part of signature + virtual void Sign(const DL_GroupParameters ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0; + + /// \brief Verify a message using a public key + /// \param params GroupParameters + /// \param publicKey public key + /// \param e encoded message + /// \param r r part of signature + /// \param s s part of signature + virtual bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0; + + /// \brief Recover a Presignature + /// \param params GroupParameters + /// \param publicKey public key + /// \param r r part of signature + /// \param s s part of signature + virtual Integer RecoverPresignature(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &r, const Integer &s) const + { + CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s); + throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery"); + MAYBE_RETURN(Integer::Zero()); + } + + /// \brief Retrieve R length + /// \param params GroupParameters + virtual size_t RLen(const DL_GroupParameters ¶ms) const + {return params.GetSubgroupOrder().ByteCount();} + + /// \brief Retrieve S length + /// \param params GroupParameters + virtual size_t SLen(const DL_GroupParameters ¶ms) const + {return params.GetSubgroupOrder().ByteCount();} + + /// \brief Signature scheme flag + /// \return true if the signature scheme is deterministic, false otherwise + /// \details IsDeterministic() is provided for DL signers. It is used by RFC 6979 signature schemes. + virtual bool IsDeterministic() const + {return false;} +}; + +/// \brief Interface for deterministic signers +/// \details RFC 6979 signers which generate k based on the encoded message and private key +class CRYPTOPP_NO_VTABLE DeterministicSignatureAlgorithm +{ +public: + virtual ~DeterministicSignatureAlgorithm() {} + + /// \brief Generate k + /// \param x private key + /// \param q subgroup generator + /// \param e encoded message + virtual Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const =0; +}; + +/// \brief Interface for DL key agreement algorithms +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +/// \sa DLIES, ECIES, ECIES_P1363 +template +class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm +{ +public: + typedef T Element; + + virtual ~DL_KeyAgreementAlgorithm() {} + + virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters ¶ms, const DL_FixedBasePrecomputation &publicPrecomputation, const Integer &privateExponent) const =0; + virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0; +}; + +/// \brief Interface for key derivation algorithms used in DL cryptosystems +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +/// \sa DLIES, ECIES, ECIES_P1363 +template +class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm +{ +public: + virtual ~DL_KeyDerivationAlgorithm() {} + + virtual bool ParameterSupported(const char *name) const + {CRYPTOPP_UNUSED(name); return false;} + virtual void Derive(const DL_GroupParameters &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0; +}; + +/// \brief Interface for symmetric encryption algorithms used in DL cryptosystems +/// \sa DLIES, ECIES, ECIES_P1363 +class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm +{ +public: + virtual ~DL_SymmetricEncryptionAlgorithm() {} + + virtual bool ParameterSupported(const char *name) const + {CRYPTOPP_UNUSED(name); return false;} + virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0; + virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0; + virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0; + virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const =0; + virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const =0; +}; + +/// \brief Discrete Log (DL) base interface +/// \tparam KI public or private key interface +template +class CRYPTOPP_NO_VTABLE DL_Base +{ +protected: + typedef KI KeyInterface; + typedef typename KI::Element Element; + + virtual ~DL_Base() {} + + const DL_GroupParameters & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();} + DL_GroupParameters & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();} + + virtual KeyInterface & AccessKeyInterface() =0; + virtual const KeyInterface & GetKeyInterface() const =0; +}; + +/// \brief Discrete Log (DL) signature scheme base implementation +/// \tparam INTFACE PK_Signer or PK_Verifier derived class +/// \tparam KEY_INTFACE DL_Base key base used in the scheme +/// \details DL_SignatureSchemeBase provides common functions for signers and verifiers. +/// DL_Base is used for signers, and DL_Base is used for verifiers. +template +class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTFACE, public DL_Base +{ +public: + virtual ~DL_SignatureSchemeBase() {} + + /// \brief Provides the signature length + /// \return signature length, in bytes + /// \details SignatureLength returns the size required for r+s. + size_t SignatureLength() const + { + return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters()) + + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters()); + } + + /// \brief Provides the maximum recoverable length + /// \return maximum recoverable length, in bytes + size_t MaxRecoverableLength() const + {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());} + + /// \brief Provides the maximum recoverable length + /// \param signatureLength the size of the signature + /// \return maximum recoverable length based on signature length, in bytes + /// \details this function is not implemented and always returns 0. + size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const + {CRYPTOPP_UNUSED(signatureLength); CRYPTOPP_ASSERT(false); return 0;} // TODO + + /// \brief Determines if the scheme is probabilistic + /// \return true if the scheme is probabilistic, false otherwise + bool IsProbabilistic() const + {return true;} + + /// \brief Determines if the scheme has non-recoverable part + /// \return true if the message encoding has a non-recoverable part, false otherwise. + bool AllowNonrecoverablePart() const + {return GetMessageEncodingInterface().AllowNonrecoverablePart();} + + /// \brief Determines if the scheme allows recoverable part first + /// \return true if the message encoding allows the recoverable part, false otherwise. + bool RecoverablePartFirst() const + {return GetMessageEncodingInterface().RecoverablePartFirst();} + +protected: + size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} + size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();} + + // true if the scheme conforms to RFC 6979 + virtual bool IsDeterministic() const {return false;} + + virtual const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const =0; + virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0; + virtual HashIdentifier GetHashIdentifier() const =0; + virtual size_t GetDigestSize() const =0; +}; + +/// \brief Discrete Log (DL) signature scheme signer base implementation +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +template +class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase > +{ +public: + virtual ~DL_SignerBase() {} + + /// \brief Testing interface + /// \param k Integer + /// \param e Integer + /// \param r Integer + /// \param s Integer + void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PrivateKey &key = this->GetKeyInterface(); + + r = params.ConvertElementToInteger(params.ExponentiateBase(k)); + alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); + } + + void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const + { + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); + this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(), + recoverableMessage, recoverableMessageLength, + ma.m_presignature, ma.m_presignature.size(), + ma.m_semisignature); + } + + size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const + { + this->GetMaterial().DoQuickSanityCheck(); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PrivateKey &key = this->GetKeyInterface(); + + SecByteBlock representative(this->MessageRepresentativeLength()); + this->GetMessageEncodingInterface().ComputeMessageRepresentative( + rng, + ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, + representative, this->MessageRepresentativeBitLength()); + ma.m_empty = true; + Integer e(representative, representative.size()); + + // hash message digest into random number k to prevent reusing the same k on + // different messages after virtual machine rollback + if (rng.CanIncorporateEntropy()) + rng.IncorporateEntropy(representative, representative.size()); + + Integer k, ks; + const Integer& q = params.GetSubgroupOrder(); + if (alg.IsDeterministic()) + { + const Integer& x = key.GetPrivateExponent(); + const DeterministicSignatureAlgorithm& det = dynamic_cast(alg); + k = det.GenerateRandom(x, q, e); + } + else + { + k.Randomize(rng, 1, params.GetSubgroupOrder()-1); + } + + // Due to timing attack on nonce length by Jancar + // https://github.com/weidai11/cryptopp/issues/869 + ks = k + q; + if (ks.BitCount() == q.BitCount()) { + ks += q; + } + + Integer r, s; + r = params.ConvertElementToInteger(params.ExponentiateBase(ks)); + alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); + + /* + Integer r, s; + if (this->MaxRecoverableLength() > 0) + r.Decode(ma.m_semisignature, ma.m_semisignature.size()); + else + r.Decode(ma.m_presignature, ma.m_presignature.size()); + alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s); + */ + + const size_t rLen = alg.RLen(params); + r.Encode(signature, rLen); + s.Encode(signature+rLen, alg.SLen(params)); + + if (restart) + RestartMessageAccumulator(rng, ma); + + return this->SignatureLength(); + } + +protected: + void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const + { + // k needs to be generated before hashing for signature schemes with recovery + // but to defend against VM rollbacks we need to generate k after hashing. + // so this code is commented out, since no DL-based signature scheme with recovery + // has been implemented in Crypto++ anyway + /* + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1); + ma.m_presignature.New(params.GetEncodedElementSize(false)); + params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size()); + */ + CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma); + } +}; + +/// \brief Discret Log (DL) Verifier base class +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +template +class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase > +{ +public: + virtual ~DL_VerifierBase() {} + + void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const + { + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + + // Validation due to https://github.com/weidai11/cryptopp/issues/981 + // We allow a caller to provide R and S in oversized buffer. R and S + // are read based on the field element size, and not the buffer size. + const size_t rLen = alg.RLen(params); + const size_t sLen = alg.SLen(params); + CRYPTOPP_ASSERT(signatureLength >= rLen + sLen); + if (signatureLength < rLen + sLen) + throw InvalidDataFormat("DL_VerifierBase: signature length is not valid."); + + ma.m_semisignature.Assign(signature, rLen); + ma.m_s.Decode(signature+rLen, sLen); + + this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size()); + } + + bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const + { + this->GetMaterial().DoQuickSanityCheck(); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PublicKey &key = this->GetKeyInterface(); + + SecByteBlock representative(this->MessageRepresentativeLength()); + this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, + representative, this->MessageRepresentativeBitLength()); + ma.m_empty = true; + Integer e(representative, representative.size()); + + Integer r(ma.m_semisignature, ma.m_semisignature.size()); + return alg.Verify(params, key, e, r, ma.m_s); + } + + DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const + { + this->GetMaterial().DoQuickSanityCheck(); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PublicKey &key = this->GetKeyInterface(); + + SecByteBlock representative(this->MessageRepresentativeLength()); + this->GetMessageEncodingInterface().ComputeMessageRepresentative( + NullRNG(), + ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, + representative, this->MessageRepresentativeBitLength()); + ma.m_empty = true; + Integer e(representative, representative.size()); + + ma.m_presignature.New(params.GetEncodedElementSize(false)); + Integer r(ma.m_semisignature, ma.m_semisignature.size()); + alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size()); + + return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature( + ma.AccessHash(), this->GetHashIdentifier(), + ma.m_presignature, ma.m_presignature.size(), + ma.m_semisignature, ma.m_semisignature.size(), + recoveredMessage); + } +}; + +/// \brief Discrete Log (DL) cryptosystem base implementation +/// \tparam PK field element type +/// \tparam KI public or private key interface +template +class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base +{ +public: + typedef typename DL_Base::Element Element; + + virtual ~DL_CryptoSystemBase() {} + + size_t MaxPlaintextLength(size_t ciphertextLength) const + { + unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true); + return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen); + } + + size_t CiphertextLength(size_t plaintextLength) const + { + size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength); + return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len; + } + + bool ParameterSupported(const char *name) const + {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);} + +protected: + virtual const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const =0; + virtual const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const =0; + virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0; +}; + +/// \brief Discrete Log (DL) decryptor base implementation +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +template +class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase > +{ +public: + typedef T Element; + + virtual ~DL_DecryptorBase() {} + + DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const + { + try + { + CRYPTOPP_UNUSED(rng); + const DL_KeyAgreementAlgorithm &agreeAlg = this->GetKeyAgreementAlgorithm(); + const DL_KeyDerivationAlgorithm &derivAlg = this->GetKeyDerivationAlgorithm(); + const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PrivateKey &key = this->GetKeyInterface(); + + Element q = params.DecodeElement(ciphertext, true); + size_t elementSize = params.GetEncodedElementSize(true); + ciphertext += elementSize; + ciphertextLength -= elementSize; + + Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent()); + + SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength))); + derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters); + + return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters); + } + catch (DL_BadElement &) + { + return DecodingResult(); + } + } +}; + +/// \brief Discrete Log (DL) encryptor base implementation +/// \tparam T Field element type or class +/// \details Field element T can be Integer, ECP or EC2N. +template +class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase > +{ +public: + typedef T Element; + + virtual ~DL_EncryptorBase() {} + + void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const + { + const DL_KeyAgreementAlgorithm &agreeAlg = this->GetKeyAgreementAlgorithm(); + const DL_KeyDerivationAlgorithm &derivAlg = this->GetKeyDerivationAlgorithm(); + const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PublicKey &key = this->GetKeyInterface(); + + Integer x(rng, Integer::One(), params.GetMaxExponent()); + Element q = params.ExponentiateBase(x); + params.EncodeElement(true, q, ciphertext); + unsigned int elementSize = params.GetEncodedElementSize(true); + ciphertext += elementSize; + + Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x); + + SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength)); + derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters); + + encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters); + } +}; + +/// \brief Discrete Log (DL) scheme options +/// \tparam T1 algorithm information +/// \tparam T2 group parameters for the scheme +template +struct DL_SchemeOptionsBase +{ + typedef T1 AlgorithmInfo; + typedef T2 GroupParameters; + typedef typename GroupParameters::Element Element; +}; + +/// \brief Discrete Log (DL) key options +/// \tparam T1 algorithm information +/// \tparam T2 keys used in the scheme +template +struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase +{ + typedef T2 Keys; + typedef typename Keys::PrivateKey PrivateKey; + typedef typename Keys::PublicKey PublicKey; +}; + +/// \brief Discrete Log (DL) signature scheme options +/// \tparam T1 algorithm information +/// \tparam T2 keys used in the scheme +/// \tparam T3 signature algorithm +/// \tparam T4 message encoding method +/// \tparam T5 hash function +template +struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions +{ + typedef T3 SignatureAlgorithm; + typedef T4 MessageEncodingMethod; + typedef T5 HashFunction; +}; + +/// \brief Discrete Log (DL) crypto scheme options +/// \tparam T1 algorithm information +/// \tparam T2 keys used in the scheme +/// \tparam T3 key agreement algorithm +/// \tparam T4 key derivation algorithm +/// \tparam T5 symmetric encryption algorithm +template +struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions +{ + typedef T3 KeyAgreementAlgorithm; + typedef T4 KeyDerivationAlgorithm; + typedef T5 SymmetricEncryptionAlgorithm; +}; + +/// \brief Discrete Log (DL) base object implementation +/// \tparam BASE TODO +/// \tparam SCHEME_OPTIONS options for the scheme +/// \tparam KEY key used in the scheme +template +class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl +{ +public: + typedef SCHEME_OPTIONS SchemeOptions; + typedef typename KEY::Element Element; + + virtual ~DL_ObjectImplBase() {} + + PrivateKey & AccessPrivateKey() {return m_key;} + PublicKey & AccessPublicKey() {return m_key;} + + // KeyAccessor + const KEY & GetKey() const {return m_key;} + KEY & AccessKey() {return m_key;} + +protected: + typename BASE::KeyInterface & AccessKeyInterface() {return m_key;} + const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;} + + // for signature scheme + HashIdentifier GetHashIdentifier() const + { + typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup; + return HashLookup::template HashIdentifierLookup2::Lookup(); + } + size_t GetDigestSize() const + { + typedef typename SchemeOptions::HashFunction H; + return H::DIGESTSIZE; + } + +private: + KEY m_key; +}; + +/// \brief Discrete Log (DL) object implementation +/// \tparam BASE TODO +/// \tparam SCHEME_OPTIONS options for the scheme +/// \tparam KEY key used in the scheme +template +class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase +{ +public: + typedef typename KEY::Element Element; + + virtual ~DL_ObjectImpl() {} + +protected: + const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const + {return Singleton().Ref();} + const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const + {return Singleton().Ref();} + const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const + {return Singleton().Ref();} + const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const + {return Singleton().Ref();} + HashIdentifier GetHashIdentifier() const + {return HashIdentifier();} + const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const + {return Singleton().Ref();} +}; + +/// \brief Discrete Log (DL) signer implementation +/// \tparam SCHEME_OPTIONS options for the scheme +template +class DL_SignerImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> +{ +public: + PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const + { + member_ptr p(new PK_MessageAccumulatorImpl); + this->RestartMessageAccumulator(rng, *p); + return p.release(); + } +}; + +/// \brief Discrete Log (DL) verifier implementation +/// \tparam SCHEME_OPTIONS options for the scheme +template +class DL_VerifierImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> +{ +public: + PK_MessageAccumulator * NewVerificationAccumulator() const + { + return new PK_MessageAccumulatorImpl; + } +}; + +/// \brief Discrete Log (DL) encryptor implementation +/// \tparam SCHEME_OPTIONS options for the scheme +template +class DL_EncryptorImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> +{ +}; + +/// \brief Discrete Log (DL) decryptor implementation +/// \tparam SCHEME_OPTIONS options for the scheme +template +class DL_DecryptorImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> +{ +}; + +// ******************************************************** + +/// \brief Discrete Log (DL) simple key agreement base implementation +/// \tparam T class or type +template +class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain +{ +public: + typedef T Element; + + virtual ~DL_SimpleKeyAgreementDomainBase() {} + + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, PrivateKeyLength()); + } + + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + CRYPTOPP_UNUSED(rng); + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, PrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const + { + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, PrivateKeyLength()); + Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey); + + Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey( + GetAbstractGroupParameters(), w, validateOtherPublicKey, x); + params.EncodeElement(false, z, agreedValue); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + + /// \brief Retrieves a reference to the group generator + /// \return const reference to the group generator + const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();} + +protected: + virtual const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const =0; + virtual DL_GroupParameters & AccessAbstractGroupParameters() =0; + const DL_GroupParameters & GetAbstractGroupParameters() const {return const_cast *>(this)->AccessAbstractGroupParameters();} +}; + +/// \brief Methods for avoiding "Small-Subgroup" attacks on Diffie-Hellman Key Agreement +/// \details Additional methods exist and include public key validation and choice of prime p. +/// \sa Methods for Avoiding the "Small-Subgroup" Attacks on the +/// Diffie-Hellman Key Agreement Method for S/MIME +enum CofactorMultiplicationOption { + /// \brief No cofactor multiplication applied + NO_COFACTOR_MULTIPLICTION, + /// \brief Cofactor multiplication compatible with ordinary Diffie-Hellman + /// \details Modifies the computation of ZZ by including j (the cofactor) in the computations and is + /// compatible with ordinary Diffie-Hellman. + COMPATIBLE_COFACTOR_MULTIPLICTION, + /// \brief Cofactor multiplication incompatible with ordinary Diffie-Hellman + /// \details Modifies the computation of ZZ by including j (the cofactor) in the computations but is + /// not compatible with ordinary Diffie-Hellman. + INCOMPATIBLE_COFACTOR_MULTIPLICTION}; + +typedef EnumToType NoCofactorMultiplication; +typedef EnumToType CompatibleCofactorMultiplication; +typedef EnumToType IncompatibleCofactorMultiplication; + +/// \brief Diffie-Hellman key agreement algorithm +template +class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm +{ +public: + typedef ELEMENT Element; + + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() + {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";} + + virtual ~DL_KeyAgreementAlgorithm_DH() {} + + Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters ¶ms, const DL_FixedBasePrecomputation &publicPrecomputation, const Integer &privateExponent) const + { + return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(), + COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent); + } + + Element AgreeWithStaticPrivateKey(const DL_GroupParameters ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const + { + if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) + { + const Integer &k = params.GetCofactor(); + return params.ExponentiateElement(publicElement, + ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k); + } + else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION) + return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor()); + else + { + CRYPTOPP_ASSERT(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION); + + if (!validateOtherPublicKey) + return params.ExponentiateElement(publicElement, privateExponent); + + if (params.FastSubgroupCheckAvailable()) + { + if (!params.ValidateElement(2, publicElement, NULLPTR)) + throw DL_BadElement(); + return params.ExponentiateElement(publicElement, privateExponent); + } + else + { + const Integer e[2] = {params.GetSubgroupOrder(), privateExponent}; + Element r[2]; + params.SimultaneousExponentiate(r, publicElement, e, 2); + if (!params.IsIdentity(r[0])) + throw DL_BadElement(); + return r[1]; + } + } + } +}; + +// ******************************************************** + +/// \brief Template implementing constructors for public key algorithm classes +template +class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE +{ +public: + PK_FinalTemplate() {} + + PK_FinalTemplate(const CryptoMaterial &key) + {this->AccessKey().AssignFrom(key);} + + PK_FinalTemplate(BufferedTransformation &bt) + {this->AccessKey().BERDecode(bt);} + + PK_FinalTemplate(const AsymmetricAlgorithm &algorithm) + {this->AccessKey().AssignFrom(algorithm.GetMaterial());} + + PK_FinalTemplate(const Integer &v1) + {this->AccessKey().Initialize(v1);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2) + {this->AccessKey().Initialize(v1, v2);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3) + {this->AccessKey().Initialize(v1, v2, v3);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {this->AccessKey().Initialize(v1, v2, v3, v4);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2) + {this->AccessKey().Initialize(v1, v2);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3) + {this->AccessKey().Initialize(v1, v2, v3);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {this->AccessKey().Initialize(v1, v2, v3, v4);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} +}; + +/// \brief Base class for public key encryption standard classes. +/// \details These classes are used to select from variants of algorithms. +/// Not all standards apply to all algorithms. +struct EncryptionStandard {}; + +/// \brief Base class for public key signature standard classes. +/// \details These classes are used to select from variants of algorithms. +/// Not all standards apply to all algorithms. +struct SignatureStandard {}; + +/// \brief Trapdoor Function (TF) encryption scheme +/// \tparam STANDARD standard +/// \tparam KEYS keys used in the encryption scheme +/// \tparam ALG_INFO algorithm information +template +class TF_ES; + +template > +class TF_ES : public KEYS +{ + typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod; + +public: + /// see EncryptionStandard for a list of standards + typedef STANDARD Standard; + typedef TF_CryptoSchemeOptions SchemeOptions; + + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();} + + /// implements PK_Decryptor interface + typedef PK_FinalTemplate > Decryptor; + /// implements PK_Encryptor interface + typedef PK_FinalTemplate > Encryptor; +}; + +/// \brief Trapdoor Function (TF) Signature Scheme +/// \tparam STANDARD standard +/// \tparam H hash function +/// \tparam KEYS keys used in the signature scheme +/// \tparam ALG_INFO algorithm information +template +class TF_SS; + +template > +class TF_SS : public KEYS +{ +public: + /// see SignatureStandard for a list of standards + typedef STANDARD Standard; + typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod; + typedef TF_SignatureSchemeOptions SchemeOptions; + + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} + + /// implements PK_Signer interface + typedef PK_FinalTemplate > Signer; + /// implements PK_Verifier interface + typedef PK_FinalTemplate > Verifier; +}; + +/// \brief Discrete Log (DL) signature scheme +/// \tparam KEYS keys used in the signature scheme +/// \tparam SA signature algorithm +/// \tparam MEM message encoding method +/// \tparam H hash function +/// \tparam ALG_INFO algorithm information +template +class DL_SS; + +template > +class DL_SS : public KEYS +{ + typedef DL_SignatureSchemeOptions SchemeOptions; + +public: + static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";} + + /// implements PK_Signer interface + typedef PK_FinalTemplate > Signer; + /// implements PK_Verifier interface + typedef PK_FinalTemplate > Verifier; +}; + +/// \brief Discrete Log (DL) encryption scheme +/// \tparam KEYS keys used in the encryption scheme +/// \tparam AA key agreement algorithm +/// \tparam DA key derivation algorithm +/// \tparam EA encryption algorithm +/// \tparam ALG_INFO algorithm information +template +class DL_ES : public KEYS +{ + typedef DL_CryptoSchemeOptions SchemeOptions; + +public: + /// implements PK_Decryptor interface + typedef PK_FinalTemplate > Decryptor; + /// implements PK_Encryptor interface + typedef PK_FinalTemplate > Encryptor; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/pwdbased.h b/external/ours/library/crypto/src/shared/original/pwdbased.h new file mode 100755 index 000000000..f1e2c79f9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/pwdbased.h @@ -0,0 +1,481 @@ +// pwdbased.h - originally written and placed in the public domain by Wei Dai +// Cutover to KeyDerivationFunction interface by Uri Blumenthal +// Marcel Raad and Jeffrey Walton in March 2018. + +/// \file pwdbased.h +/// \brief Password based key derivation functions + +#ifndef CRYPTOPP_PWDBASED_H +#define CRYPTOPP_PWDBASED_H + +#include "cryptlib.h" +#include "hrtimer.h" +#include "integer.h" +#include "argnames.h" +#include "algparam.h" +#include "hmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +// ******************** PBKDF1 ******************** + +/// \brief PBKDF1 from PKCS #5 +/// \tparam T a HashTransformation class +/// \sa PasswordBasedKeyDerivationFunction, PKCS5_PBKDF1 +/// on the Crypto++ wiki +/// \since Crypto++ 2.0 +template +class PKCS5_PBKDF1 : public PasswordBasedKeyDerivationFunction +{ +public: + virtual ~PKCS5_PBKDF1() {} + + static std::string StaticAlgorithmName () { + const std::string name(std::string("PBKDF1(") + + std::string(T::StaticAlgorithmName()) + std::string(")")); + return name; + } + + // KeyDerivationFunction interface + std::string AlgorithmName() const { + return StaticAlgorithmName(); + } + + // KeyDerivationFunction interface + size_t MaxDerivedKeyLength() const { + return static_cast(T::DIGESTSIZE); + } + + // KeyDerivationFunction interface + size_t GetValidDerivedLength(size_t keylength) const; + + // KeyDerivationFunction interface + virtual size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const NameValuePairs& params = g_nullNameValuePairs) const; + + /// \brief Derive a key from a secret seed + /// \param derived the derived output buffer + /// \param derivedLen the size of the derived buffer, in bytes + /// \param purpose a purpose byte + /// \param secret the seed input buffer + /// \param secretLen the size of the secret buffer, in bytes + /// \param salt the salt input buffer + /// \param saltLen the size of the salt buffer, in bytes + /// \param iterations the number of iterations + /// \param timeInSeconds the in seconds + /// \return the number of iterations performed + /// \throw InvalidDerivedKeyLength if derivedLen is invalid for the scheme + /// \details DeriveKey() provides a standard interface to derive a key from + /// a seed and other parameters. Each class that derives from KeyDerivationFunction + /// provides an overload that accepts most parameters used by the derivation function. + /// \details If timeInSeconds is > 0.0 then DeriveKey will run for + /// the specified amount of time. If timeInSeconds is 0.0 then DeriveKey + /// will run for the specified number of iterations. + /// \details PKCS #5 says PBKDF1 should only take 8-byte salts. This implementation + /// allows salts of any length. + size_t DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const; + +protected: + // KeyDerivationFunction interface + const Algorithm & GetAlgorithm() const { + return *this; + } +}; + +template +size_t PKCS5_PBKDF1::GetValidDerivedLength(size_t keylength) const +{ + if (keylength > MaxDerivedKeyLength()) + return MaxDerivedKeyLength(); + return keylength; +} + +template +size_t PKCS5_PBKDF1::DeriveKey(byte *derived, size_t derivedLen, + const byte *secret, size_t secretLen, const NameValuePairs& params) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + byte purpose = (byte)params.GetIntValueWithDefault("Purpose", 0); + unsigned int iterations = (unsigned int)params.GetIntValueWithDefault("Iterations", 1); + + double timeInSeconds = 0.0f; + (void)params.GetValue("TimeInSeconds", timeInSeconds); + + ConstByteArrayParameter salt; + (void)params.GetValue(Name::Salt(), salt); + + return DeriveKey(derived, derivedLen, purpose, secret, secretLen, salt.begin(), salt.size(), iterations, timeInSeconds); +} + +template +size_t PKCS5_PBKDF1::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + CRYPTOPP_ASSERT(iterations > 0 || timeInSeconds > 0); + CRYPTOPP_UNUSED(purpose); + + ThrowIfInvalidDerivedKeyLength(derivedLen); + + // Business logic + if (!iterations) { iterations = 1; } + + T hash; + hash.Update(secret, secretLen); + hash.Update(salt, saltLen); + + SecByteBlock buffer(hash.DigestSize()); + hash.Final(buffer); + + unsigned int i; + ThreadUserTimer timer; + + if (timeInSeconds) + timer.StartTimer(); + + for (i=1; iPKCS5_PBKDF2_HMAC +/// on the Crypto++ wiki +/// \since Crypto++ 2.0 +template +class PKCS5_PBKDF2_HMAC : public PasswordBasedKeyDerivationFunction +{ +public: + virtual ~PKCS5_PBKDF2_HMAC() {} + + static std::string StaticAlgorithmName () { + const std::string name(std::string("PBKDF2_HMAC(") + + std::string(T::StaticAlgorithmName()) + std::string(")")); + return name; + } + + // KeyDerivationFunction interface + std::string AlgorithmName() const { + return StaticAlgorithmName(); + } + + // KeyDerivationFunction interface + // should multiply by T::DIGESTSIZE, but gets overflow that way + size_t MaxDerivedKeyLength() const { + return 0xffffffffU; + } + + // KeyDerivationFunction interface + size_t GetValidDerivedLength(size_t keylength) const; + + // KeyDerivationFunction interface + size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const NameValuePairs& params = g_nullNameValuePairs) const; + + /// \brief Derive a key from a secret seed + /// \param derived the derived output buffer + /// \param derivedLen the size of the derived buffer, in bytes + /// \param purpose a purpose byte + /// \param secret the seed input buffer + /// \param secretLen the size of the secret buffer, in bytes + /// \param salt the salt input buffer + /// \param saltLen the size of the salt buffer, in bytes + /// \param iterations the number of iterations + /// \param timeInSeconds the in seconds + /// \return the number of iterations performed + /// \throw InvalidDerivedKeyLength if derivedLen is invalid for the scheme + /// \details DeriveKey() provides a standard interface to derive a key from + /// a seed and other parameters. Each class that derives from KeyDerivationFunction + /// provides an overload that accepts most parameters used by the derivation function. + /// \details If timeInSeconds is > 0.0 then DeriveKey will run for + /// the specified amount of time. If timeInSeconds is 0.0 then DeriveKey + /// will run for the specified number of iterations. + size_t DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, + const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const; + +protected: + // KeyDerivationFunction interface + const Algorithm & GetAlgorithm() const { + return *this; + } +}; + +template +size_t PKCS5_PBKDF2_HMAC::GetValidDerivedLength(size_t keylength) const +{ + if (keylength > MaxDerivedKeyLength()) + return MaxDerivedKeyLength(); + return keylength; +} + +template +size_t PKCS5_PBKDF2_HMAC::DeriveKey(byte *derived, size_t derivedLen, + const byte *secret, size_t secretLen, const NameValuePairs& params) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + byte purpose = (byte)params.GetIntValueWithDefault("Purpose", 0); + unsigned int iterations = (unsigned int)params.GetIntValueWithDefault("Iterations", 1); + + double timeInSeconds = 0.0f; + (void)params.GetValue("TimeInSeconds", timeInSeconds); + + ConstByteArrayParameter salt; + (void)params.GetValue(Name::Salt(), salt); + + return DeriveKey(derived, derivedLen, purpose, secret, secretLen, salt.begin(), salt.size(), iterations, timeInSeconds); +} + +template +size_t PKCS5_PBKDF2_HMAC::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + CRYPTOPP_ASSERT(iterations > 0 || timeInSeconds > 0); + CRYPTOPP_UNUSED(purpose); + + ThrowIfInvalidDerivedKeyLength(derivedLen); + + // Business logic + if (!iterations) { iterations = 1; } + + // DigestSize check due to https://github.com/weidai11/cryptopp/issues/855 + HMAC hmac(secret, secretLen); + if (hmac.DigestSize() == 0) + throw InvalidArgument("PKCS5_PBKDF2_HMAC: DigestSize cannot be 0"); + + SecByteBlock buffer(hmac.DigestSize()); + ThreadUserTimer timer; + + unsigned int i=1; + while (derivedLen > 0) + { + hmac.Update(salt, saltLen); + unsigned int j; + for (j=0; j<4; j++) + { + byte b = byte(i >> ((3-j)*8)); + hmac.Update(&b, 1); + } + hmac.Final(buffer); + +#if CRYPTOPP_MSC_VERSION + const size_t segmentLen = STDMIN(derivedLen, buffer.size()); + memcpy_s(derived, segmentLen, buffer, segmentLen); +#else + const size_t segmentLen = STDMIN(derivedLen, buffer.size()); + std::memcpy(derived, buffer, segmentLen); +#endif + + if (timeInSeconds) + { + timeInSeconds = timeInSeconds / ((derivedLen + buffer.size() - 1) / buffer.size()); + timer.StartTimer(); + } + + for (j=1; jPKCS12_PBKDF +/// on the Crypto++ wiki +/// \since Crypto++ 2.0 +template +class PKCS12_PBKDF : public PasswordBasedKeyDerivationFunction +{ +public: + virtual ~PKCS12_PBKDF() {} + + static std::string StaticAlgorithmName () { + const std::string name(std::string("PBKDF_PKCS12(") + + std::string(T::StaticAlgorithmName()) + std::string(")")); + return name; + } + + // KeyDerivationFunction interface + std::string AlgorithmName() const { + return StaticAlgorithmName(); + } + + // TODO - check this + size_t MaxDerivedKeyLength() const { + return static_cast(-1); + } + + // KeyDerivationFunction interface + size_t GetValidDerivedLength(size_t keylength) const; + + // KeyDerivationFunction interface + size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const NameValuePairs& params = g_nullNameValuePairs) const; + + /// \brief Derive a key from a secret seed + /// \param derived the derived output buffer + /// \param derivedLen the size of the derived buffer, in bytes + /// \param purpose a purpose byte + /// \param secret the seed input buffer + /// \param secretLen the size of the secret buffer, in bytes + /// \param salt the salt input buffer + /// \param saltLen the size of the salt buffer, in bytes + /// \param iterations the number of iterations + /// \param timeInSeconds the in seconds + /// \return the number of iterations performed + /// \throw InvalidDerivedKeyLength if derivedLen is invalid for the scheme + /// \details DeriveKey() provides a standard interface to derive a key from + /// a seed and other parameters. Each class that derives from KeyDerivationFunction + /// provides an overload that accepts most parameters used by the derivation function. + /// \details If timeInSeconds is > 0.0 then DeriveKey will run for + /// the specified amount of time. If timeInSeconds is 0.0 then DeriveKey + /// will run for the specified number of iterations. + size_t DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, + const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const; + +protected: + // KeyDerivationFunction interface + const Algorithm & GetAlgorithm() const { + return *this; + } +}; + +template +size_t PKCS12_PBKDF::GetValidDerivedLength(size_t keylength) const +{ + if (keylength > MaxDerivedKeyLength()) + return MaxDerivedKeyLength(); + return keylength; +} + +template +size_t PKCS12_PBKDF::DeriveKey(byte *derived, size_t derivedLen, + const byte *secret, size_t secretLen, const NameValuePairs& params) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + byte purpose = (byte)params.GetIntValueWithDefault("Purpose", 0); + unsigned int iterations = (unsigned int)params.GetIntValueWithDefault("Iterations", 1); + + double timeInSeconds = 0.0f; + (void)params.GetValue("TimeInSeconds", timeInSeconds); + + // NULL or 0 length salt OK + ConstByteArrayParameter salt; + (void)params.GetValue(Name::Salt(), salt); + + return DeriveKey(derived, derivedLen, purpose, secret, secretLen, salt.begin(), salt.size(), iterations, timeInSeconds); +} + +template +size_t PKCS12_PBKDF::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + CRYPTOPP_ASSERT(iterations > 0 || timeInSeconds > 0); + + ThrowIfInvalidDerivedKeyLength(derivedLen); + + // Business logic + if (!iterations) { iterations = 1; } + + const size_t v = T::BLOCKSIZE; // v is in bytes rather than bits as in PKCS #12 + const size_t DLen = v, SLen = RoundUpToMultipleOf(saltLen, v); + const size_t PLen = RoundUpToMultipleOf(secretLen, v), ILen = SLen + PLen; + SecByteBlock buffer(DLen + SLen + PLen); + byte *D = buffer, *S = buffer+DLen, *P = buffer+DLen+SLen, *I = S; + + if (D) // GCC analyzer + std::memset(D, purpose, DLen); + + size_t i; + for (i=0; i 0) + { + hash.CalculateDigest(Ai, buffer, buffer.size()); + + if (timeInSeconds) + { + timeInSeconds = timeInSeconds / ((derivedLen + Ai.size() - 1) / Ai.size()); + timer.StartTimer(); + } + + for (i=1; inext; current; current = current->next) - { - m_tail->next = new ByteQueueNode(*current); - m_tail = m_tail->next; - } - - m_tail->next = nullptr; - - Put(copy.m_lazyString, copy.m_lazyLength); -} - -ByteQueue::~ByteQueue() -{ - Destroy(); -} - -void ByteQueue::Destroy() -{ - ByteQueueNode *next; - - for (ByteQueueNode *current = m_head; current; current = next) - { - next = current->next; - delete current; - } -} - -unsigned long ByteQueue::CurrentSize() const -{ - unsigned long size = 0; - - for (ByteQueueNode *current = m_head; current; current = current->next) - size += current->CurrentSize(); - - return size + m_lazyLength; -} - -bool ByteQueue::IsEmpty() const -{ - return m_head == m_tail && m_head->CurrentSize() == 0 && m_lazyLength == 0; -} - -void ByteQueue::Clear() -{ - Destroy(); - m_head = m_tail = new ByteQueueNode(m_nodeSize); - m_lazyLength = 0; -} - -void ByteQueue::Put(byte inByte) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - if (!m_tail->Put(inByte)) - { - m_tail->next = new ByteQueueNode(m_nodeSize); - m_tail = m_tail->next; - m_tail->Put(inByte); - } -} - -void ByteQueue::Put(const byte *inString, unsigned int length) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - unsigned int len; - while ((len = m_tail->Put(inString, length)) < length) - { - m_tail->next = new ByteQueueNode(m_nodeSize); - m_tail = m_tail->next; - inString += len; - length -= len; - } -} - -void ByteQueue::CleanupUsedNodes() -{ - while (m_head != m_tail && m_head->UsedUp()) - { - ByteQueueNode *temp = m_head; - m_head = m_head->next; - delete temp; - } - - if (m_head->CurrentSize() == 0) - m_head->Clear(); -} - -void ByteQueue::LazyPut(const byte *inString, unsigned int size) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - m_lazyString = inString; - m_lazyLength = size; -} - -void ByteQueue::FinalizeLazyPut() -{ - unsigned int len = m_lazyLength; - m_lazyLength = 0; - Put(m_lazyString, len); -} - -unsigned int ByteQueue::Get(byte &outByte) -{ - if (m_head->Get(outByte)) - { - if (m_head->UsedUp()) - CleanupUsedNodes(); - return 1; - } - else if (m_lazyLength > 0) - { - outByte = *m_lazyString++; - m_lazyLength--; - return 1; - } - else - return 0; -} - -unsigned int ByteQueue::Get(byte *outString, unsigned int getMax) -{ - ArraySink sink(outString, getMax); - return TransferTo(sink, getMax); -} - -unsigned int ByteQueue::Peek(byte &outByte) const -{ - if (m_head->Peek(outByte)) - return 1; - else if (m_lazyLength > 0) - { - outByte = *m_lazyString; - return 1; - } - else - return 0; -} - -unsigned int ByteQueue::Peek(byte *outString, unsigned int peekMax) const -{ - ArraySink sink(outString, peekMax); - return CopyTo(sink, peekMax); -} - -unsigned long ByteQueue::Skip(unsigned long skipMax) -{ - return TransferTo(g_bitBucket, skipMax); -} - -unsigned long ByteQueue::TransferTo(BufferedTransformation &target, unsigned long transferMax) -{ - unsigned long bytesLeft = transferMax; - for (ByteQueueNode *current = m_head; bytesLeft && current; current = current->next) - bytesLeft -= current->TransferTo(target, bytesLeft); - CleanupUsedNodes(); - - unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); - if (len) - { - target.Put(m_lazyString, len); - m_lazyString += len; - m_lazyLength -= len; - bytesLeft -= len; - } - return transferMax - bytesLeft; -} - -unsigned long ByteQueue::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - unsigned long bytesLeft = copyMax; - for (ByteQueueNode *current = m_head; bytesLeft && current; current = current->next) - bytesLeft -= current->CopyTo(target, bytesLeft); - if (bytesLeft && m_lazyLength) - { - unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); - target.Put(m_lazyString, len); - bytesLeft -= len; - } - return copyMax - bytesLeft; -} - -void ByteQueue::Unget(byte inByte) -{ - Unget(&inByte, 1); -} - -void ByteQueue::Unget(const byte *inString, unsigned int length) -{ - ByteQueueNode *newHead = new ByteQueueNode(length); - newHead->next = m_head; - m_head = newHead; - m_head->Put(inString, length); -} -/* -byte * ByteQueue::Spy(unsigned int &contiguousSize) -{ - contiguousSize = m_head->m_tail - m_head->m_head; - return m_head->buf + m_head->m_head; -} -*/ -const byte * ByteQueue::Spy(unsigned int &contiguousSize) const -{ - contiguousSize = m_head->m_tail - m_head->m_head; - if (contiguousSize == 0 && m_lazyLength > 0) - { - contiguousSize = m_lazyLength; - return m_lazyString; - } - else - return m_head->buf + m_head->m_head; -} - -byte * ByteQueue::MakeNewSpace(unsigned int &contiguousSize) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - if (m_tail->m_tail == m_tail->MaxSize()) - { - m_tail->next = new ByteQueueNode(m_nodeSize); - m_tail = m_tail->next; - } - - contiguousSize = m_tail->MaxSize() - m_tail->m_tail; - return m_tail->buf + m_tail->m_tail; -} - -void ByteQueue::OccupyNewSpace(unsigned int size) -{ - m_tail->m_tail += size; - assert(m_tail->m_tail <= m_tail->MaxSize()); -} - -ByteQueue & ByteQueue::operator=(const ByteQueue &rhs) -{ - Destroy(); - CopyFrom(rhs); - return *this; -} - -bool ByteQueue::operator==(const ByteQueue &rhs) const -{ - const unsigned long currentSize = CurrentSize(); - - if (currentSize != rhs.CurrentSize()) - return false; - - Walker walker1(*this), walker2(rhs); - byte b1, b2; - - while (walker1.Get(b1) && walker2.Get(b2)) - if (b1 != b2) - return false; - - return true; -} - -byte ByteQueue::operator[](unsigned long i) const -{ - for (ByteQueueNode *current = m_head; current; current = current->next) - { - if (i < current->CurrentSize()) - return (*current)[i]; - - i -= current->CurrentSize(); - } - - assert(i < m_lazyLength); - return m_lazyString[i]; -} - -void ByteQueue::swap(ByteQueue &rhs) -{ - std::swap(m_nodeSize, rhs.m_nodeSize); - std::swap(m_head, rhs.m_head); - std::swap(m_tail, rhs.m_tail); - std::swap(m_lazyString, rhs.m_lazyString); - std::swap(m_lazyLength, rhs.m_lazyLength); -} - -// ******************************************************** - -unsigned int ByteQueue::Walker::Get(byte &outByte) -{ - ArraySink sink(&outByte, 1); - return TransferTo(sink, 1); -} - -unsigned int ByteQueue::Walker::Get(byte *outString, unsigned int getMax) -{ - ArraySink sink(outString, getMax); - return TransferTo(sink, getMax); -} - -unsigned int ByteQueue::Walker::Peek(byte &outByte) const -{ - ArraySink sink(&outByte, 1); - return CopyTo(sink, 1); -} - -unsigned int ByteQueue::Walker::Peek(byte *outString, unsigned int peekMax) const -{ - ArraySink sink(outString, peekMax); - return CopyTo(sink, peekMax); -} - -unsigned long ByteQueue::Walker::TransferTo(BufferedTransformation &target, unsigned long transferMax) -{ - unsigned long bytesLeft = transferMax; - while (m_node) - { - unsigned int len = STDMIN(bytesLeft, (unsigned long)m_node->CurrentSize() - m_offset); - target.Put(m_node->buf + m_node->m_head + m_offset, len); - m_position += len; - bytesLeft -= len; - - if (!bytesLeft) - { - m_offset += len; - break; - } - - m_node = m_node->next; - m_offset = 0; - } - - unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); - if (len) - { - target.Put(m_lazyString, len); - m_lazyString += len; - m_lazyLength -= len; - bytesLeft -= len; - } - return transferMax - bytesLeft; -} - -unsigned long ByteQueue::Walker::Skip(unsigned long skipMax) -{ - return TransferTo(g_bitBucket, skipMax); -} - -unsigned long ByteQueue::Walker::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - return Walker(*this).TransferTo(target, copyMax); -} - -NAMESPACE_END \ No newline at end of file +// queue.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "queue.h" +#include "filters.h" +#include "misc.h" +#include "trap.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const unsigned int s_maxAutoNodeSize = 16*1024u; + +// this class for use by ByteQueue only +class ByteQueueNode +{ +public: + ByteQueueNode(size_t maxSize) + : m_buf(maxSize) + { + // See GH #962 for the reason for this assert. + CRYPTOPP_ASSERT(maxSize != SIZE_MAX); + + m_head = m_tail = 0; + m_next = NULLPTR; + } + + inline size_t MaxSize() const {return m_buf.size();} + + inline size_t CurrentSize() const + { + return m_tail-m_head; + } + + inline bool UsedUp() const + { + return (m_head==MaxSize()); + } + + inline void Clear() + { + m_head = m_tail = 0; + } + + inline size_t Put(const byte *begin, size_t length) + { + // Avoid passing NULL to memcpy + if (!begin || !length) return length; + size_t l = STDMIN(length, MaxSize()-m_tail); + if (m_buf+m_tail != begin) + memcpy(m_buf+m_tail, begin, l); + m_tail += l; + return l; + } + + inline size_t Peek(byte &outByte) const + { + if (m_tail==m_head) + return 0; + + outByte=m_buf[m_head]; + return 1; + } + + inline size_t Peek(byte *target, size_t copyMax) const + { + size_t len = STDMIN(copyMax, m_tail-m_head); + memcpy(target, m_buf+m_head, len); + return len; + } + + inline size_t CopyTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const + { + size_t len = m_tail-m_head; + target.ChannelPut(channel, m_buf+m_head, len); + return len; + } + + inline size_t CopyTo(BufferedTransformation &target, size_t copyMax, const std::string &channel=DEFAULT_CHANNEL) const + { + size_t len = STDMIN(copyMax, m_tail-m_head); + target.ChannelPut(channel, m_buf+m_head, len); + return len; + } + + inline size_t Get(byte &outByte) + { + size_t len = Peek(outByte); + m_head += len; + return len; + } + + inline size_t Get(byte *outString, size_t getMax) + { + size_t len = Peek(outString, getMax); + m_head += len; + return len; + } + + inline size_t TransferTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) + { + size_t len = m_tail-m_head; + target.ChannelPutModifiable(channel, m_buf+m_head, len); + m_head = m_tail; + return len; + } + + inline size_t TransferTo(BufferedTransformation &target, lword transferMax, const std::string &channel=DEFAULT_CHANNEL) + { + size_t len = UnsignedMin(m_tail-m_head, transferMax); + target.ChannelPutModifiable(channel, m_buf+m_head, len); + m_head += len; + return len; + } + + inline size_t Skip(size_t skipMax) + { + size_t len = STDMIN(skipMax, m_tail-m_head); + m_head += len; + return len; + } + + inline byte operator[](size_t i) const + { + return m_buf[m_head+i]; + } + + ByteQueueNode* m_next; + + SecByteBlock m_buf; + size_t m_head, m_tail; +}; + +// ******************************************************** + +ByteQueue::ByteQueue(size_t nodeSize) + : Bufferless() + , m_head(NULLPTR), m_tail(NULLPTR), m_lazyString(NULLPTR), m_lazyLength(0) + , m_nodeSize(nodeSize), m_lazyStringModifiable(false), m_autoNodeSize(!nodeSize) +{ + // See GH #962 for the reason for this assert. + CRYPTOPP_ASSERT(nodeSize != SIZE_MAX); + + SetNodeSize(nodeSize); + m_head = m_tail = new ByteQueueNode(m_nodeSize); +} + +void ByteQueue::SetNodeSize(size_t nodeSize) +{ + m_autoNodeSize = !nodeSize; + m_nodeSize = m_autoNodeSize ? 256 : nodeSize; +} + +ByteQueue::ByteQueue(const ByteQueue ©) + : Bufferless(copy), m_lazyString(NULLPTR), m_lazyLength(0) +{ + CopyFrom(copy); +} + +void ByteQueue::CopyFrom(const ByteQueue ©) +{ + m_lazyLength = 0; + m_autoNodeSize = copy.m_autoNodeSize; + m_nodeSize = copy.m_nodeSize; + m_head = m_tail = new ByteQueueNode(*copy.m_head); + + for (ByteQueueNode *current=copy.m_head->m_next; current; current=current->m_next) + { + m_tail->m_next = new ByteQueueNode(*current); + m_tail = m_tail->m_next; + } + + m_tail->m_next = NULLPTR; + + Put(copy.m_lazyString, copy.m_lazyLength); +} + +ByteQueue::~ByteQueue() +{ + Destroy(); +} + +void ByteQueue::Destroy() +{ + for (ByteQueueNode *next, *current=m_head; current; current=next) + { + next=current->m_next; + delete current; + } +} + +void ByteQueue::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_nodeSize = parameters.GetIntValueWithDefault("NodeSize", 256); + Clear(); +} + +lword ByteQueue::CurrentSize() const +{ + lword size=0; + + for (ByteQueueNode *current=m_head; current; current=current->m_next) + size += current->CurrentSize(); + + return size + m_lazyLength; +} + +bool ByteQueue::IsEmpty() const +{ + return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0; +} + +void ByteQueue::Clear() +{ + for (ByteQueueNode *next, *current=m_head->m_next; current; current=next) + { + next=current->m_next; + delete current; + } + + m_tail = m_head; + m_head->Clear(); + m_head->m_next = NULLPTR; + m_lazyLength = 0; +} + +size_t ByteQueue::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + CRYPTOPP_UNUSED(messageEnd), CRYPTOPP_UNUSED(blocking); + + if (m_lazyLength > 0) + FinalizeLazyPut(); + + size_t len; + while ((len=m_tail->Put(inString, length)) < length) + { + inString = PtrAdd(inString, len); + length -= len; + if (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize) + { + do + { + m_nodeSize *= 2; + } + while (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize); + } + m_tail->m_next = new ByteQueueNode(STDMAX(m_nodeSize, length)); + m_tail = m_tail->m_next; + } + + return 0; +} + +void ByteQueue::CleanupUsedNodes() +{ + // Test for m_head due to Enterprise Anlysis finding + while (m_head && m_head != m_tail && m_head->UsedUp()) + { + ByteQueueNode *temp=m_head; + m_head=m_head->m_next; + delete temp; + } + + // Test for m_head due to Enterprise Anlysis finding + if (m_head && m_head->CurrentSize() == 0) + m_head->Clear(); +} + +void ByteQueue::LazyPut(const byte *inString, size_t size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + if (inString == m_tail->m_buf+m_tail->m_tail) + Put(inString, size); + else + { + m_lazyString = const_cast(inString); + m_lazyLength = size; + m_lazyStringModifiable = false; + } +} + +void ByteQueue::LazyPutModifiable(byte *inString, size_t size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + m_lazyString = inString; + m_lazyLength = size; + m_lazyStringModifiable = true; +} + +void ByteQueue::UndoLazyPut(size_t size) +{ + if (m_lazyLength < size) + throw InvalidArgument("ByteQueue: size specified for UndoLazyPut is too large"); + + m_lazyLength -= size; +} + +void ByteQueue::FinalizeLazyPut() +{ + size_t len = m_lazyLength; + m_lazyLength = 0; + if (len) + Put(m_lazyString, len); +} + +size_t ByteQueue::Get(byte &outByte) +{ + if (m_head->Get(outByte)) + { + if (m_head->UsedUp()) + CleanupUsedNodes(); + return 1; + } + else if (m_lazyLength > 0) + { + outByte = *m_lazyString++; + m_lazyLength--; + return 1; + } + else + return 0; +} + +size_t ByteQueue::Get(byte *outString, size_t getMax) +{ + ArraySink sink(outString, getMax); + return (size_t)TransferTo(sink, getMax); +} + +size_t ByteQueue::Peek(byte &outByte) const +{ + if (m_head->Peek(outByte)) + return 1; + else if (m_lazyLength > 0) + { + outByte = *m_lazyString; + return 1; + } + else + return 0; +} + +size_t ByteQueue::Peek(byte *outString, size_t peekMax) const +{ + ArraySink sink(outString, peekMax); + return (size_t)CopyTo(sink, peekMax); +} + +size_t ByteQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + // No need for CRYPTOPP_ASSERT on transferBytes here. + // TransferTo2 handles LWORD_MAX as expected. + + if (blocking) + { + lword bytesLeft = transferBytes; + for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->m_next) + bytesLeft -= current->TransferTo(target, bytesLeft, channel); + CleanupUsedNodes(); + + size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); + if (len) + { + if (m_lazyStringModifiable) + target.ChannelPutModifiable(channel, m_lazyString, len); + else + target.ChannelPut(channel, m_lazyString, len); + m_lazyString = PtrAdd(m_lazyString, len); + m_lazyLength -= len; + bytesLeft -= len; + } + transferBytes -= bytesLeft; + return 0; + } + else + { + Walker walker(*this); + size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); + Skip(transferBytes); + return blockedBytes; + } +} + +size_t ByteQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + Walker walker(*this); + walker.Skip(begin); + lword transferBytes = end-begin; + + size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); + begin += transferBytes; + return blockedBytes; +} + +void ByteQueue::Unget(byte inByte) +{ + Unget(&inByte, 1); +} + +void ByteQueue::Unget(const byte *inString, size_t length) +{ + // See GH #962 for the reason for this assert. + CRYPTOPP_ASSERT(length != SIZE_MAX); + + size_t len = STDMIN(length, m_head->m_head); + length -= len; + m_head->m_head = m_head->m_head - len; + memcpy(m_head->m_buf + m_head->m_head, inString + length, len); + + if (length > 0) + { + ByteQueueNode *newHead = new ByteQueueNode(length); + newHead->m_next = m_head; + m_head = newHead; + m_head->Put(inString, length); + } +} + +const byte * ByteQueue::Spy(size_t &contiguousSize) const +{ + contiguousSize = m_head->m_tail - m_head->m_head; + if (contiguousSize == 0 && m_lazyLength > 0) + { + contiguousSize = m_lazyLength; + return m_lazyString; + } + else + return m_head->m_buf + m_head->m_head; +} + +byte * ByteQueue::CreatePutSpace(size_t &size) +{ + // See GH #962 for the reason for this assert. + CRYPTOPP_ASSERT(size != SIZE_MAX); + // Sanity check for a reasonable size + CRYPTOPP_ASSERT(size <= 16U*1024*1024); + + if (m_lazyLength > 0) + FinalizeLazyPut(); + + if (m_tail->m_tail == m_tail->MaxSize()) + { + m_tail->m_next = new ByteQueueNode(STDMAX(m_nodeSize, size)); + m_tail = m_tail->m_next; + } + + size = m_tail->MaxSize() - m_tail->m_tail; + return PtrAdd(m_tail->m_buf.begin(), m_tail->m_tail); +} + +ByteQueue & ByteQueue::operator=(const ByteQueue &rhs) +{ + Destroy(); + CopyFrom(rhs); + return *this; +} + +bool ByteQueue::operator==(const ByteQueue &rhs) const +{ + const lword currentSize = CurrentSize(); + + if (currentSize != rhs.CurrentSize()) + return false; + + Walker walker1(*this), walker2(rhs); + byte b1, b2; + + while (walker1.Get(b1) && walker2.Get(b2)) + if (b1 != b2) + return false; + + return true; +} + +byte ByteQueue::operator[](lword index) const +{ + for (ByteQueueNode *current=m_head; current; current=current->m_next) + { + if (index < current->CurrentSize()) + return (*current)[(size_t)index]; + + index -= current->CurrentSize(); + } + + CRYPTOPP_ASSERT(index < m_lazyLength); + return m_lazyString[index]; +} + +void ByteQueue::swap(ByteQueue &rhs) +{ + std::swap(m_autoNodeSize, rhs.m_autoNodeSize); + std::swap(m_nodeSize, rhs.m_nodeSize); + std::swap(m_head, rhs.m_head); + std::swap(m_tail, rhs.m_tail); + std::swap(m_lazyString, rhs.m_lazyString); + std::swap(m_lazyLength, rhs.m_lazyLength); + std::swap(m_lazyStringModifiable, rhs.m_lazyStringModifiable); +} + +// ******************************************************** + +void ByteQueue::Walker::IsolatedInitialize(const NameValuePairs ¶meters) +{ + CRYPTOPP_UNUSED(parameters); + + m_node = m_queue.m_head; + m_position = 0; + m_offset = 0; + m_lazyString = m_queue.m_lazyString; + m_lazyLength = m_queue.m_lazyLength; +} + +size_t ByteQueue::Walker::Get(byte &outByte) +{ + ArraySink sink(&outByte, 1); + return (size_t)TransferTo(sink, 1); +} + +size_t ByteQueue::Walker::Get(byte *outString, size_t getMax) +{ + ArraySink sink(outString, getMax); + return (size_t)TransferTo(sink, getMax); +} + +size_t ByteQueue::Walker::Peek(byte &outByte) const +{ + ArraySink sink(&outByte, 1); + return (size_t)CopyTo(sink, 1); +} + +size_t ByteQueue::Walker::Peek(byte *outString, size_t peekMax) const +{ + ArraySink sink(outString, peekMax); + return (size_t)CopyTo(sink, peekMax); +} + +size_t ByteQueue::Walker::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + // No need for CRYPTOPP_ASSERT on transferBytes here. + // TransferTo2 handles LWORD_MAX as expected. + + lword bytesLeft = transferBytes; + size_t blockedBytes = 0; + + while (m_node) + { + size_t len = (size_t)STDMIN(bytesLeft, (lword)m_node->CurrentSize()-m_offset); + blockedBytes = target.ChannelPut2(channel, m_node->m_buf+m_node->m_head+m_offset, len, 0, blocking); + + if (blockedBytes) + goto done; + + m_position += len; + bytesLeft -= len; + + if (!bytesLeft) + { + m_offset += len; + goto done; + } + + m_node = m_node->m_next; + m_offset = 0; + } + + if (bytesLeft && m_lazyLength) + { + size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); + blockedBytes = target.ChannelPut2(channel, m_lazyString, len, 0, blocking); + if (blockedBytes) + goto done; + + m_lazyString = PtrAdd(m_lazyString, len); + m_lazyLength -= len; + bytesLeft -= len; + } + +done: + transferBytes -= bytesLeft; + return blockedBytes; +} + +size_t ByteQueue::Walker::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + Walker walker(*this); + walker.Skip(begin); + lword transferBytes = end-begin; + + size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); + begin += transferBytes; + return blockedBytes; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/queue.h b/external/ours/library/crypto/src/shared/original/queue.h index 76cf58d7f..f2d0dc53f 100755 --- a/external/ours/library/crypto/src/shared/original/queue.h +++ b/external/ours/library/crypto/src/shared/original/queue.h @@ -1,128 +1,272 @@ -// specification file for an unlimited queue for storing bytes - -#ifndef CRYPTOPP_QUEUE_H -#define CRYPTOPP_QUEUE_H - -#include "cryptlib.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -/** The queue is implemented as a linked list of arrays, but you don't need to - know about that. So just ignore this next line. :) */ -class ByteQueueNode; - -//! Byte Queue -class ByteQueue : public BufferedTransformation -{ -public: - ByteQueue(unsigned int m_nodeSize=256); - ByteQueue(const ByteQueue ©); - ~ByteQueue(); - - unsigned long MaxRetrievable() const - {return CurrentSize();} - bool AnyRetrievable() const - {return !IsEmpty();} - - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - - unsigned int Get(byte &outByte); - unsigned int Get(byte *outString, unsigned int getMax); - - unsigned int Peek(byte &outByte) const; - unsigned int Peek(byte *outString, unsigned int peekMax) const; - - unsigned long Skip(unsigned long skipMax=ULONG_MAX); - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - - // these member functions are not inherited - unsigned long CurrentSize() const; - bool IsEmpty() const; - - void Clear(); - - void Unget(byte inByte); - void Unget(const byte *inString, unsigned int length); - - const byte * Spy(unsigned int &contiguousSize) const; - - byte * MakeNewSpace(unsigned int &contiguousSize); - void OccupyNewSpace(unsigned int size); - - void LazyPut(const byte *inString, unsigned int size); - void FinalizeLazyPut(); - - ByteQueue & operator=(const ByteQueue &rhs); - bool operator==(const ByteQueue &rhs) const; - byte operator[](unsigned long i) const; - void swap(ByteQueue &rhs); - - class Walker : public BufferedTransformation - { - public: - Walker(const ByteQueue &queue) - : m_queue(queue), m_node(queue.m_head), m_position(0), m_offset(0) - , m_lazyString(queue.m_lazyString), m_lazyLength(queue.m_lazyLength) {} - - unsigned long MaxRetrievable() const - {return m_queue.CurrentSize() - m_position;} - - void Put(byte inByte) {} - void Put(const byte *inString, unsigned int length) {} - - unsigned int Get(byte &outByte); - unsigned int Get(byte *outString, unsigned int getMax); - - unsigned int Peek(byte &outByte) const; - unsigned int Peek(byte *outString, unsigned int peekMax) const; - - unsigned long Skip(unsigned long skipMax=ULONG_MAX); - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - - private: - const ByteQueue &m_queue; - const ByteQueueNode *m_node; - unsigned int m_position, m_offset; - const byte *m_lazyString; - unsigned int m_lazyLength; - }; - - friend class Walker; - -private: - void CleanupUsedNodes(); - void CopyFrom(const ByteQueue ©); - void Destroy(); - - unsigned int m_nodeSize; - ByteQueueNode *m_head, *m_tail; - const byte *m_lazyString; - unsigned int m_lazyLength; -}; - -//! use this to make sure LazyPut is finalized in event of exception -class LazyPutter -{ -public: - LazyPutter(ByteQueue &bq, const byte *inString, unsigned int size) - : m_bq(bq) {bq.LazyPut(inString, size);} - ~LazyPutter() - {try {m_bq.FinalizeLazyPut();} catch(...) {}} -private: - ByteQueue &m_bq; -}; - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) -{ - a.swap(b); -} -NAMESPACE_END - -#endif +// queue.h - originally written and placed in the public domain by Wei Dai + +/// \file +/// \brief Classes for an unlimited queue to store bytes + +#ifndef CRYPTOPP_QUEUE_H +#define CRYPTOPP_QUEUE_H + +#include "cryptlib.h" +#include "simple.h" + +NAMESPACE_BEGIN(CryptoPP) + +class ByteQueueNode; + +/// \brief Data structure used to store byte strings +/// \details The queue is implemented as a linked list of byte arrays. +/// Each byte array is stored in a ByteQueueNode. +/// \sa ByteQueue +/// on the Crypto++ wiki. +/// \since Crypto++ 2.0 +class CRYPTOPP_DLL ByteQueue : public Bufferless +{ +public: + virtual ~ByteQueue(); + + /// \brief Construct a ByteQueue + /// \param nodeSize the initial node size + /// \details Internally, ByteQueue uses a ByteQueueNode to store bytes, + /// and nodeSize determines the size of the ByteQueueNode. A value + /// of 0 indicates the ByteQueueNode should be automatically sized, + /// which means a value of 256 is used. + ByteQueue(size_t nodeSize=0); + + /// \brief Copy construct a ByteQueue + /// \param copy the other ByteQueue + ByteQueue(const ByteQueue ©); + + // BufferedTransformation + lword MaxRetrievable() const + {return CurrentSize();} + bool AnyRetrievable() const + {return !IsEmpty();} + + void IsolatedInitialize(const NameValuePairs ¶meters); + byte * CreatePutSpace(size_t &size); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + + size_t Get(byte &outByte); + size_t Get(byte *outString, size_t getMax); + + size_t Peek(byte &outByte) const; + size_t Peek(byte *outString, size_t peekMax) const; + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + + /// \brief Set node size + /// \param nodeSize the new node size, in bytes + /// \details The default node size is 256. + void SetNodeSize(size_t nodeSize); + + /// \brief Determine data size + /// \return the data size, in bytes + lword CurrentSize() const; + + /// \brief Determine data availability + /// \return true if the ByteQueue has data, false otherwise + bool IsEmpty() const; + + /// \brief Empty the queue + void Clear(); + + /// \brief Insert data in the queue + /// \param inByte a byte to insert + /// \details Unget() inserts a byte at the head of the queue + void Unget(byte inByte); + + /// \brief Insert data in the queue + /// \param inString a byte array to insert + /// \param length the size of the byte array + /// \details Unget() inserts a byte array at the head of the queue + void Unget(const byte *inString, size_t length); + + /// \brief Peek data in the queue + /// \param contiguousSize the size of the data + /// \details Spy() peeks at data at the head of the queue. Spy() does + /// not remove data from the queue. + /// \details The data's size is returned in contiguousSize. + /// Spy() returns the size of the first byte array in the list. The + /// entire data may be larger since the queue is a linked list of + /// byte arrays. + const byte * Spy(size_t &contiguousSize) const; + + /// \brief Insert data in the queue + /// \param inString a byte array to insert + /// \param size the length of the byte array + /// \details LazyPut() inserts a byte array at the tail of the queue. + /// The data may not be copied at this point. Rather, the pointer + /// and size to external data are recorded. + /// \details Another call to Put() or LazyPut() will force the data to + /// be copied. When lazy puts are used, the data is copied when + /// FinalizeLazyPut() is called. + /// \sa LazyPutter + void LazyPut(const byte *inString, size_t size); + + /// \brief Insert data in the queue + /// \param inString a byte array to insert + /// \param size the length of the byte array + /// \details LazyPut() inserts a byte array at the tail of the queue. + /// The data may not be copied at this point. Rather, the pointer + /// and size to external data are recorded. + /// \details Another call to Put() or LazyPut() will force the data to + /// be copied. When lazy puts are used, the data is copied when + /// FinalizeLazyPut() is called. + /// \sa LazyPutter + void LazyPutModifiable(byte *inString, size_t size); + + /// \brief Remove data from the queue + /// \param size the length of the data + /// \throw InvalidArgument if there is no lazy data in the queue or if + /// size is larger than the lazy string + /// \details UndoLazyPut() truncates data inserted using LazyPut() by + /// modifying size. + /// \sa LazyPutter + void UndoLazyPut(size_t size); + + /// \brief Insert data in the queue + /// \details FinalizeLazyPut() copies external data inserted using + /// LazyPut() or LazyPutModifiable() into the tail of the queue. + /// \sa LazyPutter + void FinalizeLazyPut(); + + /// \brief Assign contents from another ByteQueue + /// \param rhs the other ByteQueue + /// \return reference to this ByteQueue + ByteQueue & operator=(const ByteQueue &rhs); + + /// \brief Bitwise compare two ByteQueue + /// \param rhs the other ByteQueue + /// \return true if the size and bits are equal, false otherwise + /// \details operator==() walks each ByteQueue comparing bytes in + /// each queue. operator==() is not constant time. + bool operator==(const ByteQueue &rhs) const; + + /// \brief Bitwise compare two ByteQueue + /// \param rhs the other ByteQueue + /// \return true if the size and bits are not equal, false otherwise + /// \details operator!=() is implemented in terms of operator==(). + /// operator==() is not constant time. + bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);} + + /// \brief Retrieve data from the queue + /// \param index of byte to retrieve + /// \return byte at the specified index + /// \details operator[]() does not perform bounds checking. + byte operator[](lword index) const; + + /// \brief Swap contents with another ByteQueue + /// \param rhs the other ByteQueue + void swap(ByteQueue &rhs); + + /// \brief A ByteQueue iterator + class Walker : public InputRejecting + { + public: + /// \brief Construct a ByteQueue Walker + /// \param queue a ByteQueue + Walker(const ByteQueue &queue) + : m_queue(queue), m_node(NULLPTR), m_position(0), m_offset(0), m_lazyString(NULLPTR), m_lazyLength(0) + {Initialize();} + + lword GetCurrentPosition() {return m_position;} + + lword MaxRetrievable() const + {return m_queue.CurrentSize() - m_position;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + + size_t Get(byte &outByte); + size_t Get(byte *outString, size_t getMax); + + size_t Peek(byte &outByte) const; + size_t Peek(byte *outString, size_t peekMax) const; + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; + + private: + const ByteQueue &m_queue; + const ByteQueueNode *m_node; + lword m_position; + size_t m_offset; + const byte *m_lazyString; + size_t m_lazyLength; + }; + + friend class Walker; + +protected: + void CleanupUsedNodes(); + void CopyFrom(const ByteQueue ©); + void Destroy(); + +private: + ByteQueueNode *m_head, *m_tail; + byte *m_lazyString; + size_t m_lazyLength; + size_t m_nodeSize; + bool m_lazyStringModifiable; + bool m_autoNodeSize; +}; + +/// \brief Helper class to finalize Puts on ByteQueue +/// \details LazyPutter ensures LazyPut is committed to the ByteQueue +/// in event of exception. During destruction, the LazyPutter class +/// calls FinalizeLazyPut. +class CRYPTOPP_DLL LazyPutter +{ +public: + virtual ~LazyPutter() { + try {m_bq.FinalizeLazyPut();} + catch(const Exception&) {CRYPTOPP_ASSERT(0);} + } + + /// \brief Construct a LazyPutter + /// \param bq the ByteQueue + /// \param inString a byte array to insert + /// \param size the length of the byte array + /// \details LazyPutter ensures LazyPut is committed to the ByteQueue + /// in event of exception. During destruction, the LazyPutter class + /// calls FinalizeLazyPut. + LazyPutter(ByteQueue &bq, const byte *inString, size_t size) + : m_bq(bq) {bq.LazyPut(inString, size);} + +protected: + LazyPutter(ByteQueue &bq) : m_bq(bq) {} + +private: + ByteQueue &m_bq; +}; + +/// \brief Helper class to finalize Puts on ByteQueue +/// \details LazyPutterModifiable ensures LazyPut is committed to the +/// ByteQueue in event of exception. During destruction, the +/// LazyPutterModifiable class calls FinalizeLazyPut. +class LazyPutterModifiable : public LazyPutter +{ +public: + /// \brief Construct a LazyPutterModifiable + /// \param bq the ByteQueue + /// \param inString a byte array to insert + /// \param size the length of the byte array + /// \details LazyPutterModifiable ensures LazyPut is committed to the + /// ByteQueue in event of exception. During destruction, the + /// LazyPutterModifiable class calls FinalizeLazyPut. + LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size) + : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);} +}; + +NAMESPACE_END + +#ifndef __BORLANDC__ +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) +{ + a.swap(b); +} +NAMESPACE_END +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rabbit.cpp b/external/ours/library/crypto/src/shared/original/rabbit.cpp new file mode 100755 index 000000000..4f6551117 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rabbit.cpp @@ -0,0 +1,259 @@ +// rabbit.cpp - written and placed in the public domain by Jeffrey Walton +// based on public domain code by Martin Boesgaard, Mette Vesterager, +// Thomas Pedersen, Jesper Christiansen and Ove Scavenius. +// +// The reference materials and source files are available at +// The eSTREAM Project, http://www.ecrypt.eu.org/stream/e2-rabbit.html. + +#include "pch.h" +#include "config.h" + +#include "rabbit.h" +#include "secblock.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlConstant; + +word32 G_func(word32 x) +{ +#if 0 + /* Temporary variables */ + word32 a, b, h, l; + + /* Construct high and low argument for squaring */ + a = x & 0xFFFF; + b = x >> 16; + + /* Calculate high and low result of squaring */ + h = (((static_cast(a*a) >> 17U) + static_cast(a*b)) >> 15U) + b*b; + l = x*x; + + /* Return high XOR low */ + return static_cast(h^l); +#endif + + // Thanks to Jack Lloyd for suggesting the 64-bit multiply. + word64 z = x; + z *= x; + return static_cast((z >> 32) ^ z); +} + +word32 NextState(word32 c[8], word32 x[8], word32 carry) +{ + /* Temporary variables */ + word32 g[8], c_old[8], i; + + /* Save old counter values */ + for (i = 0; i<8; i++) + c_old[i] = c[i]; + + /* Calculate new counter values */ + c[0] = static_cast(c[0] + 0x4D34D34D + carry); + c[1] = static_cast(c[1] + 0xD34D34D3 + (c[0] < c_old[0])); + c[2] = static_cast(c[2] + 0x34D34D34 + (c[1] < c_old[1])); + c[3] = static_cast(c[3] + 0x4D34D34D + (c[2] < c_old[2])); + c[4] = static_cast(c[4] + 0xD34D34D3 + (c[3] < c_old[3])); + c[5] = static_cast(c[5] + 0x34D34D34 + (c[4] < c_old[4])); + c[6] = static_cast(c[6] + 0x4D34D34D + (c[5] < c_old[5])); + c[7] = static_cast(c[7] + 0xD34D34D3 + (c[6] < c_old[6])); + carry = (c[7] < c_old[7]); + + /* Calculate the g-values */ + for (i = 0; i<8; i++) + g[i] = G_func(static_cast(x[i] + c[i])); + + /* Calculate new state values */ + x[0] = static_cast(g[0] + rotlConstant<16>(g[7]) + rotlConstant<16>(g[6])); + x[1] = static_cast(g[1] + rotlConstant<8>(g[0]) + g[7]); + x[2] = static_cast(g[2] + rotlConstant<16>(g[1]) + rotlConstant<16>(g[0])); + x[3] = static_cast(g[3] + rotlConstant<8>(g[2]) + g[1]); + x[4] = static_cast(g[4] + rotlConstant<16>(g[3]) + rotlConstant<16>(g[2])); + x[5] = static_cast(g[5] + rotlConstant<8>(g[4]) + g[3]); + x[6] = static_cast(g[6] + rotlConstant<16>(g[5]) + rotlConstant<16>(g[4])); + x[7] = static_cast(g[7] + rotlConstant<8>(g[6]) + g[5]); + + return carry; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void RabbitPolicy::CipherSetKey(const NameValuePairs ¶ms, const byte *userKey, size_t keylen) +{ + /* Generate four subkeys */ + CRYPTOPP_UNUSED(params); + GetUserKey(LITTLE_ENDIAN_ORDER, m_t.begin(), 4, userKey, keylen); + + /* Generate initial state variables */ + m_mx[0] = m_t[0]; + m_mx[2] = m_t[1]; + m_mx[4] = m_t[2]; + m_mx[6] = m_t[3]; + m_mx[1] = static_cast(m_t[3] << 16) | (m_t[2] >> 16); + m_mx[3] = static_cast(m_t[0] << 16) | (m_t[3] >> 16); + m_mx[5] = static_cast(m_t[1] << 16) | (m_t[0] >> 16); + m_mx[7] = static_cast(m_t[2] << 16) | (m_t[1] >> 16); + + /* Generate initial counter values */ + m_mc[0] = rotlConstant<16>(m_t[2]); + m_mc[2] = rotlConstant<16>(m_t[3]); + m_mc[4] = rotlConstant<16>(m_t[0]); + m_mc[6] = rotlConstant<16>(m_t[1]); + m_mc[1] = (m_t[0] & 0xFFFF0000) | (m_t[1] & 0xFFFF); + m_mc[3] = (m_t[1] & 0xFFFF0000) | (m_t[2] & 0xFFFF); + m_mc[5] = (m_t[2] & 0xFFFF0000) | (m_t[3] & 0xFFFF); + m_mc[7] = (m_t[3] & 0xFFFF0000) | (m_t[0] & 0xFFFF); + + /* Clear carry bit */ + m_mcy = 0; + + /* Iterate the system four times */ + for (unsigned int i = 0; i<4; i++) + m_mcy = NextState(m_mc, m_mx, m_mcy); + + /* Modify the counters */ + for (unsigned int i = 0; i<8; i++) + m_mc[i] ^= m_mx[(i + 4) & 0x7]; + + /* Copy master instance to work instance */ + for (unsigned int i = 0; i<8; i++) + { + m_wx[i] = m_mx[i]; + m_wc[i] = m_mc[i]; + } + m_wcy = m_mcy; +} + +void RabbitPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + byte* out = output; + for (size_t i = 0; i> 16) ^ (m_wx[3] << 16)); + PutWord(false, LITTLE_ENDIAN_ORDER, out + 4, m_wx[2] ^ (m_wx[7] >> 16) ^ (m_wx[5] << 16)); + PutWord(false, LITTLE_ENDIAN_ORDER, out + 8, m_wx[4] ^ (m_wx[1] >> 16) ^ (m_wx[7] << 16)); + PutWord(false, LITTLE_ENDIAN_ORDER, out + 12, m_wx[6] ^ (m_wx[3] >> 16) ^ (m_wx[1] << 16)); + } + + // If AdditiveCipherTemplate does not have an accumulated keystream + // then it will ask OperateKeystream to generate one. Optionally it + // will ask for an XOR of the input with the keystream while + // writing the result to the output buffer. In all cases the + // keystream is written to the output buffer. The optional part is + // adding the input buffer and keystream. + if ((operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL)) + xorbuf(output, input, GetBytesPerIteration() * iterationCount); +} + +void RabbitWithIVPolicy::CipherSetKey(const NameValuePairs ¶ms, const byte *userKey, size_t keylen) +{ + /* Generate four subkeys */ + CRYPTOPP_UNUSED(params); + GetUserKey(LITTLE_ENDIAN_ORDER, m_t.begin(), 4, userKey, keylen); + + /* Generate initial state variables */ + m_mx[0] = m_t[0]; + m_mx[2] = m_t[1]; + m_mx[4] = m_t[2]; + m_mx[6] = m_t[3]; + m_mx[1] = static_cast(m_t[3] << 16) | (m_t[2] >> 16); + m_mx[3] = static_cast(m_t[0] << 16) | (m_t[3] >> 16); + m_mx[5] = static_cast(m_t[1] << 16) | (m_t[0] >> 16); + m_mx[7] = static_cast(m_t[2] << 16) | (m_t[1] >> 16); + + /* Generate initial counter values */ + m_mc[0] = rotlConstant<16>(m_t[2]); + m_mc[2] = rotlConstant<16>(m_t[3]); + m_mc[4] = rotlConstant<16>(m_t[0]); + m_mc[6] = rotlConstant<16>(m_t[1]); + m_mc[1] = (m_t[0] & 0xFFFF0000) | (m_t[1] & 0xFFFF); + m_mc[3] = (m_t[1] & 0xFFFF0000) | (m_t[2] & 0xFFFF); + m_mc[5] = (m_t[2] & 0xFFFF0000) | (m_t[3] & 0xFFFF); + m_mc[7] = (m_t[3] & 0xFFFF0000) | (m_t[0] & 0xFFFF); + + /* Clear carry bit */ + m_mcy = 0; + + /* Iterate the system four times */ + for (unsigned int i = 0; i<4; i++) + m_mcy = NextState(m_mc, m_mx, m_mcy); + + /* Modify the counters */ + for (unsigned int i = 0; i<8; i++) + m_mc[i] ^= m_mx[(i + 4) & 0x7]; + + /* Copy master instance to work instance */ + for (unsigned int i = 0; i<8; i++) + { + m_wx[i] = m_mx[i]; + m_wc[i] = m_mc[i]; + } + m_wcy = m_mcy; +} + +void RabbitWithIVPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer); + CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length == 8); + + /* Generate four subvectors */ + GetBlock v(iv); v(m_t[0])(m_t[2]); + m_t[1] = (m_t[0] >> 16) | (m_t[2] & 0xFFFF0000); + m_t[3] = (m_t[2] << 16) | (m_t[0] & 0x0000FFFF); + + /* Modify counter values */ + m_wc[0] = m_mc[0] ^ m_t[0]; + m_wc[1] = m_mc[1] ^ m_t[1]; + m_wc[2] = m_mc[2] ^ m_t[2]; + m_wc[3] = m_mc[3] ^ m_t[3]; + m_wc[4] = m_mc[4] ^ m_t[0]; + m_wc[5] = m_mc[5] ^ m_t[1]; + m_wc[6] = m_mc[6] ^ m_t[2]; + m_wc[7] = m_mc[7] ^ m_t[3]; + + /* Copy state variables */ + for (unsigned int i = 0; i<8; i++) + m_wx[i] = m_mx[i]; + m_wcy = m_mcy; + + /* Iterate the system four times */ + for (unsigned int i = 0; i<4; i++) + m_wcy = NextState(m_wc, m_wx, m_wcy); +} + +void RabbitWithIVPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + byte* out = output; + for (unsigned int i = 0; i> 16) ^ (m_wx[3] << 16)); + PutWord(false, LITTLE_ENDIAN_ORDER, out + 4, m_wx[2] ^ (m_wx[7] >> 16) ^ (m_wx[5] << 16)); + PutWord(false, LITTLE_ENDIAN_ORDER, out + 8, m_wx[4] ^ (m_wx[1] >> 16) ^ (m_wx[7] << 16)); + PutWord(false, LITTLE_ENDIAN_ORDER, out + 12, m_wx[6] ^ (m_wx[3] >> 16) ^ (m_wx[1] << 16)); + } + + // If AdditiveCipherTemplate does not have an accumulated keystream + // then it will ask OperateKeystream to generate one. Optionally it + // will ask for an XOR of the input with the keystream while + // writing the result to the output buffer. In all cases the + // keystream is written to the output buffer. The optional part is + // adding the input buffer and keystream. + if ((operation & EnumToInt(INPUT_NULL)) != EnumToInt(INPUT_NULL)) + xorbuf(output, input, GetBytesPerIteration() * iterationCount); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/rabbit.h b/external/ours/library/crypto/src/shared/original/rabbit.h new file mode 100755 index 000000000..6601dcd19 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rabbit.h @@ -0,0 +1,112 @@ +// rabbit.h - written and placed in the public domain by Jeffrey Walton +// based on public domain code by Martin Boesgaard, Mette Vesterager, +// Thomas Pedersen, Jesper Christiansen and Ove Scavenius. +// +// The reference materials and source files are available at +// The eSTREAM Project, http://www.ecrypt.eu.org/stream/e2-rabbit.html. + +/// \file rabbit.h +/// \brief Classes for Rabbit stream cipher +/// \sa The +/// eSTREAM Project | Rabbit and +/// Crypto++ Wiki | Rabbit. +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_RABBIT_H +#define CRYPTOPP_RABBIT_H + +#include "strciphr.h" +#include "secblock.h" + +// The library does not have a way to describe an optional IV. Rabbit takes +// an optional IV so two classes are offered to bridge the gap. One provides +// Rabbit without an IV and the second provides Rabbit with an IV. + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Rabbit stream cipher information +/// \since Crypto++ 8.0 +struct RabbitInfo : public FixedKeyLength<16, SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "Rabbit"; } +}; + +/// \brief Rabbit stream cipher information +/// \since Crypto++ 8.0 +struct RabbitWithIVInfo : public FixedKeyLength<16, SimpleKeyingInterface::UNIQUE_IV, 8> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RabbitWithIV"; } +}; + +/// \brief Rabbit stream cipher implementation +/// \since Crypto++ 8.0 +class RabbitPolicy : public AdditiveCipherConcretePolicy, public RabbitInfo +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + bool CanOperateKeystream() const { return true; } + bool CipherIsRandomAccess() const { return false; } + +private: + // Master and working states + FixedSizeSecBlock m_mx, m_mc, m_wx, m_wc; + // Workspace + FixedSizeSecBlock m_t; + word32 m_mcy, m_wcy; // carry +}; + +/// \brief Rabbit stream cipher implementation +/// \since Crypto++ 8.0 +class RabbitWithIVPolicy : public AdditiveCipherConcretePolicy, public RabbitWithIVInfo +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); + bool CanOperateKeystream() const { return true; } + bool CipherIsRandomAccess() const { return false; } + +private: + // Master and working states + FixedSizeSecBlock m_mx, m_mc, m_wx, m_wc; + // Workspace + FixedSizeSecBlock m_t; + word32 m_mcy, m_wcy; // carry +}; + +/// \brief Rabbit stream cipher +/// \details Rabbit is a stream cipher developed by Martin Boesgaard, Mette Vesterager, +/// Thomas Pedersen, Jesper Christiansen and Ove Scavenius. Rabbit is one of the final four +/// Profile 1 (software) ciphers selected for the eSTREAM portfolio. +/// \details Crypto++ provides Rabbit and RabbitWithIV classes. Two classes are necessary +/// because the library lacks the means to describe and manage optional IVs. +/// \sa RabbitWithIV, The +/// eSTREAM Project | Rabbit and +/// Crypto++ Wiki | Rabbit. +/// \since Crypto++ 8.0 +struct Rabbit : public RabbitInfo, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, RabbitInfo> Encryption; + typedef Encryption Decryption; +}; + +/// \brief Rabbit stream cipher +/// \details Rabbit is a stream cipher developed by Martin Boesgaard, Mette Vesterager, +/// Thomas Pedersen, Jesper Christiansen and Ove Scavenius. Rabbit is one of the final four +/// Profile 1 (software) ciphers selected for the eSTREAM portfolio. +/// \details Crypto++ provides Rabbit and RabbitWithIV classes. Two classes are necessary +/// because the library lacks the means to describe and manage optional IVs. +/// \sa Rabbit, The +/// eSTREAM Project | Rabbit and +/// Crypto++ Wiki | Rabbit. +/// \since Crypto++ 8.0 +struct RabbitWithIV : public RabbitWithIVInfo, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, RabbitWithIVInfo> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_RABBIT_H diff --git a/external/ours/library/crypto/src/shared/original/rabin.cpp b/external/ours/library/crypto/src/shared/original/rabin.cpp new file mode 100755 index 000000000..e112d9b86 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rabin.cpp @@ -0,0 +1,241 @@ +// rabin.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rabin.h" +#include "integer.h" +#include "nbtheory.h" +#include "modarith.h" +#include "asn.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RabinFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_r.BERDecode(seq); + m_s.BERDecode(seq); + seq.MessageEnd(); +} + +void RabinFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_r.DEREncode(seq); + m_s.DEREncode(seq); + seq.MessageEnd(); +} + +Integer RabinFunction::ApplyFunction(const Integer &in) const +{ + DoQuickSanityCheck(); + + Integer out = in.Squared()%m_n; + if (in.IsOdd()) + out = out*m_r%m_n; + if (Jacobi(in, m_n)==-1) + out = out*m_s%m_n; + return out; +} + +bool RabinFunction::Validate(RandomNumberGenerator& /*rng*/, unsigned int level) const +{ + bool pass = true; + pass = pass && m_n > Integer::One() && m_n%4 == 1; + CRYPTOPP_ASSERT(pass); + pass = pass && m_r > Integer::One() && m_r < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_s > Integer::One() && m_s < m_n; + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && Jacobi(m_r, m_n) == -1 && Jacobi(m_s, m_n) == -1; + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool RabinFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(QuadraticResidueModPrime1) + CRYPTOPP_GET_FUNCTION_ENTRY(QuadraticResidueModPrime2) + ; +} + +void RabinFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(QuadraticResidueModPrime1) + CRYPTOPP_SET_FUNCTION_ENTRY(QuadraticResidueModPrime2) + ; +} + +// ***************************************************************************** +// private key operations: + +// generate a random private key +void InvertibleRabinFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleRabinFunction: specified modulus size is too small"); + + // VC70 workaround: putting these after primeParam causes overlapped stack allocation + bool rFound=false, sFound=false; + Integer t=2; + + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + ("EquivalentTo", 3)("Mod", 4); + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + + while (!(rFound && sFound)) + { + int jp = Jacobi(t, m_p); + int jq = Jacobi(t, m_q); + + if (!rFound && jp==1 && jq==-1) + { + m_r = t; + rFound = true; + } + + if (!sFound && jp==-1 && jq==1) + { + m_s = t; + sFound = true; + } + + ++t; + } + + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); +} + +void InvertibleRabinFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_r.BERDecode(seq); + m_s.BERDecode(seq); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_u.BERDecode(seq); + seq.MessageEnd(); +} + +void InvertibleRabinFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_r.DEREncode(seq); + m_s.DEREncode(seq); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_u.DEREncode(seq); + seq.MessageEnd(); +} + +Integer InvertibleRabinFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const +{ + DoQuickSanityCheck(); + + ModularArithmetic modn(m_n); + Integer r(rng, Integer::One(), m_n - Integer::One()); + r = modn.Square(r); + Integer r2 = modn.Square(r); + Integer c = modn.Multiply(in, r2); // blind + + Integer cp=c%m_p, cq=c%m_q; + + int jp = Jacobi(cp, m_p); + int jq = Jacobi(cq, m_q); + + if (jq==-1) + { + cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p; + cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q; + } + + if (jp==-1) + { + cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p; + cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q; + } + + cp = ModularSquareRoot(cp, m_p); + cq = ModularSquareRoot(cq, m_q); + + if (jp==-1) + cp = m_p-cp; + + Integer out = CRT(cq, m_q, cp, m_p, m_u); + + out = modn.Divide(out, r); // unblind + + if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd())) + out = m_n-out; + + return out; +} + +bool InvertibleRabinFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = RabinFunction::Validate(rng, level); + CRYPTOPP_ASSERT(pass); + pass = pass && m_p > Integer::One() && m_p%4 == 3 && m_p < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_q > Integer::One() && m_q%4 == 3 && m_q < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_u.IsPositive() && m_u < m_p; + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_u * m_q % m_p == 1; + CRYPTOPP_ASSERT(pass); + pass = pass && Jacobi(m_r, m_p) == 1; + CRYPTOPP_ASSERT(pass); + pass = pass && Jacobi(m_r, m_q) == -1; + CRYPTOPP_ASSERT(pass); + pass = pass && Jacobi(m_s, m_p) == -1; + CRYPTOPP_ASSERT(pass); + pass = pass && Jacobi(m_s, m_q) == 1; + CRYPTOPP_ASSERT(pass); + } + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool InvertibleRabinFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleRabinFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/rabin.h b/external/ours/library/crypto/src/shared/original/rabin.h new file mode 100755 index 000000000..1cea7d454 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rabin.h @@ -0,0 +1,135 @@ +// rabin.h - originally written and placed in the public domain by Wei Dai + +/// \file rabin.h +/// \brief Classes for Rabin encryption and signature schemes + +#ifndef CRYPTOPP_RABIN_H +#define CRYPTOPP_RABIN_H + +#include "cryptlib.h" +#include "oaep.h" +#include "pssr.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Rabin trapdoor function using the public key +/// \since Crypto++ 2.0 +class RabinFunction : public TrapdoorFunction, public PublicKey +{ + typedef RabinFunction ThisClass; + +public: + + /// \brief Initialize a Rabin public key + /// \param n the modulus + /// \param r element r + /// \param s element s + void Initialize(const Integer &n, const Integer &r, const Integer &s) + {m_n = n; m_r = r; m_s = s;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return m_n;} + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + const Integer& GetModulus() const {return m_n;} + const Integer& GetQuadraticResidueModPrime1() const {return m_r;} + const Integer& GetQuadraticResidueModPrime2() const {return m_s;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetQuadraticResidueModPrime1(const Integer &r) {m_r = r;} + void SetQuadraticResidueModPrime2(const Integer &s) {m_s = s;} + +protected: + Integer m_n, m_r, m_s; +}; + +/// \brief Rabin trapdoor function using the private key +/// \since Crypto++ 2.0 +class InvertibleRabinFunction : public RabinFunction, public TrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleRabinFunction ThisClass; + +public: + + /// \brief Initialize a Rabin private key + /// \param n modulus + /// \param r element r + /// \param s element s + /// \param p first prime factor + /// \param q second prime factor + /// \param u q-1 mod p + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const Integer &n, const Integer &r, const Integer &s, const Integer &p, const Integer &q, const Integer &u) + {m_n = n; m_r = r; m_s = s; m_p = p; m_q = q; m_u = u;} + + /// \brief Create a Rabin private key + /// \param rng a RandomNumberGenerator derived class + /// \param keybits the size of the key, in bits + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int keybits) + {GenerateRandomWithKeySize(rng, keybits);} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_p, m_q, m_u; +}; + +/// \brief Rabin keys +struct Rabin +{ + static std::string StaticAlgorithmName() {return "Rabin-Crypto++Variant";} + typedef RabinFunction PublicKey; + typedef InvertibleRabinFunction PrivateKey; +}; + +/// \brief Rabin encryption scheme +/// \tparam STANDARD encryption standard +template +struct RabinES : public TF_ES +{ +}; + +/// \brief Rabin signature scheme +/// \tparam STANDARD signature standard +/// \tparam H hash transformation +template +struct RabinSS : public TF_SS +{ +}; + +// More typedefs for backwards compatibility +class SHA1; +typedef RabinES >::Decryptor RabinDecryptor; +typedef RabinES >::Encryptor RabinEncryptor; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/randpool.cpp b/external/ours/library/crypto/src/shared/original/randpool.cpp new file mode 100755 index 000000000..8e686f07c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/randpool.cpp @@ -0,0 +1,174 @@ +// randpool.cpp - originally written and placed in the public domain by Wei Dai +// RandomPool used to follow the design of randpool in PGP 2.6.x, +// but as of version 5.5 it has been redesigned to reduce the risk +// of reusing random numbers after state rollback (which may occur +// when running in a virtual machine like VMware). + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "randpool.h" +#include "aes.h" +#include "sha.h" +#include "hrtimer.h" +#include "trap.h" + +// OldRandomPool +#include "mdc.h" +#include "modes.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +RandomPool::RandomPool() + : m_pCipher(new AES::Encryption), m_keySet(false) +{ + std::memset(m_key, 0, m_key.SizeInBytes()); + std::memset(m_seed, 0, m_seed.SizeInBytes()); +} + +void RandomPool::IncorporateEntropy(const byte *input, size_t length) +{ + SHA256 hash; + hash.Update(m_key, 32); + hash.Update(input, length); + hash.Final(m_key); + m_keySet = false; +} + +void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) +{ + if (size > 0) + { + if (!m_keySet) + m_pCipher->SetKey(m_key, 32); + + CRYPTOPP_COMPILE_ASSERT(sizeof(TimerWord) <= 16); + CRYPTOPP_COMPILE_ASSERT(sizeof(time_t) <= 8); + + Timer timer; + TimerWord tw = timer.GetCurrentTimerValue(); + + *(TimerWord *)(void*)m_seed.data() += tw; + time_t t = time(NULLPTR); + + // UBsan finding: signed integer overflow: 1876017710 + 1446085457 cannot be represented in type 'long int' + // *(time_t *)(m_seed.data()+8) += t; + word64 tt1 = 0, tt2 = (word64)t; + std::memcpy(&tt1, m_seed.data()+8, 8); + std::memcpy(m_seed.data()+8, &(tt2 += tt1), 8); + + // Wipe the intermediates + *((volatile TimerWord*)&tw) = 0; + *((volatile word64*)&tt1) = 0; + *((volatile word64*)&tt2) = 0; + + do + { + m_pCipher->ProcessBlock(m_seed); + size_t len = UnsignedMin(16, size); + target.ChannelPut(channel, m_seed, len); + size -= len; + } while (size > 0); + } +} + +// OldRandomPool is provided for backwards compatibility for a migration path +typedef MDC OldRandomPoolCipher; + +OldRandomPool::OldRandomPool(unsigned int poolSize) + : pool(poolSize), key(OldRandomPoolCipher::DEFAULT_KEYLENGTH), addPos(0), getPos(poolSize) +{ + CRYPTOPP_ASSERT(poolSize > key.size()); + std::memset(pool, 0, poolSize); + std::memset(key, 0, key.size()); +} + +void OldRandomPool::IncorporateEntropy(const byte *input, size_t length) +{ + size_t t; + while (length > (t = pool.size() - addPos)) + { + xorbuf(pool+addPos, input, t); + input += t; + length -= t; + Stir(); + } + + if (length) + { + xorbuf(pool+addPos, input, length); + addPos += length; + getPos = pool.size(); // Force stir on get + } +} + +// GenerateWord32 is overriden and provides Crypto++ 5.4 behavior. +// Taken from RandomNumberGenerator::GenerateWord32 in cryptlib.cpp. +word32 OldRandomPool::GenerateWord32 (word32 min, word32 max) +{ + const word32 range = max-min; + const unsigned int maxBytes = BytePrecision(range); + const unsigned int maxBits = BitPrecision(range); + + word32 value; + + do + { + value = 0; + for (unsigned int i=0; i range); + + return value+min; +} + +void OldRandomPool::Stir() +{ + CFB_Mode::Encryption cipher; + + for (int i=0; i<2; i++) + { + cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize()); + cipher.ProcessString(pool, pool.size()); + std::memcpy(key, pool, key.size()); + } + + addPos = 0; + getPos = key.size(); +} + +void OldRandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) +{ + while (size > 0) + { + if (getPos == pool.size()) + Stir(); + size_t t = UnsignedMin(pool.size() - getPos, size); + target.ChannelPut(channel, pool+getPos, t); + size -= t; + getPos += t; + } +} + +byte OldRandomPool::GenerateByte() +{ + if (getPos == pool.size()) + Stir(); + + return pool[getPos++]; +} + +void OldRandomPool::GenerateBlock(byte *outString, size_t size) +{ + ArraySink sink(outString, size); + GenerateIntoBufferedTransformation(sink, DEFAULT_CHANNEL, size); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/randpool.h b/external/ours/library/crypto/src/shared/original/randpool.h new file mode 100755 index 000000000..e640b943f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/randpool.h @@ -0,0 +1,104 @@ +// randpool.h - originally written and placed in the public domain by Wei Dai +// OldRandPool added by JW in August, 2017. + +/// \file randpool.h +/// \brief Class file for Randomness Pool +/// \details RandomPool can be used to generate cryptographic quality pseudorandom bytes +/// after seeding the pool with IncorporateEntropy(). Internally, the generator uses +/// AES-256 to produce the stream. Entropy is stirred in using SHA-256. +/// \details RandomPool used to follow the design of randpool in PGP 2.6.x. At version 5.5 +/// RandomPool was redesigned to reduce the risk of reusing random numbers after state +/// rollback (which may occur when running in a virtual machine like VMware or a hosted +/// environment). +/// \details If you need the pre-Crypto++ 5.5 generator then use OldRandomPool class. You +/// should migrate away from OldRandomPool at the earliest opportunity. Use RandomPool +/// or AutoSeededRandomPool instead. +/// \since Crypto++ 4.0 (PGP 2.6.x style), Crypto++ 5.5 (AES-256 based) + +#ifndef CRYPTOPP_RANDPOOL_H +#define CRYPTOPP_RANDPOOL_H + +#include "cryptlib.h" +#include "filters.h" +#include "secblock.h" +#include "smartptr.h" +#include "aes.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Randomness Pool based on AES-256 +/// \details RandomPool can be used to generate cryptographic quality pseudorandom bytes +/// after seeding the pool with IncorporateEntropy(). Internally, the generator uses +/// AES-256 to produce the stream. Entropy is stirred in using SHA-256. +/// \details RandomPool used to follow the design of randpool in PGP 2.6.x. At version 5.5 +/// RandomPool was redesigned to reduce the risk of reusing random numbers after state +/// rollback, which may occur when running in a virtual machine like VMware or a hosted +/// environment. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \details If you need the pre-Crypto++ 5.5 generator then use OldRandomPool class. You +/// should migrate away from OldRandomPool at the earliest opportunity. +/// \sa OldRandomPool +/// \since Crypto++ 4.0 (PGP 2.6.x style), Crypto++ 5.5 (AES-256 based) +class CRYPTOPP_DLL RandomPool : public RandomNumberGenerator, public NotCopyable +{ +public: + /// \brief Construct a RandomPool + RandomPool(); + + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length); + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); + +private: + FixedSizeAlignedSecBlock m_seed; + FixedSizeAlignedSecBlock m_key; + member_ptr m_pCipher; + bool m_keySet; +}; + +/// \brief Randomness Pool based on PGP 2.6.x with MDC +/// \details If you need the pre-Crypto++ 5.5 generator then use OldRandomPool class. The +/// OldRandomPool also provides the modern interface, including CanIncorporateEntropy, +/// IncorporateEntropy and GenerateIntoBufferedTransformation. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \details You should migrate away from OldRandomPool at the earliest opportunity. Use a +/// modern random number generator or key derivation function, like AutoSeededRandomPool or +/// HKDF. +/// \warning This class uses an old style PGP 2.6.x with MDC. The generator risks reusing +/// random numbers after state rollback. You should migrate away from OldRandomPool at +/// the earliest opportunity. +/// \sa RandomPool, AutoSeededRandomPool, HKDF, P1363_KDF2, PKCS12_PBKDF, PKCS5_PBKDF2_HMAC +/// \since Crypto++ 6.0 +class CRYPTOPP_DLL OldRandomPool : public RandomNumberGenerator +{ +public: + /// \brief Construct an OldRandomPool + /// \param poolSize internal pool size of the generator + /// \details poolSize must be greater than 16 + OldRandomPool(unsigned int poolSize=384); + + // RandomNumberGenerator interface (Crypto++ 5.5 and above) + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length); + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); + + byte GenerateByte(); + void GenerateBlock(byte *output, size_t size); + + // GenerateWord32 is overriden and provides Crypto++ 5.4 behavior. + // Taken from RandomNumberSource::GenerateWord32 in cryptlib.cpp. + word32 GenerateWord32 (word32 min=0, word32 max=0xffffffffUL); + +protected: + void Stir(); + +private: + SecByteBlock pool, key; + size_t addPos, getPos; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rc2.cpp b/external/ours/library/crypto/src/shared/original/rc2.cpp new file mode 100755 index 000000000..1469cc59e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rc2.cpp @@ -0,0 +1,118 @@ +// rc2.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rc2.h" +#include "misc.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RC2::Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keyLen); + + int effectiveLen = params.GetIntValueWithDefault(Name::EffectiveKeyLength(), DEFAULT_EFFECTIVE_KEYLENGTH); + if (effectiveLen > MAX_EFFECTIVE_KEYLENGTH) + throw InvalidArgument("RC2: effective key length parameter exceeds maximum"); + + static const unsigned char PITABLE[256] = { + 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, + 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, + 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, + 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, + 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, + 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, + 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, + 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, + 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, + 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, + 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, + 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, + 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, + 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, + 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, + 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173}; + + SecByteBlock L(128); + memcpy(L, key, keyLen); + + int i; + for (i=keyLen; i<128; i++) + L[i] = PITABLE[(L[i-1] + L[i-keyLen]) & 255]; + + unsigned int T8 = (effectiveLen+7) / 8; + byte TM = byte((int)255 >> ((8-(effectiveLen%8))%8)); + L[128-T8] = PITABLE[L[128-T8] & TM]; + + for (i=127-T8; i>=0; i--) + L[i] = PITABLE[L[i+1] ^ L[i+T8]]; + + for (i=0; i<64; i++) + K[i] = L[2*i] + (L[2*i+1] << 8); +} + +typedef BlockGetAndPut Block; + +void RC2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 R0, R1, R2, R3; + Block::Get(inBlock)(R0)(R1)(R2)(R3); + + for (int i = 0; i < 16; i++) + { + R0 += (R1 & ~R3) + (R2 & R3) + K[4*i+0]; + R0 = rotlConstant<1>(R0); + + R1 += (R2 & ~R0) + (R3 & R0) + K[4*i+1]; + R1 = rotlConstant<2>(R1); + + R2 += (R3 & ~R1) + (R0 & R1) + K[4*i+2]; + R2 = rotlConstant<3>(R2); + + R3 += (R0 & ~R2) + (R1 & R2) + K[4*i+3]; + R3 = rotlConstant<5>(R3); + + if (i == 4 || i == 10) + { + R0 = word16(R0 + K[R3 & 63]); + R1 = word16(R1 + K[R0 & 63]); + R2 = word16(R2 + K[R1 & 63]); + R3 = word16(R3 + K[R2 & 63]); + } + } + + Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3); +} + +void RC2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 R0, R1, R2, R3; + Block::Get(inBlock)(R0)(R1)(R2)(R3); + + for (int i = 15; i >= 0; i--) + { + if (i == 4 || i == 10) + { + R3 = word16(R3 - K[R2 & 63]); + R2 = word16(R2 - K[R1 & 63]); + R1 = word16(R1 - K[R0 & 63]); + R0 = word16(R0 - K[R3 & 63]); + } + + R3 = rotrConstant<5>(R3); + R3 = word16(R3 - ((R0 & ~R2) + (R1 & R2) + K[4*i+3])); + + R2 = rotrConstant<3>(R2); + R2 = word16(R2 - ((R3 & ~R1) + (R0 & R1) + K[4*i+2])); + + R1 = rotrConstant<2>(R1); + R1 = word16(R1 - ((R2 & ~R0) + (R3 & R0) + K[4*i+1])); + + R0 = rotrConstant<1>(R0); + R0 = word16(R0 - ((R1 & ~R3) + (R2 & R3) + K[4*i+0])); + } + + Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/rc2.h b/external/ours/library/crypto/src/shared/original/rc2.h new file mode 100755 index 000000000..50a39ae8c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rc2.h @@ -0,0 +1,90 @@ +// rc2.h - originally written and placed in the public domain by Wei Dai + +/// \file rc2.h +/// \brief Classes for the RC2 block cipher +/// \since Crypto++ 3.0 + +#ifndef CRYPTOPP_RC2_H +#define CRYPTOPP_RC2_H + +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief RC2 block cipher information +/// \since Crypto++ 3.0 +struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128> +{ + CRYPTOPP_CONSTANT(DEFAULT_EFFECTIVE_KEYLENGTH = 1024); + CRYPTOPP_CONSTANT(MAX_EFFECTIVE_KEYLENGTH = 1024); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RC2";} +}; + +/// \brief RC2 block cipher +/// \sa RC2 on the Crypto Lounge. +/// \since Crypto++ 3.0 +class RC2 : public RC2_Info, public BlockCipherDocumentation +{ + /// \brief Class specific methods used to operate the cipher. + /// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + protected: + FixedSizeSecBlock K; // expanded key table + }; + + /// \brief Class specific methods used to operate the cipher in the forward direction. + /// \details Implementations and overrides in \p Enc apply to \p ENCRYPTION. + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Class specific methods used to operate the cipher in the reverse direction. + /// \details Implementations and overrides in \p Dec apply to \p DECRYPTION. + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + + /// \brief Class specific methods used to operate the cipher in the forward direction. + /// \details Implementations and overrides in \p Encryption apply to \p ENCRYPTION. + class Encryption : public BlockCipherFinal + { + public: + Encryption() {} + Encryption(const byte *key, size_t keyLen=DEFAULT_KEYLENGTH) + {SetKey(key, keyLen);} + Encryption(const byte *key, size_t keyLen, int effectiveKeyLen) + {SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));} + }; + + /// \brief Class specific methods used to operate the cipher in the reverse direction. + /// \details Implementations and overrides in \p Decryption apply to \p DECRYPTION. + class Decryption : public BlockCipherFinal + { + public: + Decryption() {} + Decryption(const byte *key, size_t keyLen=DEFAULT_KEYLENGTH) + {SetKey(key, keyLen);} + Decryption(const byte *key, size_t keyLen, int effectiveKeyLen) + {SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));} + }; +}; + +typedef RC2::Encryption RC2Encryption; +typedef RC2::Decryption RC2Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rc5.cpp b/external/ours/library/crypto/src/shared/original/rc5.cpp new file mode 100755 index 000000000..262c9aec2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rc5.cpp @@ -0,0 +1,80 @@ +// rc5.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rc5.h" +#include "misc.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RC5::Base::UncheckedSetKey(const byte *k, unsigned int keylen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keylen); + + r = GetRoundsAndThrowIfInvalid(params, this); + sTable.New(2*(r+1)); + + static const RC5_WORD MAGIC_P = 0xb7e15163L; // magic constant P for wordsize + static const RC5_WORD MAGIC_Q = 0x9e3779b9L; // magic constant Q for wordsize + static const int U=sizeof(RC5_WORD); + + const unsigned int c = STDMAX((keylen+U-1)/U, 1U); // RC6 paper says c=1 if keylen==0 + SecBlock l(c); + + GetUserKey(LITTLE_ENDIAN_ORDER, l.begin(), c, k, keylen); + + sTable[0] = MAGIC_P; + for (unsigned j=1; j((sTable[h % sTable.size()] + a + b)); + b = l[h % c] = rotlMod((l[h % c] + a + b), (a+b)); + } +} + +typedef BlockGetAndPut Block; + +void RC5::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + const RC5_WORD *sptr = sTable; + RC5_WORD a, b; + + Block::Get(inBlock)(a)(b); + a += sptr[0]; + b += sptr[1]; + sptr += 2; + + for(unsigned i=0; i, public VariableKeyLength<16, 0, 255>, public VariableRounds<16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RC5";} + typedef word32 RC5_WORD; +}; + +/// \brief RC5 block cipher +/// \sa RC5 +/// \since Crypto++ 1.0 +class RC5 : public RC5_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + unsigned int r; // number of rounds + SecBlock sTable; // expanded key table + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef RC5::Encryption RC5Encryption; +typedef RC5::Decryption RC5Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rc6.cpp b/external/ours/library/crypto/src/shared/original/rc6.cpp new file mode 100755 index 000000000..a03c51081 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rc6.cpp @@ -0,0 +1,96 @@ +// rc6.cpp - written and placed in the public domain by Sean Woods +// based on Wei Dai's RC5 code. + +#include "pch.h" +#include "rc6.h" +#include "misc.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RC6::Base::UncheckedSetKey(const byte *k, unsigned int keylen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keylen); + + r = GetRoundsAndThrowIfInvalid(params, this); + sTable.New(2*(r+2)); + + static const RC6_WORD MAGIC_P = 0xb7e15163L; // magic constant P for wordsize + static const RC6_WORD MAGIC_Q = 0x9e3779b9L; // magic constant Q for wordsize + static const int U=sizeof(RC6_WORD); + + const unsigned int c = STDMAX((keylen+U-1)/U, 1U); // RC6 paper says c=1 if keylen==0 + SecBlock l(c); + + GetUserKey(LITTLE_ENDIAN_ORDER, l.begin(), c, k, keylen); + + sTable[0] = MAGIC_P; + for (unsigned j=1; j((sTable[h % sTable.size()] + a + b)); + b = l[h % c] = rotlMod((l[h % c] + a + b), (a+b)); + } +} + +typedef BlockGetAndPut Block; + +void RC6::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + const RC6_WORD *sptr = sTable; + RC6_WORD a, b, c, d, t, u; + + Block::Get(inBlock)(a)(b)(c)(d); + b += sptr[0]; + d += sptr[1]; + sptr += 2; + + for(unsigned i=0; i(b*(2*b+1)); + u = rotlConstant<5>(d*(2*d+1)); + a = rotlMod(a^t,u) + sptr[0]; + c = rotlMod(c^u,t) + sptr[1]; + t = a; a = b; b = c; c = d; d = t; + sptr += 2; + } + + a += sptr[0]; + c += sptr[1]; + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d); +} + +void RC6::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + const RC6_WORD *sptr = sTable.end(); + RC6_WORD a, b, c, d, t, u; + + Block::Get(inBlock)(a)(b)(c)(d); + + sptr -= 2; + c -= sptr[1]; + a -= sptr[0]; + + for (unsigned i=0; i < r; i++) + { + sptr -= 2; + t = a; a = d; d = c; c = b; b = t; + u = rotlConstant<5>(d*(2 * d + 1)); + t = rotlConstant<5>(b*(2 * b + 1)); + c = rotrMod(c-sptr[1], t) ^ u; + a = rotrMod(a-sptr[0], u) ^ t; + } + + d -= sTable[1]; + b -= sTable[0]; + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/rc6.h b/external/ours/library/crypto/src/shared/original/rc6.h new file mode 100755 index 000000000..1a41ab2c4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rc6.h @@ -0,0 +1,60 @@ +// rc6.h - originally written and placed in the public domain by Wei Dai + +/// \file rc6.h +/// \brief Classes for the RC6 block cipher +/// \since Crypto++ 3.0 + +#ifndef CRYPTOPP_RC6_H +#define CRYPTOPP_RC6_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief RC6 block cipher information +/// \since Crypto++ 3.0 +struct RC6_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8>, public VariableRounds<20> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RC6";} + typedef word32 RC6_WORD; +}; + +/// \brief RC6 block cipher +/// \sa RC6 +/// \since Crypto++ 3.0 +class RC6 : public RC6_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + unsigned int r; // number of rounds + SecBlock sTable; // expanded key table + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef RC6::Encryption RC6Encryption; +typedef RC6::Decryption RC6Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rdrand.cpp b/external/ours/library/crypto/src/shared/original/rdrand.cpp new file mode 100755 index 000000000..f8ebe82bb --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rdrand.cpp @@ -0,0 +1,327 @@ +// rdrand.cpp - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. + +#include "pch.h" +#include "config.h" +#include "cryptlib.h" +#include "secblock.h" +#include "rdrand.h" +#include "cpu.h" + +// This file (and friends) provides both RDRAND and RDSEED. They were added +// at Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64} +// to select an implementation or throws "NotImplemented". Users of the +// classes should call HasRDRAND() or HasRDSEED() to determine if a +// generator is available at runtime. +// The original classes accepted a retry count. Retries were superflous for +// RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending +// on the processor. Retries were removed at Crypto++ 6.0 because +// GenerateBlock unconditionally retries and always fulfills the request. +// Intel recommends using a retry count in case RDRAND or RDSEED circuit +// is bad. This implemenation does not follow the advice and requires +// good silicon. If the circuit or processor is bad then the user has +// bigger problems than generating random numbers. + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4702) +#endif + +#if defined(CRYPTOPP_RDRAND_AVAILABLE) +# if defined(CRYPTOPP_MSC_VERSION) +# define MASM_RDRAND_ASM_AVAILABLE 1 +# endif +# if (__SUNPRO_CC >= 0x5100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_GCC_VERSION >= 30200) +# define GCC_RDRAND_ASM_AVAILABLE 1 +# endif +#endif // CRYPTOPP_RDRAND_AVAILABLE + +#if defined(CRYPTOPP_RDSEED_AVAILABLE) +# if defined(CRYPTOPP_MSC_VERSION) +# define MASM_RDSEED_ASM_AVAILABLE 1 +# endif +# if (__SUNPRO_CC >= 0x5100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_GCC_VERSION >= 30200) +# define GCC_RDSEED_ASM_AVAILABLE 1 +# endif +#endif // CRYPTOPP_RDSEED_AVAILABLE + +typedef unsigned char byte; + +#if MASM_RDRAND_ASM_AVAILABLE +extern "C" void CRYPTOPP_FASTCALL MASM_RDRAND_GenerateBlock(byte*, size_t); +#endif + +#if MASM_RDSEED_ASM_AVAILABLE +extern "C" void CRYPTOPP_FASTCALL MASM_RDSEED_GenerateBlock(byte*, size_t); +#endif + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_RDRAND_AVAILABLE) + +// Fills 4 bytes +inline void RDRAND32(void* output) +{ + CRYPTOPP_UNUSED(output); // MSC warning +# if defined(GCC_RDRAND_ASM_AVAILABLE) + __asm__ __volatile__ + ( + "1:\n" + ".byte 0x0f, 0xc7, 0xf0;\n" + "jnc 1b;\n" + : "=a" (*reinterpret_cast(output)) + : : "cc" + ); +# endif +} + +# if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32) +// Fills 8 bytes +inline void RDRAND64(void* output) +{ + CRYPTOPP_UNUSED(output); // MSC warning +# if defined(GCC_RDRAND_ASM_AVAILABLE) + __asm__ __volatile__ + ( + "1:\n" + ".byte 0x48, 0x0f, 0xc7, 0xf0;\n" + "jnc 1b;\n" + : "=a" (*reinterpret_cast(output)) + : : "cc" + ); +# endif +} +# endif // RDRAND64 + +RDRAND::RDRAND() +{ + if (!HasRDRAND()) + throw RDRAND_Err("HasRDRAND"); +} + +void RDRAND::GenerateBlock(byte *output, size_t size) +{ + CRYPTOPP_ASSERT((output && size) || !(output || size)); + if (size == 0) return; + +# if defined(MASM_RDRAND_ASM_AVAILABLE) + + MASM_RDRAND_GenerateBlock(output, size); + +# elif defined(GCC_RDRAND_ASM_AVAILABLE) + +# if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32) + size_t i = 0; + for (i = 0; i < size/8; i++) + RDRAND64(output+i*8); + + output += i*8; + size -= i*8; + + if (size) + { + word64 val; + RDRAND64(&val); + std::memcpy(output, &val, size); + } +# else + size_t i = 0; + for (i = 0; i < size/4; i++) + RDRAND32(output+i*4); + + output += i*4; + size -= i*4; + + if (size) + { + word32 val; + RDRAND32(&val); + std::memcpy(output, &val, size); + } +# endif +# else + // No suitable compiler found + CRYPTOPP_UNUSED(output); + throw NotImplemented("RDRAND: failed to find a suitable implementation"); +# endif +} + +void RDRAND::DiscardBytes(size_t n) +{ + // RoundUpToMultipleOf is used because a full word is read, and its cheaper + // to discard full words. There's no sense in dealing with tail bytes. + FixedSizeSecBlock discard; + n = RoundUpToMultipleOf(n, sizeof(word64)); + + size_t count = STDMIN(n, discard.SizeInBytes()); + while (count) + { + GenerateBlock(discard.BytePtr(), count); + n -= count; + count = STDMIN(n, discard.SizeInBytes()); + } +} + +#endif // CRYPTOPP_RDRAND_AVAILABLE + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +#if defined(CRYPTOPP_RDSEED_AVAILABLE) + +// Fills 4 bytes +inline void RDSEED32(void* output) +{ + CRYPTOPP_UNUSED(output); // MSC warning +# if defined(GCC_RDSEED_ASM_AVAILABLE) + __asm__ __volatile__ + ( + "1:\n" + ".byte 0x0f, 0xc7, 0xf8;\n" + "jnc 1b;\n" + : "=a" (*reinterpret_cast(output)) + : : "cc" + ); +# endif +} + +# if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32) +// Fills 8 bytes +inline void RDSEED64(void* output) +{ + CRYPTOPP_UNUSED(output); // MSC warning +# if defined(GCC_RDSEED_ASM_AVAILABLE) + __asm__ __volatile__ + ( + "1:\n" + ".byte 0x48, 0x0f, 0xc7, 0xf8;\n" + "jnc 1b;\n" + : "=a" (*reinterpret_cast(output)) + : : "cc" + ); +# endif +} +# endif // RDSEED64 + +RDSEED::RDSEED() +{ + if (!HasRDSEED()) + throw RDSEED_Err("HasRDSEED"); +} + +void RDSEED::GenerateBlock(byte *output, size_t size) +{ + CRYPTOPP_ASSERT((output && size) || !(output || size)); + if (size == 0) return; + +# if defined(MASM_RDSEED_ASM_AVAILABLE) + + MASM_RDSEED_GenerateBlock(output, size); + +# elif defined(GCC_RDSEED_ASM_AVAILABLE) +# if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32) + size_t i = 0; + for (i = 0; i < size/8; i++) + RDSEED64(output+i*8); + + output += i*8; + size -= i*8; + + if (size) + { + word64 val; + RDSEED64(&val); + std::memcpy(output, &val, size); + } +# else + size_t i = 0; + for (i = 0; i < size/4; i++) + RDSEED32(output+i*4); + + output += i*4; + size -= i*4; + + if (size) + { + word32 val; + RDSEED32(&val); + std::memcpy(output, &val, size); + } +# endif +# else + // No suitable compiler found + CRYPTOPP_UNUSED(output); + throw NotImplemented("RDSEED: failed to find a suitable implementation"); +# endif // RDSEED64 +} + +void RDSEED::DiscardBytes(size_t n) +{ + // RoundUpToMultipleOf is used because a full word is read, and its cheaper + // to discard full words. There's no sense in dealing with tail bytes. + FixedSizeSecBlock discard; + n = RoundUpToMultipleOf(n, sizeof(word64)); + + size_t count = STDMIN(n, discard.SizeInBytes()); + while (count) + { + GenerateBlock(discard.BytePtr(), count); + n -= count; + count = STDMIN(n, discard.SizeInBytes()); + } +} + +#endif // CRYPTOPP_RDSEED_AVAILABLE + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +#if !defined(CRYPTOPP_RDRAND_AVAILABLE) + +RDRAND::RDRAND() +{ + throw RDRAND_Err("HasRDRAND"); +} + +void RDRAND::GenerateBlock(byte *output, size_t size) +{ + // Constructor will throw, should not get here + CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size); +} + +void RDRAND::DiscardBytes(size_t n) +{ + // Constructor will throw, should not get here + CRYPTOPP_UNUSED(n); +} + +#endif // CRYPTOPP_RDRAND_AVAILABLE + +#if !defined(CRYPTOPP_RDSEED_AVAILABLE) + +RDSEED::RDSEED() +{ + throw RDSEED_Err("HasRDSEED"); +} + +void RDSEED::GenerateBlock(byte *output, size_t size) +{ + // Constructor will throw, should not get here + CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size); +} + +void RDSEED::DiscardBytes(size_t n) +{ + // Constructor will throw, should not get here + CRYPTOPP_UNUSED(n); +} + +#endif // CRYPTOPP_RDSEED_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/rdrand.h b/external/ours/library/crypto/src/shared/original/rdrand.h new file mode 100755 index 000000000..11d29ca99 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rdrand.h @@ -0,0 +1,145 @@ +// rdrand.h - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. + +/// \file rdrand.h +/// \brief Classes for RDRAND and RDSEED +/// \since Crypto++ 5.6.3 + +#ifndef CRYPTOPP_RDRAND_H +#define CRYPTOPP_RDRAND_H + +#include "cryptlib.h" + +// This class file provides both RDRAND and RDSEED. They were added at +// Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64} +// to select an implementation or "throw NotImplemented". At runtime the +// constructor will throw RDRAND_Err or RDSEED_Err if a generator is +// is not available. +// The original classes accepted a retry count. Retries were superflous for +// RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending +// on the processor. Retries were removed at Crypto++ 6.0 because +// GenerateBlock unconditionally retries and always fulfills the request. + +// Throughput varies wildly depending on processor and manufacturer. A Core i5 or +// Core i7 RDRAND can generate at over 200 MiB/s. It is below theroetical +// maximum, but it takes about 5 instructions to generate, retry and store a +// result. A low-end Celeron may perform RDRAND at about 7 MiB/s. RDSEED +// performs at about 1/4 to 1/2 the rate of RDRAND. AMD RDRAND performed poorly +// during testing with Athlon X4 845. The Bulldozer v4 only performed at 1 MiB/s. + +// Microsoft added RDRAND in August 2012, VS2012; RDSEED in October 2013, VS2013. +// GCC added RDRAND in December 2010, GCC 4.6. LLVM added RDRAND in July 2012, +// Clang 3.2. Intel added RDRAND in September 2011, ICC 12.1. + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Exception thrown when a RDRAND generator encounters +/// a generator related error. +/// \since Crypto++ 5.6.3 +class RDRAND_Err : public Exception +{ +public: + RDRAND_Err(const std::string &operation) + : Exception(OTHER_ERROR, "RDRAND: " + operation + " operation failed") {} +}; + +/// \brief Hardware generated random numbers using RDRAND instruction +/// \sa MaurerRandomnessTest() for random bit generators +/// \since Crypto++ 5.6.3 +class RDRAND : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RDRAND"; } + + virtual ~RDRAND() {} + + /// \brief Construct a RDRAND generator + /// \details According to DJ of Intel, the Intel RDRAND circuit does not underflow. + /// If it did hypothetically underflow, then it would return 0 for the random value. + /// AMD's RDRAND implementation appears to provide the same behavior. + /// \throw RDRAND_Err if the random number generator is not available + RDRAND(); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + virtual void GenerateBlock(byte *output, size_t size); + + /// \brief Generate and discard n bytes + /// \param n the number of bytes to generate and discard + /// \details the RDSEED generator discards words, not bytes. If n is + /// not a multiple of a machine word, then it is rounded up to + /// that size. + virtual void DiscardBytes(size_t n); + + /// \brief Update RNG state with additional unpredictable values + /// \param input unused + /// \param length unused + /// \details The operation is a nop for this generator. + virtual void IncorporateEntropy(const byte *input, size_t length) + { + // Override to avoid the base class' throw. + CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); + } + + std::string AlgorithmProvider() const { + return "RDRAND"; + } +}; + +/// \brief Exception thrown when a RDSEED generator encounters +/// a generator related error. +/// \since Crypto++ 5.6.3 +class RDSEED_Err : public Exception +{ +public: + RDSEED_Err(const std::string &operation) + : Exception(OTHER_ERROR, "RDSEED: " + operation + " operation failed") {} +}; + +/// \brief Hardware generated random numbers using RDSEED instruction +/// \sa MaurerRandomnessTest() for random bit generators +/// \since Crypto++ 5.6.3 +class RDSEED : public RandomNumberGenerator +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RDSEED"; } + + virtual ~RDSEED() {} + + /// \brief Construct a RDSEED generator + /// \details Empirical testing under a 6th generaton i7 (6200U) shows RDSEED fails + /// to fulfill requests at about once every for every 256 bytes requested. + /// The generator runs about 4 times slower than RDRAND. + /// \throw RDSEED_Err if the random number generator is not available + RDSEED(); + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + virtual void GenerateBlock(byte *output, size_t size); + + /// \brief Generate and discard n bytes + /// \param n the number of bytes to generate and discard + /// \details the RDSEED generator discards words, not bytes. If n is + /// not a multiple of a machine word, then it is rounded up to + /// that size. + virtual void DiscardBytes(size_t n); + + /// \brief Update RNG state with additional unpredictable values + /// \param input unused + /// \param length unused + /// \details The operation is a nop for this generator. + virtual void IncorporateEntropy(const byte *input, size_t length) + { + // Override to avoid the base class' throw. + CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); + } + + std::string AlgorithmProvider() const { + return "RDSEED"; + } +}; + +NAMESPACE_END + +#endif // CRYPTOPP_RDRAND_H diff --git a/external/ours/library/crypto/src/shared/original/rdtables.cpp b/external/ours/library/crypto/src/shared/original/rdtables.cpp new file mode 100755 index 000000000..8ceb800f1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rdtables.cpp @@ -0,0 +1,166 @@ +// Rijndael tables + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "rijndael.h" + +NAMESPACE_BEGIN(CryptoPP) + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +*/ + +const byte Rijndael::Base::Se[256] = { + 0x63, 0x7c, 0x77, 0x7b, + 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, + 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, + 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, + 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, + 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, + 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, + 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, + 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, + 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, + 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, + 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, + 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, + 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, + 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, + 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, + 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, + 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, + 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, + 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, + 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, + 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, + 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, + 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, + 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, + 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, + 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, + 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, + 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, + 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, + 0xb0, 0x54, 0xbb, 0x16, +}; + +const byte Rijndael::Base::Sd[256] = { + 0x52, 0x09, 0x6a, 0xd5, + 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, + 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, + 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, + 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, + 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, + 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, + 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, + 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, + 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, + 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, + 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, + 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, + 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, + 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, + 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, + 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, + 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, + 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, + 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, + 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, + 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, + 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, + 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, + 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, + 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, + 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, + 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, + 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, + 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0c, 0x7d, +}; + +/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +const word32 Rijndael::Base::rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000 +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/regtest1.cpp b/external/ours/library/crypto/src/shared/original/regtest1.cpp new file mode 100755 index 000000000..4e71b68c9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/regtest1.cpp @@ -0,0 +1,160 @@ +// regtest1.cpp - originally written and placed in the public domain by Wei Dai +// regtest.cpp split into 3 files due to OOM kills by JW +// in April 2017. A second split occurred in July 2018. + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "factory.h" +#include "bench.h" +#include "cpu.h" + +#include "crc.h" +#include "adler32.h" +#include "md2.h" +#include "md5.h" +#include "keccak.h" +#include "sha3.h" +#include "shake.h" +#include "blake2.h" +#include "sha.h" +#include "sha3.h" +#include "sm3.h" +#include "hkdf.h" +#include "tiger.h" +#include "ripemd.h" +#include "panama.h" +#include "whrlpool.h" +#include "lsh.h" + +#include "osrng.h" +#include "drbg.h" +#include "darn.h" +#include "mersenne.h" +#include "rdrand.h" +#include "padlkrng.h" + +#include "modes.h" +#include "aes.h" + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +USING_NAMESPACE(CryptoPP) + +// Unkeyed ciphers +void RegisterFactories1(); +// MAC ciphers +void RegisterFactories2(); +// Stream ciphers +void RegisterFactories3(); +// Block ciphers +void RegisterFactories4(); +// Public key ciphers +void RegisterFactories5(); + +void RegisterFactories(Test::TestClass suites) +{ + static bool s_registered = false; + if (s_registered) + return; + + if ((suites & Test::Unkeyed) == Test::Unkeyed) + RegisterFactories1(); + + if ((suites & Test::SharedKeyMAC) == Test::SharedKeyMAC) + RegisterFactories2(); + + if ((suites & Test::SharedKeyStream) == Test::SharedKeyStream) + RegisterFactories3(); + + if ((suites & Test::SharedKeyBlock) == Test::SharedKeyBlock) + RegisterFactories4(); + + if ((suites & Test::PublicKey) == Test::PublicKey) + RegisterFactories5(); + + s_registered = true; +} + +// Unkeyed ciphers +void RegisterFactories1() +{ + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + +#ifdef BLOCKING_RNG_AVAILABLE + RegisterDefaultFactoryFor(); +#endif +#ifdef NONBLOCKING_RNG_AVAILABLE + RegisterDefaultFactoryFor(); +#endif +#ifdef OS_RNG_AVAILABLE + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); +#endif + RegisterDefaultFactoryFor(); +#if (CRYPTOPP_BOOL_X86) + if (HasPadlockRNG()) + RegisterDefaultFactoryFor(); +#endif +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + if (HasRDRAND()) + RegisterDefaultFactoryFor(); + if (HasRDSEED()) + RegisterDefaultFactoryFor(); +#endif +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + if (HasDARN()) + RegisterDefaultFactoryFor(); +#endif + RegisterDefaultFactoryFor::Encryption >("AES/OFB RNG"); + RegisterDefaultFactoryFor >("Hash_DRBG(SHA1)"); + RegisterDefaultFactoryFor >("Hash_DRBG(SHA256)"); + RegisterDefaultFactoryFor >("HMAC_DRBG(SHA1)"); + RegisterDefaultFactoryFor >("HMAC_DRBG(SHA256)"); + + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); +} diff --git a/external/ours/library/crypto/src/shared/original/regtest2.cpp b/external/ours/library/crypto/src/shared/original/regtest2.cpp new file mode 100755 index 000000000..e379432dc --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/regtest2.cpp @@ -0,0 +1,105 @@ +// regtest2.cpp - originally written and placed in the public domain by Wei Dai +// regtest.cpp split into 3 files due to OOM kills by JW +// in April 2017. A second split occurred in July 2018. + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "factory.h" +#include "bench.h" +#include "cpu.h" + +// For MAC's +#include "hmac.h" +#include "cmac.h" +#include "dmac.h" +#include "vmac.h" +#include "ttmac.h" + +// Ciphers +#include "md5.h" +#include "keccak.h" +#include "sha.h" +#include "sha3.h" +#include "blake2.h" +#include "ripemd.h" +#include "chacha.h" +#include "poly1305.h" +#include "siphash.h" +#include "panama.h" + +// Stream ciphers +#include "arc4.h" +#include "seal.h" +#include "wake.h" +#include "chacha.h" +#include "salsa.h" +#include "rabbit.h" +#include "hc128.h" +#include "hc256.h" +#include "panama.h" +#include "sosemanuk.h" + +// Block for CMAC +#include "aes.h" +#include "des.h" + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +USING_NAMESPACE(CryptoPP) + +// MAC ciphers +void RegisterFactories2() +{ + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); +} + +// Stream ciphers +void RegisterFactories3() +{ + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); +} diff --git a/external/ours/library/crypto/src/shared/original/regtest3.cpp b/external/ours/library/crypto/src/shared/original/regtest3.cpp new file mode 100755 index 000000000..0d2f6fdca --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/regtest3.cpp @@ -0,0 +1,156 @@ +// regtest3.cpp - originally written and placed in the public domain by Wei Dai +// regtest.cpp split into 3 files due to OOM kills by JW +// in April 2017. A second split occurred in July 2018. + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "factory.h" +#include "bench.h" +#include "cpu.h" + +#include "modes.h" +#include "aria.h" +#include "seed.h" +#include "hight.h" +#include "camellia.h" +#include "shacal2.h" +#include "tea.h" +#include "aes.h" +#include "tiger.h" +#include "ccm.h" +#include "gcm.h" +#include "eax.h" +#include "xts.h" +#include "twofish.h" +#include "serpent.h" +#include "cast.h" +#include "rc6.h" +#include "mars.h" +#include "kalyna.h" +#include "threefish.h" +#include "cham.h" +#include "lea.h" +#include "simeck.h" +#include "simon.h" +#include "speck.h" +#include "sm4.h" +#include "des.h" +#include "idea.h" +#include "rc5.h" +#include "skipjack.h" +#include "blowfish.h" +#include "chachapoly.h" + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +USING_NAMESPACE(CryptoPP) + +// Shared key ciphers +void RegisterFactories4() +{ + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + + RegisterAuthenticatedSymmetricCipherDefaultFactories >(); + RegisterAuthenticatedSymmetricCipherDefaultFactories >(); + RegisterAuthenticatedSymmetricCipherDefaultFactories >(); + RegisterAuthenticatedSymmetricCipherDefaultFactories(); + RegisterAuthenticatedSymmetricCipherDefaultFactories(); + + RegisterSymmetricCipherDefaultFactories >(); // For test vectors + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks +} diff --git a/external/ours/library/crypto/src/shared/original/regtest4.cpp b/external/ours/library/crypto/src/shared/original/regtest4.cpp new file mode 100755 index 000000000..f45320839 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/regtest4.cpp @@ -0,0 +1,58 @@ +// regtest4.cpp - originally written and placed in the public domain by Wei Dai +// regtest.cpp split into 3 files due to OOM kills by JW +// in April 2017. A second split occurred in July 2018. + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "factory.h" +#include "bench.h" +#include "cpu.h" + +#include "dh.h" +#include "nr.h" +#include "rw.h" +#include "rsa.h" +#include "dsa.h" +#include "pssr.h" +#include "esign.h" + +// Hashes +#include "md2.h" +#include "md5.h" +#include "sha.h" + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +USING_NAMESPACE(CryptoPP) + +void RegisterFactories5() +{ + RegisterDefaultFactoryFor(); + RegisterAsymmetricCipherDefaultFactories > >("RSA/OAEP-MGF1(SHA-1)"); + RegisterAsymmetricCipherDefaultFactories >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); + RegisterSignatureSchemeDefaultFactories(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >(); + RegisterSignatureSchemeDefaultFactories >("NR(1363)/EMSA1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("DSA-1363/EMSA1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("RSA/PKCS1-1.5(MD2)"); + RegisterSignatureSchemeDefaultFactories >("RSA/PKCS1-1.5(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("ESIGN/EMSA5-MGF1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("RW/EMSA2(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("RSA/PSS-MGF1(SHA-1)"); +} diff --git a/external/ours/library/crypto/src/shared/original/resource.h b/external/ours/library/crypto/src/shared/original/resource.h new file mode 100755 index 000000000..80f1df1a3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by cryptopp.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/external/ours/library/crypto/src/shared/original/rijndael.cpp b/external/ours/library/crypto/src/shared/original/rijndael.cpp new file mode 100755 index 000000000..65f6d9e0a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rijndael.cpp @@ -0,0 +1,1334 @@ +// rijndael.cpp - modified by Chris Morgan +// and Wei Dai from Paulo Baretto's Rijndael implementation +// The original code and all modifications are in the public domain. + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM rijndael.cpp" to generate MASM code + +/* +July 2018: Added support for ARMv7 AES instructions via Cryptogams ASM. + See the head notes in aes_armv4.S for copyright and license. +*/ + +/* +September 2017: Added support for Power8 AES instructions via compiler intrinsics. +*/ + +/* +July 2017: Added support for ARMv8 AES instructions via compiler intrinsics. +*/ + +/* +July 2010: Added support for AES-NI instructions via compiler intrinsics. +*/ + +/* +Feb 2009: The x86/x64 assembly code was rewritten in by Wei Dai to do counter mode +caching, which was invented by Hongjun Wu and popularized by Daniel J. Bernstein +and Peter Schwabe in their paper "New AES software speed records". The round +function was also modified to include a trick similar to one in Brian Gladman's +x86 assembly code, doing an 8-bit register move to minimize the number of +register spills. Also switched to compressed tables and copying round keys to +the stack. + +The C++ implementation uses compressed tables if +CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS is defined. +It is defined on x86 platforms by default but no others. +*/ + +/* +July 2006: Defense against timing attacks was added in by Wei Dai. + +The code now uses smaller tables in the first and last rounds, +and preloads them into L1 cache before usage (by loading at least +one element in each cache line). + +We try to delay subsequent accesses to each table (used in the first +and last rounds) until all of the table has been preloaded. Hopefully +the compiler isn't smart enough to optimize that code away. + +After preloading the table, we also try not to access any memory location +other than the table and the stack, in order to prevent table entries from +being unloaded from L1 cache, until that round is finished. +(Some popular CPUs have 2-way associative caches.) +*/ + +// This is the original introductory comment: + +/** + * version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * author Vincent Rijmen + * author Antoon Bosselaers + * author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_IMPORTS +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "rijndael.h" +#include "misc.h" +#include "cpu.h" + +// VS2017 and global optimization bug. TODO, figure out when +// we can re-enable full optimizations for VS2017. Also see +// https://github.com/weidai11/cryptopp/issues/649 +#if (_MSC_VER >= 1910) +# ifndef CRYPTOPP_DEBUG +# pragma optimize("", off) +# pragma optimize("ts", on) +# endif +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// Hack for http://github.com/weidai11/cryptopp/issues/42 and http://github.com/weidai11/cryptopp/issues/132 +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) +# define CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS 1 +#endif + +// Clang intrinsic casts +#define M128I_CAST(x) ((__m128i *)(void *)(x)) +#define CONST_M128I_CAST(x) ((const __m128i *)(const void *)(x)) + +#if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) +# if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) +namespace rdtable {CRYPTOPP_ALIGN_DATA(16) word64 Te[256+2];} +using namespace rdtable; +# else +static word64 Te[256]; +# endif +static word64 Td[256]; +#else // Not CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS +# if defined(CRYPTOPP_X64_MASM_AVAILABLE) +// Unused; avoids linker error on Microsoft X64 non-AESNI platforms +namespace rdtable {CRYPTOPP_ALIGN_DATA(16) word64 Te[256+2];} +# endif +CRYPTOPP_ALIGN_DATA(16) static word32 Te[256*4]; +CRYPTOPP_ALIGN_DATA(16) static word32 Td[256*4]; +#endif // CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS + +static volatile bool s_TeFilled = false, s_TdFilled = false; + +ANONYMOUS_NAMESPACE_BEGIN + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 + +// Determine whether the range between begin and end overlaps +// with the same 4k block offsets as the Te table. Logically, +// the code is trying to create the condition: +// +// Two sepearate memory pages: +// +// +-----+ +-----+ +// |XXXXX| |YYYYY| +// |XXXXX| |YYYYY| +// | | | | +// | | | | +// +-----+ +-----+ +// Te Table Locals +// +// Have a logical cache view of (X and Y may be inverted): +// +// +-----+ +// |XXXXX| +// |XXXXX| +// |YYYYY| +// |YYYYY| +// +-----+ +// +static inline bool AliasedWithTable(const byte *begin, const byte *end) +{ + ptrdiff_t s0 = uintptr_t(begin)%4096, s1 = uintptr_t(end)%4096; + ptrdiff_t t0 = uintptr_t(Te)%4096, t1 = (uintptr_t(Te)+sizeof(Te))%4096; + if (t1 > t0) + return (s0 >= t0 && s0 < t1) || (s1 > t0 && s1 <= t1); + else + return (s0 < t1 || s1 <= t1) || (s0 >= t0 || s1 > t0); +} + +struct Locals +{ + word32 subkeys[4*12], workspace[8]; + const byte *inBlocks, *inXorBlocks, *outXorBlocks; + byte *outBlocks; + size_t inIncrement, inXorIncrement, outXorIncrement, outIncrement; + size_t regSpill, lengthAndCounterFlag, keysBegin; +}; + +const size_t s_aliasPageSize = 4096; +const size_t s_aliasBlockSize = 256; +const size_t s_sizeToAllocate = s_aliasPageSize + s_aliasBlockSize + sizeof(Locals); + +#endif // CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 + +ANONYMOUS_NAMESPACE_END + +// ************************* Portable Code ************************************ + +#define QUARTER_ROUND(L, T, t, a, b, c, d) \ + a ^= L(T, 3, byte(t)); t >>= 8;\ + b ^= L(T, 2, byte(t)); t >>= 8;\ + c ^= L(T, 1, byte(t)); t >>= 8;\ + d ^= L(T, 0, t); + +#define QUARTER_ROUND_LE(t, a, b, c, d) \ + tempBlock[a] = ((byte *)(Te+byte(t)))[1]; t >>= 8;\ + tempBlock[b] = ((byte *)(Te+byte(t)))[1]; t >>= 8;\ + tempBlock[c] = ((byte *)(Te+byte(t)))[1]; t >>= 8;\ + tempBlock[d] = ((byte *)(Te+t))[1]; + +#if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + #define QUARTER_ROUND_LD(t, a, b, c, d) \ + tempBlock[a] = ((byte *)(Td+byte(t)))[GetNativeByteOrder()*7]; t >>= 8;\ + tempBlock[b] = ((byte *)(Td+byte(t)))[GetNativeByteOrder()*7]; t >>= 8;\ + tempBlock[c] = ((byte *)(Td+byte(t)))[GetNativeByteOrder()*7]; t >>= 8;\ + tempBlock[d] = ((byte *)(Td+t))[GetNativeByteOrder()*7]; +#else + #define QUARTER_ROUND_LD(t, a, b, c, d) \ + tempBlock[a] = Sd[byte(t)]; t >>= 8;\ + tempBlock[b] = Sd[byte(t)]; t >>= 8;\ + tempBlock[c] = Sd[byte(t)]; t >>= 8;\ + tempBlock[d] = Sd[t]; +#endif + +#define QUARTER_ROUND_E(t, a, b, c, d) QUARTER_ROUND(TL_M, Te, t, a, b, c, d) +#define QUARTER_ROUND_D(t, a, b, c, d) QUARTER_ROUND(TL_M, Td, t, a, b, c, d) + +#if (CRYPTOPP_LITTLE_ENDIAN) + #define QUARTER_ROUND_FE(t, a, b, c, d) QUARTER_ROUND(TL_F, Te, t, d, c, b, a) + #define QUARTER_ROUND_FD(t, a, b, c, d) QUARTER_ROUND(TL_F, Td, t, d, c, b, a) + #if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + #define TL_F(T, i, x) (*(word32 *)(void *)((byte *)T + x*8 + (6-i)%4+1)) + #define TL_M(T, i, x) (*(word32 *)(void *)((byte *)T + x*8 + (i+3)%4+1)) + #else + #define TL_F(T, i, x) rotrFixed(T[x], (3-i)*8) + #define TL_M(T, i, x) T[i*256 + x] + #endif +#else + #define QUARTER_ROUND_FE(t, a, b, c, d) QUARTER_ROUND(TL_F, Te, t, a, b, c, d) + #define QUARTER_ROUND_FD(t, a, b, c, d) QUARTER_ROUND(TL_F, Td, t, a, b, c, d) + #if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + #define TL_F(T, i, x) (*(word32 *)(void *)((byte *)T + x*8 + (4-i)%4)) + #define TL_M TL_F + #else + #define TL_F(T, i, x) rotrFixed(T[x], i*8) + #define TL_M(T, i, x) T[i*256 + x] + #endif +#endif + + +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b)) +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b)) +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b)) + +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) + +unsigned int Rijndael::Base::OptimalDataAlignment() const +{ +#if (CRYPTOPP_AESNI_AVAILABLE) + if (HasAESNI()) + return 16; // load __m128i +#endif +#if (CRYPTOPP_ARM_AES_AVAILABLE) + if (HasAES()) + return 4; // load uint32x4_t +#endif +#if (CRYPTOGAMS_ARM_AES) + // Must use 1 here for Cryptogams AES. Also see + // https://github.com/weidai11/cryptopp/issues/683 + if (HasARMv7()) + return 1; +#endif +#if (CRYPTOPP_POWER8_AES_AVAILABLE) + if (HasAES()) + return 16; // load uint32x4_p +#endif + return BlockTransformation::OptimalDataAlignment(); +} + +void Rijndael::Base::FillEncTable() +{ + for (int i=0; i<256; i++) + { + byte x = Se[i]; +#if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + word32 y = word32(x)<<8 | word32(x)<<16 | word32(f2(x))<<24; + Te[i] = word64(y | f3(x))<<32 | y; +#else + word32 y = f3(x) | word32(x)<<8 | word32(x)<<16 | word32(f2(x))<<24; + for (int j=0; j<4; j++) + { + Te[i+j*256] = y; + y = rotrConstant<8>(y); + } +#endif + } +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) + Te[256] = Te[257] = 0; +#endif + s_TeFilled = true; +} + +void Rijndael::Base::FillDecTable() +{ + for (int i=0; i<256; i++) + { + byte x = Sd[i]; +#if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + word32 y = word32(fd(x))<<8 | word32(f9(x))<<16 | word32(fe(x))<<24; + Td[i] = word64(y | fb(x))<<32 | y | x; +#else + word32 y = fb(x) | word32(fd(x))<<8 | word32(f9(x))<<16 | word32(fe(x))<<24; + for (int j=0; j<4; j++) + { + Td[i+j*256] = y; + y = rotrConstant<8>(y); + } +#endif + } + s_TdFilled = true; +} + +#if (CRYPTOPP_AESNI_AVAILABLE) +extern void Rijndael_UncheckedSetKey_SSE4_AESNI(const byte *userKey, size_t keyLen, word32* rk); +extern void Rijndael_UncheckedSetKeyRev_AESNI(word32 *key, unsigned int rounds); + +extern size_t Rijndael_Enc_AdvancedProcessBlocks_AESNI(const word32 *subkeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +extern size_t Rijndael_Dec_AdvancedProcessBlocks_AESNI(const word32 *subkeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOPP_ARM_AES_AVAILABLE) +extern size_t Rijndael_Enc_AdvancedProcessBlocks_ARMV8(const word32 *subkeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +extern size_t Rijndael_Dec_AdvancedProcessBlocks_ARMV8(const word32 *subkeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOGAMS_ARM_AES) +extern "C" int cryptogams_AES_set_encrypt_key(const unsigned char *userKey, const int bitLen, word32 *rkey); +extern "C" int cryptogams_AES_set_decrypt_key(const unsigned char *userKey, const int bitLen, word32 *rkey); +extern "C" void cryptogams_AES_encrypt_block(const unsigned char *in, unsigned char *out, const word32 *rkey); +extern "C" void cryptogams_AES_decrypt_block(const unsigned char *in, unsigned char *out, const word32 *rkey); +#endif + +#if (CRYPTOPP_POWER8_AES_AVAILABLE) +extern void Rijndael_UncheckedSetKey_POWER8(const byte* userKey, size_t keyLen, + word32* rk, const byte* Se); + +extern size_t Rijndael_Enc_AdvancedProcessBlocks128_6x1_ALTIVEC(const word32 *subkeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +extern size_t Rijndael_Dec_AdvancedProcessBlocks128_6x1_ALTIVEC(const word32 *subkeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOGAMS_ARM_AES) +int CRYPTOGAMS_set_encrypt_key(const byte *userKey, const int bitLen, word32 *rkey) +{ + return cryptogams_AES_set_encrypt_key(userKey, bitLen, rkey); +} +int CRYPTOGAMS_set_decrypt_key(const byte *userKey, const int bitLen, word32 *rkey) +{ + return cryptogams_AES_set_decrypt_key(userKey, bitLen, rkey); +} +void CRYPTOGAMS_encrypt(const byte *inBlock, const byte *xorBlock, byte *outBlock, const word32 *rkey) +{ + cryptogams_AES_encrypt_block(inBlock, outBlock, rkey); + if (xorBlock) + xorbuf (outBlock, xorBlock, 16); +} +void CRYPTOGAMS_decrypt(const byte *inBlock, const byte *xorBlock, byte *outBlock, const word32 *rkey) +{ + cryptogams_AES_decrypt_block(inBlock, outBlock, rkey); + if (xorBlock) + xorbuf (outBlock, xorBlock, 16); +} +#endif + +std::string Rijndael::Base::AlgorithmProvider() const +{ +#if (CRYPTOPP_AESNI_AVAILABLE) + if (HasAESNI()) + return "AESNI"; +#endif +#if CRYPTOPP_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) + if (HasSSE2()) + return "SSE2"; +#endif +#if (CRYPTOPP_ARM_AES_AVAILABLE) + if (HasAES()) + return "ARMv8"; +#endif +#if (CRYPTOGAMS_ARM_AES) + if (HasARMv7()) + return "ARMv7"; +#endif +#if (CRYPTOPP_POWER8_AES_AVAILABLE) + if (HasAES()) + return "Power8"; +#endif + return "C++"; +} + +void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLen, const NameValuePairs &) +{ + AssertValidKeyLength(keyLen); + +#if (CRYPTOGAMS_ARM_AES) + if (HasARMv7()) + { + m_rounds = keyLen/4 + 6; + m_key.New(4*(14+1)+4); + + if (IsForwardTransformation()) + CRYPTOGAMS_set_encrypt_key(userKey, keyLen*8, m_key.begin()); + else + CRYPTOGAMS_set_decrypt_key(userKey, keyLen*8, m_key.begin()); + return; + } +#endif + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 + m_aliasBlock.New(s_sizeToAllocate); + // The alias block is only used on IA-32 when unaligned data access is in effect. + // Setting the low water mark to 0 avoids zeroization when m_aliasBlock is unused. + m_aliasBlock.SetMark(0); +#endif + + m_rounds = keyLen/4 + 6; + m_key.New(4*(m_rounds+1)); + word32 *rk = m_key; + +#if (CRYPTOPP_AESNI_AVAILABLE && CRYPTOPP_SSE41_AVAILABLE && (!defined(_MSC_VER) || _MSC_VER >= 1600 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)) + // MSVC 2008 SP1 generates bad code for _mm_extract_epi32() when compiling for X64 + if (HasAESNI() && HasSSE41()) + { + // TODO: Add non-SSE4.1 variant for low-end Atoms. The low-end + // Atoms have SSE2-SSSE3 and AES-NI, but not SSE4.1 or SSE4.2. + Rijndael_UncheckedSetKey_SSE4_AESNI(userKey, keyLen, rk); + if (!IsForwardTransformation()) + Rijndael_UncheckedSetKeyRev_AESNI(m_key, m_rounds); + + return; + } +#endif + +#if CRYPTOPP_POWER8_AES_AVAILABLE + if (HasAES()) + { + // We still need rcon and Se to fallback to C/C++ for AES-192 and AES-256. + // The IBM docs on AES sucks. Intel's docs on AESNI puts IBM to shame. + Rijndael_UncheckedSetKey_POWER8(userKey, keyLen, rk, Se); + return; + } +#endif + + GetUserKey(BIG_ENDIAN_ORDER, rk, keyLen/4, userKey, keyLen); + const word32 *rc = rcon; + word32 temp; + + while (true) + { + temp = rk[keyLen/4-1]; + word32 x = (word32(Se[GETBYTE(temp, 2)]) << 24) ^ (word32(Se[GETBYTE(temp, 1)]) << 16) ^ + (word32(Se[GETBYTE(temp, 0)]) << 8) ^ Se[GETBYTE(temp, 3)]; + rk[keyLen/4] = rk[0] ^ x ^ *(rc++); + rk[keyLen/4+1] = rk[1] ^ rk[keyLen/4]; + rk[keyLen/4+2] = rk[2] ^ rk[keyLen/4+1]; + rk[keyLen/4+3] = rk[3] ^ rk[keyLen/4+2]; + + if (rk + keyLen/4 + 4 == m_key.end()) + break; + + if (keyLen == 24) + { + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + } + else if (keyLen == 32) + { + temp = rk[11]; + rk[12] = rk[ 4] ^ (word32(Se[GETBYTE(temp, 3)]) << 24) ^ (word32(Se[GETBYTE(temp, 2)]) << 16) ^ (word32(Se[GETBYTE(temp, 1)]) << 8) ^ Se[GETBYTE(temp, 0)]; + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + } + rk += keyLen/4; + } + + rk = m_key; + + if (IsForwardTransformation()) + { + if (!s_TeFilled) + FillEncTable(); + + ConditionalByteReverse(BIG_ENDIAN_ORDER, rk, rk, 16); + ConditionalByteReverse(BIG_ENDIAN_ORDER, rk + m_rounds*4, rk + m_rounds*4, 16); + } + else + { + if (!s_TdFilled) + FillDecTable(); + + #define InverseMixColumn(x) \ + TL_M(Td, 0, Se[GETBYTE(x, 3)]) ^ TL_M(Td, 1, Se[GETBYTE(x, 2)]) ^ \ + TL_M(Td, 2, Se[GETBYTE(x, 1)]) ^ TL_M(Td, 3, Se[GETBYTE(x, 0)]) + + unsigned int i, j; + for (i = 4, j = 4*m_rounds-4; i < j; i += 4, j -= 4) + { + temp = InverseMixColumn(rk[i ]); rk[i ] = InverseMixColumn(rk[j ]); rk[j ] = temp; + temp = InverseMixColumn(rk[i + 1]); rk[i + 1] = InverseMixColumn(rk[j + 1]); rk[j + 1] = temp; + temp = InverseMixColumn(rk[i + 2]); rk[i + 2] = InverseMixColumn(rk[j + 2]); rk[j + 2] = temp; + temp = InverseMixColumn(rk[i + 3]); rk[i + 3] = InverseMixColumn(rk[j + 3]); rk[j + 3] = temp; + } + + rk[i+0] = InverseMixColumn(rk[i+0]); + rk[i+1] = InverseMixColumn(rk[i+1]); + rk[i+2] = InverseMixColumn(rk[i+2]); + rk[i+3] = InverseMixColumn(rk[i+3]); + + temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[0]); rk[0] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+0]); rk[4*m_rounds+0] = temp; + temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[1]); rk[1] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+1]); rk[4*m_rounds+1] = temp; + temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[2]); rk[2] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+2]); rk[4*m_rounds+2] = temp; + temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[3]); rk[3] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+3]); rk[4*m_rounds+3] = temp; + } + +#if CRYPTOPP_AESNI_AVAILABLE + if (HasAESNI()) + ConditionalByteReverse(BIG_ENDIAN_ORDER, rk+4, rk+4, (m_rounds-1)*16); +#endif +#if CRYPTOPP_ARM_AES_AVAILABLE + if (HasAES()) + ConditionalByteReverse(BIG_ENDIAN_ORDER, rk+4, rk+4, (m_rounds-1)*16); +#endif +} + +void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) || CRYPTOPP_AESNI_AVAILABLE +# if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) + if (HasSSE2()) +# else + if (HasAESNI()) +# endif + { + (void)Rijndael::Enc::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); + return; + } +#endif + +#if (CRYPTOPP_ARM_AES_AVAILABLE) + if (HasAES()) + { + (void)Rijndael::Enc::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); + return; + } +#endif + +#if (CRYPTOGAMS_ARM_AES) + if (HasARMv7()) + { + CRYPTOGAMS_encrypt(inBlock, xorBlock, outBlock, m_key.begin()); + return; + } +#endif + +#if (CRYPTOPP_POWER8_AES_AVAILABLE) + if (HasAES()) + { + (void)Rijndael::Enc::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); + return; + } +#endif + + typedef BlockGetAndPut Block; + + word32 s0, s1, s2, s3, t0, t1, t2, t3; + Block::Get(inBlock)(s0)(s1)(s2)(s3); + + const word32 *rk = m_key; + s0 ^= rk[0]; + s1 ^= rk[1]; + s2 ^= rk[2]; + s3 ^= rk[3]; + t0 = rk[4]; + t1 = rk[5]; + t2 = rk[6]; + t3 = rk[7]; + rk += 8; + + // timing attack countermeasure. see comments at top for more details. + // also see http://github.com/weidai11/cryptopp/issues/146 + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + volatile word32 _u = 0; + word32 u = _u; +#if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + for (i=0; i<2048; i+=cacheLineSize) +#else + for (i=0; i<1024; i+=cacheLineSize) +#endif + u &= *(const word32 *)(const void *)(((const byte *)Te)+i); + u &= Te[255]; + s0 |= u; s1 |= u; s2 |= u; s3 |= u; + + QUARTER_ROUND_FE(s3, t0, t1, t2, t3) + QUARTER_ROUND_FE(s2, t3, t0, t1, t2) + QUARTER_ROUND_FE(s1, t2, t3, t0, t1) + QUARTER_ROUND_FE(s0, t1, t2, t3, t0) + + // Nr - 2 full rounds: + unsigned int r = m_rounds/2 - 1; + do + { + s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; + + QUARTER_ROUND_E(t3, s0, s1, s2, s3) + QUARTER_ROUND_E(t2, s3, s0, s1, s2) + QUARTER_ROUND_E(t1, s2, s3, s0, s1) + QUARTER_ROUND_E(t0, s1, s2, s3, s0) + + t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7]; + + QUARTER_ROUND_E(s3, t0, t1, t2, t3) + QUARTER_ROUND_E(s2, t3, t0, t1, t2) + QUARTER_ROUND_E(s1, t2, t3, t0, t1) + QUARTER_ROUND_E(s0, t1, t2, t3, t0) + + rk += 8; + } while (--r); + + word32 tbw[4]; + byte *const tempBlock = (byte *)tbw; + + QUARTER_ROUND_LE(t2, 15, 2, 5, 8) + QUARTER_ROUND_LE(t1, 11, 14, 1, 4) + QUARTER_ROUND_LE(t0, 7, 10, 13, 0) + QUARTER_ROUND_LE(t3, 3, 6, 9, 12) + + Block::Put(xorBlock, outBlock)(tbw[0]^rk[0])(tbw[1]^rk[1])(tbw[2]^rk[2])(tbw[3]^rk[3]); +} + +void Rijndael::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ +#if CRYPTOPP_AESNI_AVAILABLE + if (HasAESNI()) + { + (void)Rijndael::Dec::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); + return; + } +#endif + +#if (CRYPTOPP_ARM_AES_AVAILABLE) + if (HasAES()) + { + (void)Rijndael::Dec::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); + return; + } +#endif + +#if (CRYPTOGAMS_ARM_AES) + if (HasARMv7()) + { + CRYPTOGAMS_decrypt(inBlock, xorBlock, outBlock, m_key.begin()); + return; + } +#endif + +#if (CRYPTOPP_POWER8_AES_AVAILABLE) + if (HasAES()) + { + (void)Rijndael::Dec::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); + return; + } +#endif + + typedef BlockGetAndPut Block; + + word32 s0, s1, s2, s3, t0, t1, t2, t3; + Block::Get(inBlock)(s0)(s1)(s2)(s3); + + const word32 *rk = m_key; + s0 ^= rk[0]; + s1 ^= rk[1]; + s2 ^= rk[2]; + s3 ^= rk[3]; + t0 = rk[4]; + t1 = rk[5]; + t2 = rk[6]; + t3 = rk[7]; + rk += 8; + + // timing attack countermeasure. see comments at top for more details. + // also see http://github.com/weidai11/cryptopp/issues/146 + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + volatile word32 _u = 0; + word32 u = _u; +#if defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS) + for (i=0; i<2048; i+=cacheLineSize) +#else + for (i=0; i<1024; i+=cacheLineSize) +#endif + u &= *(const word32 *)(const void *)(((const byte *)Td)+i); + u &= Td[255]; + s0 |= u; s1 |= u; s2 |= u; s3 |= u; + + QUARTER_ROUND_FD(s3, t2, t1, t0, t3) + QUARTER_ROUND_FD(s2, t1, t0, t3, t2) + QUARTER_ROUND_FD(s1, t0, t3, t2, t1) + QUARTER_ROUND_FD(s0, t3, t2, t1, t0) + + // Nr - 2 full rounds: + unsigned int r = m_rounds/2 - 1; + do + { + s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; + + QUARTER_ROUND_D(t3, s2, s1, s0, s3) + QUARTER_ROUND_D(t2, s1, s0, s3, s2) + QUARTER_ROUND_D(t1, s0, s3, s2, s1) + QUARTER_ROUND_D(t0, s3, s2, s1, s0) + + t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7]; + + QUARTER_ROUND_D(s3, t2, t1, t0, t3) + QUARTER_ROUND_D(s2, t1, t0, t3, t2) + QUARTER_ROUND_D(s1, t0, t3, t2, t1) + QUARTER_ROUND_D(s0, t3, t2, t1, t0) + + rk += 8; + } while (--r); + +#if !(defined(CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS)) + // timing attack countermeasure. see comments at top for more details + // If CRYPTOPP_ALLOW_RIJNDAEL_UNALIGNED_DATA_ACCESS is defined, + // QUARTER_ROUND_LD will use Td, which is already preloaded. + u = _u; + for (i=0; i<256; i+=cacheLineSize) + u &= *(const word32 *)(const void *)(Sd+i); + u &= *(const word32 *)(const void *)(Sd+252); + t0 |= u; t1 |= u; t2 |= u; t3 |= u; +#endif + + word32 tbw[4]; + byte *const tempBlock = (byte *)tbw; + + QUARTER_ROUND_LD(t2, 7, 2, 13, 8) + QUARTER_ROUND_LD(t1, 3, 14, 9, 4) + QUARTER_ROUND_LD(t0, 15, 10, 5, 0) + QUARTER_ROUND_LD(t3, 11, 6, 1, 12) + + Block::Put(xorBlock, outBlock)(tbw[0]^rk[0])(tbw[1]^rk[1])(tbw[2]^rk[2])(tbw[3]^rk[3]); +} + +// ************************* Assembly Code ************************************ + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code +#endif + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM + +#if CRYPTOPP_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) + +CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks_SSE2(void *locals, const word32 *k) +{ + CRYPTOPP_UNUSED(locals); CRYPTOPP_UNUSED(k); + +#if CRYPTOPP_BOOL_X86 + +#define L_REG esp +#define L_INDEX(i) (L_REG+768+i) +#define L_INXORBLOCKS L_INBLOCKS+4 +#define L_OUTXORBLOCKS L_INBLOCKS+8 +#define L_OUTBLOCKS L_INBLOCKS+12 +#define L_INCREMENTS L_INDEX(16*15) +#define L_SP L_INDEX(16*16) +#define L_LENGTH L_INDEX(16*16+4) +#define L_KEYS_BEGIN L_INDEX(16*16+8) + +#define MOVD movd +#define MM(i) mm##i + +#define MXOR(a,b,c) \ + AS2( movzx esi, b)\ + AS2( movd mm7, DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ + AS2( pxor MM(a), mm7)\ + +#define MMOV(a,b,c) \ + AS2( movzx esi, b)\ + AS2( movd MM(a), DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ + +#else + +#define L_REG r8 +#define L_INDEX(i) (L_REG+i) +#define L_INXORBLOCKS L_INBLOCKS+8 +#define L_OUTXORBLOCKS L_INBLOCKS+16 +#define L_OUTBLOCKS L_INBLOCKS+24 +#define L_INCREMENTS L_INDEX(16*16) +#define L_LENGTH L_INDEX(16*18+8) +#define L_KEYS_BEGIN L_INDEX(16*19) + +#define MOVD mov +#define MM_0 r9d +#define MM_1 r12d +#ifdef __GNUC__ +#define MM_2 r11d +#else +#define MM_2 r10d +#endif +#define MM(i) MM_##i + +#define MXOR(a,b,c) \ + AS2( movzx esi, b)\ + AS2( xor MM(a), DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ + +#define MMOV(a,b,c) \ + AS2( movzx esi, b)\ + AS2( mov MM(a), DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ + +#endif + +#define L_SUBKEYS L_INDEX(0) +#define L_SAVED_X L_SUBKEYS +#define L_KEY12 L_INDEX(16*12) +#define L_LASTROUND L_INDEX(16*13) +#define L_INBLOCKS L_INDEX(16*14) +#define MAP0TO4(i) (ASM_MOD(i+3,4)+1) + +#define XOR(a,b,c) \ + AS2( movzx esi, b)\ + AS2( xor a, DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ + +#define MOV(a,b,c) \ + AS2( movzx esi, b)\ + AS2( mov a, DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ + +#ifdef CRYPTOPP_GENERATE_X64_MASM + ALIGN 8 + Rijndael_Enc_AdvancedProcessBlocks PROC FRAME + rex_push_reg rsi + push_reg rdi + push_reg rbx + push_reg r12 + .endprolog + mov L_REG, rcx + mov AS_REG_7, ?Te@rdtable@CryptoPP@@3PA_KA + mov edi, DWORD PTR [?g_cacheLineSize@CryptoPP@@3IA] +#elif defined(__GNUC__) + __asm__ __volatile__ + ( + INTEL_NOPREFIX + #if CRYPTOPP_BOOL_X64 + AS2( mov L_REG, rcx) + #endif + AS_PUSH_IF86(bx) + AS_PUSH_IF86(bp) + AS2( mov AS_REG_7, WORD_REG(si)) +#else + AS_PUSH_IF86(si) + AS_PUSH_IF86(di) + AS_PUSH_IF86(bx) + AS_PUSH_IF86(bp) + AS2( lea AS_REG_7, [Te]) + AS2( mov edi, [g_cacheLineSize]) +#endif + +#if CRYPTOPP_BOOL_X86 + AS2( mov [ecx+16*12+16*4], esp) // save esp to L_SP + AS2( lea esp, [ecx-768]) +#endif + + // copy subkeys to stack + AS2( mov WORD_REG(si), [L_KEYS_BEGIN]) + AS2( mov WORD_REG(ax), 16) + AS2( and WORD_REG(ax), WORD_REG(si)) + AS2( movdqa xmm3, XMMWORD_PTR [WORD_REG(dx)+16+WORD_REG(ax)]) // subkey 1 (non-counter) or 2 (counter) + AS2( movdqa [L_KEY12], xmm3) + AS2( lea WORD_REG(ax), [WORD_REG(dx)+WORD_REG(ax)+2*16]) + AS2( sub WORD_REG(ax), WORD_REG(si)) + ASL(0) + AS2( movdqa xmm0, [WORD_REG(ax)+WORD_REG(si)]) + AS2( movdqa XMMWORD_PTR [L_SUBKEYS+WORD_REG(si)], xmm0) + AS2( add WORD_REG(si), 16) + AS2( cmp WORD_REG(si), 16*12) + ATT_NOPREFIX + ASJ( jl, 0, b) + INTEL_NOPREFIX + + // read subkeys 0, 1 and last + AS2( movdqa xmm4, [WORD_REG(ax)+WORD_REG(si)]) // last subkey + AS2( movdqa xmm1, [WORD_REG(dx)]) // subkey 0 + AS2( MOVD MM(1), [WORD_REG(dx)+4*4]) // 0,1,2,3 + AS2( mov ebx, [WORD_REG(dx)+5*4]) // 4,5,6,7 + AS2( mov ecx, [WORD_REG(dx)+6*4]) // 8,9,10,11 + AS2( mov edx, [WORD_REG(dx)+7*4]) // 12,13,14,15 + + // load table into cache + AS2( xor WORD_REG(ax), WORD_REG(ax)) + ASL(9) + AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) + AS2( add WORD_REG(ax), WORD_REG(di)) + AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) + AS2( add WORD_REG(ax), WORD_REG(di)) + AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) + AS2( add WORD_REG(ax), WORD_REG(di)) + AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) + AS2( add WORD_REG(ax), WORD_REG(di)) + AS2( cmp WORD_REG(ax), 2048) + ATT_NOPREFIX + ASJ( jl, 9, b) + INTEL_NOPREFIX + AS1( lfence) + + AS2( test DWORD PTR [L_LENGTH], 1) + ATT_NOPREFIX + ASJ( jz, 8, f) + INTEL_NOPREFIX + + // counter mode one-time setup + AS2( mov WORD_REG(si), [L_INBLOCKS]) + AS2( movdqu xmm2, [WORD_REG(si)]) // counter + AS2( pxor xmm2, xmm1) + AS2( psrldq xmm1, 14) + AS2( movd eax, xmm1) + AS2( mov al, BYTE PTR [WORD_REG(si)+15]) + AS2( MOVD MM(2), eax) +#if CRYPTOPP_BOOL_X86 + AS2( mov eax, 1) + AS2( movd mm3, eax) +#endif + + // partial first round, in: xmm2(15,14,13,12;11,10,9,8;7,6,5,4;3,2,1,0), out: mm1, ebx, ecx, edx + AS2( movd eax, xmm2) + AS2( psrldq xmm2, 4) + AS2( movd edi, xmm2) + AS2( psrldq xmm2, 4) + MXOR( 1, al, 0) // 0 + XOR( edx, ah, 1) // 1 + AS2( shr eax, 16) + XOR( ecx, al, 2) // 2 + XOR( ebx, ah, 3) // 3 + AS2( mov eax, edi) + AS2( movd edi, xmm2) + AS2( psrldq xmm2, 4) + XOR( ebx, al, 0) // 4 + MXOR( 1, ah, 1) // 5 + AS2( shr eax, 16) + XOR( edx, al, 2) // 6 + XOR( ecx, ah, 3) // 7 + AS2( mov eax, edi) + AS2( movd edi, xmm2) + XOR( ecx, al, 0) // 8 + XOR( ebx, ah, 1) // 9 + AS2( shr eax, 16) + MXOR( 1, al, 2) // 10 + XOR( edx, ah, 3) // 11 + AS2( mov eax, edi) + XOR( edx, al, 0) // 12 + XOR( ecx, ah, 1) // 13 + AS2( shr eax, 16) + XOR( ebx, al, 2) // 14 + AS2( psrldq xmm2, 3) + + // partial second round, in: ebx(4,5,6,7), ecx(8,9,10,11), edx(12,13,14,15), out: eax, ebx, edi, mm0 + AS2( mov eax, [L_KEY12+0*4]) + AS2( mov edi, [L_KEY12+2*4]) + AS2( MOVD MM(0), [L_KEY12+3*4]) + MXOR( 0, cl, 3) /* 11 */ + XOR( edi, bl, 3) /* 7 */ + MXOR( 0, bh, 2) /* 6 */ + AS2( shr ebx, 16) /* 4,5 */ + XOR( eax, bl, 1) /* 5 */ + MOV( ebx, bh, 0) /* 4 */ + AS2( xor ebx, [L_KEY12+1*4]) + XOR( eax, ch, 2) /* 10 */ + AS2( shr ecx, 16) /* 8,9 */ + XOR( eax, dl, 3) /* 15 */ + XOR( ebx, dh, 2) /* 14 */ + AS2( shr edx, 16) /* 12,13 */ + XOR( edi, ch, 0) /* 8 */ + XOR( ebx, cl, 1) /* 9 */ + XOR( edi, dl, 1) /* 13 */ + MXOR( 0, dh, 0) /* 12 */ + + AS2( movd ecx, xmm2) + AS2( MOVD edx, MM(1)) + AS2( MOVD [L_SAVED_X+3*4], MM(0)) + AS2( mov [L_SAVED_X+0*4], eax) + AS2( mov [L_SAVED_X+1*4], ebx) + AS2( mov [L_SAVED_X+2*4], edi) + ATT_NOPREFIX + ASJ( jmp, 5, f) + INTEL_NOPREFIX + ASL(3) + // non-counter mode per-block setup + AS2( MOVD MM(1), [L_KEY12+0*4]) // 0,1,2,3 + AS2( mov ebx, [L_KEY12+1*4]) // 4,5,6,7 + AS2( mov ecx, [L_KEY12+2*4]) // 8,9,10,11 + AS2( mov edx, [L_KEY12+3*4]) // 12,13,14,15 + ASL(8) + AS2( mov WORD_REG(ax), [L_INBLOCKS]) + AS2( movdqu xmm2, [WORD_REG(ax)]) + AS2( mov WORD_REG(si), [L_INXORBLOCKS]) + AS2( movdqu xmm5, [WORD_REG(si)]) + AS2( pxor xmm2, xmm1) + AS2( pxor xmm2, xmm5) + + // first round, in: xmm2(15,14,13,12;11,10,9,8;7,6,5,4;3,2,1,0), out: eax, ebx, ecx, edx + AS2( movd eax, xmm2) + AS2( psrldq xmm2, 4) + AS2( movd edi, xmm2) + AS2( psrldq xmm2, 4) + MXOR( 1, al, 0) // 0 + XOR( edx, ah, 1) // 1 + AS2( shr eax, 16) + XOR( ecx, al, 2) // 2 + XOR( ebx, ah, 3) // 3 + AS2( mov eax, edi) + AS2( movd edi, xmm2) + AS2( psrldq xmm2, 4) + XOR( ebx, al, 0) // 4 + MXOR( 1, ah, 1) // 5 + AS2( shr eax, 16) + XOR( edx, al, 2) // 6 + XOR( ecx, ah, 3) // 7 + AS2( mov eax, edi) + AS2( movd edi, xmm2) + XOR( ecx, al, 0) // 8 + XOR( ebx, ah, 1) // 9 + AS2( shr eax, 16) + MXOR( 1, al, 2) // 10 + XOR( edx, ah, 3) // 11 + AS2( mov eax, edi) + XOR( edx, al, 0) // 12 + XOR( ecx, ah, 1) // 13 + AS2( shr eax, 16) + XOR( ebx, al, 2) // 14 + MXOR( 1, ah, 3) // 15 + AS2( MOVD eax, MM(1)) + + AS2( add L_REG, [L_KEYS_BEGIN]) + AS2( add L_REG, 4*16) + ATT_NOPREFIX + ASJ( jmp, 2, f) + INTEL_NOPREFIX + ASL(1) + // counter-mode per-block setup + AS2( MOVD ecx, MM(2)) + AS2( MOVD edx, MM(1)) + AS2( mov eax, [L_SAVED_X+0*4]) + AS2( mov ebx, [L_SAVED_X+1*4]) + AS2( xor cl, ch) + AS2( and WORD_REG(cx), 255) + ASL(5) +#if CRYPTOPP_BOOL_X86 + AS2( paddb MM(2), mm3) +#else + AS2( add MM(2), 1) +#endif + // remaining part of second round, in: edx(previous round),esi(keyed counter byte) eax,ebx,[L_SAVED_X+2*4],[L_SAVED_X+3*4], out: eax,ebx,ecx,edx + AS2( xor edx, DWORD PTR [AS_REG_7+WORD_REG(cx)*8+3]) + XOR( ebx, dl, 3) + MOV( ecx, dh, 2) + AS2( shr edx, 16) + AS2( xor ecx, [L_SAVED_X+2*4]) + XOR( eax, dh, 0) + MOV( edx, dl, 1) + AS2( xor edx, [L_SAVED_X+3*4]) + + AS2( add L_REG, [L_KEYS_BEGIN]) + AS2( add L_REG, 3*16) + ATT_NOPREFIX + ASJ( jmp, 4, f) + INTEL_NOPREFIX + +// in: eax(0,1,2,3), ebx(4,5,6,7), ecx(8,9,10,11), edx(12,13,14,15) +// out: eax, ebx, edi, mm0 +#define ROUND() \ + MXOR( 0, cl, 3) /* 11 */\ + AS2( mov cl, al) /* 8,9,10,3 */\ + XOR( edi, ah, 2) /* 2 */\ + AS2( shr eax, 16) /* 0,1 */\ + XOR( edi, bl, 3) /* 7 */\ + MXOR( 0, bh, 2) /* 6 */\ + AS2( shr ebx, 16) /* 4,5 */\ + MXOR( 0, al, 1) /* 1 */\ + MOV( eax, ah, 0) /* 0 */\ + XOR( eax, bl, 1) /* 5 */\ + MOV( ebx, bh, 0) /* 4 */\ + XOR( eax, ch, 2) /* 10 */\ + XOR( ebx, cl, 3) /* 3 */\ + AS2( shr ecx, 16) /* 8,9 */\ + XOR( eax, dl, 3) /* 15 */\ + XOR( ebx, dh, 2) /* 14 */\ + AS2( shr edx, 16) /* 12,13 */\ + XOR( edi, ch, 0) /* 8 */\ + XOR( ebx, cl, 1) /* 9 */\ + XOR( edi, dl, 1) /* 13 */\ + MXOR( 0, dh, 0) /* 12 */\ + + ASL(2) // 2-round loop + AS2( MOVD MM(0), [L_SUBKEYS-4*16+3*4]) + AS2( mov edi, [L_SUBKEYS-4*16+2*4]) + ROUND() + AS2( mov ecx, edi) + AS2( xor eax, [L_SUBKEYS-4*16+0*4]) + AS2( xor ebx, [L_SUBKEYS-4*16+1*4]) + AS2( MOVD edx, MM(0)) + + ASL(4) + AS2( MOVD MM(0), [L_SUBKEYS-4*16+7*4]) + AS2( mov edi, [L_SUBKEYS-4*16+6*4]) + ROUND() + AS2( mov ecx, edi) + AS2( xor eax, [L_SUBKEYS-4*16+4*4]) + AS2( xor ebx, [L_SUBKEYS-4*16+5*4]) + AS2( MOVD edx, MM(0)) + + AS2( add L_REG, 32) + AS2( test L_REG, 255) + ATT_NOPREFIX + ASJ( jnz, 2, b) + INTEL_NOPREFIX + AS2( sub L_REG, 16*16) + +#define LAST(a, b, c) \ + AS2( movzx esi, a )\ + AS2( movzx edi, BYTE PTR [AS_REG_7+WORD_REG(si)*8+1] )\ + AS2( movzx esi, b )\ + AS2( xor edi, DWORD PTR [AS_REG_7+WORD_REG(si)*8+0] )\ + AS2( mov WORD PTR [L_LASTROUND+c], di )\ + + // last round + LAST(ch, dl, 2) + LAST(dh, al, 6) + AS2( shr edx, 16) + LAST(ah, bl, 10) + AS2( shr eax, 16) + LAST(bh, cl, 14) + AS2( shr ebx, 16) + LAST(dh, al, 12) + AS2( shr ecx, 16) + LAST(ah, bl, 0) + LAST(bh, cl, 4) + LAST(ch, dl, 8) + + AS2( mov WORD_REG(ax), [L_OUTXORBLOCKS]) + AS2( mov WORD_REG(bx), [L_OUTBLOCKS]) + + AS2( mov WORD_REG(cx), [L_LENGTH]) + AS2( sub WORD_REG(cx), 16) + + AS2( movdqu xmm2, [WORD_REG(ax)]) + AS2( pxor xmm2, xmm4) + +#if CRYPTOPP_BOOL_X86 + AS2( movdqa xmm0, [L_INCREMENTS]) + AS2( paddd xmm0, [L_INBLOCKS]) + AS2( movdqa [L_INBLOCKS], xmm0) +#else + AS2( movdqa xmm0, [L_INCREMENTS+16]) + AS2( paddq xmm0, [L_INBLOCKS+16]) + AS2( movdqa [L_INBLOCKS+16], xmm0) +#endif + + AS2( pxor xmm2, [L_LASTROUND]) + AS2( movdqu [WORD_REG(bx)], xmm2) + + ATT_NOPREFIX + ASJ( jle, 7, f) + INTEL_NOPREFIX + AS2( mov [L_LENGTH], WORD_REG(cx)) + AS2( test WORD_REG(cx), 1) + ATT_NOPREFIX + ASJ( jnz, 1, b) + INTEL_NOPREFIX +#if CRYPTOPP_BOOL_X64 + AS2( movdqa xmm0, [L_INCREMENTS]) + AS2( paddq xmm0, [L_INBLOCKS]) + AS2( movdqa [L_INBLOCKS], xmm0) +#endif + ATT_NOPREFIX + ASJ( jmp, 3, b) + INTEL_NOPREFIX + + ASL(7) + // erase keys on stack + AS2( xorps xmm0, xmm0) + AS2( lea WORD_REG(ax), [L_SUBKEYS+7*16]) + AS2( movaps [WORD_REG(ax)-7*16], xmm0) + AS2( movaps [WORD_REG(ax)-6*16], xmm0) + AS2( movaps [WORD_REG(ax)-5*16], xmm0) + AS2( movaps [WORD_REG(ax)-4*16], xmm0) + AS2( movaps [WORD_REG(ax)-3*16], xmm0) + AS2( movaps [WORD_REG(ax)-2*16], xmm0) + AS2( movaps [WORD_REG(ax)-1*16], xmm0) + AS2( movaps [WORD_REG(ax)+0*16], xmm0) + AS2( movaps [WORD_REG(ax)+1*16], xmm0) + AS2( movaps [WORD_REG(ax)+2*16], xmm0) + AS2( movaps [WORD_REG(ax)+3*16], xmm0) + AS2( movaps [WORD_REG(ax)+4*16], xmm0) + AS2( movaps [WORD_REG(ax)+5*16], xmm0) + AS2( movaps [WORD_REG(ax)+6*16], xmm0) +#if CRYPTOPP_BOOL_X86 + AS2( mov esp, [L_SP]) + AS1( emms) +#endif + AS_POP_IF86(bp) + AS_POP_IF86(bx) +#if defined(_MSC_VER) && CRYPTOPP_BOOL_X86 + AS_POP_IF86(di) + AS_POP_IF86(si) + AS1(ret) +#endif +#ifdef CRYPTOPP_GENERATE_X64_MASM + pop r12 + pop rbx + pop rdi + pop rsi + ret + Rijndael_Enc_AdvancedProcessBlocks ENDP +#endif +#ifdef __GNUC__ + ATT_PREFIX + : + : "c" (locals), "d" (k), "S" (Te), "D" (g_cacheLineSize) + : "memory", "cc", "%eax" + #if CRYPTOPP_BOOL_X64 + , "%rbx", "%r8", "%r9", "%r10", "%r11", "%r12" + #endif + ); +#endif +} + +#endif + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Rijndael_Enc_AdvancedProcessBlocks_SSE2(void *locals, const word32 *k); +} +#endif + +#if CRYPTOPP_RIJNDAEL_ADVANCED_PROCESS_BLOCKS +size_t Rijndael::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const +{ +#if CRYPTOPP_AESNI_AVAILABLE + if (HasAESNI()) + return Rijndael_Enc_AdvancedProcessBlocks_AESNI(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if CRYPTOPP_ARM_AES_AVAILABLE + if (HasAES()) + return Rijndael_Enc_AdvancedProcessBlocks_ARMV8(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if CRYPTOPP_POWER8_AES_AVAILABLE + if (HasAES()) + return Rijndael_Enc_AdvancedProcessBlocks128_6x1_ALTIVEC(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); +#endif + +#if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) + if (HasSSE2()) + { + if (length < BLOCKSIZE) + return length; + + static const byte *zeros = (const byte*)(Te+256); + m_aliasBlock.SetMark(m_aliasBlock.size()); + byte *space = NULLPTR, *originalSpace = const_cast(m_aliasBlock.data()); + + // round up to nearest 256 byte boundary + space = originalSpace + (s_aliasBlockSize - (uintptr_t)originalSpace % s_aliasBlockSize) % s_aliasBlockSize; + while (AliasedWithTable(space, space + sizeof(Locals))) + { + space += 256; + CRYPTOPP_ASSERT(space < (originalSpace + s_aliasPageSize)); + } + + size_t increment = BLOCKSIZE; + if (flags & BT_ReverseDirection) + { + CRYPTOPP_ASSERT(length % BLOCKSIZE == 0); + inBlocks += length - BLOCKSIZE; + xorBlocks += length - BLOCKSIZE; + outBlocks += length - BLOCKSIZE; + increment = 0-increment; + } + + Locals &locals = *(Locals *)(void *)space; + + locals.inBlocks = inBlocks; + locals.inXorBlocks = (flags & BT_XorInput) && xorBlocks ? xorBlocks : zeros; + locals.outXorBlocks = (flags & BT_XorInput) || !xorBlocks ? zeros : xorBlocks; + locals.outBlocks = outBlocks; + + locals.inIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : increment; + locals.inXorIncrement = (flags & BT_XorInput) && xorBlocks ? increment : 0; + locals.outXorIncrement = (flags & BT_XorInput) || !xorBlocks ? 0 : increment; + locals.outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : increment; + + locals.lengthAndCounterFlag = length - (length%16) - bool(flags & BT_InBlockIsCounter); + int keysToCopy = m_rounds - (flags & BT_InBlockIsCounter ? 3 : 2); + locals.keysBegin = (12-keysToCopy)*16; + + Rijndael_Enc_AdvancedProcessBlocks_SSE2(&locals, m_key); + + return length % BLOCKSIZE; + } +#endif + + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t Rijndael::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const +{ +#if CRYPTOPP_AESNI_AVAILABLE + if (HasAESNI()) + return Rijndael_Dec_AdvancedProcessBlocks_AESNI(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if CRYPTOPP_ARM_AES_AVAILABLE + if (HasAES()) + return Rijndael_Dec_AdvancedProcessBlocks_ARMV8(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if CRYPTOPP_POWER8_AES_AVAILABLE + if (HasAES()) + return Rijndael_Dec_AdvancedProcessBlocks128_6x1_ALTIVEC(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); +#endif + + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_RIJNDAEL_ADVANCED_PROCESS_BLOCKS + +NAMESPACE_END + +#endif +#endif diff --git a/external/ours/library/crypto/src/shared/original/rijndael.h b/external/ours/library/crypto/src/shared/original/rijndael.h new file mode 100755 index 000000000..bfb80fa12 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rijndael.h @@ -0,0 +1,109 @@ +// rijndael.h - originally written and placed in the public domain by Wei Dai + +/// \file rijndael.h +/// \brief Classes for Rijndael encryption algorithm +/// \details All key sizes are supported. The library only provides Rijndael with 128-bit blocks, +/// and not 192-bit or 256-bit blocks +/// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, +/// Power8 AES since Crypto++ 6.0, ARMv7 AES since Crypto++ 8.0 + +#ifndef CRYPTOPP_RIJNDAEL_H +#define CRYPTOPP_RIJNDAEL_H + +#include "seckey.h" +#include "secblock.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_RIJNDAEL_ASM 1 +#endif + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_ARM32 || \ + CRYPTOPP_BOOL_ARMV8 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 +# define CRYPTOPP_RIJNDAEL_ADVANCED_PROCESS_BLOCKS 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Rijndael block cipher information +/// \details All key sizes are supported. The library only provides Rijndael with 128-bit blocks, +/// and not 192-bit or 256-bit blocks +/// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, +/// Power8 AES since Crypto++ 6.0, ARMv7 AES since Crypto++ 8.0 +struct Rijndael_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "AES";} +}; + +/// \brief Rijndael block cipher +/// \details All key sizes are supported. The library only provides Rijndael with 128-bit blocks, +/// and not 192-bit or 256-bit blocks +/// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, +/// Power8 AES since Crypto++ 6.0, ARMv7 AES since Crypto++ 8.0 +/// \sa Rijndael +class CRYPTOPP_DLL Rijndael : public Rijndael_Info, public BlockCipherDocumentation +{ + /// \brief Rijndael block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + std::string AlgorithmProvider() const; + unsigned int OptimalDataAlignment() const; + + protected: + static void FillEncTable(); + static void FillDecTable(); + + // VS2005 workaround: have to put these on separate lines, or error C2487 is triggered in DLL build + static const byte Se[256]; + static const byte Sd[256]; + + static const word32 rcon[]; + + unsigned int m_rounds; + SecBlock > m_key; + mutable SecByteBlock m_aliasBlock; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key sizes are supported. + /// The library only provides Rijndael with 128-bit blocks, and not 192-bit or 256-bit blocks + /// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, + /// Power8 AES since Crypto++ 6.0, ARMv7 AES since Crypto++ 8.0 + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_RIJNDAEL_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key sizes are supported. + /// The library only provides Rijndael with 128-bit blocks, and not 192-bit or 256-bit blocks + /// \since Rijndael since Crypto++ 3.1, Intel AES-NI since Crypto++ 5.6.1, ARMv8 AES since Crypto++ 6.0, + /// Power8 AES since Crypto++ 6.0, ARMv7 AES since Crypto++ 8.0 + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_RIJNDAEL_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Rijndael::Encryption RijndaelEncryption; +typedef Rijndael::Decryption RijndaelDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rijndael_simd.cpp b/external/ours/library/crypto/src/shared/original/rijndael_simd.cpp new file mode 100755 index 000000000..c3421b3e9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rijndael_simd.cpp @@ -0,0 +1,734 @@ +// rijndael_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// AES-NI code originally written by Wei Dai. +// +// This source file uses intrinsics and built-ins to gain access to +// AES-NI, ARMv8a AES and Power8 AES instructions. A separate source +// file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. +// +// ARMv8a AES code based on CriticalBlue code from Johannes Schneiders, +// Skip Hovsmith and Barry O'Rourke for the mbedTLS project. Stepping +// mbedTLS under a debugger was helped for us to determine problems +// with our subkey generation and scheduling. +// +// AltiVec and Power8 code based on http://github.com/noloader/AES-Intrinsics and +// http://www.ibm.com/developerworks/library/se-power8-in-core-cryptography/ +// For Power8 do not remove the casts, even when const-ness is cast away. It causes +// failed compiles and a 0.3 to 0.6 cpb drop in performance. The IBM documentation +// absolutely sucks. Thanks to Andy Polyakov, Paul R and Trudeaun for answering +// questions and filling the gaps in the IBM documentation. +// + +#include "pch.h" +#include "config.h" +#include "misc.h" + +#if (CRYPTOPP_AESNI_AVAILABLE) +# include "adv_simd.h" +# include +# include +# include +#endif + +// Android makes available with ARMv7-a +#if (CRYPTOPP_BOOL_ARMV8) +# include "adv_simd.h" +# if (CRYPTOPP_ARM_NEON_HEADER) +# include +# endif +# if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +# endif +#endif + +#if defined(_M_ARM64) +# include "adv_simd.h" +#endif + +#if defined(CRYPTOPP_POWER8_AES_AVAILABLE) +# include "adv_simd.h" +# include "ppc_simd.h" +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char RIJNDAEL_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// ************************* Feature Probes ************************* // + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) +bool CPU_ProbeAES() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (CRYPTOPP_ARM_AES_AVAILABLE) +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + // AES encrypt and decrypt + uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0); + uint8x16_t r1 = vaeseq_u8(data, key); + uint8x16_t r2 = vaesdq_u8(data, key); + r1 = vaesmcq_u8(r1); + r2 = vaesimcq_u8(r2); + + result = !!(vgetq_lane_u8(r1,0) | vgetq_lane_u8(r2,7)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +# else + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0); + uint8x16_t r1 = vaeseq_u8(data, key); + uint8x16_t r2 = vaesdq_u8(data, key); + r1 = vaesmcq_u8(r1); + r2 = vaesimcq_u8(r2); + + // Hack... GCC optimizes away the code and returns true + result = !!(vgetq_lane_u8(r1,0) | vgetq_lane_u8(r2,7)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_AES_AVAILABLE +} +#endif // ARM32 or ARM64 + +// ***************************** ARMv8 ***************************** // + +#if (CRYPTOPP_ARM_AES_AVAILABLE) + +ANONYMOUS_NAMESPACE_BEGIN + +inline void ARMV8_Enc_Block(uint64x2_t &data, const word32 *subkeys, unsigned int rounds) +{ + CRYPTOPP_ASSERT(subkeys); + const byte *keys = reinterpret_cast(subkeys); + uint8x16_t block = vreinterpretq_u8_u64(data); + + // AES single round encryption + block = vaeseq_u8(block, vld1q_u8(keys+0*16)); + // AES mix columns + block = vaesmcq_u8(block); + + for (unsigned int i=1; i(subkeys); + + uint8x16_t block0 = vreinterpretq_u8_u64(data0); + uint8x16_t block1 = vreinterpretq_u8_u64(data1); + uint8x16_t block2 = vreinterpretq_u8_u64(data2); + uint8x16_t block3 = vreinterpretq_u8_u64(data3); + uint8x16_t block4 = vreinterpretq_u8_u64(data4); + uint8x16_t block5 = vreinterpretq_u8_u64(data5); + + uint8x16_t key; + for (unsigned int i=0; i(subkeys); + uint8x16_t block = vreinterpretq_u8_u64(data); + + // AES single round decryption + block = vaesdq_u8(block, vld1q_u8(keys+0*16)); + // AES inverse mix columns + block = vaesimcq_u8(block); + + for (unsigned int i=1; i(subkeys); + + uint8x16_t block0 = vreinterpretq_u8_u64(data0); + uint8x16_t block1 = vreinterpretq_u8_u64(data1); + uint8x16_t block2 = vreinterpretq_u8_u64(data2); + uint8x16_t block3 = vreinterpretq_u8_u64(data3); + uint8x16_t block4 = vreinterpretq_u8_u64(data4); + uint8x16_t block5 = vreinterpretq_u8_u64(data5); + + uint8x16_t key; + for (unsigned int i=0; i(subkeys); + + block = _mm_xor_si128(block, skeys[0]); + for (unsigned int i=1; i(subkeys); + + __m128i rk = skeys[0]; + block0 = _mm_xor_si128(block0, rk); + block1 = _mm_xor_si128(block1, rk); + block2 = _mm_xor_si128(block2, rk); + block3 = _mm_xor_si128(block3, rk); + for (unsigned int i=1; i(subkeys); + + block = _mm_xor_si128(block, skeys[0]); + for (unsigned int i=1; i(subkeys); + + __m128i rk = skeys[0]; + block0 = _mm_xor_si128(block0, rk); + block1 = _mm_xor_si128(block1, rk); + block2 = _mm_xor_si128(block2, rk); + block3 = _mm_xor_si128(block3, rk); + for (unsigned int i=1; i(subkeys); + + uint32x4_p k = VecLoadAligned(keys); + block = VecXor(block, k); + + for (size_t i=1; i(subkeys); + + uint32x4_p k = VecLoadAligned(keys); + block0 = VecXor(block0, k); + block1 = VecXor(block1, k); + block2 = VecXor(block2, k); + block3 = VecXor(block3, k); + block4 = VecXor(block4, k); + block5 = VecXor(block5, k); + + for (size_t i=1; i(subkeys); + + uint32x4_p k = VecLoadAligned(rounds*16, keys); + block = VecXor(block, k); + + for (size_t i=rounds-1; i>1; i-=2) + { + block = VecDecrypt(block, VecLoadAligned( i*16, keys)); + block = VecDecrypt(block, VecLoadAligned((i-1)*16, keys)); + } + + block = VecDecrypt(block, VecLoadAligned(16, keys)); + block = VecDecryptLast(block, VecLoadAligned(0, keys)); +} + +inline void POWER8_Dec_6_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, uint32x4_p &block4, + uint32x4_p &block5, const word32 *subkeys, unsigned int rounds) +{ + CRYPTOPP_ASSERT(IsAlignedOn(subkeys, 16)); + const byte *keys = reinterpret_cast(subkeys); + + uint32x4_p k = VecLoadAligned(rounds*16, keys); + block0 = VecXor(block0, k); + block1 = VecXor(block1, k); + block2 = VecXor(block2, k); + block3 = VecXor(block3, k); + block4 = VecXor(block4, k); + block5 = VecXor(block5, k); + + for (size_t i=rounds-1; i>0; --i) + { + k = VecLoadAligned(i*16, keys); + block0 = VecDecrypt(block0, k); + block1 = VecDecrypt(block1, k); + block2 = VecDecrypt(block2, k); + block3 = VecDecrypt(block3, k); + block4 = VecDecrypt(block4, k); + block5 = VecDecrypt(block5, k); + } + + k = VecLoadAligned(0, keys); + block0 = VecDecryptLast(block0, k); + block1 = VecDecryptLast(block1, k); + block2 = VecDecryptLast(block2, k); + block3 = VecDecryptLast(block3, k); + block4 = VecDecryptLast(block4, k); + block5 = VecDecryptLast(block5, k); +} + +ANONYMOUS_NAMESPACE_END + +void Rijndael_UncheckedSetKey_POWER8(const byte* userKey, size_t keyLen, word32* rk, const byte* Se) +{ + const size_t rounds = keyLen / 4 + 6; + const word32 *rc = s_rconBE; + word32 *rkey = rk, temp; + + GetUserKey(BIG_ENDIAN_ORDER, rkey, keyLen/4, userKey, keyLen); + + // keySize: m_key allocates 4*(rounds+1) word32's. + const size_t keySize = 4*(rounds+1); + const word32* end = rkey + keySize; + + while (true) + { + temp = rkey[keyLen/4-1]; + word32 x = (word32(Se[GETBYTE(temp, 2)]) << 24) ^ (word32(Se[GETBYTE(temp, 1)]) << 16) ^ + (word32(Se[GETBYTE(temp, 0)]) << 8) ^ Se[GETBYTE(temp, 3)]; + rkey[keyLen/4] = rkey[0] ^ x ^ *(rc++); + rkey[keyLen/4+1] = rkey[1] ^ rkey[keyLen/4]; + rkey[keyLen/4+2] = rkey[2] ^ rkey[keyLen/4+1]; + rkey[keyLen/4+3] = rkey[3] ^ rkey[keyLen/4+2]; + + if (rkey + keyLen/4 + 4 == end) + break; + + if (keyLen == 24) + { + rkey[10] = rkey[ 4] ^ rkey[ 9]; + rkey[11] = rkey[ 5] ^ rkey[10]; + } + else if (keyLen == 32) + { + temp = rkey[11]; + rkey[12] = rkey[ 4] ^ (word32(Se[GETBYTE(temp, 3)]) << 24) ^ (word32(Se[GETBYTE(temp, 2)]) << 16) ^ (word32(Se[GETBYTE(temp, 1)]) << 8) ^ Se[GETBYTE(temp, 0)]; + rkey[13] = rkey[ 5] ^ rkey[12]; + rkey[14] = rkey[ 6] ^ rkey[13]; + rkey[15] = rkey[ 7] ^ rkey[14]; + } + rkey += keyLen/4; + } + +#if (CRYPTOPP_LITTLE_ENDIAN) + rkey = rk; + const uint8x16_p mask = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; + + unsigned int i=0; + for (i=0; i((word32)c) + +void RIPEMD160::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + state[4] = 0xc3d2e1f0L; +} + +void RIPEMD160::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; + a1 = a2 = digest[0]; + b1 = b2 = digest[1]; + c1 = c2 = digest[2]; + d1 = d2 = digest[3]; + e1 = e2 = digest[4]; + + Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); + Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); + Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); + Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); + Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); + Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); + Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); + Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); + + Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); + Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); + Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); + Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); + + Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); + Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); + Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); + Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); + Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); + Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); + + Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); + Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); + Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); + Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); + Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); + Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); + + Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); + Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); + Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); + Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); + Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); + Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); + Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); + Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); + Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); + + Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); + Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); + Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); + Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); + Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); + Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); + Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); + Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); + + Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); + Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); + Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); + Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); + Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); + Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); + + Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); + Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); + Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); + Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); + Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); + + Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); + Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); + Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); + Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); + Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); + Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); + Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); + Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); + Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); + Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); + + Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); + Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); + Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); + Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); + Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); + Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); + Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); + + c1 = digest[1] + c1 + d2; + digest[1] = digest[2] + d1 + e2; + digest[2] = digest[3] + e1 + a2; + digest[3] = digest[4] + a1 + b2; + digest[4] = digest[0] + b1 + c2; + digest[0] = c1; +} + +// ************************************************************* + +void RIPEMD320::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + state[4] = 0xc3d2e1f0L; + state[5] = 0x76543210L; + state[6] = 0xfedcba98L; + state[7] = 0x89abcdefL; + state[8] = 0x01234567L; + state[9] = 0x3c2d1e0fL; +} + +void RIPEMD320::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2, t; + a1 = digest[0]; + b1 = digest[1]; + c1 = digest[2]; + d1 = digest[3]; + e1 = digest[4]; + a2 = digest[5]; + b2 = digest[6]; + c2 = digest[7]; + d2 = digest[8]; + e2 = digest[9]; + + Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); + Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); + Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); + Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); + Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); + Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); + Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); + Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); + + Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); + Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); + Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); + Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); + Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); + Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); + Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); + Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); + + t = a1; a1 = a2; a2 = t; + + Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); + Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); + Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); + Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); + + Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); + Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); + Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); + Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); + Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); + Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); + + t = b1; b1 = b2; b2 = t; + + Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); + Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); + Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); + Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); + Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); + Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); + + Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); + Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); + Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); + Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); + Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); + + t = c1; c1 = c2; c2 = t; + + Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); + Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); + Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); + Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); + Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); + Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); + + Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); + Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); + Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); + Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); + Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); + Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); + Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); + Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); + Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); + Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); + + t = d1; d1 = d2; d2 = t; + + Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); + Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); + Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); + Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); + Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); + Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); + Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); + Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); + Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); + + Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); + Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); + Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); + Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); + Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); + Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); + Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); + + t = e1; e1 = e2; e2 = t; + + digest[0] += a1; + digest[1] += b1; + digest[2] += c1; + digest[3] += d1; + digest[4] += e1; + digest[5] += a2; + digest[6] += b2; + digest[7] += c2; + digest[8] += d2; + digest[9] += e2; +} + +#undef Subround + +// ************************************************************* + +// for 128 and 256 +#define Subround(f, a, b, c, d, x, s, k) \ + a += f(b, c, d) + x + k;\ + a = rotlVariable((word32)a, s); + +void RIPEMD128::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; +} + +void RIPEMD128::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, a2, b2, c2, d2; + a1 = a2 = digest[0]; + b1 = b2 = digest[1]; + c1 = c2 = digest[2]; + d1 = d2 = digest[3]; + + Subround(F, a1, b1, c1, d1, X[ 0], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 1], 14, k0); + Subround(F, c1, d1, a1, b1, X[ 2], 15, k0); + Subround(F, b1, c1, d1, a1, X[ 3], 12, k0); + Subround(F, a1, b1, c1, d1, X[ 4], 5, k0); + Subround(F, d1, a1, b1, c1, X[ 5], 8, k0); + Subround(F, c1, d1, a1, b1, X[ 6], 7, k0); + Subround(F, b1, c1, d1, a1, X[ 7], 9, k0); + Subround(F, a1, b1, c1, d1, X[ 8], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 9], 13, k0); + Subround(F, c1, d1, a1, b1, X[10], 14, k0); + Subround(F, b1, c1, d1, a1, X[11], 15, k0); + Subround(F, a1, b1, c1, d1, X[12], 6, k0); + Subround(F, d1, a1, b1, c1, X[13], 7, k0); + Subround(F, c1, d1, a1, b1, X[14], 9, k0); + Subround(F, b1, c1, d1, a1, X[15], 8, k0); + + Subround(G, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, X[10], 11, k1); + Subround(G, d1, a1, b1, c1, X[ 6], 9, k1); + Subround(G, c1, d1, a1, b1, X[15], 7, k1); + Subround(G, b1, c1, d1, a1, X[ 3], 15, k1); + Subround(G, a1, b1, c1, d1, X[12], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 0], 12, k1); + Subround(G, c1, d1, a1, b1, X[ 9], 15, k1); + Subround(G, b1, c1, d1, a1, X[ 5], 9, k1); + Subround(G, a1, b1, c1, d1, X[ 2], 11, k1); + Subround(G, d1, a1, b1, c1, X[14], 7, k1); + Subround(G, c1, d1, a1, b1, X[11], 13, k1); + Subround(G, b1, c1, d1, a1, X[ 8], 12, k1); + + Subround(H, a1, b1, c1, d1, X[ 3], 11, k2); + Subround(H, d1, a1, b1, c1, X[10], 13, k2); + Subround(H, c1, d1, a1, b1, X[14], 6, k2); + Subround(H, b1, c1, d1, a1, X[ 4], 7, k2); + Subround(H, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, X[ 2], 14, k2); + Subround(H, d1, a1, b1, c1, X[ 7], 8, k2); + Subround(H, c1, d1, a1, b1, X[ 0], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 6], 6, k2); + Subround(H, a1, b1, c1, d1, X[13], 5, k2); + Subround(H, d1, a1, b1, c1, X[11], 12, k2); + Subround(H, c1, d1, a1, b1, X[ 5], 7, k2); + Subround(H, b1, c1, d1, a1, X[12], 5, k2); + + Subround(I, a1, b1, c1, d1, X[ 1], 11, k3); + Subround(I, d1, a1, b1, c1, X[ 9], 12, k3); + Subround(I, c1, d1, a1, b1, X[11], 14, k3); + Subround(I, b1, c1, d1, a1, X[10], 15, k3); + Subround(I, a1, b1, c1, d1, X[ 0], 14, k3); + Subround(I, d1, a1, b1, c1, X[ 8], 15, k3); + Subround(I, c1, d1, a1, b1, X[12], 9, k3); + Subround(I, b1, c1, d1, a1, X[ 4], 8, k3); + Subround(I, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, X[14], 8, k3); + Subround(I, d1, a1, b1, c1, X[ 5], 6, k3); + Subround(I, c1, d1, a1, b1, X[ 6], 5, k3); + Subround(I, b1, c1, d1, a1, X[ 2], 12, k3); + + Subround(I, a2, b2, c2, d2, X[ 5], 8, k5); + Subround(I, d2, a2, b2, c2, X[14], 9, k5); + Subround(I, c2, d2, a2, b2, X[ 7], 9, k5); + Subround(I, b2, c2, d2, a2, X[ 0], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 9], 13, k5); + Subround(I, d2, a2, b2, c2, X[ 2], 15, k5); + Subround(I, c2, d2, a2, b2, X[11], 15, k5); + Subround(I, b2, c2, d2, a2, X[ 4], 5, k5); + Subround(I, a2, b2, c2, d2, X[13], 7, k5); + Subround(I, d2, a2, b2, c2, X[ 6], 7, k5); + Subround(I, c2, d2, a2, b2, X[15], 8, k5); + Subround(I, b2, c2, d2, a2, X[ 8], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 1], 14, k5); + Subround(I, d2, a2, b2, c2, X[10], 14, k5); + Subround(I, c2, d2, a2, b2, X[ 3], 12, k5); + Subround(I, b2, c2, d2, a2, X[12], 6, k5); + + Subround(H, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(H, d2, a2, b2, c2, X[11], 13, k6); + Subround(H, c2, d2, a2, b2, X[ 3], 15, k6); + Subround(H, b2, c2, d2, a2, X[ 7], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 0], 12, k6); + Subround(H, d2, a2, b2, c2, X[13], 8, k6); + Subround(H, c2, d2, a2, b2, X[ 5], 9, k6); + Subround(H, b2, c2, d2, a2, X[10], 11, k6); + Subround(H, a2, b2, c2, d2, X[14], 7, k6); + Subround(H, d2, a2, b2, c2, X[15], 7, k6); + Subround(H, c2, d2, a2, b2, X[ 8], 12, k6); + Subround(H, b2, c2, d2, a2, X[12], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 4], 6, k6); + Subround(H, d2, a2, b2, c2, X[ 9], 15, k6); + Subround(H, c2, d2, a2, b2, X[ 1], 13, k6); + Subround(H, b2, c2, d2, a2, X[ 2], 11, k6); + + Subround(G, a2, b2, c2, d2, X[15], 9, k7); + Subround(G, d2, a2, b2, c2, X[ 5], 7, k7); + Subround(G, c2, d2, a2, b2, X[ 1], 15, k7); + Subround(G, b2, c2, d2, a2, X[ 3], 11, k7); + Subround(G, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(G, d2, a2, b2, c2, X[14], 6, k7); + Subround(G, c2, d2, a2, b2, X[ 6], 6, k7); + Subround(G, b2, c2, d2, a2, X[ 9], 14, k7); + Subround(G, a2, b2, c2, d2, X[11], 12, k7); + Subround(G, d2, a2, b2, c2, X[ 8], 13, k7); + Subround(G, c2, d2, a2, b2, X[12], 5, k7); + Subround(G, b2, c2, d2, a2, X[ 2], 14, k7); + Subround(G, a2, b2, c2, d2, X[10], 13, k7); + Subround(G, d2, a2, b2, c2, X[ 0], 13, k7); + Subround(G, c2, d2, a2, b2, X[ 4], 7, k7); + Subround(G, b2, c2, d2, a2, X[13], 5, k7); + + Subround(F, a2, b2, c2, d2, X[ 8], 15, k9); + Subround(F, d2, a2, b2, c2, X[ 6], 5, k9); + Subround(F, c2, d2, a2, b2, X[ 4], 8, k9); + Subround(F, b2, c2, d2, a2, X[ 1], 11, k9); + Subround(F, a2, b2, c2, d2, X[ 3], 14, k9); + Subround(F, d2, a2, b2, c2, X[11], 14, k9); + Subround(F, c2, d2, a2, b2, X[15], 6, k9); + Subround(F, b2, c2, d2, a2, X[ 0], 14, k9); + Subround(F, a2, b2, c2, d2, X[ 5], 6, k9); + Subround(F, d2, a2, b2, c2, X[12], 9, k9); + Subround(F, c2, d2, a2, b2, X[ 2], 12, k9); + Subround(F, b2, c2, d2, a2, X[13], 9, k9); + Subround(F, a2, b2, c2, d2, X[ 9], 12, k9); + Subround(F, d2, a2, b2, c2, X[ 7], 5, k9); + Subround(F, c2, d2, a2, b2, X[10], 15, k9); + Subround(F, b2, c2, d2, a2, X[14], 8, k9); + + c1 = digest[1] + c1 + d2; + digest[1] = digest[2] + d1 + a2; + digest[2] = digest[3] + a1 + b2; + digest[3] = digest[0] + b1 + c2; + digest[0] = c1; +} + +// ************************************************************* + +void RIPEMD256::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + state[4] = 0x76543210L; + state[5] = 0xfedcba98L; + state[6] = 0x89abcdefL; + state[7] = 0x01234567L; +} + +void RIPEMD256::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, a2, b2, c2, d2, t; + a1 = digest[0]; + b1 = digest[1]; + c1 = digest[2]; + d1 = digest[3]; + a2 = digest[4]; + b2 = digest[5]; + c2 = digest[6]; + d2 = digest[7]; + + Subround(F, a1, b1, c1, d1, X[ 0], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 1], 14, k0); + Subround(F, c1, d1, a1, b1, X[ 2], 15, k0); + Subround(F, b1, c1, d1, a1, X[ 3], 12, k0); + Subround(F, a1, b1, c1, d1, X[ 4], 5, k0); + Subround(F, d1, a1, b1, c1, X[ 5], 8, k0); + Subround(F, c1, d1, a1, b1, X[ 6], 7, k0); + Subround(F, b1, c1, d1, a1, X[ 7], 9, k0); + Subround(F, a1, b1, c1, d1, X[ 8], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 9], 13, k0); + Subround(F, c1, d1, a1, b1, X[10], 14, k0); + Subround(F, b1, c1, d1, a1, X[11], 15, k0); + Subround(F, a1, b1, c1, d1, X[12], 6, k0); + Subround(F, d1, a1, b1, c1, X[13], 7, k0); + Subround(F, c1, d1, a1, b1, X[14], 9, k0); + Subround(F, b1, c1, d1, a1, X[15], 8, k0); + + Subround(I, a2, b2, c2, d2, X[ 5], 8, k5); + Subround(I, d2, a2, b2, c2, X[14], 9, k5); + Subround(I, c2, d2, a2, b2, X[ 7], 9, k5); + Subround(I, b2, c2, d2, a2, X[ 0], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 9], 13, k5); + Subround(I, d2, a2, b2, c2, X[ 2], 15, k5); + Subround(I, c2, d2, a2, b2, X[11], 15, k5); + Subround(I, b2, c2, d2, a2, X[ 4], 5, k5); + Subround(I, a2, b2, c2, d2, X[13], 7, k5); + Subround(I, d2, a2, b2, c2, X[ 6], 7, k5); + Subround(I, c2, d2, a2, b2, X[15], 8, k5); + Subround(I, b2, c2, d2, a2, X[ 8], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 1], 14, k5); + Subround(I, d2, a2, b2, c2, X[10], 14, k5); + Subround(I, c2, d2, a2, b2, X[ 3], 12, k5); + Subround(I, b2, c2, d2, a2, X[12], 6, k5); + + t = a1; a1 = a2; a2 = t; + + Subround(G, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, X[10], 11, k1); + Subround(G, d1, a1, b1, c1, X[ 6], 9, k1); + Subround(G, c1, d1, a1, b1, X[15], 7, k1); + Subround(G, b1, c1, d1, a1, X[ 3], 15, k1); + Subround(G, a1, b1, c1, d1, X[12], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 0], 12, k1); + Subround(G, c1, d1, a1, b1, X[ 9], 15, k1); + Subround(G, b1, c1, d1, a1, X[ 5], 9, k1); + Subround(G, a1, b1, c1, d1, X[ 2], 11, k1); + Subround(G, d1, a1, b1, c1, X[14], 7, k1); + Subround(G, c1, d1, a1, b1, X[11], 13, k1); + Subround(G, b1, c1, d1, a1, X[ 8], 12, k1); + + Subround(H, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(H, d2, a2, b2, c2, X[11], 13, k6); + Subround(H, c2, d2, a2, b2, X[ 3], 15, k6); + Subround(H, b2, c2, d2, a2, X[ 7], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 0], 12, k6); + Subround(H, d2, a2, b2, c2, X[13], 8, k6); + Subround(H, c2, d2, a2, b2, X[ 5], 9, k6); + Subround(H, b2, c2, d2, a2, X[10], 11, k6); + Subround(H, a2, b2, c2, d2, X[14], 7, k6); + Subround(H, d2, a2, b2, c2, X[15], 7, k6); + Subround(H, c2, d2, a2, b2, X[ 8], 12, k6); + Subround(H, b2, c2, d2, a2, X[12], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 4], 6, k6); + Subround(H, d2, a2, b2, c2, X[ 9], 15, k6); + Subround(H, c2, d2, a2, b2, X[ 1], 13, k6); + Subround(H, b2, c2, d2, a2, X[ 2], 11, k6); + + t = b1; b1 = b2; b2 = t; + + Subround(H, a1, b1, c1, d1, X[ 3], 11, k2); + Subround(H, d1, a1, b1, c1, X[10], 13, k2); + Subround(H, c1, d1, a1, b1, X[14], 6, k2); + Subround(H, b1, c1, d1, a1, X[ 4], 7, k2); + Subround(H, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, X[ 2], 14, k2); + Subround(H, d1, a1, b1, c1, X[ 7], 8, k2); + Subround(H, c1, d1, a1, b1, X[ 0], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 6], 6, k2); + Subround(H, a1, b1, c1, d1, X[13], 5, k2); + Subround(H, d1, a1, b1, c1, X[11], 12, k2); + Subround(H, c1, d1, a1, b1, X[ 5], 7, k2); + Subround(H, b1, c1, d1, a1, X[12], 5, k2); + + Subround(G, a2, b2, c2, d2, X[15], 9, k7); + Subround(G, d2, a2, b2, c2, X[ 5], 7, k7); + Subround(G, c2, d2, a2, b2, X[ 1], 15, k7); + Subround(G, b2, c2, d2, a2, X[ 3], 11, k7); + Subround(G, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(G, d2, a2, b2, c2, X[14], 6, k7); + Subround(G, c2, d2, a2, b2, X[ 6], 6, k7); + Subround(G, b2, c2, d2, a2, X[ 9], 14, k7); + Subround(G, a2, b2, c2, d2, X[11], 12, k7); + Subround(G, d2, a2, b2, c2, X[ 8], 13, k7); + Subround(G, c2, d2, a2, b2, X[12], 5, k7); + Subround(G, b2, c2, d2, a2, X[ 2], 14, k7); + Subround(G, a2, b2, c2, d2, X[10], 13, k7); + Subround(G, d2, a2, b2, c2, X[ 0], 13, k7); + Subround(G, c2, d2, a2, b2, X[ 4], 7, k7); + Subround(G, b2, c2, d2, a2, X[13], 5, k7); + + t = c1; c1 = c2; c2 = t; + + Subround(I, a1, b1, c1, d1, X[ 1], 11, k3); + Subround(I, d1, a1, b1, c1, X[ 9], 12, k3); + Subround(I, c1, d1, a1, b1, X[11], 14, k3); + Subround(I, b1, c1, d1, a1, X[10], 15, k3); + Subround(I, a1, b1, c1, d1, X[ 0], 14, k3); + Subround(I, d1, a1, b1, c1, X[ 8], 15, k3); + Subround(I, c1, d1, a1, b1, X[12], 9, k3); + Subround(I, b1, c1, d1, a1, X[ 4], 8, k3); + Subround(I, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, X[14], 8, k3); + Subround(I, d1, a1, b1, c1, X[ 5], 6, k3); + Subround(I, c1, d1, a1, b1, X[ 6], 5, k3); + Subround(I, b1, c1, d1, a1, X[ 2], 12, k3); + + Subround(F, a2, b2, c2, d2, X[ 8], 15, k9); + Subround(F, d2, a2, b2, c2, X[ 6], 5, k9); + Subround(F, c2, d2, a2, b2, X[ 4], 8, k9); + Subround(F, b2, c2, d2, a2, X[ 1], 11, k9); + Subround(F, a2, b2, c2, d2, X[ 3], 14, k9); + Subround(F, d2, a2, b2, c2, X[11], 14, k9); + Subround(F, c2, d2, a2, b2, X[15], 6, k9); + Subround(F, b2, c2, d2, a2, X[ 0], 14, k9); + Subround(F, a2, b2, c2, d2, X[ 5], 6, k9); + Subround(F, d2, a2, b2, c2, X[12], 9, k9); + Subround(F, c2, d2, a2, b2, X[ 2], 12, k9); + Subround(F, b2, c2, d2, a2, X[13], 9, k9); + Subround(F, a2, b2, c2, d2, X[ 9], 12, k9); + Subround(F, d2, a2, b2, c2, X[ 7], 5, k9); + Subround(F, c2, d2, a2, b2, X[10], 15, k9); + Subround(F, b2, c2, d2, a2, X[14], 8, k9); + + t = d1; d1 = d2; d2 = t; + + digest[0] += a1; + digest[1] += b1; + digest[2] += c1; + digest[3] += d1; + digest[4] += a2; + digest[5] += b2; + digest[6] += c2; + digest[7] += d2; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ripemd.h b/external/ours/library/crypto/src/shared/original/ripemd.h new file mode 100755 index 000000000..b5fbb4ae8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ripemd.h @@ -0,0 +1,65 @@ +// ripemd.h - originally written and placed in the public domain by Wei Dai + +/// \file +/// \brief Classes for RIPEMD message digest + +#ifndef CRYPTOPP_RIPEMD_H +#define CRYPTOPP_RIPEMD_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief RIPEMD-160 message digest +/// \details Digest size is 160-bits. +/// \sa RIPEMD-160 +/// \since Crypto++ 2.1 +class RIPEMD160 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RIPEMD-160";} +}; + +/// \brief RIPEMD-320 message digest +/// \details Digest size is 320-bits. +/// \sa RIPEMD-320 +/// \since Crypto++ 2.1 +class RIPEMD320 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RIPEMD-320";} +}; + +/// \brief RIPEMD-128 message digest +/// \details Digest size is 128-bits. +/// \warning RIPEMD-128 is considered insecure, and should not be used unless you absolutely need it for compatibility. +/// \sa RIPEMD-128 +/// \since Crypto++ 2.1 +class RIPEMD128 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RIPEMD-128";} +}; + +/// \brief RIPEMD-256 message digest +/// \details Digest size is 256-bits. +/// \warning RIPEMD-256 is considered insecure, and should not be used unless you absolutely need it for compatibility. +/// \sa RIPEMD-256 +/// \since Crypto++ 2.1 +class RIPEMD256 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RIPEMD-256";} +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rng.cpp b/external/ours/library/crypto/src/shared/original/rng.cpp new file mode 100755 index 000000000..1bb525e90 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rng.cpp @@ -0,0 +1,166 @@ +// rng.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "rng.h" +#include "fips140.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +// linear congruential generator +// originally by William S. England + +// do not use for cryptographic purposes + +/* +** Original_numbers are the original published m and q in the +** ACM article above. John Burton has furnished numbers for +** a reportedly better generator. The new numbers are now +** used in this program by default. +*/ + +#ifndef LCRNG_ORIGINAL_NUMBERS +const word32 LC_RNG::m=2147483647L; +const word32 LC_RNG::q=44488L; + +const word16 LC_RNG::a=(unsigned int)48271L; +const word16 LC_RNG::r=3399; +#else +const word32 LC_RNG::m=2147483647L; +const word32 LC_RNG::q=127773L; + +const word16 LC_RNG::a=16807; +const word16 LC_RNG::r=2836; +#endif + +void LC_RNG::GenerateBlock(byte *output, size_t size) +{ + while (size--) + { + const word32 hi = seed/q; + const word32 lo = seed%q; + const sword64 test = a*lo - r*hi; + + if (test > 0) + seed = static_cast(test); + else + seed = static_cast(test + m); + + *output++ = byte((GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3))); + } +} + +// ******************************************************** + +#ifndef CRYPTOPP_IMPORTS + +X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector) + : m_cipher(c), + m_size(m_cipher->BlockSize()), + m_datetime(m_size), + m_randseed(seed, m_size), + m_lastBlock(m_size), + m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? m_size : 0) +{ + // Valgrind finding, http://github.com/weidai11/cryptopp/issues/105 + // Garbage in the tail creates a non-conforming X9.17 or X9.31 generator. + if (m_size > 8) + { + memset(m_datetime, 0x00, m_size); + memset(m_lastBlock, 0x00, m_size); + } + + if (!deterministicTimeVector) + { + time_t tstamp1 = ::time(NULLPTR); + xorbuf(m_datetime, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), m_size)); + m_cipher->ProcessBlock(m_datetime); + clock_t tstamp2 = clock(); + xorbuf(m_datetime, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), m_size)); + m_cipher->ProcessBlock(m_datetime); + } + + // for FIPS 140-2 + // GenerateBlock(m_lastBlock, m_size); + + // Make explicit call to avoid virtual-dispatch findings in ctor + ArraySink target(m_lastBlock, m_size); + X917RNG::GenerateIntoBufferedTransformation(target, DEFAULT_CHANNEL, m_size); +} + +void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) +{ + while (size > 0) + { + // calculate new enciphered timestamp + if (m_deterministicTimeVector.size()) + { + m_cipher->ProcessBlock(m_deterministicTimeVector, m_datetime); + IncrementCounterByOne(m_deterministicTimeVector, m_size); + } + else + { + clock_t c = clock(); + xorbuf(m_datetime, (byte *)&c, UnsignedMin(sizeof(c), m_size)); + time_t t = ::time(NULLPTR); + xorbuf(m_datetime+m_size-UnsignedMin(sizeof(t), m_size), (byte *)&t, UnsignedMin(sizeof(t), m_size)); + m_cipher->ProcessBlock(m_datetime); + } + + // combine enciphered timestamp with seed + xorbuf(m_randseed, m_datetime, m_size); + + // generate a new block of random bytes + m_cipher->ProcessBlock(m_randseed); + if (memcmp(m_lastBlock, m_randseed, m_size) == 0) + throw SelfTestFailure("X917RNG: Continuous random number generator test failed."); + + // output random bytes + size_t len = UnsignedMin(m_size, size); + target.ChannelPut(channel, m_randseed, len); + size -= len; + + // compute new seed vector + memcpy(m_lastBlock, m_randseed, m_size); + xorbuf(m_randseed, m_datetime, m_size); + m_cipher->ProcessBlock(m_randseed); + } +} + +#endif + +MaurerRandomnessTest::MaurerRandomnessTest() + : sum(0.0), n(0) +{ + for (unsigned i=0; i= Q) + sum += ::log(double(n - tab[inByte])); + tab[inByte] = n; + n++; + } + return 0; +} + +double MaurerRandomnessTest::GetTestValue() const +{ + if (BytesNeeded() > 0) + throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed"); + + double fTu = (sum/(n-Q))/::log(2.0); // this is the test value defined by Maurer + + double value = fTu * 0.1392; // arbitrarily normalize it to + return value > 1.0 ? 1.0 : value; // a number between 0 and 1 +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/rng.h b/external/ours/library/crypto/src/shared/original/rng.h new file mode 100755 index 000000000..7f982ab17 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rng.h @@ -0,0 +1,111 @@ +// rng.h - originally written and placed in the public domain by Wei Dai + +/// \file rng.h +/// \brief Miscellaneous classes for RNGs +/// \details This file contains miscellaneous classes for RNGs, including LC_RNG(), +/// X917RNG() and MaurerRandomnessTest() +/// \sa osrng.h, randpool.h + +#ifndef CRYPTOPP_RNG_H +#define CRYPTOPP_RNG_H + +#include "cryptlib.h" +#include "filters.h" +#include "smartptr.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Linear Congruential Generator (LCG) +/// \details Originally propsed by William S. England. +/// \warning LC_RNG is suitable for simulations, where uniformaly distrubuted numbers are +/// required quickly. It should not be used for cryptographic purposes. +class LC_RNG : public RandomNumberGenerator +{ +public: + /// \brief Construct a Linear Congruential Generator (LCG) + /// \param init_seed the initial value for the generator + LC_RNG(word32 init_seed) + : seed(init_seed) {} + + void GenerateBlock(byte *output, size_t size); + + word32 GetSeed() {return seed;} + +private: + word32 seed; + + static const word32 m; + static const word32 q; + static const word16 a; + static const word16 r; +}; + +/// \brief ANSI X9.17 RNG +/// \details X917RNG is from ANSI X9.17 Appendix C, and it uses a 64-bit block cipher, like TripleDES. +/// If you use a 128-bit block cipher, like AES, then you are effectively using an ANSI X9.31 generator. +/// \details You should reseed the generator after a fork() to avoid multiple generators +/// with the same internal state. +/// \sa AutoSeededX917RNG, DefaultAutoSeededRNG +class CRYPTOPP_DLL X917RNG : public RandomNumberGenerator, public NotCopyable +{ +public: + /// \brief Construct a X917RNG + /// \param cipher the block cipher to use for the generator + /// \param seed a byte buffer to use as a seed + /// \param deterministicTimeVector additional entropy + /// \details cipher will be deleted by the destructor. seed must be at least + /// BlockSize() in length. deterministicTimeVector = 0 means obtain time vector + /// from the system. + /// \details When constructing a X917RNG, the generator must be keyed or an access + /// violation will occur because the time vector is encrypted using the block cipher. + /// To key the generator during constructions, perform the following: + ///
+	///  SecByteBlock key(AES::DEFAULT_KEYLENGTH), seed(AES::BLOCKSIZE);
+	///  OS_GenerateRandomBlock(false, key, key.size());
+	///  OS_GenerateRandomBlock(false, seed, seed.size());
+	///  X917RNG prng(new AES::Encryption(key, AES::DEFAULT_KEYLENGTH), seed, NULLPTR);
+ /// \sa AutoSeededX917RNG + X917RNG(BlockTransformation *cipher, const byte *seed, const byte *deterministicTimeVector = NULLPTR); + + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); + +private: + member_ptr m_cipher; + const unsigned int m_size; // S, blocksize of cipher + SecByteBlock m_datetime; // DT, buffer for enciphered timestamp + SecByteBlock m_randseed, m_lastBlock, m_deterministicTimeVector; +}; + +/// \brief Maurer's Universal Statistical Test for Random Bit Generators +/// \details This class implements Maurer's Universal Statistical Test for +/// Random Bit Generators. It is intended for measuring the randomness of +/// *PHYSICAL* RNGs. +/// \details For more details see Maurer's paper in Journal of Cryptology, 1992. +class MaurerRandomnessTest : public Bufferless +{ +public: + /// \brief Construct a MaurerRandomnessTest + MaurerRandomnessTest(); + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + + /// \brief Provides the number of bytes of input is needed by the test + /// \return how many more bytes of input is needed by the test + // BytesNeeded() returns how many more bytes of input is needed by the test + // GetTestValue() should not be called before BytesNeeded()==0 + unsigned int BytesNeeded() const {return n >= (Q+K) ? 0 : Q+K-n;} + + // returns a number between 0.0 and 1.0, describing the quality of the + // random numbers entered + double GetTestValue() const; + +private: + enum {L=8, V=256, Q=2000, K=2000}; + double sum; + unsigned int n; + unsigned int tab[V]; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rsa.cpp b/external/ours/library/crypto/src/shared/original/rsa.cpp new file mode 100755 index 000000000..f3e668664 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rsa.cpp @@ -0,0 +1,330 @@ +// rsa.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rsa.h" +#include "asn.h" +#include "sha.h" +#include "oids.h" +#include "modarith.h" +#include "nbtheory.h" +#include "algparam.h" +#include "fips140.h" +#include "pkcspad.h" + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) && !defined(CRYPTOPP_IS_DLL) +#include "sha3.h" +#include "pssr.h" +NAMESPACE_BEGIN(CryptoPP) +void RSA_TestInstantiations() +{ + RSASS::Verifier x1(1, 1); + RSASS::Signer x2(NullRNG(), 1); + RSASS::Verifier x3(x2); + RSASS::Verifier x4(x2.GetKey()); + RSASS::Verifier x5(x3); +#ifndef __MWERKS__ + RSASS::Signer x6 = x2; + x3 = x2; + x6 = x2; +#endif + RSAES::Encryptor x7(x2); +#ifndef __GNUC__ + RSAES::Encryptor x8(x3); +#endif + RSAES >::Encryptor x9(x2); + x4 = x2.GetKey(); + + RSASS::Verifier x10(1, 1); + RSASS::Signer x11(NullRNG(), 1); + RSASS::Verifier x12(x11); + RSASS::Verifier x13(x11.GetKey()); +} +NAMESPACE_END +#endif + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +OID RSAFunction::GetAlgorithmID() const +{ + return ASN1::rsaEncryption(); +} + +void RSAFunction::BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_e.BERDecode(seq); + seq.MessageEnd(); +} + +void RSAFunction::DEREncodePublicKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_e.DEREncode(seq); + seq.MessageEnd(); +} + +Integer RSAFunction::ApplyFunction(const Integer &x) const +{ + DoQuickSanityCheck(); + return a_exp_b_mod_c(x, m_e, m_n); +} + +bool RSAFunction::Validate(RandomNumberGenerator& rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(level); + + bool pass = true; + pass = pass && m_n > Integer::One() && m_n.IsOdd(); + CRYPTOPP_ASSERT(pass); + pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n; + CRYPTOPP_ASSERT(pass); + return pass; +} + +bool RSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) + ; +} + +void RSAFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) + ; +} + +// ***************************************************************************** + +class RSAPrimeSelector : public PrimeSelector +{ +public: + RSAPrimeSelector(const Integer &e) : m_e(e) {} + bool IsAcceptable(const Integer &candidate) const {return RelativelyPrime(m_e, candidate-Integer::One());} + Integer m_e; +}; + +void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize); + + CRYPTOPP_ASSERT(modulusSize >= 16); + if (modulusSize < 16) + throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small"); + + m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17)); + + CRYPTOPP_ASSERT(m_e >= 3); CRYPTOPP_ASSERT(!m_e.IsEven()); + if (m_e < 3 || m_e.IsEven()) + throw InvalidArgument("InvertibleRSAFunction: invalid public exponent"); + + RSAPrimeSelector selector(m_e); + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + (Name::PointerToPrimeSelector(), selector.GetSelectorPointer()); + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + + m_d = m_e.InverseMod(LCM(m_p-1, m_q-1)); + CRYPTOPP_ASSERT(m_d.IsPositive()); + + m_dp = m_d % (m_p-1); + m_dq = m_d % (m_q-1); + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); + + if (FIPS_140_2_ComplianceEnabled()) + { + RSASS::Signer signer(*this); + RSASS::Verifier verifier(signer); + SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); + + RSAES >::Decryptor decryptor(*this); + RSAES >::Encryptor encryptor(decryptor); + EncryptionPairwiseConsistencyTest_FIPS_140_Only(encryptor, decryptor); + } +} + +void InvertibleRSAFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e) +{ + GenerateRandom(rng, MakeParameters(Name::ModulusSize(), (int)keybits)(Name::PublicExponent(), e+e.IsEven())); +} + +void InvertibleRSAFunction::Initialize(const Integer &n, const Integer &e, const Integer &d) +{ + if (n.IsEven() || e.IsEven() | d.IsEven()) + throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key"); + + m_n = n; + m_e = e; + m_d = d; + + Integer r = --(d*e); + unsigned int s = 0; + while (r.IsEven()) + { + r >>= 1; + s++; + } + + ModularArithmetic modn(n); + for (Integer i = 2; ; ++i) + { + Integer a = modn.Exponentiate(i, r); + if (a == 1) + continue; + Integer b; + unsigned int j = 0; + while (a != n-1) + { + b = modn.Square(a); + if (b == 1) + { + m_p = GCD(a-1, n); + m_q = n/m_p; + m_dp = m_d % (m_p-1); + m_dq = m_d % (m_q-1); + m_u = m_q.InverseMod(m_p); + return; + } + if (++j == s) + throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key"); + a = b; + } + } +} + +void InvertibleRSAFunction::BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) +{ + BERSequenceDecoder privateKey(bt); + word32 version; + BERDecodeUnsigned(privateKey, version, INTEGER, 0, 0); // check version + m_n.BERDecode(privateKey); + m_e.BERDecode(privateKey); + m_d.BERDecode(privateKey); + m_p.BERDecode(privateKey); + m_q.BERDecode(privateKey); + m_dp.BERDecode(privateKey); + m_dq.BERDecode(privateKey); + m_u.BERDecode(privateKey); + privateKey.MessageEnd(); +} + +void InvertibleRSAFunction::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + DEREncodeUnsigned(privateKey, 0); // version + m_n.DEREncode(privateKey); + m_e.DEREncode(privateKey); + m_d.DEREncode(privateKey); + m_p.DEREncode(privateKey); + m_q.DEREncode(privateKey); + m_dp.DEREncode(privateKey); + m_dq.DEREncode(privateKey); + m_u.DEREncode(privateKey); + privateKey.MessageEnd(); +} + +Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + DoQuickSanityCheck(); + ModularArithmetic modn(m_n); + Integer r, rInv; + do { // do this in a loop for people using small numbers for testing + r.Randomize(rng, Integer::One(), m_n - Integer::One()); + rInv = modn.MultiplicativeInverse(r); + } while (rInv.IsZero()); + Integer re = modn.Exponentiate(r, m_e); + re = modn.Multiply(re, x); // blind + // here we follow the notation of PKCS #1 and let u=q inverse mod p + // but in ModRoot, u=p inverse mod q, so we reverse the order of p and q + Integer y = ModularRoot(re, m_dq, m_dp, m_q, m_p, m_u); + y = modn.Multiply(y, rInv); // unblind + if (modn.Exponentiate(y, m_e) != x) // check + throw Exception(Exception::OTHER_ERROR, "InvertibleRSAFunction: computational error during private key operation"); + return y; +} + +bool InvertibleRSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = RSAFunction::Validate(rng, level); + CRYPTOPP_ASSERT(pass); + pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_d > Integer::One() && m_d.IsOdd() && m_d < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_dp > Integer::One() && m_dp.IsOdd() && m_dp < m_p; + CRYPTOPP_ASSERT(pass); + pass = pass && m_dq > Integer::One() && m_dq.IsOdd() && m_dq < m_q; + CRYPTOPP_ASSERT(pass); + pass = pass && m_u.IsPositive() && m_u < m_p; + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_e*m_d % LCM(m_p-1, m_q-1) == 1; + CRYPTOPP_ASSERT(pass); + pass = pass && m_dp == m_d%(m_p-1) && m_dq == m_d%(m_q-1); + CRYPTOPP_ASSERT(pass); + pass = pass && m_u * m_q % m_p == 1; + CRYPTOPP_ASSERT(pass); + } + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool InvertibleRSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent) + CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime1PrivateExponent) + CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime2PrivateExponent) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleRSAFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent) + CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime1PrivateExponent) + CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime2PrivateExponent) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +// ***************************************************************************** + +Integer RSAFunction_ISO::ApplyFunction(const Integer &x) const +{ + Integer t = RSAFunction::ApplyFunction(x); + return t % 16 == 12 ? t : m_n - t; +} + +Integer InvertibleRSAFunction_ISO::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + Integer t = InvertibleRSAFunction::CalculateInverse(rng, x); + return STDMIN(t, m_n-t); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rsa.h b/external/ours/library/crypto/src/shared/original/rsa.h new file mode 100755 index 000000000..62c1111ea --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rsa.h @@ -0,0 +1,263 @@ +// rsa.h - originally written and placed in the public domain by Wei Dai + +/// \file rsa.h +/// \brief Classes for the RSA cryptosystem +/// \details This file contains classes that implement the RSA +/// ciphers and signature schemes as defined in PKCS #1 v2.0. + +#ifndef CRYPTOPP_RSA_H +#define CRYPTOPP_RSA_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "integer.h" +#include "pkcspad.h" +#include "oaep.h" +#include "emsa2.h" +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief RSA trapdoor function using the public key +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL RSAFunction : public TrapdoorFunction, public X509PublicKey +{ + typedef RSAFunction ThisClass; + +public: + /// \brief Initialize a RSA public key + /// \param n the modulus + /// \param e the public exponent + void Initialize(const Integer &n, const Integer &e) + {m_n = n; m_e = e;} + + // X509PublicKey + OID GetAlgorithmID() const; + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // TrapdoorFunction + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return m_n;} + + // non-derived + const Integer & GetModulus() const {return m_n;} + const Integer & GetPublicExponent() const {return m_e;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetPublicExponent(const Integer &e) {m_e = e;} + +protected: + Integer m_n, m_e; +}; + +/// \brief RSA trapdoor function using the private key +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey +{ + typedef InvertibleRSAFunction ThisClass; + +public: + /// \brief Create a RSA private key + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulus, in bits + /// \param e the desired public exponent + /// \details Initialize() creates a new keypair using a public exponent of 17. + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &e = 17); + + /// \brief Initialize a RSA private key + /// \param n modulus + /// \param e public exponent + /// \param d private exponent + /// \param p first prime factor + /// \param q second prime factor + /// \param dp d mod p + /// \param dq d mod q + /// \param u q-1 mod p + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const Integer &n, const Integer &e, const Integer &d, const Integer &p, const Integer &q, const Integer &dp, const Integer &dq, const Integer &u) + {m_n = n; m_e = e; m_d = d; m_p = p; m_q = q; m_dp = dp; m_dq = dq; m_u = u;} + + /// \brief Initialize a RSA private key + /// \param n modulus + /// \param e public exponent + /// \param d private exponent + /// \details This Initialize() function overload initializes a private key from existing parameters. + /// Initialize() will factor n using d and populate {p,q,dp,dq,u}. + void Initialize(const Integer &n, const Integer &e, const Integer &d); + + // PKCS8PrivateKey + void BERDecode(BufferedTransformation &bt) + {PKCS8PrivateKey::BERDecode(bt);} + void DEREncode(BufferedTransformation &bt) const + {PKCS8PrivateKey::DEREncode(bt);} + void Load(BufferedTransformation &bt) + {PKCS8PrivateKey::BERDecode(bt);} + void Save(BufferedTransformation &bt) const + {PKCS8PrivateKey::DEREncode(bt);} + OID GetAlgorithmID() const {return RSAFunction::GetAlgorithmID();} + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; + + // TrapdoorFunctionInverse + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + // GeneratableCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + // parameters: (ModulusSize, PublicExponent (default 17)) + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // non-derived interface + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetPrivateExponent() const {return m_d;} + const Integer& GetModPrime1PrivateExponent() const {return m_dp;} + const Integer& GetModPrime2PrivateExponent() const {return m_dq;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetPrivateExponent(const Integer &d) {m_d = d;} + void SetModPrime1PrivateExponent(const Integer &dp) {m_dp = dp;} + void SetModPrime2PrivateExponent(const Integer &dq) {m_dq = dq;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_d, m_p, m_q, m_dp, m_dq, m_u; +}; + +/// \brief RSA trapdoor function using the public key +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL RSAFunction_ISO : public RSAFunction +{ +public: + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} +}; + +/// \brief RSA trapdoor function using the private key +/// \since Crypto++ 1.0 +class CRYPTOPP_DLL InvertibleRSAFunction_ISO : public InvertibleRSAFunction +{ +public: + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} +}; + +/// \brief RSA algorithm +/// \since Crypto++ 1.0 +struct CRYPTOPP_DLL RSA +{ + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "RSA";} + typedef RSAFunction PublicKey; + typedef InvertibleRSAFunction PrivateKey; +}; + +/// \brief RSA encryption algorithm +/// \tparam STANDARD signature standard +/// \sa RSA cryptosystem +/// \since Crypto++ 1.0 +template +struct RSAES : public TF_ES +{ +}; + +/// \brief RSA signature algorithm +/// \tparam STANDARD signature standard +/// \tparam H hash transformation +/// \details See documentation of PKCS1v15 for a list of hash functions that can be used with it. +/// \sa RSA signature scheme with appendix +/// \since Crypto++ 1.0 +template +struct RSASS : public TF_SS +{ +}; + +/// \brief RSA algorithm +/// \since Crypto++ 1.0 +struct CRYPTOPP_DLL RSA_ISO +{ + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "RSA-ISO";} + typedef RSAFunction_ISO PublicKey; + typedef InvertibleRSAFunction_ISO PrivateKey; +}; + +/// \brief RSA signature algorithm +/// \tparam H hash transformation +/// \since Crypto++ 1.0 +template +struct RSASS_ISO : public TF_SS +{ +}; + +/// \brief \ref RSAES "RSAES::Decryptor" typedef +/// \details RSA encryption scheme defined in PKCS #1 v2.0 +DOCUMENTED_TYPEDEF(RSAES::Decryptor, RSAES_PKCS1v15_Decryptor); +/// \brief \ref RSAES "RSAES::Encryptor" typedef +/// \details RSA encryption scheme defined in PKCS #1 v2.0 +DOCUMENTED_TYPEDEF(RSAES::Encryptor, RSAES_PKCS1v15_Encryptor); + +/// \brief \ref RSAES "RSAES>::Decryptor" typedef +/// \details RSA encryption scheme defined in PKCS #1 v2.0 +DOCUMENTED_TYPEDEF(RSAES >::Decryptor, RSAES_OAEP_SHA_Decryptor); +/// \brief \ref RSAES "RSAES>::Encryptor" typedef +/// \details RSA encryption scheme defined in PKCS #1 v2.0 +DOCUMENTED_TYPEDEF(RSAES >::Encryptor, RSAES_OAEP_SHA_Encryptor); + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING +/// \brief \ref RSASS "RSASS::Signer" typedef +/// \details RSA signature schemes defined in PKCS #1 v2.0 +/// \since Crypto++ 1.0 +class RSASSA_PKCS1v15_SHA_Signer : public RSASS::Signer {}; +/// \brief \ref RSASS "RSASS::Verifier" typedef +/// \details RSA signature schemes defined in PKCS #1 v2.0 +/// \since Crypto++ 1.0 +class RSASSA_PKCS1v15_SHA_Verifier : public RSASS::Verifier {}; + +namespace Weak { + +/// \brief \ref RSASS "RSASS::Signer" typedef +/// \details RSA signature schemes defined in PKCS #1 v2.0 +/// \since Crypto++ 1.0 +class RSASSA_PKCS1v15_MD2_Signer : public RSASS::Signer {}; +/// \brief \ref RSASS "RSASS::Verifier" typedef +/// \details RSA signature schemes defined in PKCS #1 v2.0 +/// \since Crypto++ 1.0 +class RSASSA_PKCS1v15_MD2_Verifier : public RSASS::Verifier {}; + +/// \brief \ref RSASS "RSASS::Signer" typedef +/// \details RSA signature schemes defined in PKCS #1 v2.0 +/// \since Crypto++ 1.0 +class RSASSA_PKCS1v15_MD5_Signer : public RSASS::Signer {}; +/// \brief \ref RSASS "RSASS::Verifier" typedef +/// \details RSA signature schemes defined in PKCS #1 v2.0 +/// \since Crypto++ 1.0 +class RSASSA_PKCS1v15_MD5_Verifier : public RSASS::Verifier {}; +} + +#else +typedef RSASS::Signer RSASSA_PKCS1v15_SHA_Signer; +typedef RSASS::Verifier RSASSA_PKCS1v15_SHA_Verifier; + +namespace Weak { + typedef RSASS::Signer RSASSA_PKCS1v15_MD2_Signer; + typedef RSASS::Verifier RSASSA_PKCS1v15_MD2_Verifier; + typedef RSASS::Signer RSASSA_PKCS1v15_MD5_Signer; + typedef RSASS::Verifier RSASSA_PKCS1v15_MD5_Verifier; +} +#endif // CRYPTOPP_DOXYGEN_PROCESSING + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rw.cpp b/external/ours/library/crypto/src/shared/original/rw.cpp new file mode 100755 index 000000000..ab79358cb --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rw.cpp @@ -0,0 +1,314 @@ +// rw.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "rw.h" +#include "asn.h" +#include "integer.h" +#include "nbtheory.h" +#include "modarith.h" +#include "asn.h" + +#ifndef CRYPTOPP_IMPORTS + +#if defined(_OPENMP) +# define CRYPTOPP_RW_USE_OMP 1 +#else +# define CRYPTOPP_RW_USE_OMP 0 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +void RWFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + seq.MessageEnd(); +} + +void RWFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + seq.MessageEnd(); +} + +Integer RWFunction::ApplyFunction(const Integer &in) const +{ + DoQuickSanityCheck(); + + Integer out = in.Squared()%m_n; + const word r = 12; + // this code was written to handle both r = 6 and r = 12, + // but now only r = 12 is used in P1363 + const word r2 = r/2; + const word r3a = (16 + 5 - r) % 16; // n%16 could be 5 or 13 + const word r3b = (16 + 13 - r) % 16; + const word r4 = (8 + 5 - r/2) % 8; // n%8 == 5 + switch (out % 16) + { + case r: + break; + case r2: + case r2+8: + out <<= 1; + break; + case r3a: + case r3b: + out.Negate(); + out += m_n; + break; + case r4: + case r4+8: + out.Negate(); + out += m_n; + out <<= 1; + break; + default: + out = Integer::Zero(); + } + return out; +} + +bool RWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(level); + bool pass = true; + pass = pass && m_n > Integer::One() && m_n%8 == 5; + CRYPTOPP_ASSERT(pass); + return pass; +} + +bool RWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + ; +} + +void RWFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + ; +} + +// ***************************************************************************** +// private key operations: + +// generate a random private key +void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleRWFunction: specified modulus length is too small"); + + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize); + m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 3)("Mod", 8))); + m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 7)("Mod", 8))); + + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); + + Precompute(); +} + +void InvertibleRWFunction::Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u) +{ + m_n = n; m_p = p; m_q = q; m_u = u; + + Precompute(); +} + +void InvertibleRWFunction::PrecomputeTweakedRoots() const +{ + ModularArithmetic modp(m_p), modq(m_q); + + // GCC warning bug, https://stackoverflow.com/q/12842306/608639 +#ifdef _OPENMP + #pragma omp parallel sections if(CRYPTOPP_RW_USE_OMP) + { + #pragma omp section + m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8); + #pragma omp section + m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8); + #pragma omp section + m_pre_q_p = modp.Exponentiate(m_q, m_p - 2); + } +#else + m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8); + m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8); + m_pre_q_p = modp.Exponentiate(m_q, m_p - 2); +#endif + + m_precompute = true; +} + +void InvertibleRWFunction::LoadPrecomputation(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_pre_2_9p.BERDecode(seq); + m_pre_2_3q.BERDecode(seq); + m_pre_q_p.BERDecode(seq); + seq.MessageEnd(); + + m_precompute = true; +} + +void InvertibleRWFunction::SavePrecomputation(BufferedTransformation &bt) const +{ + if(!m_precompute) + Precompute(); + + DERSequenceEncoder seq(bt); + m_pre_2_9p.DEREncode(seq); + m_pre_2_3q.DEREncode(seq); + m_pre_q_p.DEREncode(seq); + seq.MessageEnd(); +} + +void InvertibleRWFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_u.BERDecode(seq); + seq.MessageEnd(); + + m_precompute = false; +} + +void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_u.DEREncode(seq); + seq.MessageEnd(); +} + +// DJB's "RSA signatures and Rabin-Williams signatures..." (http://cr.yp.to/sigs/rwsota-20080131.pdf). +Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + DoQuickSanityCheck(); + + if(!m_precompute) + Precompute(); + + ModularArithmetic modn(m_n), modp(m_p), modq(m_q); + Integer r, rInv; + + do + { + // Do this in a loop for people using small numbers for testing + r.Randomize(rng, Integer::One(), m_n - Integer::One()); + // Fix for CVE-2015-2141. Thanks to Evgeny Sidorov for reporting. + // Squaring to satisfy Jacobi requirements suggested by Jean-Pierre Munch. + r = modn.Square(r); + rInv = modn.MultiplicativeInverse(r); + } while (rInv.IsZero()); + + Integer re = modn.Square(r); + re = modn.Multiply(re, x); // blind + + const Integer &h = re, &p = m_p, &q = m_q; + Integer e, f; + + const Integer U = modq.Exponentiate(h, (q+1)/8); + if(((modq.Exponentiate(U, 4) - h) % q).IsZero()) + e = Integer::One(); + else + e = -1; + + const Integer eh = e*h, V = modp.Exponentiate(eh, (p-3)/8); + if(((modp.Multiply(modp.Exponentiate(V, 4), modp.Exponentiate(eh, 2)) - eh) % p).IsZero()) + f = Integer::One(); + else + f = 2; + +#ifdef _OPENMP + Integer W, X; + #pragma omp parallel sections if(CRYPTOPP_RW_USE_OMP) + { + #pragma omp section + { + W = (f.IsUnit() ? U : modq.Multiply(m_pre_2_3q, U)); + } + #pragma omp section + { + const Integer t = modp.Multiply(modp.Exponentiate(V, 3), eh); + X = (f.IsUnit() ? t : modp.Multiply(m_pre_2_9p, t)); + } + } +#else + const Integer W = (f.IsUnit() ? U : modq.Multiply(m_pre_2_3q, U)); + const Integer t = modp.Multiply(modp.Exponentiate(V, 3), eh); + const Integer X = (f.IsUnit() ? t : modp.Multiply(m_pre_2_9p, t)); +#endif + + const Integer Y = W + q * modp.Multiply(m_pre_q_p, (X - W)); + + // Signature + Integer s = modn.Multiply(modn.Square(Y), rInv); + CRYPTOPP_ASSERT((e * f * s.Squared()) % m_n == x); + + // IEEE P1363, Section 8.2.8 IFSP-RW, p.44 + s = STDMIN(s, m_n - s); + if (ApplyFunction(s) != x) // check + throw Exception(Exception::OTHER_ERROR, "InvertibleRWFunction: computational error during private key operation"); + + return s; +} + +bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = RWFunction::Validate(rng, level); + CRYPTOPP_ASSERT(pass); + pass = pass && m_p > Integer::One() && m_p%8 == 3 && m_p < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_q > Integer::One() && m_q%8 == 7 && m_q < m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_u.IsPositive() && m_u < m_p; + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + CRYPTOPP_ASSERT(pass); + pass = pass && m_u * m_q % m_p == 1; + CRYPTOPP_ASSERT(pass); + } + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool InvertibleRWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleRWFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; + + m_precompute = false; +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/rw.h b/external/ours/library/crypto/src/shared/original/rw.h new file mode 100755 index 000000000..48aa28915 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/rw.h @@ -0,0 +1,146 @@ +// rw.h - originally written and placed in the public domain by Wei Dai + +/// \file rw.h +/// \brief Classes for Rabin-Williams signature scheme +/// \details The implementation provides Rabin-Williams signature schemes as defined in +/// IEEE P1363. It uses Bernstein's tweaked square roots in place of square roots to +/// speedup calculations. +/// \sa RSA signatures and Rabin–Williams +/// signatures: the state of the art (20080131), Section 6, The tweaks e and f. +/// \since Crypto++ 3.0 + +#ifndef CRYPTOPP_RW_H +#define CRYPTOPP_RW_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Rabin-Williams trapdoor function using the public key +/// \since Crypto++ 3.0, Tweaked roots using e and f since Crypto++ 5.6.4 +class CRYPTOPP_DLL RWFunction : public TrapdoorFunction, public PublicKey +{ + typedef RWFunction ThisClass; + +public: + + /// \brief Initialize a Rabin-Williams public key + /// \param n the modulus + void Initialize(const Integer &n) + {m_n = n;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + void Save(BufferedTransformation &bt) const + {DEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} + Integer ImageBound() const {return m_n;} + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + const Integer& GetModulus() const {return m_n;} + void SetModulus(const Integer &n) {m_n = n;} + +protected: + Integer m_n; +}; + +/// \brief Rabin-Williams trapdoor function using the private key +/// \since Crypto++ 3.0, Tweaked roots using e and f since Crypto++ 5.6.4 +class CRYPTOPP_DLL InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleRWFunction ThisClass; + +public: + /// \brief Construct an InvertibleRWFunction + InvertibleRWFunction() : m_precompute(false) {} + + /// \brief Initialize a Rabin-Williams private key + /// \param n modulus + /// \param p first prime factor + /// \param q second prime factor + /// \param u q-1 mod p + /// \details This Initialize() function overload initializes a private key from existing parameters. + void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u); + + /// \brief Create a Rabin-Williams private key + /// \param rng a RandomNumberGenerator derived class + /// \param modulusBits the size of the modulus, in bits + /// \details This function overload of Initialize() creates a new private key because it + /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + /// then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {GenerateRandomWithKeySize(rng, modulusBits);} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + void Save(BufferedTransformation &bt) const + {DEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + // GeneratibleCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + + virtual bool SupportsPrecomputation() const {return true;} + virtual void Precompute(unsigned int unused = 0) {CRYPTOPP_UNUSED(unused); PrecomputeTweakedRoots();} + virtual void Precompute(unsigned int unused = 0) const {CRYPTOPP_UNUSED(unused); PrecomputeTweakedRoots();} + + virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation); + virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const; + +protected: + void PrecomputeTweakedRoots() const; + +protected: + Integer m_p, m_q, m_u; + + mutable Integer m_pre_2_9p, m_pre_2_3q, m_pre_q_p; + mutable bool m_precompute; +}; + +/// \brief Rabin-Williams keys +/// \since Crypto++ 3.0 +struct RW +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RW";} + typedef RWFunction PublicKey; + typedef InvertibleRWFunction PrivateKey; +}; + +/// \brief Rabin-Williams signature scheme +/// \tparam STANDARD signature standard +/// \tparam H hash transformation +/// \since Crypto++ 3.0 +template +struct RWSS : public TF_SS +{ +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/safer.cpp b/external/ours/library/crypto/src/shared/original/safer.cpp new file mode 100755 index 000000000..83f415175 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/safer.cpp @@ -0,0 +1,157 @@ +// safer.cpp - modified by by Wei Dai from Richard De Moliner's safer.c + +#include "pch.h" +#include "safer.h" +#include "misc.h" +#include "argnames.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4244) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +const byte SAFER::Base::exp_tab[256] = + {1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, + 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, + 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, + 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, + 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, + 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, + 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, + 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, + 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40}; + +const byte SAFER::Base::log_tab[256] = + {128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, + 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, + 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, + 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, + 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, + 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, + 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, + 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, + 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, + 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, + 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, + 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, + 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48}; + +#define EXP(x) exp_tab[(x)] +#define LOG(x) log_tab[(x)] +#define PHT(x, y) { y += x; x += y; } +#define IPHT(x, y) { x -= y; y -= x; } + +static const unsigned int BLOCKSIZE = 8; +static const unsigned int MAX_ROUNDS = 13; + +void SAFER::Base::UncheckedSetKey(const byte *userkey_1, unsigned int length, const NameValuePairs ¶ms) +{ + bool strengthened = Strengthened(); + unsigned int nof_rounds = params.GetIntValueWithDefault(Name::Rounds(), length == 8 ? (strengthened ? 8 : 6) : 10); + + const byte *userkey_2 = length == 8 ? userkey_1 : userkey_1 + 8; + keySchedule.New(1 + BLOCKSIZE * (1 + 2 * nof_rounds)); + + unsigned int i, j; + byte *key = keySchedule; + SecByteBlock ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); + + if (MAX_ROUNDS < nof_rounds) + nof_rounds = MAX_ROUNDS; + *key++ = (unsigned char)nof_rounds; + ka[BLOCKSIZE] = 0; + kb[BLOCKSIZE] = 0; + for (j = 0; j < BLOCKSIZE; j++) + { + ka[BLOCKSIZE] ^= ka[j] = rotlConstant<5>(userkey_1[j]); + kb[BLOCKSIZE] ^= kb[j] = *key++ = userkey_2[j]; + } + + for (i = 1; i <= nof_rounds; i++) + { + for (j = 0; j < BLOCKSIZE + 1; j++) + { + ka[j] = rotlConstant<6>(ka[j]); + kb[j] = rotlConstant<6>(kb[j]); + } + for (j = 0; j < BLOCKSIZE; j++) + if (strengthened) + *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] + + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; + else + *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; + for (j = 0; j < BLOCKSIZE; j++) + if (strengthened) + *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] + + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; + else + *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; + } +} + +typedef BlockGetAndPut Block; + +void SAFER::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + byte a, b, c, d, e, f, g, h, t; + const byte *key = keySchedule+1; + unsigned int round = keySchedule[0]; + + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + while(round--) + { + a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; + e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; + a = EXP(a) + key[ 8]; b = LOG(b) ^ key[ 9]; + c = LOG(c) ^ key[10]; d = EXP(d) + key[11]; + e = EXP(e) + key[12]; f = LOG(f) ^ key[13]; + g = LOG(g) ^ key[14]; h = EXP(h) + key[15]; + key += 16; + PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); + PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); + PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); + t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; + } + a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; + e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +void SAFER::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + byte a, b, c, d, e, f, g, h, t; + unsigned int round = keySchedule[0]; + const byte *key = keySchedule + BLOCKSIZE * (1 + 2 * round) - 7; + + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + h ^= key[7]; g -= key[6]; f -= key[5]; e ^= key[4]; + d ^= key[3]; c -= key[2]; b -= key[1]; a ^= key[0]; + while (round--) + { + key -= 16; + t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; + IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); + IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); + IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); + h -= key[15]; g ^= key[14]; f ^= key[13]; e -= key[12]; + d -= key[11]; c ^= key[10]; b ^= key[9]; a -= key[8]; + h = LOG(h) ^ key[7]; g = EXP(g) - key[6]; + f = EXP(f) - key[5]; e = LOG(e) ^ key[4]; + d = LOG(d) ^ key[3]; c = EXP(c) - key[2]; + b = EXP(b) - key[1]; a = LOG(a) ^ key[0]; + } + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/safer.h b/external/ours/library/crypto/src/shared/original/safer.h new file mode 100755 index 000000000..b28ad82cc --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/safer.h @@ -0,0 +1,98 @@ +// safer.h - originally written and placed in the public domain by Wei Dai + +/// \file safer.h +/// \brief Classes for the SAFER and SAFER-K block ciphers + +#ifndef CRYPTOPP_SAFER_H +#define CRYPTOPP_SAFER_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SAFER block cipher +class SAFER +{ +public: + /// \brief SAFER block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public BlockCipher + { + public: + unsigned int OptimalDataAlignment() const {return 1;} + void UncheckedSetKey(const byte *userkey, unsigned int length, const NameValuePairs ¶ms); + + protected: + virtual bool Strengthened() const =0; + + SecByteBlock keySchedule; + static const byte exp_tab[256]; + static const byte log_tab[256]; + }; + + /// \brief SAFER block cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief SAFER block cipher decryption operation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; +}; + +/// \brief SAFER block cipher default implementation +/// \tparam BASE SAFER::Enc or SAFER::Dec derived base class +/// \tparam INFO SAFER_Info derived class +/// \tparam STR flag indicating a strengthened implementation +/// \details SAFER-K is not strengthened; while SAFER-SK is strengthened. +template +class CRYPTOPP_NO_VTABLE SAFER_Impl : public BlockCipherImpl +{ +protected: + bool Strengthened() const {return STR;} +}; + +/// \brief SAFER-K block cipher information +struct SAFER_K_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 8, 16, 8>, public VariableRounds<10, 1, 13> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SAFER-K";} +}; + +/// \brief SAFER-K block cipher +/// \sa SAFER-K +class SAFER_K : public SAFER_K_Info, public SAFER, public BlockCipherDocumentation +{ +public: + typedef BlockCipherFinal > Encryption; + typedef BlockCipherFinal > Decryption; +}; + +/// \brief SAFER-SK block cipher information +struct SAFER_SK_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 8, 16, 8>, public VariableRounds<10, 1, 13> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SAFER-SK";} +}; + +/// \brief SAFER-SK block cipher +/// \sa SAFER-SK +class SAFER_SK : public SAFER_SK_Info, public SAFER, public BlockCipherDocumentation +{ +public: + typedef BlockCipherFinal > Encryption; + typedef BlockCipherFinal > Decryption; +}; + +typedef SAFER_K::Encryption SAFER_K_Encryption; +typedef SAFER_K::Decryption SAFER_K_Decryption; + +typedef SAFER_SK::Encryption SAFER_SK_Encryption; +typedef SAFER_SK::Decryption SAFER_SK_Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/salsa.cpp b/external/ours/library/crypto/src/shared/original/salsa.cpp new file mode 100755 index 000000000..987cd3022 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/salsa.cpp @@ -0,0 +1,759 @@ +// salsa.cpp - originally written and placed in the public domain by Wei Dai + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM salsa.cpp" to generate MASM code + +#include "pch.h" +#include "config.h" + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "salsa.h" +#include "argnames.h" +#include "misc.h" +#include "cpu.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4702 4740) +#endif + +// Clang due to "Inline assembly operands don't work with .intel_syntax" +// https://llvm.org/bugs/show_bug.cgi?id=24232 +#if defined(CRYPTOPP_DISABLE_SALSA_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +# undef CRYPTOPP_SSSE3_ASM_AVAILABLE +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +// Can't use GetAlignmentOf() because of C++11 and constexpr +// Can use 'const unsigned int' because of MSVC 2013 +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +# define ALIGN_SPEC 16 +#else +# define ALIGN_SPEC 4 +#endif + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void Salsa20_TestInstantiations() +{ + Salsa20::Encryption x1; + XSalsa20::Encryption x2; +} +#endif + +void Salsa20_Core(word32* data, unsigned int rounds) +{ + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(rounds % 2 == 0); + + CRYPTOPP_ALIGN_DATA(ALIGN_SPEC) word32 x[16]; + + for (size_t i = 0; i < 16; ++i) + x[i] = data[i]; + + // Rounds must be even + for (size_t i = 0; i < rounds; i += 2) + { + x[ 4] ^= rotlConstant< 7>(x[ 0]+x[12]); + x[ 8] ^= rotlConstant< 9>(x[ 4]+x[ 0]); + x[12] ^= rotlConstant<13>(x[ 8]+x[ 4]); + x[ 0] ^= rotlConstant<18>(x[12]+x[ 8]); + + x[ 9] ^= rotlConstant< 7>(x[ 5]+x[ 1]); + x[13] ^= rotlConstant< 9>(x[ 9]+x[ 5]); + x[ 1] ^= rotlConstant<13>(x[13]+x[ 9]); + x[ 5] ^= rotlConstant<18>(x[ 1]+x[13]); + + x[14] ^= rotlConstant< 7>(x[10]+x[ 6]); + x[ 2] ^= rotlConstant< 9>(x[14]+x[10]); + x[ 6] ^= rotlConstant<13>(x[ 2]+x[14]); + x[10] ^= rotlConstant<18>(x[ 6]+x[ 2]); + + x[ 3] ^= rotlConstant< 7>(x[15]+x[11]); + x[ 7] ^= rotlConstant< 9>(x[ 3]+x[15]); + x[11] ^= rotlConstant<13>(x[ 7]+x[ 3]); + x[15] ^= rotlConstant<18>(x[11]+x[ 7]); + + x[ 1] ^= rotlConstant< 7>(x[ 0]+x[ 3]); + x[ 2] ^= rotlConstant< 9>(x[ 1]+x[ 0]); + x[ 3] ^= rotlConstant<13>(x[ 2]+x[ 1]); + x[ 0] ^= rotlConstant<18>(x[ 3]+x[ 2]); + + x[ 6] ^= rotlConstant< 7>(x[ 5]+x[ 4]); + x[ 7] ^= rotlConstant< 9>(x[ 6]+x[ 5]); + x[ 4] ^= rotlConstant<13>(x[ 7]+x[ 6]); + x[ 5] ^= rotlConstant<18>(x[ 4]+x[ 7]); + + x[11] ^= rotlConstant< 7>(x[10]+x[ 9]); + x[ 8] ^= rotlConstant< 9>(x[11]+x[10]); + x[ 9] ^= rotlConstant<13>(x[ 8]+x[11]); + x[10] ^= rotlConstant<18>(x[ 9]+x[ 8]); + + x[12] ^= rotlConstant< 7>(x[15]+x[14]); + x[13] ^= rotlConstant< 9>(x[12]+x[15]); + x[14] ^= rotlConstant<13>(x[13]+x[12]); + x[15] ^= rotlConstant<18>(x[14]+x[13]); + } + +// OpenMP 4.0 released July 2013. +#if _OPENMP >= 201307 + #pragma omp simd + for (size_t i = 0; i < 16; ++i) + data[i] += x[i]; +#else + for (size_t i = 0; i < 16; ++i) + data[i] += x[i]; +#endif +} + +std::string Salsa20_Policy::AlgorithmProvider() const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_SALSA_ASM) + if (HasSSE2()) + return "SSE2"; +#endif + return "C++"; +} + +void Salsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + // Use previous rounds as the default value + int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds); + if (rounds != 20 && rounds != 12 && rounds != 8) + throw InvalidRounds(Salsa20::StaticAlgorithmName(), rounds); + + // Latch a good value + m_rounds = rounds; + + // m_state is reordered for SSE2 + GetBlock get1(key); + get1(m_state[13])(m_state[10])(m_state[7])(m_state[4]); + GetBlock get2(key + length - 16); + get2(m_state[15])(m_state[12])(m_state[9])(m_state[6]); + + // "expand 16-byte k" or "expand 32-byte k" + m_state[0] = 0x61707865; + m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e; + m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32; + m_state[3] = 0x6b206574; +} + +void Salsa20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==8); + + GetBlock get(IV); + get(m_state[14])(m_state[11]); + m_state[8] = m_state[5] = 0; +} + +void Salsa20_Policy::SeekToIteration(lword iterationCount) +{ + m_state[8] = (word32)iterationCount; + m_state[5] = (word32)SafeRightShift<32>(iterationCount); +} + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +unsigned int Salsa20_Policy::GetAlignment() const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return 16; + else +#endif + return GetAlignmentOf(); +} + +unsigned int Salsa20_Policy::GetOptimalBlockSize() const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return 4*BYTES_PER_ITERATION; + else +#endif + return BYTES_PER_ITERATION; +} +#endif + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Salsa20_OperateKeystream(byte *output, const byte *input, size_t iterationCount, int rounds, void *state); +} +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code +#endif + +void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE + Salsa20_OperateKeystream(output, input, iterationCount, m_rounds, m_state.data()); + return; +#endif + +#if CRYPTOPP_SSE2_ASM_AVAILABLE +#ifdef CRYPTOPP_GENERATE_X64_MASM + ALIGN 8 + Salsa20_OperateKeystream PROC FRAME + mov r10, [rsp + 5*8] ; state + alloc_stack(10*16 + 32*16 + 8) + save_xmm128 xmm6, 0200h + save_xmm128 xmm7, 0210h + save_xmm128 xmm8, 0220h + save_xmm128 xmm9, 0230h + save_xmm128 xmm10, 0240h + save_xmm128 xmm11, 0250h + save_xmm128 xmm12, 0260h + save_xmm128 xmm13, 0270h + save_xmm128 xmm14, 0280h + save_xmm128 xmm15, 0290h + .endprolog + + #define REG_output rcx + #define REG_input rdx + #define REG_iterationCount r8 + #define REG_state r10 + #define REG_rounds e9d + #define REG_roundsLeft eax + #define REG_temp32 r11d + #define REG_temp r11 + #define SSE2_WORKSPACE rsp +#else + if (HasSSE2()) + { + #if CRYPTOPP_BOOL_X64 + #define REG_output %1 + #define REG_input %0 + #define REG_iterationCount %2 + #define REG_state %4 /* constant */ + #define REG_rounds %3 /* constant */ + #define REG_roundsLeft eax + #define REG_temp32 edx + #define REG_temp rdx + #define SSE2_WORKSPACE %5 /* constant */ + + CRYPTOPP_ALIGN_DATA(16) byte workspace[16*32]; + #else + #define REG_output edi + #define REG_input eax + #define REG_iterationCount ecx + #define REG_state esi + #define REG_rounds edx + #define REG_roundsLeft ebx + #define REG_temp32 ebp + #define REG_temp ebp + #define SSE2_WORKSPACE esp + WORD_SZ + #endif + + #ifdef __GNUC__ + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS_PUSH_IF86( bx) + #else + void *s = m_state.data(); + word32 r = m_rounds; + + AS2( mov REG_iterationCount, iterationCount) + AS2( mov REG_input, input) + AS2( mov REG_output, output) + AS2( mov REG_state, s) + AS2( mov REG_rounds, r) + #endif +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM + + AS_PUSH_IF86( bp) + AS2( cmp REG_iterationCount, 4) + ASJ( jl, 5, f) + +#if CRYPTOPP_BOOL_X86 + AS2( mov ebx, esp) + AS2( and esp, -16) + AS2( sub esp, 32*16) + AS1( push ebx) +#endif + +#define SSE2_EXPAND_S(i, j) \ + ASS( pshufd xmm4, xmm##i, j, j, j, j) \ + AS2( movdqa [SSE2_WORKSPACE + (i*4+j)*16 + 256], xmm4) + + AS2( movdqa xmm0, [REG_state + 0*16]) + AS2( movdqa xmm1, [REG_state + 1*16]) + AS2( movdqa xmm2, [REG_state + 2*16]) + AS2( movdqa xmm3, [REG_state + 3*16]) + SSE2_EXPAND_S(0, 0) + SSE2_EXPAND_S(0, 1) + SSE2_EXPAND_S(0, 2) + SSE2_EXPAND_S(0, 3) + SSE2_EXPAND_S(1, 0) + SSE2_EXPAND_S(1, 2) + SSE2_EXPAND_S(1, 3) + SSE2_EXPAND_S(2, 1) + SSE2_EXPAND_S(2, 2) + SSE2_EXPAND_S(2, 3) + SSE2_EXPAND_S(3, 0) + SSE2_EXPAND_S(3, 1) + SSE2_EXPAND_S(3, 2) + SSE2_EXPAND_S(3, 3) + +#define SSE2_EXPAND_S85(i) \ + AS2( mov dword ptr [SSE2_WORKSPACE + 8*16 + i*4 + 256], REG_roundsLeft) \ + AS2( mov dword ptr [SSE2_WORKSPACE + 5*16 + i*4 + 256], REG_temp32) \ + AS2( add REG_roundsLeft, 1) \ + AS2( adc REG_temp32, 0) + + ASL(1) + AS2( mov REG_roundsLeft, dword ptr [REG_state + 8*4]) + AS2( mov REG_temp32, dword ptr [REG_state + 5*4]) + SSE2_EXPAND_S85(0) + SSE2_EXPAND_S85(1) + SSE2_EXPAND_S85(2) + SSE2_EXPAND_S85(3) + AS2( mov dword ptr [REG_state + 8*4], REG_roundsLeft) + AS2( mov dword ptr [REG_state + 5*4], REG_temp32) + +#ifdef __XOP__ +#define SSE2_QUARTER_ROUND(a, b, d, i) \ + AS2( movdqa xmm4, xmm##d) \ + AS2( paddd xmm4, xmm##a) \ + AS3( vprotd xmm4, xmm4, i) \ + AS2( pxor xmm##b, xmm4) +#else +#define SSE2_QUARTER_ROUND(a, b, d, i) \ + AS2( movdqa xmm4, xmm##d) \ + AS2( paddd xmm4, xmm##a) \ + AS2( movdqa xmm5, xmm4) \ + AS2( pslld xmm4, i) \ + AS2( psrld xmm5, 32-i) \ + AS2( pxor xmm##b, xmm4) \ + AS2( pxor xmm##b, xmm5) +#endif + +#define L01(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##A, [SSE2_WORKSPACE + d*16 + i*256]) /* y3 */ +#define L02(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##C, [SSE2_WORKSPACE + a*16 + i*256]) /* y0 */ +#define L03(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##C) /* y0+y3 */ + +#ifdef __XOP__ +#define L04(A,B,C,D,a,b,c,d,i) +#define L05(A,B,C,D,a,b,c,d,i) AS3( vprotd xmm##A, xmm##A, 7) +#define L06(A,B,C,D,a,b,c,d,i) +#define L07(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + b*16 + i*256]) +#define L08(A,B,C,D,a,b,c,d,i) +#else +#define L04(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##B, xmm##A) +#define L05(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 7) +#define L06(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##B, 32-7) +#define L07(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + b*16 + i*256]) +#define L08(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##B) /* z1 */ +#endif + +#define L09(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + b*16], xmm##A) +#define L10(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##B, xmm##A) +#define L11(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##C) /* z1+y0 */ + +#ifdef __XOP__ +#define L12(A,B,C,D,a,b,c,d,i) +#define L13(A,B,C,D,a,b,c,d,i) AS3( vprotd xmm##A, xmm##A, 9) +#define L14(A,B,C,D,a,b,c,d,i) +#define L15(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + c*16 + i*256]) +#define L16(A,B,C,D,a,b,c,d,i) +#else +#define L12(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##D, xmm##A) +#define L13(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 9) +#define L14(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##D, 32-9) +#define L15(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + c*16 + i*256]) +#define L16(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##D) /* z2 */ +#endif + +#define L17(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + c*16], xmm##A) +#define L18(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##D, xmm##A) +#define L19(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##B) /* z2+z1 */ + +#ifdef __XOP__ +#define L20(A,B,C,D,a,b,c,d,i) +#define L21(A,B,C,D,a,b,c,d,i) AS3( vprotd xmm##A, xmm##A, 13) +#define L22(A,B,C,D,a,b,c,d,i) +#define L23(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + d*16 + i*256]) +#define L24(A,B,C,D,a,b,c,d,i) +#else +#define L20(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##B, xmm##A) +#define L21(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 13) +#define L22(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##B, 32-13) +#define L23(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + d*16 + i*256]) +#define L24(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##B) /* z3 */ +#endif + +#define L25(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + d*16], xmm##A) +#define L26(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##D) /* z3+z2 */ + +#ifdef __XOP__ +#define L27(A,B,C,D,a,b,c,d,i) +#define L28(A,B,C,D,a,b,c,d,i) AS3( vprotd xmm##A, xmm##A, 18) +#define L29(A,B,C,D,a,b,c,d,i) +#define L30(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##C) /* xor y0 */ +#define L31(A,B,C,D,a,b,c,d,i) +#else +#define L27(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##D, xmm##A) +#define L28(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 18) +#define L29(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##D, 32-18) +#define L30(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##C) /* xor y0 */ +#define L31(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##D) /* z0 */ +#endif + +#define L32(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + a*16], xmm##A) + +#define SSE2_QUARTER_ROUND_X8(i, a, b, c, d, e, f, g, h) \ + L01(0,1,2,3, a,b,c,d, i) L01(4,5,6,7, e,f,g,h, i) \ + L02(0,1,2,3, a,b,c,d, i) L02(4,5,6,7, e,f,g,h, i) \ + L03(0,1,2,3, a,b,c,d, i) L03(4,5,6,7, e,f,g,h, i) \ + L04(0,1,2,3, a,b,c,d, i) L04(4,5,6,7, e,f,g,h, i) \ + L05(0,1,2,3, a,b,c,d, i) L05(4,5,6,7, e,f,g,h, i) \ + L06(0,1,2,3, a,b,c,d, i) L06(4,5,6,7, e,f,g,h, i) \ + L07(0,1,2,3, a,b,c,d, i) L07(4,5,6,7, e,f,g,h, i) \ + L08(0,1,2,3, a,b,c,d, i) L08(4,5,6,7, e,f,g,h, i) \ + L09(0,1,2,3, a,b,c,d, i) L09(4,5,6,7, e,f,g,h, i) \ + L10(0,1,2,3, a,b,c,d, i) L10(4,5,6,7, e,f,g,h, i) \ + L11(0,1,2,3, a,b,c,d, i) L11(4,5,6,7, e,f,g,h, i) \ + L12(0,1,2,3, a,b,c,d, i) L12(4,5,6,7, e,f,g,h, i) \ + L13(0,1,2,3, a,b,c,d, i) L13(4,5,6,7, e,f,g,h, i) \ + L14(0,1,2,3, a,b,c,d, i) L14(4,5,6,7, e,f,g,h, i) \ + L15(0,1,2,3, a,b,c,d, i) L15(4,5,6,7, e,f,g,h, i) \ + L16(0,1,2,3, a,b,c,d, i) L16(4,5,6,7, e,f,g,h, i) \ + L17(0,1,2,3, a,b,c,d, i) L17(4,5,6,7, e,f,g,h, i) \ + L18(0,1,2,3, a,b,c,d, i) L18(4,5,6,7, e,f,g,h, i) \ + L19(0,1,2,3, a,b,c,d, i) L19(4,5,6,7, e,f,g,h, i) \ + L20(0,1,2,3, a,b,c,d, i) L20(4,5,6,7, e,f,g,h, i) \ + L21(0,1,2,3, a,b,c,d, i) L21(4,5,6,7, e,f,g,h, i) \ + L22(0,1,2,3, a,b,c,d, i) L22(4,5,6,7, e,f,g,h, i) \ + L23(0,1,2,3, a,b,c,d, i) L23(4,5,6,7, e,f,g,h, i) \ + L24(0,1,2,3, a,b,c,d, i) L24(4,5,6,7, e,f,g,h, i) \ + L25(0,1,2,3, a,b,c,d, i) L25(4,5,6,7, e,f,g,h, i) \ + L26(0,1,2,3, a,b,c,d, i) L26(4,5,6,7, e,f,g,h, i) \ + L27(0,1,2,3, a,b,c,d, i) L27(4,5,6,7, e,f,g,h, i) \ + L28(0,1,2,3, a,b,c,d, i) L28(4,5,6,7, e,f,g,h, i) \ + L29(0,1,2,3, a,b,c,d, i) L29(4,5,6,7, e,f,g,h, i) \ + L30(0,1,2,3, a,b,c,d, i) L30(4,5,6,7, e,f,g,h, i) \ + L31(0,1,2,3, a,b,c,d, i) L31(4,5,6,7, e,f,g,h, i) \ + L32(0,1,2,3, a,b,c,d, i) L32(4,5,6,7, e,f,g,h, i) + +#define SSE2_QUARTER_ROUND_X16(i, a, b, c, d, e, f, g, h, A, B, C, D, E, F, G, H) \ + L01(0,1,2,3, a,b,c,d, i) L01(4,5,6,7, e,f,g,h, i) L01(8,9,10,11, A,B,C,D, i) L01(12,13,14,15, E,F,G,H, i) \ + L02(0,1,2,3, a,b,c,d, i) L02(4,5,6,7, e,f,g,h, i) L02(8,9,10,11, A,B,C,D, i) L02(12,13,14,15, E,F,G,H, i) \ + L03(0,1,2,3, a,b,c,d, i) L03(4,5,6,7, e,f,g,h, i) L03(8,9,10,11, A,B,C,D, i) L03(12,13,14,15, E,F,G,H, i) \ + L04(0,1,2,3, a,b,c,d, i) L04(4,5,6,7, e,f,g,h, i) L04(8,9,10,11, A,B,C,D, i) L04(12,13,14,15, E,F,G,H, i) \ + L05(0,1,2,3, a,b,c,d, i) L05(4,5,6,7, e,f,g,h, i) L05(8,9,10,11, A,B,C,D, i) L05(12,13,14,15, E,F,G,H, i) \ + L06(0,1,2,3, a,b,c,d, i) L06(4,5,6,7, e,f,g,h, i) L06(8,9,10,11, A,B,C,D, i) L06(12,13,14,15, E,F,G,H, i) \ + L07(0,1,2,3, a,b,c,d, i) L07(4,5,6,7, e,f,g,h, i) L07(8,9,10,11, A,B,C,D, i) L07(12,13,14,15, E,F,G,H, i) \ + L08(0,1,2,3, a,b,c,d, i) L08(4,5,6,7, e,f,g,h, i) L08(8,9,10,11, A,B,C,D, i) L08(12,13,14,15, E,F,G,H, i) \ + L09(0,1,2,3, a,b,c,d, i) L09(4,5,6,7, e,f,g,h, i) L09(8,9,10,11, A,B,C,D, i) L09(12,13,14,15, E,F,G,H, i) \ + L10(0,1,2,3, a,b,c,d, i) L10(4,5,6,7, e,f,g,h, i) L10(8,9,10,11, A,B,C,D, i) L10(12,13,14,15, E,F,G,H, i) \ + L11(0,1,2,3, a,b,c,d, i) L11(4,5,6,7, e,f,g,h, i) L11(8,9,10,11, A,B,C,D, i) L11(12,13,14,15, E,F,G,H, i) \ + L12(0,1,2,3, a,b,c,d, i) L12(4,5,6,7, e,f,g,h, i) L12(8,9,10,11, A,B,C,D, i) L12(12,13,14,15, E,F,G,H, i) \ + L13(0,1,2,3, a,b,c,d, i) L13(4,5,6,7, e,f,g,h, i) L13(8,9,10,11, A,B,C,D, i) L13(12,13,14,15, E,F,G,H, i) \ + L14(0,1,2,3, a,b,c,d, i) L14(4,5,6,7, e,f,g,h, i) L14(8,9,10,11, A,B,C,D, i) L14(12,13,14,15, E,F,G,H, i) \ + L15(0,1,2,3, a,b,c,d, i) L15(4,5,6,7, e,f,g,h, i) L15(8,9,10,11, A,B,C,D, i) L15(12,13,14,15, E,F,G,H, i) \ + L16(0,1,2,3, a,b,c,d, i) L16(4,5,6,7, e,f,g,h, i) L16(8,9,10,11, A,B,C,D, i) L16(12,13,14,15, E,F,G,H, i) \ + L17(0,1,2,3, a,b,c,d, i) L17(4,5,6,7, e,f,g,h, i) L17(8,9,10,11, A,B,C,D, i) L17(12,13,14,15, E,F,G,H, i) \ + L18(0,1,2,3, a,b,c,d, i) L18(4,5,6,7, e,f,g,h, i) L18(8,9,10,11, A,B,C,D, i) L18(12,13,14,15, E,F,G,H, i) \ + L19(0,1,2,3, a,b,c,d, i) L19(4,5,6,7, e,f,g,h, i) L19(8,9,10,11, A,B,C,D, i) L19(12,13,14,15, E,F,G,H, i) \ + L20(0,1,2,3, a,b,c,d, i) L20(4,5,6,7, e,f,g,h, i) L20(8,9,10,11, A,B,C,D, i) L20(12,13,14,15, E,F,G,H, i) \ + L21(0,1,2,3, a,b,c,d, i) L21(4,5,6,7, e,f,g,h, i) L21(8,9,10,11, A,B,C,D, i) L21(12,13,14,15, E,F,G,H, i) \ + L22(0,1,2,3, a,b,c,d, i) L22(4,5,6,7, e,f,g,h, i) L22(8,9,10,11, A,B,C,D, i) L22(12,13,14,15, E,F,G,H, i) \ + L23(0,1,2,3, a,b,c,d, i) L23(4,5,6,7, e,f,g,h, i) L23(8,9,10,11, A,B,C,D, i) L23(12,13,14,15, E,F,G,H, i) \ + L24(0,1,2,3, a,b,c,d, i) L24(4,5,6,7, e,f,g,h, i) L24(8,9,10,11, A,B,C,D, i) L24(12,13,14,15, E,F,G,H, i) \ + L25(0,1,2,3, a,b,c,d, i) L25(4,5,6,7, e,f,g,h, i) L25(8,9,10,11, A,B,C,D, i) L25(12,13,14,15, E,F,G,H, i) \ + L26(0,1,2,3, a,b,c,d, i) L26(4,5,6,7, e,f,g,h, i) L26(8,9,10,11, A,B,C,D, i) L26(12,13,14,15, E,F,G,H, i) \ + L27(0,1,2,3, a,b,c,d, i) L27(4,5,6,7, e,f,g,h, i) L27(8,9,10,11, A,B,C,D, i) L27(12,13,14,15, E,F,G,H, i) \ + L28(0,1,2,3, a,b,c,d, i) L28(4,5,6,7, e,f,g,h, i) L28(8,9,10,11, A,B,C,D, i) L28(12,13,14,15, E,F,G,H, i) \ + L29(0,1,2,3, a,b,c,d, i) L29(4,5,6,7, e,f,g,h, i) L29(8,9,10,11, A,B,C,D, i) L29(12,13,14,15, E,F,G,H, i) \ + L30(0,1,2,3, a,b,c,d, i) L30(4,5,6,7, e,f,g,h, i) L30(8,9,10,11, A,B,C,D, i) L30(12,13,14,15, E,F,G,H, i) \ + L31(0,1,2,3, a,b,c,d, i) L31(4,5,6,7, e,f,g,h, i) L31(8,9,10,11, A,B,C,D, i) L31(12,13,14,15, E,F,G,H, i) \ + L32(0,1,2,3, a,b,c,d, i) L32(4,5,6,7, e,f,g,h, i) L32(8,9,10,11, A,B,C,D, i) L32(12,13,14,15, E,F,G,H, i) + +#if CRYPTOPP_BOOL_X64 + SSE2_QUARTER_ROUND_X16(1, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15) +#else + SSE2_QUARTER_ROUND_X8(1, 2, 6, 10, 14, 3, 7, 11, 15) + SSE2_QUARTER_ROUND_X8(1, 0, 4, 8, 12, 1, 5, 9, 13) +#endif + AS2( mov REG_roundsLeft, REG_rounds) + ASJ( jmp, 2, f) + + ASL(SSE2_Salsa_Output) + AS2( movdqa xmm0, xmm4) + AS2( punpckldq xmm4, xmm5) + AS2( movdqa xmm1, xmm6) + AS2( punpckldq xmm6, xmm7) + AS2( movdqa xmm2, xmm4) + AS2( punpcklqdq xmm4, xmm6) // e + AS2( punpckhqdq xmm2, xmm6) // f + AS2( punpckhdq xmm0, xmm5) + AS2( punpckhdq xmm1, xmm7) + AS2( movdqa xmm6, xmm0) + AS2( punpcklqdq xmm0, xmm1) // g + AS2( punpckhqdq xmm6, xmm1) // h + AS_XMM_OUTPUT4(SSE2_Salsa_Output_A, REG_input, REG_output, 4, 2, 0, 6, 1, 0, 4, 8, 12, 1) + AS1( ret) + + ASL(6) +#if CRYPTOPP_BOOL_X64 + SSE2_QUARTER_ROUND_X16(0, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15) + ASL(2) + SSE2_QUARTER_ROUND_X16(0, 0, 13, 10, 7, 1, 14, 11, 4, 2, 15, 8, 5, 3, 12, 9, 6) +#else + SSE2_QUARTER_ROUND_X8(0, 2, 6, 10, 14, 3, 7, 11, 15) + SSE2_QUARTER_ROUND_X8(0, 0, 4, 8, 12, 1, 5, 9, 13) + ASL(2) + SSE2_QUARTER_ROUND_X8(0, 2, 15, 8, 5, 3, 12, 9, 6) + SSE2_QUARTER_ROUND_X8(0, 0, 13, 10, 7, 1, 14, 11, 4) +#endif + AS2( sub REG_roundsLeft, 2) + ASJ( jnz, 6, b) + +#define SSE2_OUTPUT_4(a, b, c, d) \ + AS2( movdqa xmm4, [SSE2_WORKSPACE + a*16 + 256])\ + AS2( paddd xmm4, [SSE2_WORKSPACE + a*16])\ + AS2( movdqa xmm5, [SSE2_WORKSPACE + b*16 + 256])\ + AS2( paddd xmm5, [SSE2_WORKSPACE + b*16])\ + AS2( movdqa xmm6, [SSE2_WORKSPACE + c*16 + 256])\ + AS2( paddd xmm6, [SSE2_WORKSPACE + c*16])\ + AS2( movdqa xmm7, [SSE2_WORKSPACE + d*16 + 256])\ + AS2( paddd xmm7, [SSE2_WORKSPACE + d*16])\ + ASC( call, SSE2_Salsa_Output) + + SSE2_OUTPUT_4(0, 13, 10, 7) + SSE2_OUTPUT_4(4, 1, 14, 11) + SSE2_OUTPUT_4(8, 5, 2, 15) + SSE2_OUTPUT_4(12, 9, 6, 3) + AS2( test REG_input, REG_input) + ASJ( jz, 9, f) + AS2( add REG_input, 12*16) + ASL(9) + AS2( add REG_output, 12*16) + AS2( sub REG_iterationCount, 4) + AS2( cmp REG_iterationCount, 4) + ASJ( jge, 1, b) + AS_POP_IF86( sp) + + ASL(5) + AS2( sub REG_iterationCount, 1) + ASJ( jl, 4, f) + AS2( movdqa xmm0, [REG_state + 0*16]) + AS2( movdqa xmm1, [REG_state + 1*16]) + AS2( movdqa xmm2, [REG_state + 2*16]) + AS2( movdqa xmm3, [REG_state + 3*16]) + AS2( mov REG_roundsLeft, REG_rounds) + + ASL(0) + SSE2_QUARTER_ROUND(0, 1, 3, 7) + SSE2_QUARTER_ROUND(1, 2, 0, 9) + SSE2_QUARTER_ROUND(2, 3, 1, 13) + SSE2_QUARTER_ROUND(3, 0, 2, 18) + ASS( pshufd xmm1, xmm1, 2, 1, 0, 3) + ASS( pshufd xmm2, xmm2, 1, 0, 3, 2) + ASS( pshufd xmm3, xmm3, 0, 3, 2, 1) + SSE2_QUARTER_ROUND(0, 3, 1, 7) + SSE2_QUARTER_ROUND(3, 2, 0, 9) + SSE2_QUARTER_ROUND(2, 1, 3, 13) + SSE2_QUARTER_ROUND(1, 0, 2, 18) + ASS( pshufd xmm1, xmm1, 0, 3, 2, 1) + ASS( pshufd xmm2, xmm2, 1, 0, 3, 2) + ASS( pshufd xmm3, xmm3, 2, 1, 0, 3) + AS2( sub REG_roundsLeft, 2) + ASJ( jnz, 0, b) + + AS2( paddd xmm0, [REG_state + 0*16]) + AS2( paddd xmm1, [REG_state + 1*16]) + AS2( paddd xmm2, [REG_state + 2*16]) + AS2( paddd xmm3, [REG_state + 3*16]) + + AS2( add dword ptr [REG_state + 8*4], 1) + AS2( adc dword ptr [REG_state + 5*4], 0) + + AS2( pcmpeqb xmm6, xmm6) // all ones + AS2( psrlq xmm6, 32) // lo32 mask + ASS( pshufd xmm7, xmm6, 0, 1, 2, 3) // hi32 mask + AS2( movdqa xmm4, xmm0) + AS2( movdqa xmm5, xmm3) + AS2( pand xmm0, xmm7) + AS2( pand xmm4, xmm6) + AS2( pand xmm3, xmm6) + AS2( pand xmm5, xmm7) + AS2( por xmm4, xmm5) // 0,13,2,15 + AS2( movdqa xmm5, xmm1) + AS2( pand xmm1, xmm7) + AS2( pand xmm5, xmm6) + AS2( por xmm0, xmm5) // 4,1,6,3 + AS2( pand xmm6, xmm2) + AS2( pand xmm2, xmm7) + AS2( por xmm1, xmm6) // 8,5,10,7 + AS2( por xmm2, xmm3) // 12,9,14,11 + + AS2( movdqa xmm5, xmm4) + AS2( movdqa xmm6, xmm0) + AS3( shufpd xmm4, xmm1, 2) // 0,13,10,7 + AS3( shufpd xmm0, xmm2, 2) // 4,1,14,11 + AS3( shufpd xmm1, xmm5, 2) // 8,5,2,15 + AS3( shufpd xmm2, xmm6, 2) // 12,9,6,3 + + // output keystream + AS_XMM_OUTPUT4(SSE2_Salsa_Output_B, REG_input, REG_output, 4, 0, 1, 2, 3, 0, 1, 2, 3, 4) + ASJ( jmp, 5, b) + ASL(4) + + AS_POP_IF86( bp) +#ifdef __GNUC__ + AS_POP_IF86( bx) + ATT_PREFIX + #if CRYPTOPP_BOOL_X64 + : "+r" (input), "+r" (output), "+r" (iterationCount) + : "r" (m_rounds), "r" (m_state.begin()), "r" (workspace) + : "%eax", "%rdx", "memory", "cc", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15" + #else + : "+a" (input), "+D" (output), "+c" (iterationCount) + : "d" (m_rounds), "S" (m_state.begin()) + : "memory", "cc" + #endif + ); +#endif +#ifdef CRYPTOPP_GENERATE_X64_MASM + movdqa xmm6, [rsp + 0200h] + movdqa xmm7, [rsp + 0210h] + movdqa xmm8, [rsp + 0220h] + movdqa xmm9, [rsp + 0230h] + movdqa xmm10, [rsp + 0240h] + movdqa xmm11, [rsp + 0250h] + movdqa xmm12, [rsp + 0260h] + movdqa xmm13, [rsp + 0270h] + movdqa xmm14, [rsp + 0280h] + movdqa xmm15, [rsp + 0290h] + add rsp, 10*16 + 32*16 + 8 + ret +Salsa20_OperateKeystream ENDP +#else + } + else +#endif +#endif +#ifndef CRYPTOPP_GENERATE_X64_MASM + { + word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + while (iterationCount--) + { + x0 = m_state[0]; x1 = m_state[1]; x2 = m_state[2]; x3 = m_state[3]; + x4 = m_state[4]; x5 = m_state[5]; x6 = m_state[6]; x7 = m_state[7]; + x8 = m_state[8]; x9 = m_state[9]; x10 = m_state[10]; x11 = m_state[11]; + x12 = m_state[12]; x13 = m_state[13]; x14 = m_state[14]; x15 = m_state[15]; + + for (int i=m_rounds; i>0; i-=2) + { + #define QUARTER_ROUND(a, b, c, d) \ + b = b ^ rotlConstant<7>(a + d); \ + c = c ^ rotlConstant<9>(b + a); \ + d = d ^ rotlConstant<13>(c + b); \ + a = a ^ rotlConstant<18>(d + c); + + QUARTER_ROUND(x0, x4, x8, x12) + QUARTER_ROUND(x1, x5, x9, x13) + QUARTER_ROUND(x2, x6, x10, x14) + QUARTER_ROUND(x3, x7, x11, x15) + + QUARTER_ROUND(x0, x13, x10, x7) + QUARTER_ROUND(x1, x14, x11, x4) + QUARTER_ROUND(x2, x15, x8, x5) + QUARTER_ROUND(x3, x12, x9, x6) + } + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + #define SALSA_OUTPUT(x) {\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + m_state[0]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x13 + m_state[13]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x10 + m_state[10]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x7 + m_state[7]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + m_state[4]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x1 + m_state[1]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x14 + m_state[14]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x11 + m_state[11]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + m_state[8]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x5 + m_state[5]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x2 + m_state[2]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x15 + m_state[15]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + m_state[12]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x9 + m_state[9]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x6 + m_state[6]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x3 + m_state[3]);} + + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SALSA_OUTPUT, BYTES_PER_ITERATION); + #undef SALSA_OUTPUT +#endif + + if (++m_state[8] == 0) + ++m_state[5]; + } + } +} // see comment above if an internal compiler error occurs here + +void XSalsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + m_rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds); + if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20)) + throw InvalidRounds(XSalsa20::StaticAlgorithmName(), m_rounds); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_key.begin(), m_key.size(), key, length); + if (length == 16) + memcpy(m_key.begin()+4, m_key.begin(), 16); + + // "expand 32-byte k" + m_state[0] = 0x61707865; + m_state[1] = 0x3320646e; + m_state[2] = 0x79622d32; + m_state[3] = 0x6b206574; +} + +void XSalsa20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==24); + + word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + GetBlock get(IV); + get(x14)(x11)(x8)(x5)(m_state[14])(m_state[11]); + + x13 = m_key[0]; x10 = m_key[1]; x7 = m_key[2]; x4 = m_key[3]; + x15 = m_key[4]; x12 = m_key[5]; x9 = m_key[6]; x6 = m_key[7]; + x0 = m_state[0]; x1 = m_state[1]; x2 = m_state[2]; x3 = m_state[3]; + + for (int i=m_rounds; i>0; i-=2) + { + QUARTER_ROUND(x0, x4, x8, x12) + QUARTER_ROUND(x1, x5, x9, x13) + QUARTER_ROUND(x2, x6, x10, x14) + QUARTER_ROUND(x3, x7, x11, x15) + + QUARTER_ROUND(x0, x13, x10, x7) + QUARTER_ROUND(x1, x14, x11, x4) + QUARTER_ROUND(x2, x15, x8, x5) + QUARTER_ROUND(x3, x12, x9, x6) + } + + m_state[13] = x0; m_state[10] = x1; m_state[7] = x2; m_state[4] = x3; + m_state[15] = x14; m_state[12] = x11; m_state[9] = x8; m_state[6] = x5; + m_state[8] = m_state[5] = 0; +} + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM diff --git a/external/ours/library/crypto/src/shared/original/salsa.h b/external/ours/library/crypto/src/shared/original/salsa.h new file mode 100755 index 000000000..1468d8c1c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/salsa.h @@ -0,0 +1,104 @@ +// salsa.h - originally written and placed in the public domain by Wei Dai + +/// \file salsa.h +/// \brief Classes for Salsa and Salsa20 stream ciphers + +#ifndef CRYPTOPP_SALSA_H +#define CRYPTOPP_SALSA_H + +#include "strciphr.h" +#include "secblock.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_SALSA_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Salsa20 core transform +/// \param data the data to transform +/// \param rounds the number of rounds +/// \details Several algorithms, like CryptoBox and Scrypt, require access to +/// the core Salsa20 transform. The current Crypto++ implementation does not +/// lend itself to disgorging the Salsa20 cipher from the Salsa20 core transform. +/// Instead Salsa20_Core is provided with customary accelerations. +void Salsa20_Core(word32* data, unsigned int rounds); + +/// \brief Salsa20 stream cipher information +/// \since Crypto++ 5.4 +struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8> +{ + static std::string StaticAlgorithmName() {return "Salsa20";} +}; + +/// \brief Salsa20 stream cipher operation +/// \since Crypto++ 5.4 +class CRYPTOPP_NO_VTABLE Salsa20_Policy : public AdditiveCipherConcretePolicy +{ +protected: + Salsa20_Policy() : m_rounds(ROUNDS) {} + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + bool CipherIsRandomAccess() const {return true;} + void SeekToIteration(lword iterationCount); + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; +#endif + + std::string AlgorithmProvider() const; + + CRYPTOPP_CONSTANT(ROUNDS = 20); // Default rounds + FixedSizeAlignedSecBlock m_state; + int m_rounds; +}; + +/// \brief Salsa20 stream cipher +/// \details Salsa20 provides a variable number of rounds: 8, 12 or 20. The default number of rounds is 20. +/// \sa The Salsa20 +/// family of stream ciphers (20071225), +/// Snuffle 2005: the Salsa20 encryption +/// function and Salsa20 +/// \since Crypto++ 5.4 +struct Salsa20 : public Salsa20_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, Salsa20_Info> Encryption; + typedef Encryption Decryption; +}; + +/// \brief XSalsa20 stream cipher information +/// \since Crypto++ 5.4 +struct XSalsa20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24> +{ + static std::string StaticAlgorithmName() {return "XSalsa20";} +}; + +/// \brief XSalsa20 stream cipher operation +/// \since Crypto++ 5.4 +class CRYPTOPP_NO_VTABLE XSalsa20_Policy : public Salsa20_Policy +{ +public: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + +protected: + FixedSizeSecBlock m_key; +}; + +/// \brief XSalsa20 stream cipher +/// \details XSalsa20 provides a variable number of rounds: 8, 12 or 20. The default number of rounds is 20. +/// \sa XSalsa20 +/// \since Crypto++ 5.4 +struct XSalsa20 : public XSalsa20_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, XSalsa20_Info> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/scrypt.cpp b/external/ours/library/crypto/src/shared/original/scrypt.cpp new file mode 100755 index 000000000..3b995813f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/scrypt.cpp @@ -0,0 +1,329 @@ +// scrypt.cpp - written and placed in public domain by Jeffrey Walton. +// Based on reference source code by Colin Percival for +// Scrypt and Daniel Bernstein for Salsa20 core. + +#include "pch.h" + +#include "scrypt.h" +#include "algparam.h" +#include "argnames.h" +#include "pwdbased.h" +#include "stdcpp.h" +#include "salsa.h" +#include "misc.h" +#include "sha.h" + +#include +#include + +#ifdef _OPENMP +# include +#endif + +// https://github.com/weidai11/cryptopp/issues/777 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# if defined(__clang__) +# pragma GCC diagnostic ignored "-Wtautological-compare" +# elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wtype-limits" +# endif +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::GetWord; +using CryptoPP::PutWord; +using CryptoPP::Salsa20_Core; +using CryptoPP::rotlConstant; +using CryptoPP::LITTLE_ENDIAN_ORDER; +using CryptoPP::AlignedSecByteBlock; + +inline void LE32ENC(byte* out, word32 in) +{ + PutWord(false, LITTLE_ENDIAN_ORDER, out, in); +} + +inline word32 LE32DEC(const byte* in) +{ + return GetWord(false, LITTLE_ENDIAN_ORDER, in); +} + +inline word64 LE64DEC(const byte* in) +{ + return GetWord(false, LITTLE_ENDIAN_ORDER, in); +} + +inline void BlockCopy(byte* dest, byte* src, size_t len) +{ +// OpenMP 4.0 released July 2013. +#if _OPENMP >= 201307 + #pragma omp simd + for (size_t i = 0; i < len; ++i) + dest[i] = src[i]; +#else + for (size_t i = 0; i < len; ++i) + dest[i] = src[i]; +#endif +} + +inline void BlockXOR(byte* dest, byte* src, size_t len) +{ +// OpenMP 4.0 released July 2013. +#if _OPENMP >= 201307 + #pragma omp simd + for (size_t i = 0; i < len; ++i) + dest[i] ^= src[i]; +#else + for (size_t i = 0; i < len; ++i) + dest[i] ^= src[i]; +#endif +} + +inline void PBKDF2_SHA256(byte* buf, size_t dkLen, + const byte* passwd, size_t passwdlen, + const byte* salt, size_t saltlen, byte count) +{ + using CryptoPP::SHA256; + using CryptoPP::PKCS5_PBKDF2_HMAC; + + PKCS5_PBKDF2_HMAC pbkdf; + pbkdf.DeriveKey(buf, dkLen, 0, passwd, passwdlen, salt, saltlen, count, 0.0f); +} + +inline void Salsa20_8(byte B[64]) +{ + word32 B32[16]; + + for (size_t i = 0; i < 16; ++i) + B32[i] = LE32DEC(&B[i * 4]); + + Salsa20_Core(B32, 8); + + for (size_t i = 0; i < 16; ++i) + LE32ENC(&B[4 * i], B32[i]); +} + +inline void BlockMix(byte* B, byte* Y, size_t r) +{ + byte X[64]; + + // 1: X <-- B_{2r - 1} + BlockCopy(X, &B[(2 * r - 1) * 64], 64); + + // 2: for i = 0 to 2r - 1 do + for (size_t i = 0; i < 2 * r; ++i) + { + // 3: X <-- H(X \xor B_i) + BlockXOR(X, &B[i * 64], 64); + Salsa20_8(X); + + // 4: Y_i <-- X + BlockCopy(&Y[i * 64], X, 64); + } + + // 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) + for (size_t i = 0; i < r; ++i) + BlockCopy(&B[i * 64], &Y[(i * 2) * 64], 64); + + for (size_t i = 0; i < r; ++i) + BlockCopy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64); +} + +inline word64 Integerify(byte* B, size_t r) +{ + byte* X = &B[(2 * r - 1) * 64]; + return LE64DEC(X); +} + +inline void Smix(byte* B, size_t r, word64 N, byte* V, byte* XY) +{ + byte* X = XY; + byte* Y = XY+128*r; + + // 1: X <-- B + BlockCopy(X, B, 128 * r); + + // 2: for i = 0 to N - 1 do + for (word64 i = 0; i < N; ++i) + { + // 3: V_i <-- X + BlockCopy(&V[i * (128 * r)], X, 128 * r); + + // 4: X <-- H(X) + BlockMix(X, Y, r); + } + + // 6: for i = 0 to N - 1 do + for (word64 i = 0; i < N; ++i) + { + // 7: j <-- Integerify(X) mod N + word64 j = Integerify(X, r) & (N - 1); + + // 8: X <-- H(X \xor V_j) + BlockXOR(X, &V[j * (128 * r)], 128 * r); + BlockMix(X, Y, r); + } + + // 10: B' <-- X + BlockCopy(B, X, 128 * r); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +size_t Scrypt::GetValidDerivedLength(size_t keylength) const +{ + if (keylength > MaxDerivedKeyLength()) + return MaxDerivedKeyLength(); + return keylength; +} + +void Scrypt::ValidateParameters(size_t derivedLen, word64 cost, word64 blockSize, word64 parallelization) const +{ + // https://github.com/weidai11/cryptopp/issues/842 + CRYPTOPP_ASSERT(derivedLen != 0); + CRYPTOPP_ASSERT(cost != 0); + CRYPTOPP_ASSERT(blockSize != 0); + CRYPTOPP_ASSERT(parallelization != 0); + + if (cost == 0) + throw InvalidArgument("Scrypt: cost cannot be 0"); + + if (blockSize == 0) + throw InvalidArgument("Scrypt: block size cannot be 0"); + + if (parallelization == 0) + throw InvalidArgument("Scrypt: parallelization cannot be 0"); + + // Optimizer should remove this on 32-bit platforms + if (std::numeric_limits::max() > std::numeric_limits::max()) + { + const word64 maxLen = ((static_cast(1) << 32) - 1) * 32; + if (derivedLen > maxLen) { + std::ostringstream oss; + oss << "derivedLen " << derivedLen << " is larger than " << maxLen; + throw InvalidArgument("Scrypt: " + oss.str()); + } + } + + // https://github.com/weidai11/cryptopp/issues/787 + CRYPTOPP_ASSERT(parallelization <= static_cast(std::numeric_limits::max())); + if (parallelization > static_cast(std::numeric_limits::max())) + { + std::ostringstream oss; + oss << " parallelization " << parallelization << " is larger than "; + oss << std::numeric_limits::max(); + throw InvalidArgument("Scrypt: " + oss.str()); + } + + CRYPTOPP_ASSERT(IsPowerOf2(cost)); + if (IsPowerOf2(cost) == false) + throw InvalidArgument("Scrypt: cost must be a power of 2"); + + const word64 prod = static_cast(blockSize) * parallelization; + CRYPTOPP_ASSERT(prod < (1U << 30)); + + if (prod >= (1U << 30)) { + std::ostringstream oss; + oss << "r*p " << prod << " is larger than " << (1U << 30); + throw InvalidArgument("Scrypt: " + oss.str()); + } + + // Scrypt has several tests that effectively verify allocations like + // '128 * r * N' and '128 * r * p' do not overflow. They are the tests + // that set errno to ENOMEM. We can make the logic a little more clear + // using word128. At first blush the word128 may seem like overkill. + // However, this alogirthm is dominated by slow moving parts, so a + // one-time check is insignificant in the bigger picture. +#if defined(CRYPTOPP_WORD128_AVAILABLE) + const word128 maxElems = static_cast(SIZE_MAX); + bool bLimit = (maxElems >= static_cast(cost) * blockSize * 128U); + bool xyLimit = (maxElems >= static_cast(parallelization) * blockSize * 128U); + bool vLimit = (maxElems >= static_cast(blockSize) * 256U + 64U); +#else + const word64 maxElems = static_cast(SIZE_MAX); + bool bLimit = (blockSize < maxElems / 128U / cost); + bool xyLimit = (blockSize < maxElems / 128U / parallelization); + bool vLimit = (blockSize < (maxElems - 64U) / 256U); +#endif + + CRYPTOPP_ASSERT(bLimit); CRYPTOPP_ASSERT(xyLimit); CRYPTOPP_ASSERT(vLimit); + if (!bLimit || !xyLimit || !vLimit) + throw std::bad_alloc(); +} + +size_t Scrypt::DeriveKey(byte*derived, size_t derivedLen, + const byte*secret, size_t secretLen, const NameValuePairs& params) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + word64 cost=0, blockSize=0, parallelization=0; + if(params.GetValue("Cost", cost) == false) + cost = defaultCost; + + if(params.GetValue("BlockSize", blockSize) == false) + blockSize = defaultBlockSize; + + if(params.GetValue("Parallelization", parallelization) == false) + parallelization = defaultParallelization; + + ConstByteArrayParameter salt; + (void)params.GetValue("Salt", salt); + + return DeriveKey(derived, derivedLen, secret, secretLen, salt.begin(), salt.size(), cost, blockSize, parallelization); +} + +size_t Scrypt::DeriveKey(byte*derived, size_t derivedLen, const byte*secret, size_t secretLen, + const byte*salt, size_t saltLen, word64 cost, word64 blockSize, word64 parallel) const +{ + CRYPTOPP_ASSERT(secret /*&& secretLen*/); + CRYPTOPP_ASSERT(derived && derivedLen); + CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); + + ThrowIfInvalidDerivedKeyLength(derivedLen); + ValidateParameters(derivedLen, cost, blockSize, parallel); + + AlignedSecByteBlock B(static_cast(blockSize * parallel * 128U)); + + // 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) + PBKDF2_SHA256(B, B.size(), secret, secretLen, salt, saltLen, 1); + + // Visual Studio and OpenMP 2.0 fixup. We must use int, not size_t. + int maxParallel=0; + if (!SafeConvert(parallel, maxParallel)) + maxParallel = std::numeric_limits::max(); + + #ifdef _OPENMP + int threads = STDMIN(omp_get_max_threads(), maxParallel); + #endif + + // http://stackoverflow.com/q/49604260/608639 + #pragma omp parallel num_threads(threads) + { + // Each thread gets its own copy + AlignedSecByteBlock XY(static_cast(blockSize * 256U)); + AlignedSecByteBlock V(static_cast(blockSize * cost * 128U)); + + // 2: for i = 0 to p - 1 do + #pragma omp for + for (int i = 0; i < maxParallel; ++i) + { + // 3: B_i <-- MF(B_i, N) + const ptrdiff_t offset = static_cast(blockSize*i*128); + Smix(B+offset, static_cast(blockSize), cost, V, XY); + } + } + + // 5: DK <-- PBKDF2(P, B, 1, dkLen) + PBKDF2_SHA256(derived, derivedLen, secret, secretLen, B, B.size(), 1); + + return 1; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/scrypt.h b/external/ours/library/crypto/src/shared/original/scrypt.h new file mode 100755 index 000000000..924c1f187 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/scrypt.h @@ -0,0 +1,103 @@ +// scrypt.h - written and placed in public domain by Jeffrey Walton. +// Based on reference source code by Colin Percival. + +/// \file scrypt.h +/// \brief Classes for Scrypt from RFC 7914 +/// \sa Stronger Key Derivation via +/// Sequential Memory-Hard Functions, +/// The scrypt key derivation function +/// and RFC 7914, The scrypt Password-Based +/// Key Derivation Function +/// \since Crypto++ 7.0 + +#ifndef CRYPTOPP_SCRYPT_H +#define CRYPTOPP_SCRYPT_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Scrypt key derivation function +/// \details The Crypto++ implementation uses OpenMP to accelerate the derivation when +/// available. +/// \details The Crypto++ implementation of Scrypt is limited by C++ datatypes. For +/// example, the library is limited to a derived key length of SIZE_MAX, +/// and not (2^32 - 1) * 32. +/// \sa Stronger Key Derivation via +/// Sequential Memory-Hard Functions, +/// The scrypt key derivation function +/// and RFC 7914, The scrypt Password-Based +/// Key Derivation Function +/// \since Crypto++ 7.0 +class Scrypt : public KeyDerivationFunction +{ +public: + virtual ~Scrypt() {} + + static std::string StaticAlgorithmName () { + return "scrypt"; + } + + // KeyDerivationFunction interface + std::string AlgorithmName() const { + return StaticAlgorithmName(); + } + + // KeyDerivationFunction interface + size_t MaxDerivedKeyLength() const { + return static_cast(0)-1; + } + + // KeyDerivationFunction interface + size_t GetValidDerivedLength(size_t keylength) const; + + // KeyDerivationFunction interface + size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const NameValuePairs& params) const; + + /// \brief Derive a key from a seed + /// \param derived the derived output buffer + /// \param derivedLen the size of the derived buffer, in bytes + /// \param secret the seed input buffer + /// \param secretLen the size of the secret buffer, in bytes + /// \param salt the salt input buffer + /// \param saltLen the size of the salt buffer, in bytes + /// \param cost the CPU/memory cost factor + /// \param blockSize the block size + /// \param parallelization the parallelization factor + /// \return the number of iterations performed + /// \throw InvalidDerivedKeyLength if derivedLen is invalid for the scheme + /// \details DeriveKey() provides a standard interface to derive a key from + /// a seed and other parameters. Each class that derives from KeyDerivationFunction + /// provides an overload that accepts most parameters used by the derivation function. + /// \details The CPU/Memory cost parameter ("N" in the documents) must be + /// larger than 1, a power of 2, and less than 2^(128 * r / 8). + /// \details The parameter blockSize ("r" in the documents) specifies the block + /// size. + /// \details The parallelization parameter ("p" in the documents) is a positive + /// integer less than or equal to ((2^32-1) * 32) / (128 * r). Due to Microsoft + /// and its OpenMP 2.0 implementation parallelization is limited to + /// std::numeric_limits::max(). + /// \details Scrypt always returns 1 because it only performs 1 iteration. Other + /// derivation functions, like PBKDF's, will return more interesting values. + /// \details The Crypto++ implementation of Scrypt is limited by C++ datatypes. For + /// example, the library is limited to a derived key length of SIZE_MAX, + /// and not (2^32 - 1) * 32. + size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, + const byte *salt, size_t saltLen, word64 cost=2, word64 blockSize=8, word64 parallelization=1) const; + +protected: + enum {defaultCost=2, defaultBlockSize=8, defaultParallelization=1}; + + // KeyDerivationFunction interface + const Algorithm & GetAlgorithm() const { + return *this; + } + + inline void ValidateParameters(size_t derivedlen, word64 cost, word64 blockSize, word64 parallelization) const; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SCRYPT_H diff --git a/external/ours/library/crypto/src/shared/original/seal.cpp b/external/ours/library/crypto/src/shared/original/seal.cpp new file mode 100755 index 000000000..fea047e7d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/seal.cpp @@ -0,0 +1,222 @@ +// seal.cpp - originally written and placed in the public domain by Wei Dai +// updated to SEAL 3.0 by Leonard Janke + +#include "pch.h" + +#include "seal.h" +#include "cpu.h" +#include "sha.h" +#include "misc.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void SEAL_TestInstantiations() +{ + SEAL<>::Encryption x; +} +#endif + +struct SEAL_Gamma +{ + SEAL_Gamma(const byte *key) + : H(5), Z(5), D(16), lastIndex(0xffffffff) + { + GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20); + memset(D, 0, 64); + } + + word32 Apply(word32 i); + + SecBlock H, Z, D; + word32 lastIndex; +}; + +word32 SEAL_Gamma::Apply(word32 i) +{ + word32 shaIndex = i/5; + if (shaIndex != lastIndex) + { + memcpy(Z, H, 20); + D[0] = shaIndex; + SHA1::Transform(Z, D); + lastIndex = shaIndex; + } + + return Z[i%5]; +} + +template +void SEAL_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + CRYPTOPP_UNUSED(length); + m_insideCounter = m_outsideCounter = m_startCount = 0; + + unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024); + m_iterationsPerCount = L / 8192; + + SEAL_Gamma gamma(key); + unsigned int i; + + for (i=0; i<512; i++) + m_T[i] = gamma.Apply(i); + + for (i=0; i<256; i++) + m_S[i] = gamma.Apply(0x1000+i); + + m_R.New(4*(L/8192)); + + for (i=0; i +void SEAL_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(IV), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==4); + + m_outsideCounter = IV ? GetWord(false, BIG_ENDIAN_ORDER, IV) : 0; + m_startCount = m_outsideCounter; + m_insideCounter = 0; +} + +template +void SEAL_Policy::SeekToIteration(lword iterationCount) +{ + m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount); + m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount); +} + +template +void SEAL_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + word32 a, b, c, d, n1, n2, n3, n4; + unsigned int p, q; + + CRYPTOPP_ASSERT(IsAlignedOn(m_T.begin(),GetAlignmentOf())); + for (size_t iteration = 0; iteration < iterationCount; ++iteration) + { + #define Ttab(x) *(word32 *)(void*)((byte *)m_T.begin()+x) + + a = m_outsideCounter ^ m_R[4*m_insideCounter]; + b = rotrConstant<8>(m_outsideCounter) ^ m_R[4*m_insideCounter+1]; + c = rotrConstant<16>(m_outsideCounter) ^ m_R[4 * m_insideCounter + 2]; + d = rotrConstant<24>(m_outsideCounter) ^ m_R[4 * m_insideCounter + 3]; + + for (unsigned int j=0; j<2; j++) + { + p = a & 0x7fc; + b += Ttab(p); + a = rotrConstant<9>(a); + + p = b & 0x7fc; + c += Ttab(p); + b = rotrConstant<9>(b); + + p = c & 0x7fc; + d += Ttab(p); + c = rotrConstant<9>(c); + + p = d & 0x7fc; + a += Ttab(p); + d = rotrConstant<9>(d); + } + + n1 = d, n2 = b, n3 = a, n4 = c; + + p = a & 0x7fc; + b += Ttab(p); + a = rotrConstant<9>(a); + + p = b & 0x7fc; + c += Ttab(p); + b = rotrConstant<9>(b); + + p = c & 0x7fc; + d += Ttab(p); + c = rotrConstant<9>(c); + + p = d & 0x7fc; + a += Ttab(p); + d = rotrConstant<9>(d); + + // generate 8192 bits + for (unsigned int i=0; i<64; i++) + { + p = a & 0x7fc; + a = rotrConstant<9>(a); + b += Ttab(p); + b ^= a; + + q = b & 0x7fc; + b = rotrConstant<9>(b); + c ^= Ttab(q); + c += b; + + p = (p+c) & 0x7fc; + c = rotrConstant<9>(c); + d += Ttab(p); + d ^= c; + + q = (q+d) & 0x7fc; + d = rotrConstant<9>(d); + a ^= Ttab(q); + a += d; + + p = (p+a) & 0x7fc; + b ^= Ttab(p); + a = rotrConstant<9>(a); + + q = (q+b) & 0x7fc; + c += Ttab(q); + b = rotrConstant<9>(b); + + p = (p+c) & 0x7fc; + d ^= Ttab(p); + c = rotrConstant<9>(c); + + q = (q+d) & 0x7fc; + d = rotrConstant<9>(d); + a += Ttab(q); + +#define SEAL_OUTPUT(x) \ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]); + + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4); + + if (i & 1) + { + a += n3; + b += n4; + c ^= n3; + d ^= n4; + } + else + { + a += n1; + b += n2; + c ^= n1; + d ^= n2; + } + } + + if (++m_insideCounter == m_iterationsPerCount) + { + ++m_outsideCounter; + m_insideCounter = 0; + } + } + + a = b = c = d = n1 = n2 = n3 = n4 = 0; + p = q = 0; +} + +template class SEAL_Policy; +template class SEAL_Policy; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/seal.h b/external/ours/library/crypto/src/shared/original/seal.h new file mode 100755 index 000000000..d8826aecf --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/seal.h @@ -0,0 +1,59 @@ +// seal.h - originally written and placed in the public domain by Wei Dai + +/// \file seal.h +/// \brief Classes for SEAL stream cipher +/// \since Crypto++ 2.2 + +#ifndef CRYPTOPP_SEAL_H +#define CRYPTOPP_SEAL_H + +#include "strciphr.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SEAL stream cipher information +/// \tparam B Endianness of the stream cipher +/// \since Crypto++ 2.2 +template +struct SEAL_Info : public FixedKeyLength<20, SimpleKeyingInterface::INTERNALLY_GENERATED_IV, 4> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == LITTLE_ENDIAN_ORDER ? "SEAL-3.0-LE" : "SEAL-3.0-BE";} +}; + +/// \brief SEAL stream cipher operation +/// \tparam B Endianness of the stream cipher +/// \since Crypto++ 2.2 +template +class CRYPTOPP_NO_VTABLE SEAL_Policy : public AdditiveCipherConcretePolicy, public SEAL_Info +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + bool CipherIsRandomAccess() const {return true;} + void SeekToIteration(lword iterationCount); + +private: + FixedSizeSecBlock m_T; + FixedSizeSecBlock m_S; + SecBlock m_R; + + word32 m_startCount, m_iterationsPerCount; + word32 m_outsideCounter, m_insideCounter; +}; + +/// \brief SEAL stream cipher +/// \tparam B Endianness of the stream cipher +/// \sa SEAL +/// \since Crypto++ 2.2 +template +struct SEAL : public SEAL_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, SEAL_Info > Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/secblock.h b/external/ours/library/crypto/src/shared/original/secblock.h new file mode 100755 index 000000000..56b5be6d0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/secblock.h @@ -0,0 +1,1310 @@ +// secblock.h - originally written and placed in the public domain by Wei Dai + +/// \file secblock.h +/// \brief Classes and functions for secure memory allocations. + +#ifndef CRYPTOPP_SECBLOCK_H +#define CRYPTOPP_SECBLOCK_H + +#include "config.h" +#include "allocate.h" +#include "misc.h" +#include "stdcpp.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4231 4275 4700) +# if (CRYPTOPP_MSC_VERSION >= 1400) +# pragma warning(disable: 6011 6386 28193) +# endif +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// ************** secure memory allocation *************** + +/// \brief Base class for all allocators used by SecBlock +/// \tparam T the class or type +template +class AllocatorBase +{ +public: + typedef T value_type; + typedef size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T * pointer; + typedef const T * const_pointer; + typedef T & reference; + typedef const T & const_reference; + + pointer address(reference r) const {return (&r);} + const_pointer address(const_reference r) const {return (&r); } + void construct(pointer p, const T& val) {new (p) T(val);} + void destroy(pointer p) {CRYPTOPP_UNUSED(p); p->~T();} + + /// \brief Returns the maximum number of elements the allocator can provide + /// \details ELEMS_MAX is the maximum number of elements the + /// Allocator can provide. The value of ELEMS_MAX is + /// SIZE_MAX/sizeof(T). std::numeric_limits was avoided + /// due to lack of constexpr-ness in C++03 and below. + /// \note In C++03 and below ELEMS_MAX is a static data member of type + /// size_type. In C++11 and above ELEMS_MAX is an enum + /// inheriting from size_type. In both cases ELEMS_MAX can be + /// used before objects are fully constructed, and it does not suffer the + /// limitations of class methods like max_size. + /// \sa Issue 346/CVE-2016-9939 + /// \since Crypto++ 6.0 +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + static const size_type ELEMS_MAX = ...; +#elif defined(_MSC_VER) && (_MSC_VER <= 1400) + static const size_type ELEMS_MAX = (~(size_type)0)/sizeof(T); +#elif defined(CRYPTOPP_CXX11_STRONG_ENUM) + enum : size_type {ELEMS_MAX = SIZE_MAX/sizeof(T)}; +#else + static const size_type ELEMS_MAX = SIZE_MAX/sizeof(T); +#endif + + /// \brief Returns the maximum number of elements the allocator can provide + /// \return the maximum number of elements the allocator can provide + /// \details Internally, preprocessor macros are used rather than std::numeric_limits + /// because the latter is not a constexpr. Some compilers, like Clang, do not + /// optimize it well under all circumstances. Compilers like GCC, ICC and MSVC appear + /// to optimize it well in either form. + CRYPTOPP_CONSTEXPR size_type max_size() const {return ELEMS_MAX;} + +#if defined(__SUNPRO_CC) + // https://github.com/weidai11/cryptopp/issues/770 + // and https://stackoverflow.com/q/53999461/608639 + CRYPTOPP_CONSTEXPR size_type max_size(size_type n) const {return SIZE_MAX/n;} +#endif + +#if defined(CRYPTOPP_CXX11_VARIADIC_TEMPLATES) || defined(CRYPTOPP_DOXYGEN_PROCESSING) + + /// \brief Constructs a new V using variadic arguments + /// \tparam V the type to be forwarded + /// \tparam Args the arguments to be forwarded + /// \param ptr pointer to type V + /// \param args variadic arguments + /// \details This is a C++11 feature. It is available when CRYPTOPP_CXX11_VARIADIC_TEMPLATES + /// is defined. The define is controlled by compiler versions detected in config.h. + template + void construct(V* ptr, Args&&... args) {::new ((void*)ptr) V(std::forward(args)...);} + + /// \brief Destroys an V constructed with variadic arguments + /// \tparam V the type to be forwarded + /// \details This is a C++11 feature. It is available when CRYPTOPP_CXX11_VARIADIC_TEMPLATES + /// is defined. The define is controlled by compiler versions detected in config.h. + template + void destroy(V* ptr) {if (ptr) ptr->~V();} + +#endif + +protected: + + /// \brief Verifies the allocator can satisfy a request based on size + /// \param size the size of the allocation, in elements + /// \throw InvalidArgument + /// \details CheckSize verifies the number of elements requested is valid. + /// \details If size is greater than max_size(), then InvalidArgument is thrown. + /// The library throws InvalidArgument if the size is too large to satisfy. + /// \details Internally, preprocessor macros are used rather than std::numeric_limits + /// because the latter is not a constexpr. Some compilers, like Clang, do not + /// optimize it well under all circumstances. Compilers like GCC, ICC and MSVC appear + /// to optimize it well in either form. + /// \details The sizeof(T) != 1 in the condition attempts to help the + /// compiler optimize the check for byte types. Coverity findings for + /// CONSTANT_EXPRESSION_RESULT were generated without it. For byte types, + /// size never exceeded ELEMS_MAX but the code was not removed. + /// \note size is the count of elements, and not the number of bytes + static void CheckSize(size_t size) + { + // Squash MSC C4100 warning for size. Also see commit 42b7c4ea5673. + CRYPTOPP_UNUSED(size); + // C++ throws std::bad_alloc (C++03) or std::bad_array_new_length (C++11) here. + if (sizeof(T) != 1 && size > ELEMS_MAX) + throw InvalidArgument("AllocatorBase: requested size would cause integer overflow"); + } +}; + +#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T_type) \ + typedef typename AllocatorBase::value_type value_type;\ + typedef typename AllocatorBase::size_type size_type;\ + typedef typename AllocatorBase::difference_type difference_type;\ + typedef typename AllocatorBase::pointer pointer;\ + typedef typename AllocatorBase::const_pointer const_pointer;\ + typedef typename AllocatorBase::reference reference;\ + typedef typename AllocatorBase::const_reference const_reference; + +/// \brief Reallocation function +/// \tparam T the class or type +/// \tparam A the class or type's allocator +/// \param alloc the allocator +/// \param oldPtr the previous allocation +/// \param oldSize the size of the previous allocation +/// \param newSize the new, requested size +/// \param preserve flag that indicates if the old allocation should be preserved +/// \note oldSize and newSize are the count of elements, and not the +/// number of bytes. +template +typename A::pointer StandardReallocate(A& alloc, T *oldPtr, typename A::size_type oldSize, typename A::size_type newSize, bool preserve) +{ + // Avoid assert on pointer in reallocate. SecBlock regularly uses NULL + // pointers rather returning non-NULL 0-sized pointers. + if (oldSize == newSize) + return oldPtr; + + if (preserve) + { + typename A::pointer newPtr = alloc.allocate(newSize, NULLPTR); + const typename A::size_type copySize = STDMIN(oldSize, newSize) * sizeof(T); + + if (oldPtr && newPtr) + memcpy_s(newPtr, copySize, oldPtr, copySize); + + if (oldPtr) + alloc.deallocate(oldPtr, oldSize); + + return newPtr; + } + else + { + if (oldPtr) + alloc.deallocate(oldPtr, oldSize); + + return alloc.allocate(newSize, NULLPTR); + } +} + +/// \brief Allocates a block of memory with cleanup +/// \tparam T class or type +/// \tparam T_Align16 boolean that determines whether allocations should be aligned on a 16-byte boundary +/// \details If T_Align16 is true, then AllocatorWithCleanup calls AlignedAllocate() +/// for memory allocations. If T_Align16 is false, then AllocatorWithCleanup() calls +/// UnalignedAllocate() for memory allocations. +/// \details Template parameter T_Align16 is effectively controlled by cryptlib.h and mirrors +/// CRYPTOPP_BOOL_ALIGN16. CRYPTOPP_BOOL_ALIGN16 is often used as the template parameter. +template +class AllocatorWithCleanup : public AllocatorBase +{ +public: + CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T) + + /// \brief Allocates a block of memory + /// \param ptr the size of the allocation + /// \param size the size of the allocation, in elements + /// \return a memory block + /// \throw InvalidArgument + /// \details allocate() first checks the size of the request. If it is non-0 + /// and less than max_size(), then an attempt is made to fulfill the request + /// using either AlignedAllocate() or UnalignedAllocate(). AlignedAllocate() is + /// used if T_Align16 is true. UnalignedAllocate() used if T_Align16 is false. + /// \details This is the C++ *Placement New* operator. ptr is not used, and the + /// function asserts in Debug builds if ptr is non-NULL. + /// \sa CallNewHandler() for the methods used to recover from a failed + /// allocation attempt. + /// \note size is the count of elements, and not the number of bytes + pointer allocate(size_type size, const void *ptr = NULLPTR) + { + CRYPTOPP_UNUSED(ptr); CRYPTOPP_ASSERT(ptr == NULLPTR); + this->CheckSize(size); + if (size == 0) + return NULLPTR; + +#if CRYPTOPP_BOOL_ALIGN16 + if (T_Align16) + return reinterpret_cast(AlignedAllocate(size*sizeof(T))); +#endif + + return reinterpret_cast(UnalignedAllocate(size*sizeof(T))); + } + + /// \brief Deallocates a block of memory + /// \param ptr the pointer for the allocation + /// \param size the size of the allocation, in elements + /// \details Internally, SecureWipeArray() is called before deallocating the + /// memory. Once the memory block is wiped or zeroized, AlignedDeallocate() + /// or UnalignedDeallocate() is called. + /// \details AlignedDeallocate() is used if T_Align16 is true. + /// UnalignedDeallocate() used if T_Align16 is false. + void deallocate(void *ptr, size_type size) + { + // Avoid assert on pointer in deallocate. SecBlock regularly uses NULL + // pointers rather returning non-NULL 0-sized pointers. + if (ptr) + { + SecureWipeArray(reinterpret_cast(ptr), size); + +#if CRYPTOPP_BOOL_ALIGN16 + if (T_Align16) + return AlignedDeallocate(ptr); +#endif + + UnalignedDeallocate(ptr); + } + } + + /// \brief Reallocates a block of memory + /// \param oldPtr the previous allocation + /// \param oldSize the size of the previous allocation + /// \param newSize the new, requested size + /// \param preserve flag that indicates if the old allocation should be preserved + /// \return pointer to the new memory block + /// \details Internally, reallocate() calls StandardReallocate(). + /// \details If preserve is true, then index 0 is used to begin copying the + /// old memory block to the new one. If the block grows, then the old array + /// is copied in its entirety. If the block shrinks, then only newSize + /// elements are copied from the old block to the new one. + /// \note oldSize and newSize are the count of elements, and not the + /// number of bytes. + pointer reallocate(T *oldPtr, size_type oldSize, size_type newSize, bool preserve) + { + CRYPTOPP_ASSERT((oldPtr && oldSize) || !(oldPtr || oldSize)); + return StandardReallocate(*this, oldPtr, oldSize, newSize, preserve); + } + + /// \brief Template class member Rebind + /// \tparam V bound class or type + /// \details Rebind allows a container class to allocate a different type of object + /// to store elements. For example, a std::list will allocate std::list_node to + /// store elements in the list. + /// \details VS.NET STL enforces the policy of "All STL-compliant allocators + /// have to provide a template class member called rebind". + template struct rebind { typedef AllocatorWithCleanup other; }; +#if _MSC_VER >= 1500 + AllocatorWithCleanup() {} + template AllocatorWithCleanup(const AllocatorWithCleanup &) {} +#endif +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +#if defined(CRYPTOPP_WORD128_AVAILABLE) +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; // for Integer +#endif +#if CRYPTOPP_BOOL_X86 +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; // for Integer +#endif + +/// \brief NULL allocator +/// \tparam T class or type +/// \details A NullAllocator is useful for fixed-size, stack based allocations +/// (i.e., static arrays used by FixedSizeAllocatorWithCleanup). +/// \details A NullAllocator always returns 0 for max_size(), and always returns +/// NULL for allocation requests. Though the allocator does not allocate at +/// runtime, it does perform a secure wipe or zeroization during cleanup. +template +class NullAllocator : public AllocatorBase +{ +public: + //LCOV_EXCL_START + CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T) + + // TODO: should this return NULL or throw bad_alloc? Non-Windows C++ standard + // libraries always throw. And late mode Windows throws. Early model Windows + // (circa VC++ 6.0) returned NULL. + pointer allocate(size_type n, const void* unused = NULLPTR) + { + CRYPTOPP_UNUSED(n); CRYPTOPP_UNUSED(unused); + CRYPTOPP_ASSERT(false); return NULLPTR; + } + + void deallocate(void *p, size_type n) + { + CRYPTOPP_UNUSED(p); CRYPTOPP_UNUSED(n); + CRYPTOPP_ASSERT(false); + } + + CRYPTOPP_CONSTEXPR size_type max_size() const {return 0;} + //LCOV_EXCL_STOP +}; + +/// \brief Static secure memory block with cleanup +/// \tparam T class or type +/// \tparam S fixed-size of the stack-based memory block, in elements +/// \tparam T_Align16 boolean that determines whether allocations should +/// be aligned on a 16-byte boundary +/// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- +/// based allocation at compile time. The class can grow its memory +/// block at runtime if a suitable allocator is available. If size +/// grows beyond S and a suitable allocator is available, then the +/// statically allocated array is obsoleted. +/// \note This allocator can't be used with standard collections because +/// they require that all objects of the same allocator type are equivalent. +template , bool T_Align16 = false> +class FixedSizeAllocatorWithCleanup : public AllocatorBase +{ + // The body of FixedSizeAllocatorWithCleanup is provided in the two + // partial specializations that follow. The two specializations + // pivot on the boolean template parameter T_Align16. +}; + +/// \brief Static secure memory block with cleanup +/// \tparam T class or type +/// \tparam S fixed-size of the stack-based memory block, in elements +/// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- +/// based allocation at compile time. The class can grow its memory +/// block at runtime if a suitable allocator is available. If size +/// grows beyond S and a suitable allocator is available, then the +/// statically allocated array is obsoleted. +/// \note This allocator can't be used with standard collections because +/// they require that all objects of the same allocator type are equivalent. +template +class FixedSizeAllocatorWithCleanup : public AllocatorBase +{ +public: + CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T) + + /// \brief Constructs a FixedSizeAllocatorWithCleanup + FixedSizeAllocatorWithCleanup() : m_allocated(false) {} + + /// \brief Allocates a block of memory + /// \param size the count elements in the memory block + /// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack-based + /// allocation at compile time. If size is less than or equal to + /// S, then a pointer to the static array is returned. + /// \details The class can grow its memory block at runtime if a suitable + /// allocator is available. If size grows beyond S and a suitable + /// allocator is available, then the statically allocated array is + /// obsoleted. If a suitable allocator is not available, as with a + /// NullAllocator, then the function returns NULL and a runtime error + /// eventually occurs. + /// \sa reallocate(), SecBlockWithHint + pointer allocate(size_type size) + { + CRYPTOPP_ASSERT(IsAlignedOn(m_array, 8)); + + if (size <= S && !m_allocated) + { + m_allocated = true; + return GetAlignedArray(); + } + else + return m_fallbackAllocator.allocate(size); + } + + /// \brief Allocates a block of memory + /// \param size the count elements in the memory block + /// \param hint an unused hint + /// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- + /// based allocation at compile time. If size is less than or equal to + /// S, then a pointer to the static array is returned. + /// \details The class can grow its memory block at runtime if a suitable + /// allocator is available. If size grows beyond S and a suitable + /// allocator is available, then the statically allocated array is + /// obsoleted. If a suitable allocator is not available, as with a + /// NullAllocator, then the function returns NULL and a runtime error + /// eventually occurs. + /// \sa reallocate(), SecBlockWithHint + pointer allocate(size_type size, const void *hint) + { + CRYPTOPP_ASSERT(IsAlignedOn(m_array, 8)); + + if (size <= S && !m_allocated) + { + m_allocated = true; + return GetAlignedArray(); + } + else + return m_fallbackAllocator.allocate(size, hint); + } + + /// \brief Deallocates a block of memory + /// \param ptr a pointer to the memory block to deallocate + /// \param size the count elements in the memory block + /// \details The memory block is wiped or zeroized before deallocation. + /// If the statically allocated memory block is active, then no + /// additional actions are taken after the wipe. + /// \details If a dynamic memory block is active, then the pointer and + /// size are passed to the allocator for deallocation. + void deallocate(void *ptr, size_type size) + { + // Avoid assert on pointer in deallocate. SecBlock regularly uses NULL + // pointers rather returning non-NULL 0-sized pointers. + if (ptr == GetAlignedArray()) + { + // If the m_allocated assert fires then the bit twiddling for + // GetAlignedArray() is probably incorrect for the platform. + // Be sure to check CRYPTOPP_ALIGN_DATA(8). The platform may + // not have a way to declaratively align data to 8. + CRYPTOPP_ASSERT(size <= S); + CRYPTOPP_ASSERT(m_allocated); + m_allocated = false; + SecureWipeArray(reinterpret_cast(ptr), size); + } + else + { + if (ptr) + m_fallbackAllocator.deallocate(ptr, size); + } + } + + /// \brief Reallocates a block of memory + /// \param oldPtr the previous allocation + /// \param oldSize the size of the previous allocation + /// \param newSize the new, requested size + /// \param preserve flag that indicates if the old allocation should + /// be preserved + /// \return pointer to the new memory block + /// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- + /// based allocation at compile time. If size is less than or equal to + /// S, then a pointer to the static array is returned. + /// \details The class can grow its memory block at runtime if a suitable + /// allocator is available. If size grows beyond S and a suitable + /// allocator is available, then the statically allocated array is + /// obsoleted. If a suitable allocator is not available, as with a + /// NullAllocator, then the function returns NULL and a runtime error + /// eventually occurs. + /// \note size is the count of elements, and not the number of bytes. + /// \sa reallocate(), SecBlockWithHint + pointer reallocate(pointer oldPtr, size_type oldSize, size_type newSize, bool preserve) + { + if (oldPtr == GetAlignedArray() && newSize <= S) + { + CRYPTOPP_ASSERT(oldSize <= S); + if (oldSize > newSize) + SecureWipeArray(oldPtr+newSize, oldSize-newSize); + return oldPtr; + } + + pointer newPtr = allocate(newSize, NULLPTR); + if (preserve && newSize) + { + const size_type copySize = STDMIN(oldSize, newSize); + if (newPtr && oldPtr) // GCC analyzer warning + memcpy_s(newPtr, sizeof(T)*newSize, oldPtr, sizeof(T)*copySize); + } + deallocate(oldPtr, oldSize); + return newPtr; + } + + CRYPTOPP_CONSTEXPR size_type max_size() const + { + return STDMAX(m_fallbackAllocator.max_size(), S); + } + +private: + +#if CRYPTOPP_BOOL_ALIGN16 + + // There be demons here... We cannot use CRYPTOPP_ALIGN_DATA(16) + // because linkers on 32-bit machines and some 64-bit machines + // align the stack to 8-bytes or less, and not 16-bytes as + // requested. We can only count on a smaller alignment. All + // toolchains tested appear to honor CRYPTOPP_ALIGN_DATA(8). Also + // see http://stackoverflow.com/a/1468656/608639. + // + // The 16-byte alignment is achieved by padding the requested + // size with extra elements so we have at least 8-bytes of slack + // to work with. Then the array pointer is moved to achieve a + // 16-byte alignment. + // + // The additional 8-bytes introduces a small secondary issue. + // The secondary issue is, a large T results in 0 = 8/sizeof(T). + // The library is OK but users may hit it. So we need to guard + // for a large T, and that is what the enum and PAD achieves. + T* GetAlignedArray() { + + // m_array is aligned on 8 byte boundaries due to + // CRYPTOPP_ALIGN_DATA(8). If m_array%16 is 0, then the buffer + // is 16-byte aligned and nothing needs to be done. if + // m_array%16 is 8, then the buffer is not 16-byte aligned and + // we need to add 8. 8 has that nice symmetric property. + // + // If we needed to use CRYPTOPP_ALIGN_DATA(4) due to toolchain + // limitations, then the calculation would be slightly more + // costly: ptr = m_array + (16 - (m_array % 16)) % 16; + CRYPTOPP_ASSERT(IsAlignedOn(m_array, 8)); + int off = reinterpret_cast(m_array) % 16; + byte* ptr = reinterpret_cast(m_array) + off; + + // Verify the 16-byte alignment. This is the point + // of these extra gyrations. + CRYPTOPP_ASSERT(IsAlignedOn(ptr, 16)); + // Verify the lower bound. This is Issue 982/988. + CRYPTOPP_ASSERT( + reinterpret_cast(ptr) >= + reinterpret_cast(m_array) + ); + // Verify the upper bound. Allocated array with + // pad is large enough. + CRYPTOPP_ASSERT( + reinterpret_cast(ptr+S*sizeof(T)) <= + reinterpret_cast(m_array+(S+PAD)) + ); + + // void* to silence Clang warnings + return reinterpret_cast( + static_cast(ptr) + ); + } + + // PAD is elements, not bytes, and rounded up to ensure no overflow. + enum { Q = sizeof(T), PAD = (Q >= 8) ? 1 : (Q >= 4) ? 2 : (Q >= 2) ? 4 : 8 }; + // enum { Q = sizeof(T), PAD = (Q >= 16) ? 1 : (Q >= 8) ? 2 : (Q >= 4) ? 4 : (Q >= 2) ? 8 : 16 }; + CRYPTOPP_ALIGN_DATA(8) T m_array[S+PAD]; + +#else + + // CRYPTOPP_BOOL_ALIGN16 is 0. If we are here then the user + // probably compiled with CRYPTOPP_DISABLE_ASM. Normally we + // would use the natural alignment of T. The problem we are + // having is, some toolchains are changing the boundary for + // 64-bit arrays. 64-bit elements require 8-byte alignment, + // but the toolchain is laying the array out on a 4 byte + // boundary. See GH #992 for mystery alignment, + // https://github.com/weidai11/cryptopp/issues/992 + T* GetAlignedArray() {return m_array;} + CRYPTOPP_ALIGN_DATA(8) T m_array[S]; + +#endif + + A m_fallbackAllocator; + bool m_allocated; +}; + +/// \brief Static secure memory block with cleanup +/// \tparam T class or type +/// \tparam S fixed-size of the stack-based memory block, in elements +/// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- +/// based allocation at compile time. The class can grow its memory +/// block at runtime if a suitable allocator is available. If size +/// grows beyond S and a suitable allocator is available, then the +/// statically allocated array is obsoleted. +/// \note This allocator can't be used with standard collections because +/// they require that all objects of the same allocator type are equivalent. +template +class FixedSizeAllocatorWithCleanup : public AllocatorBase +{ +public: + CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T) + + /// \brief Constructs a FixedSizeAllocatorWithCleanup + FixedSizeAllocatorWithCleanup() : m_allocated(false) {} + + /// \brief Allocates a block of memory + /// \param size the count elements in the memory block + /// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack-based + /// allocation at compile time. If size is less than or equal to + /// S, then a pointer to the static array is returned. + /// \details The class can grow its memory block at runtime if a suitable + /// allocator is available. If size grows beyond S and a suitable + /// allocator is available, then the statically allocated array is + /// obsoleted. If a suitable allocator is not available, as with a + /// NullAllocator, then the function returns NULL and a runtime error + /// eventually occurs. + /// \sa reallocate(), SecBlockWithHint + pointer allocate(size_type size) + { + CRYPTOPP_ASSERT(IsAlignedOn(m_array, 8)); + + if (size <= S && !m_allocated) + { + m_allocated = true; + return GetAlignedArray(); + } + else + return m_fallbackAllocator.allocate(size); + } + + /// \brief Allocates a block of memory + /// \param size the count elements in the memory block + /// \param hint an unused hint + /// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- + /// based allocation at compile time. If size is less than or equal to + /// S, then a pointer to the static array is returned. + /// \details The class can grow its memory block at runtime if a suitable + /// allocator is available. If size grows beyond S and a suitable + /// allocator is available, then the statically allocated array is + /// obsoleted. If a suitable allocator is not available, as with a + /// NullAllocator, then the function returns NULL and a runtime error + /// eventually occurs. + /// \sa reallocate(), SecBlockWithHint + pointer allocate(size_type size, const void *hint) + { + if (size <= S && !m_allocated) + { + m_allocated = true; + return GetAlignedArray(); + } + else + return m_fallbackAllocator.allocate(size, hint); + } + + /// \brief Deallocates a block of memory + /// \param ptr a pointer to the memory block to deallocate + /// \param size the count elements in the memory block + /// \details The memory block is wiped or zeroized before deallocation. + /// If the statically allocated memory block is active, then no + /// additional actions are taken after the wipe. + /// \details If a dynamic memory block is active, then the pointer and + /// size are passed to the allocator for deallocation. + void deallocate(void *ptr, size_type size) + { + // Avoid assert on pointer in deallocate. SecBlock regularly uses NULL + // pointers rather returning non-NULL 0-sized pointers. + if (ptr == GetAlignedArray()) + { + // If the m_allocated assert fires then + // something overwrote the flag. + CRYPTOPP_ASSERT(size <= S); + CRYPTOPP_ASSERT(m_allocated); + m_allocated = false; + SecureWipeArray((pointer)ptr, size); + } + else + { + if (ptr) + m_fallbackAllocator.deallocate(ptr, size); + m_allocated = false; + } + } + + /// \brief Reallocates a block of memory + /// \param oldPtr the previous allocation + /// \param oldSize the size of the previous allocation + /// \param newSize the new, requested size + /// \param preserve flag that indicates if the old allocation should + /// be preserved + /// \return pointer to the new memory block + /// \details FixedSizeAllocatorWithCleanup provides a fixed-size, stack- + /// based allocation at compile time. If size is less than or equal to + /// S, then a pointer to the static array is returned. + /// \details The class can grow its memory block at runtime if a suitable + /// allocator is available. If size grows beyond S and a suitable + /// allocator is available, then the statically allocated array is + /// obsoleted. If a suitable allocator is not available, as with a + /// NullAllocator, then the function returns NULL and a runtime error + /// eventually occurs. + /// \note size is the count of elements, and not the number of bytes. + /// \sa reallocate(), SecBlockWithHint + pointer reallocate(pointer oldPtr, size_type oldSize, size_type newSize, bool preserve) + { + if (oldPtr == GetAlignedArray() && newSize <= S) + { + CRYPTOPP_ASSERT(oldSize <= S); + if (oldSize > newSize) + SecureWipeArray(oldPtr+newSize, oldSize-newSize); + return oldPtr; + } + + pointer newPtr = allocate(newSize, NULLPTR); + if (preserve && newSize) + { + const size_type copySize = STDMIN(oldSize, newSize); + if (newPtr && oldPtr) // GCC analyzer warning + memcpy_s(newPtr, sizeof(T)*newSize, oldPtr, sizeof(T)*copySize); + } + deallocate(oldPtr, oldSize); + return newPtr; + } + + CRYPTOPP_CONSTEXPR size_type max_size() const + { + return STDMAX(m_fallbackAllocator.max_size(), S); + } + +private: + + // T_Align16 is false. Normally we would use the natural + // alignment of T. The problem we are having is, some toolchains + // are changing the boundary for 64-bit arrays. 64-bit elements + // require 8-byte alignment, but the toolchain is laying the array + // out on a 4 byte boundary. See GH #992 for mystery alignment, + // https://github.com/weidai11/cryptopp/issues/992 + T* GetAlignedArray() {return m_array;} + CRYPTOPP_ALIGN_DATA(8) T m_array[S]; + + A m_fallbackAllocator; + bool m_allocated; +}; + +/// \brief Secure memory block with allocator and cleanup +/// \tparam T a class or type +/// \tparam A AllocatorWithCleanup derived class for allocation and cleanup +/// \sa SecBlock +/// on the Crypto++ wiki. +/// \since Crypto++ 2.0 +template > +class SecBlock +{ +public: + typedef typename A::value_type value_type; + typedef typename A::pointer iterator; + typedef typename A::const_pointer const_iterator; + typedef typename A::size_type size_type; + + /// \brief Returns the maximum number of elements the block can hold + /// \details ELEMS_MAX is the maximum number of elements the + /// SecBlock can hold. The value of ELEMS_MAX is + /// SIZE_MAX/sizeof(T). std::numeric_limits was avoided + /// due to lack of constexpr-ness in C++03 and below. + /// \note In C++03 and below ELEMS_MAX is a static data member of type + /// size_type. In C++11 and above ELEMS_MAX is an enum + /// inheriting from size_type. In both cases ELEMS_MAX can be + /// used before objects are fully constructed, and it does not suffer the + /// limitations of class methods like max_size. + /// \sa Issue 346/CVE-2016-9939 + /// \since Crypto++ 6.0 +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) + static const size_type ELEMS_MAX = ...; +#elif defined(_MSC_VER) && (_MSC_VER <= 1400) + static const size_type ELEMS_MAX = (~(size_type)0)/sizeof(T); +#elif defined(CRYPTOPP_CXX11_STRONG_ENUM) + enum : size_type {ELEMS_MAX = A::ELEMS_MAX}; +#else + static const size_type ELEMS_MAX = SIZE_MAX/sizeof(T); +#endif + + /// \brief Construct a SecBlock with space for size elements. + /// \param size the size of the allocation, in elements + /// \throw std::bad_alloc + /// \details The elements are not initialized. + /// \since Crypto++ 2.0 + /// \note size is the count of elements, and not the number of bytes + explicit SecBlock(size_type size=0) + : m_mark(ELEMS_MAX), m_size(size), m_ptr(m_alloc.allocate(size, NULLPTR)) { } + + /// \brief Copy construct a SecBlock from another SecBlock + /// \param t the other SecBlock + /// \throw std::bad_alloc + /// \since Crypto++ 2.0 + SecBlock(const SecBlock &t) + : m_mark(t.m_mark), m_size(t.m_size), m_ptr(m_alloc.allocate(t.m_size, NULLPTR)) { + CRYPTOPP_ASSERT((!t.m_ptr && !m_size) || (t.m_ptr && m_size)); + if (m_ptr && t.m_ptr) + memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); + } + + /// \brief Construct a SecBlock from an array of elements. + /// \param ptr a pointer to an array of T + /// \param len the number of elements in the memory block + /// \throw std::bad_alloc + /// \details If ptr!=NULL and len!=0, then the block is initialized from the pointer + /// ptr. If ptr==NULL and len!=0, then the block is initialized to 0. + /// Otherwise, the block is empty and not initialized. + /// \since Crypto++ 2.0 + /// \note size is the count of elements, and not the number of bytes + SecBlock(const T *ptr, size_type len) + : m_mark(ELEMS_MAX), m_size(len), m_ptr(m_alloc.allocate(len, NULLPTR)) { + CRYPTOPP_ASSERT((!m_ptr && !m_size) || (m_ptr && m_size)); + if (m_ptr && ptr) + memcpy_s(m_ptr, m_size*sizeof(T), ptr, len*sizeof(T)); + else if (m_ptr && m_size) + memset(m_ptr, 0, m_size*sizeof(T)); + } + + ~SecBlock() + {m_alloc.deallocate(m_ptr, STDMIN(m_size, m_mark));} + +#ifdef __BORLANDC__ + /// \brief Cast operator + /// \return block pointer cast to non-const T * + /// \since Crypto++ 2.0 + operator T *() const + {return (T*)m_ptr;} +#else + /// \brief Cast operator + /// \return block pointer cast to const void * + /// \since Crypto++ 2.0 + operator const void *() const + {return m_ptr;} + + /// \brief Cast operator + /// \return block pointer cast to non-const void * + /// \since Crypto++ 2.0 + operator void *() + {return m_ptr;} + + /// \brief Cast operator + /// \return block pointer cast to const T * + /// \since Crypto++ 2.0 + operator const T *() const + {return m_ptr;} + + /// \brief Cast operator + /// \return block pointer cast to non-const T * + /// \since Crypto++ 2.0 + operator T *() + {return m_ptr;} +#endif + + /// \brief Provides an iterator pointing to the first element in the memory block + /// \return iterator pointing to the first element in the memory block + /// \since Crypto++ 2.0 + iterator begin() + {return m_ptr;} + /// \brief Provides a constant iterator pointing to the first element in the memory block + /// \return constant iterator pointing to the first element in the memory block + /// \since Crypto++ 2.0 + const_iterator begin() const + {return m_ptr;} + /// \brief Provides an iterator pointing beyond the last element in the memory block + /// \return iterator pointing beyond the last element in the memory block + /// \since Crypto++ 2.0 + iterator end() + {return m_ptr+m_size;} + /// \brief Provides a constant iterator pointing beyond the last element in the memory block + /// \return constant iterator pointing beyond the last element in the memory block + /// \since Crypto++ 2.0 + const_iterator end() const + {return m_ptr+m_size;} + + /// \brief Provides a pointer to the first element in the memory block + /// \return pointer to the first element in the memory block + /// \since Crypto++ 2.0 + typename A::pointer data() {return m_ptr;} + /// \brief Provides a pointer to the first element in the memory block + /// \return constant pointer to the first element in the memory block + /// \since Crypto++ 2.0 + typename A::const_pointer data() const {return m_ptr;} + + /// \brief Provides the count of elements in the SecBlock + /// \return number of elements in the memory block + /// \note the return value is the count of elements, and not the number of bytes + /// \since Crypto++ 2.0 + size_type size() const {return m_size;} + /// \brief Determines if the SecBlock is empty + /// \return true if number of elements in the memory block is 0, false otherwise + /// \since Crypto++ 2.0 + bool empty() const {return m_size == 0;} + + /// \brief Provides a byte pointer to the first element in the memory block + /// \return byte pointer to the first element in the memory block + /// \since Crypto++ 2.0 + byte * BytePtr() {return (byte *)m_ptr;} + /// \brief Return a byte pointer to the first element in the memory block + /// \return constant byte pointer to the first element in the memory block + /// \since Crypto++ 2.0 + const byte * BytePtr() const {return (const byte *)m_ptr;} + /// \brief Provides the number of bytes in the SecBlock + /// \return the number of bytes in the memory block + /// \note the return value is the number of bytes, and not count of elements. + /// \since Crypto++ 2.0 + size_type SizeInBytes() const {return m_size*sizeof(T);} + + /// \brief Set contents and size from an array + /// \param ptr a pointer to an array of T + /// \param len the number of elements in the memory block + /// \details The array pointed to by ptr must be distinct + /// from this SecBlock because Assign() calls New() and then memcpy(). + /// The call to New() will invalidate all pointers and iterators, like + /// the pointer returned from data(). + /// \details If the memory block is reduced in size, then the reclaimed + /// memory is set to 0. If an assignment occurs, then Assign() resets + /// the element count after the previous block is zeroized. + /// \since Crypto++ 2.0 + void Assign(const T *ptr, size_type len) + { + New(len); + if (m_ptr && ptr) // GCC analyzer warning + memcpy_s(m_ptr, m_size*sizeof(T), ptr, len*sizeof(T)); + m_mark = ELEMS_MAX; + } + + /// \brief Set contents from a value + /// \param count the number of values to copy + /// \param value the value, repeated count times + /// \details If the memory block is reduced in size, then the reclaimed + /// memory is set to 0. If an assignment occurs, then Assign() resets + /// the element count after the previous block is zeroized. + /// \since Crypto++ 6.0 + void Assign(size_type count, T value) + { + New(count); + for (size_t i=0; i &t) + { + if (this != &t) + { + New(t.m_size); + if (m_ptr && t.m_ptr) // GCC analyzer warning + memcpy_s(m_ptr, m_size*sizeof(T), t, t.m_size*sizeof(T)); + } + m_mark = ELEMS_MAX; + } + + /// \brief Append contents from an array + /// \param ptr a pointer to an array of T + /// \param len the number of elements in the memory block + /// \throw InvalidArgument if resulting size would overflow + /// \details The array pointed to by ptr must be distinct + /// from this SecBlock because Append() calls Grow() and then memcpy(). + /// The call to Grow() will invalidate all pointers and iterators, like + /// the pointer returned from data(). + /// \details Append() may be less efficient than a ByteQueue because + /// Append() must Grow() the internal array and then copy elements. + /// The ByteQueue can copy elements without growing. + /// \sa ByteQueue + /// \since Crypto++ 8.6 + void Append(const T *ptr, size_type len) + { + if (ELEMS_MAX - m_size < len) + throw InvalidArgument("SecBlock: buffer overflow"); + + const size_type oldSize = m_size; + Grow(m_size+len); + if (m_ptr && ptr) // GCC analyzer warning + memcpy_s(m_ptr+oldSize, (m_size-oldSize)*sizeof(T), ptr, len*sizeof(T)); + m_mark = ELEMS_MAX; + } + + /// \brief Append contents from another SecBlock + /// \param t the other SecBlock + /// \throw InvalidArgument if resulting size would overflow + /// \details Internally, this SecBlock calls Grow() and then appends t. + /// \details Append() may be less efficient than a ByteQueue because + /// Append() must Grow() the internal array and then copy elements. + /// The ByteQueue can copy elements without growing. + /// \sa ByteQueue + /// \since Crypto++ 8.6 + void Append(const SecBlock &t) + { + if (ELEMS_MAX - m_size < t.m_size) + throw InvalidArgument("SecBlock: buffer overflow"); + + const size_type oldSize = m_size; + if (this != &t) // s += t + { + Grow(m_size+t.m_size); + if (m_ptr && t.m_ptr) // GCC analyzer warning + memcpy_s(m_ptr+oldSize, (m_size-oldSize)*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); + } + else // t += t + { + Grow(m_size*2); + if (m_ptr) // GCC analyzer warning + memmove_s(m_ptr+oldSize, (m_size-oldSize)*sizeof(T), m_ptr, oldSize*sizeof(T)); + } + m_mark = ELEMS_MAX; + } + + /// \brief Append contents from a value + /// \param count the number of values to copy + /// \param value the value, repeated count times + /// \throw InvalidArgument if resulting size would overflow + /// \details Internally, this SecBlock calls Grow() and then appends value. + /// \details Append() may be less efficient than a ByteQueue because + /// Append() must Grow() the internal array and then copy elements. + /// The ByteQueue can copy elements without growing. + /// \sa ByteQueue + /// \since Crypto++ 8.6 + void Append(size_type count, T value) + { + if (ELEMS_MAX - m_size < count) + throw InvalidArgument("SecBlock: buffer overflow"); + + const size_type oldSize = m_size; + Grow(m_size+count); + for (size_t i=oldSize; icount controls the number of + /// elements zeroized, which can be less than size or 0. + /// \details An internal variable, m_mark, is initialized to the maximum number + /// of elements. The maximum number of elements is ELEMS_MAX. Deallocation + /// triggers a zeroization, and the number of elements zeroized is + /// STDMIN(m_size, m_mark). After zeroization, the memory is returned to the + /// system. + /// \details The ASN.1 decoder uses SetMark() to set the element count to 0 + /// before throwing an exception. In this case, the attacker provides a large + /// BER encoded length (say 64MB) but only a small number of content octets + /// (say 16). If the allocator zeroized all 64MB, then a transient DoS could + /// occur as CPU cycles are spent zeroizing uninitialized memory. + /// \details Generally speaking, any operation which changes the size of the SecBlock + /// results in the mark being reset to ELEMS_MAX. In particular, if Assign(), + /// New(), Grow(), CleanNew(), CleanGrow() are called, then the count is reset to + /// ELEMS_MAX. The list is not exhaustive. + /// \since Crypto++ 6.0 + /// \sa Issue 346/CVE-2016-9939 + void SetMark(size_t count) {m_mark = count;} + + /// \brief Assign contents from another SecBlock + /// \param t the other SecBlock + /// \return reference to this SecBlock + /// \details Internally, operator=() calls Assign(). + /// \details If the memory block is reduced in size, then the reclaimed + /// memory is set to 0. If an assignment occurs, then Assign() resets + /// the element count after the previous block is zeroized. + /// \since Crypto++ 2.0 + SecBlock& operator=(const SecBlock &t) + { + // Assign guards for self-assignment + Assign(t); + return *this; + } + + /// \brief Append contents from another SecBlock + /// \param t the other SecBlock + /// \return reference to this SecBlock + /// \details Internally, operator+=() calls Append(). + /// \since Crypto++ 2.0 + SecBlock& operator+=(const SecBlock &t) + { + // Append guards for overflow + Append(t); + return *this; + } + + /// \brief Construct a SecBlock from this and another SecBlock + /// \param t the other SecBlock + /// \return a newly constructed SecBlock that is a concatenation of this + /// and t. + /// \details Internally, a new SecBlock is created from this and a + /// concatenation of t. + /// \since Crypto++ 2.0 + SecBlock operator+(const SecBlock &t) + { + CRYPTOPP_ASSERT((!m_ptr && !m_size) || (m_ptr && m_size)); + CRYPTOPP_ASSERT((!t.m_ptr && !t.m_size) || (t.m_ptr && t.m_size)); + if(!t.m_size) return SecBlock(*this); + + SecBlock result(m_size+t.m_size); + if (m_size) + memcpy_s(result.m_ptr, result.m_size*sizeof(T), m_ptr, m_size*sizeof(T)); + if (result.m_ptr && t.m_ptr) // GCC analyzer warning + memcpy_s(result.m_ptr+m_size, (result.m_size-m_size)*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); + return result; + } + + /// \brief Bitwise compare two SecBlocks + /// \param t the other SecBlock + /// \return true if the size and bits are equal, false otherwise + /// \details Uses a constant time compare if the arrays are equal size. + /// The constant time compare is VerifyBufsEqual() found in + /// misc.h. + /// \sa operator!=() + /// \since Crypto++ 2.0 + bool operator==(const SecBlock &t) const + { + return m_size == t.m_size && VerifyBufsEqual( + reinterpret_cast(m_ptr), + reinterpret_cast(t.m_ptr), m_size*sizeof(T)); + } + + /// \brief Bitwise compare two SecBlocks + /// \param t the other SecBlock + /// \return true if the size and bits are equal, false otherwise + /// \details Uses a constant time compare if the arrays are equal size. + /// The constant time compare is VerifyBufsEqual() found in + /// misc.h. + /// \details Internally, operator!=() returns the inverse of operator==(). + /// \sa operator==() + /// \since Crypto++ 2.0 + bool operator!=(const SecBlock &t) const + { + return !operator==(t); + } + + /// \brief Change size without preserving contents + /// \param newSize the new size of the memory block + /// \details Old content is not preserved. If the memory block is + /// reduced in size, then the reclaimed content is set to 0. If the + /// memory block grows in size, then the new memory is initialized + /// to 0. New() resets the element count after the previous block + /// is zeroized. + /// \details Internally, this SecBlock calls reallocate(). + /// \sa New(), CleanNew(), Grow(), CleanGrow(), resize() + /// \since Crypto++ 2.0 + void New(size_type newSize) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false); + m_size = newSize; + m_mark = ELEMS_MAX; + } + + /// \brief Change size without preserving contents + /// \param newSize the new size of the memory block + /// \details Old content is not preserved. If the memory block is + /// reduced in size, then the reclaimed content is set to 0. If the + /// memory block grows in size, then the new memory is initialized + /// to 0. CleanNew() resets the element count after the previous + /// block is zeroized. + /// \details Internally, this SecBlock calls New(). + /// \sa New(), CleanNew(), Grow(), CleanGrow(), resize() + /// \since Crypto++ 2.0 + void CleanNew(size_type newSize) + { + New(newSize); + if (m_ptr) {memset_z(m_ptr, 0, m_size*sizeof(T));} + m_mark = ELEMS_MAX; + } + + /// \brief Change size and preserve contents + /// \param newSize the new size of the memory block + /// \details Old content is preserved. New content is not initialized. + /// \details Internally, this SecBlock calls reallocate() when size must + /// increase. If the size does not increase, then CleanGrow() does not + /// take action. If the size must change, then use resize(). CleanGrow() + /// resets the element count after the previous block is zeroized. + /// \sa New(), CleanNew(), Grow(), CleanGrow(), resize() + /// \sa New(), CleanNew(), Grow(), CleanGrow(), resize() + /// \since Crypto++ 2.0 + void Grow(size_type newSize) + { + if (newSize > m_size) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); + m_size = newSize; + } + m_mark = ELEMS_MAX; + } + + /// \brief Change size and preserve contents + /// \param newSize the new size of the memory block + /// \details Old content is preserved. New content is initialized to 0. + /// \details Internally, this SecBlock calls reallocate() when size must + /// increase. If the size does not increase, then CleanGrow() does not + /// take action. If the size must change, then use resize(). CleanGrow() + /// resets the element count after the previous block is zeroized. + /// \sa New(), CleanNew(), Grow(), CleanGrow(), resize() + /// \since Crypto++ 2.0 + void CleanGrow(size_type newSize) + { + if (newSize > m_size) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); + memset_z(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T)); + m_size = newSize; + } + m_mark = ELEMS_MAX; + } + + /// \brief Change size and preserve contents + /// \param newSize the new size of the memory block + /// \details Old content is preserved. If the memory block grows in size, then + /// new memory is not initialized. resize() resets the element count after + /// the previous block is zeroized. + /// \details Internally, this SecBlock calls reallocate(). + /// \sa New(), CleanNew(), Grow(), CleanGrow(), resize() + /// \since Crypto++ 2.0 + void resize(size_type newSize) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); + m_size = newSize; + m_mark = ELEMS_MAX; + } + + /// \brief Swap contents with another SecBlock + /// \param b the other SecBlock + /// \details Internally, std::swap() is called on m_alloc, m_size and m_ptr. + /// \since Crypto++ 2.0 + void swap(SecBlock &b) + { + // Swap must occur on the allocator in case its FixedSize that spilled into the heap. + std::swap(m_alloc, b.m_alloc); + std::swap(m_mark, b.m_mark); + std::swap(m_size, b.m_size); + std::swap(m_ptr, b.m_ptr); + } + +protected: + A m_alloc; + size_type m_mark, m_size; + T *m_ptr; +}; + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING +/// \brief \ref SecBlock "SecBlock" typedef. +class SecByteBlock : public SecBlock {}; +/// \brief \ref SecBlock "SecBlock" typedef. +class SecWordBlock : public SecBlock {}; +/// \brief SecBlock using \ref AllocatorWithCleanup "AllocatorWithCleanup" typedef +class AlignedSecByteBlock : public SecBlock > {}; +#else +typedef SecBlock SecByteBlock; +typedef SecBlock SecWordBlock; +typedef SecBlock > AlignedSecByteBlock; +#endif + +// No need for move semantics on derived class *if* the class does not add any +// data members; see http://stackoverflow.com/q/31755703, and Rule of {0|3|5}. + +/// \brief Fixed size stack-based SecBlock +/// \tparam T class or type +/// \tparam S fixed-size of the stack-based memory block, in elements +/// \tparam A AllocatorBase derived class for allocation and cleanup +template > +class FixedSizeSecBlock : public SecBlock +{ +public: + /// \brief Construct a FixedSizeSecBlock + explicit FixedSizeSecBlock() : SecBlock(S) {} +}; + +/// \brief Fixed size stack-based SecBlock with 16-byte alignment +/// \tparam T class or type +/// \tparam S fixed-size of the stack-based memory block, in elements +/// \tparam T_Align16 boolean that determines whether allocations should be +/// aligned on a 16-byte boundary +template +class FixedSizeAlignedSecBlock : public FixedSizeSecBlock, T_Align16> > +{ +}; + +/// \brief Stack-based SecBlock that grows into the heap +/// \tparam T class or type +/// \tparam S fixed-size of the stack-based memory block, in elements +/// \tparam A AllocatorBase derived class for allocation and cleanup +template > > +class SecBlockWithHint : public SecBlock +{ +public: + /// construct a SecBlockWithHint with a count of elements + explicit SecBlockWithHint(size_t size) : SecBlock(size) {} +}; + +template +inline bool operator==(const CryptoPP::AllocatorWithCleanup&, const CryptoPP::AllocatorWithCleanup&) {return (true);} +template +inline bool operator!=(const CryptoPP::AllocatorWithCleanup&, const CryptoPP::AllocatorWithCleanup&) {return (false);} + +NAMESPACE_END + +NAMESPACE_BEGIN(std) + +/// \brief Swap two SecBlocks +/// \tparam T class or type +/// \tparam A AllocatorBase derived class for allocation and cleanup +/// \param a the first SecBlock +/// \param b the second SecBlock +template +inline void swap(CryptoPP::SecBlock &a, CryptoPP::SecBlock &b) +{ + a.swap(b); +} + +#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)) +// working for STLport 5.1.3 and MSVC 6 SP5 +template +inline CryptoPP::AllocatorWithCleanup<_Tp2>& +__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*) +{ + return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a); +} +#endif + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/secblockfwd.h b/external/ours/library/crypto/src/shared/original/secblockfwd.h new file mode 100755 index 000000000..d17068ee7 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/secblockfwd.h @@ -0,0 +1,29 @@ +// secblockfwd.h - written and placed in the public domain by Jeffrey Walton + +/// \file secblockfwd.h +/// \brief Forward declarations for SecBlock +/// \details secblock.h and misc.h have a circular dependency. secblockfwd.h +/// allows the library to sidestep the circular dependency, and reference +/// SecBlock classes without the full implementation. +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_SECBLOCKFWD_H +#define CRYPTOPP_SECBLOCKFWD_H + +#include "config.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +class SecBlock; + +template +class AllocatorWithCleanup; + +typedef SecBlock > SecByteBlock; +typedef SecBlock > SecWordBlock; +typedef SecBlock > AlignedSecByteBlock; + +NAMESPACE_END + +#endif // CRYPTOPP_SECBLOCKFWD_H diff --git a/external/ours/library/crypto/src/shared/original/seckey.h b/external/ours/library/crypto/src/shared/original/seckey.h new file mode 100755 index 000000000..2b0b2b89a --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/seckey.h @@ -0,0 +1,444 @@ +// seckey.h - originally written and placed in the public domain by Wei Dai + +/// \file seckey.h +/// \brief Classes and functions for implementing secret key algorithms. + +#ifndef CRYPTOPP_SECKEY_H +#define CRYPTOPP_SECKEY_H + +#include "config.h" +#include "cryptlib.h" +#include "misc.h" +#include "simple.h" +#include "stdcpp.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4189 4296) +#endif + +// Issue 340 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Inverts the cipher's direction +/// \param dir the cipher's direction +/// \return DECRYPTION if \ref CipherDir "dir" is ENCRYPTION, DECRYPTION otherwise +inline CipherDir ReverseCipherDir(CipherDir dir) +{ + return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION; +} + +/// \brief Inherited by algorithms with fixed block size +/// \tparam N the blocksize of the algorithm +template +class FixedBlockSize +{ +public: + /// \brief The block size of the algorithm provided as a constant. + CRYPTOPP_CONSTANT(BLOCKSIZE = N); +}; + +// ************** rounds *************** + +/// \brief Inherited by algorithms with fixed number of rounds +/// \tparam R the number of rounds used by the algorithm +template +class FixedRounds +{ +public: + /// \brief The number of rounds for the algorithm provided as a constant. + CRYPTOPP_CONSTANT(ROUNDS = R); +}; + +/// \brief Inherited by algorithms with variable number of rounds +/// \tparam D Default number of rounds +/// \tparam N Minimum number of rounds +/// \tparam M Maximum number of rounds +template // use INT_MAX here because enums are treated as signed ints +class VariableRounds +{ +public: + /// \brief The default number of rounds for the algorithm provided as a constant. + CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D); + /// \brief The minimum number of rounds for the algorithm provided as a constant. + CRYPTOPP_CONSTANT(MIN_ROUNDS = N); + /// \brief The maximum number of rounds for the algorithm provided as a constant. + CRYPTOPP_CONSTANT(MAX_ROUNDS = M); + /// \brief The default number of rounds for the algorithm based on key length + /// provided by a static function. + /// \param keylength the size of the key, in bytes + /// \details keylength is unused in the default implementation. + CRYPTOPP_STATIC_CONSTEXPR unsigned int StaticGetDefaultRounds(size_t keylength) + { + return CRYPTOPP_UNUSED(keylength), static_cast(DEFAULT_ROUNDS); + } + +protected: + /// \brief Validates the number of rounds for an algorithm. + /// \param rounds the candidate number of rounds + /// \param alg an Algorithm object used if the number of rounds are invalid + /// \throw InvalidRounds if the number of rounds are invalid + /// \details ThrowIfInvalidRounds() validates the number of rounds and throws if invalid. + inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) + { + if (M == INT_MAX) // Coverity and result_independent_of_operands + { + if (rounds < MIN_ROUNDS) + throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds); + } + else + { + if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS) + throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds); + } + } + + /// \brief Validates the number of rounds for an algorithm + /// \param param the candidate number of rounds + /// \param alg an Algorithm object used if the number of rounds are invalid + /// \return the number of rounds for the algorithm + /// \throw InvalidRounds if the number of rounds are invalid + /// \details GetRoundsAndThrowIfInvalid() validates the number of rounds and throws if invalid. + inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) + { + int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); + ThrowIfInvalidRounds(rounds, alg); + return static_cast(rounds); + } +}; + +// ************** key length *************** + +/// \brief Inherited by keyed algorithms with fixed key length +/// \tparam N Default key length, in bytes +/// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements" +/// \tparam IV_L default IV length, in bytes +/// \sa SimpleKeyingInterface +template +class FixedKeyLength +{ +public: + /// \brief The default key length used by the algorithm provided as a constant + /// \details KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(KEYLENGTH=N); + /// \brief The minimum key length used by the algorithm provided as a constant + /// \details MIN_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N); + /// \brief The maximum key length used by the algorithm provided as a constant + /// \details MAX_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N); + /// \brief The default key length used by the algorithm provided as a constant + /// \details DEFAULT_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N); + /// \brief The default IV requirements for the algorithm provided as a constant + /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement + /// in cryptlib.h for allowed values. + CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ); + /// \brief The default IV length used by the algorithm provided as a constant + /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0. + CRYPTOPP_CONSTANT(IV_LENGTH = IV_L); + /// \brief The default key length for the algorithm provided by a static function. + /// \param keylength the size of the key, in bytes + /// \details The default implementation returns KEYLENGTH. keylength is unused + /// in the default implementation. + CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + { + return CRYPTOPP_UNUSED(keylength), static_cast(KEYLENGTH); + } +}; + +/// \brief Inherited by keyed algorithms with variable key length +/// \tparam D Default key length, in bytes +/// \tparam N Minimum key length, in bytes +/// \tparam M Maximum key length, in bytes +/// \tparam Q Default key length multiple, in bytes. The default multiple is 1. +/// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements" +/// \tparam IV_L default IV length, in bytes. The default length is 0. +/// \sa SimpleKeyingInterface +template +class VariableKeyLength +{ + // Make these private to avoid Doxygen documenting them in all derived classes + CRYPTOPP_COMPILE_ASSERT(Q > 0); + CRYPTOPP_COMPILE_ASSERT(N % Q == 0); + CRYPTOPP_COMPILE_ASSERT(M % Q == 0); + CRYPTOPP_COMPILE_ASSERT(N < M); + CRYPTOPP_COMPILE_ASSERT(D >= N); + CRYPTOPP_COMPILE_ASSERT(M >= D); + +public: + /// \brief The minimum key length used by the algorithm provided as a constant + /// \details MIN_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N); + /// \brief The maximum key length used by the algorithm provided as a constant + /// \details MAX_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M); + /// \brief The default key length used by the algorithm provided as a constant + /// \details DEFAULT_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D); + /// \brief The key length multiple used by the algorithm provided as a constant + /// \details MAX_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q); + /// \brief The default IV requirements for the algorithm provided as a constant + /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement + /// in cryptlib.h for allowed values. + CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ); + /// \brief The default initialization vector length for the algorithm provided as a constant + /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0. + CRYPTOPP_CONSTANT(IV_LENGTH=IV_L); + /// \brief Provides a valid key length for the algorithm provided by a static function. + /// \param keylength the size of the key, in bytes + /// \details If keylength is less than MIN_KEYLENGTH, then the function returns + /// MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function + /// returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE, + /// then keylength is returned. Otherwise, the function returns keylength rounded + /// \a down to the next smaller multiple of KEYLENGTH_MULTIPLE. + /// \details keylength is provided in bytes, not bits. + CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + { + return (keylength <= N) ? N : + (keylength >= M) ? M : + (keylength+Q-1) - (keylength+Q-1)%Q; + } +}; + +/// \brief Provides key lengths based on another class's key length +/// \tparam T another FixedKeyLength or VariableKeyLength class +/// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements" +/// \tparam IV_L default IV length, in bytes +/// \sa SimpleKeyingInterface +template +class SameKeyLengthAs +{ +public: + /// \brief The minimum key length used by the algorithm provided as a constant + /// \details MIN_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH); + /// \brief The maximum key length used by the algorithm provided as a constant + /// \details MIN_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH); + /// \brief The default key length used by the algorithm provided as a constant + /// \details MIN_KEYLENGTH is provided in bytes, not bits + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH); + /// \brief The default IV requirements for the algorithm provided as a constant + /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement + /// in cryptlib.h for allowed values. + CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ); + /// \brief The default initialization vector length for the algorithm provided as a constant + /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0. + CRYPTOPP_CONSTANT(IV_LENGTH=IV_L); + /// \brief Provides a valid key length for the algorithm provided by a static function. + /// \param keylength the size of the key, in bytes + /// \details If keylength is less than MIN_KEYLENGTH, then the function returns + /// MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function + /// returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE, + /// then keylength is returned. Otherwise, the function returns keylength rounded + /// \a down to the next smaller multiple of KEYLENGTH_MULTIPLE. + /// \details keylength is provided in bytes, not bits. + CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + {return T::StaticGetValidKeyLength(keylength);} +}; + +// ************** implementation helper for SimpleKeyingInterface *************** + +/// \brief Provides a base implementation of SimpleKeyingInterface +/// \tparam BASE a SimpleKeyingInterface derived class +/// \tparam INFO a SimpleKeyingInterface derived class +/// \details SimpleKeyingInterfaceImpl() provides a default implementation for ciphers providing a keying interface. +/// Functions are virtual and not eligible for C++11 constexpr-ness. +/// \sa Algorithm(), SimpleKeyingInterface() +template +class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE +{ +public: + /// \brief The minimum key length used by the algorithm + /// \return minimum key length used by the algorithm, in bytes + size_t MinKeyLength() const + {return INFO::MIN_KEYLENGTH;} + + /// \brief The maximum key length used by the algorithm + /// \return maximum key length used by the algorithm, in bytes + size_t MaxKeyLength() const + {return static_cast(INFO::MAX_KEYLENGTH);} + + /// \brief The default key length used by the algorithm + /// \return default key length used by the algorithm, in bytes + size_t DefaultKeyLength() const + {return INFO::DEFAULT_KEYLENGTH;} + + /// \brief Provides a valid key length for the algorithm + /// \param keylength the size of the key, in bytes + /// \return the valid key length, in bytes + /// \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH, + /// then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, + /// then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE, + /// then keylength is returned. Otherwise, the function returns a \a lower multiple of + /// KEYLENGTH_MULTIPLE. + size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);} + + /// \brief The default IV requirements for the algorithm + /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement + /// in cryptlib.h for allowed values. + SimpleKeyingInterface::IV_Requirement IVRequirement() const + {return static_cast(INFO::IV_REQUIREMENT);} + + /// \brief The initialization vector length for the algorithm + /// \details IVSize is provided in bytes, not bits. The default implementation uses + /// IV_LENGTH, which is 0. + unsigned int IVSize() const + {return INFO::IV_LENGTH;} +}; + +/// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers +/// \tparam INFO a SimpleKeyingInterface derived class +/// \tparam BASE a SimpleKeyingInterface derived class +/// \details BlockCipherImpl() provides a default implementation for block ciphers using AlgorithmImpl() +/// and SimpleKeyingInterfaceImpl(). Functions are virtual and not eligible for C++11 constexpr-ness. +/// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl() +template +class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl > > +{ +public: + /// Provides the block size of the algorithm + /// \return the block size of the algorithm, in bytes + unsigned int BlockSize() const {return this->BLOCKSIZE;} +}; + +/// \brief Provides class member functions to key a block cipher +/// \tparam DIR a CipherDir +/// \tparam BASE a BlockCipherImpl derived class +template +class BlockCipherFinal : public ClonableImpl, BASE> +{ +public: + /// \brief Construct a default BlockCipherFinal + /// \details The cipher is not keyed. + BlockCipherFinal() {} + + /// \brief Construct a BlockCipherFinal + /// \param key a byte array used to key the cipher + /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls + /// SimpleKeyingInterface::SetKey. + BlockCipherFinal(const byte *key) + {this->SetKey(key, this->DEFAULT_KEYLENGTH);} + + /// \brief Construct a BlockCipherFinal + /// \param key a byte array used to key the cipher + /// \param length the length of the byte array + /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls + /// SimpleKeyingInterface::SetKey. + BlockCipherFinal(const byte *key, size_t length) + {this->SetKey(key, length);} + + /// \brief Construct a BlockCipherFinal + /// \param key a byte array used to key the cipher + /// \param length the length of the byte array + /// \param rounds the number of rounds + /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls + /// SimpleKeyingInterface::SetKeyWithRounds. + BlockCipherFinal(const byte *key, size_t length, unsigned int rounds) + {this->SetKeyWithRounds(key, length, rounds);} + + /// \brief Provides the direction of the cipher + /// \return true if DIR is ENCRYPTION, false otherwise + /// \sa GetCipherDirection(), IsPermutation() + bool IsForwardTransformation() const {return DIR == ENCRYPTION;} +}; + +/// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for message authentication codes +/// \tparam INFO a SimpleKeyingInterface derived class +/// \tparam BASE a SimpleKeyingInterface derived class +/// \details MessageAuthenticationCodeImpl() provides a default implementation for message authentication codes +/// using AlgorithmImpl() and SimpleKeyingInterfaceImpl(). Functions are virtual and not subject to C++11 +/// constexpr. +/// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl() +template +class MessageAuthenticationCodeImpl : public AlgorithmImpl, INFO> +{ +}; + +/// \brief Provides class member functions to key a message authentication code +/// \tparam BASE a BlockCipherImpl derived class +/// \details A default implementation for MessageAuthenticationCode +template +class MessageAuthenticationCodeFinal : public ClonableImpl, MessageAuthenticationCodeImpl > +{ +public: + /// \brief Construct a default MessageAuthenticationCodeFinal + /// \details The message authentication code is not keyed. + MessageAuthenticationCodeFinal() {} + /// \brief Construct a BlockCipherFinal + /// \param key a byte array used to key the algorithm + /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls + /// SimpleKeyingInterface::SetKey. + MessageAuthenticationCodeFinal(const byte *key) + {this->SetKey(key, this->DEFAULT_KEYLENGTH);} + /// \brief Construct a BlockCipherFinal + /// \param key a byte array used to key the algorithm + /// \param length the length of the byte array + /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls + /// SimpleKeyingInterface::SetKey. + MessageAuthenticationCodeFinal(const byte *key, size_t length) + {this->SetKey(key, length);} +}; + +// ************** documentation *************** + +/// \brief Provides Encryption and Decryption typedefs used by derived classes to +/// implement a block cipher +/// \details These objects usually should not be used directly. See CipherModeDocumentation +/// instead. Each class derived from this one defines two types, Encryption and Decryption, +/// both of which implement the BlockCipher interface. +struct BlockCipherDocumentation +{ + /// implements the BlockCipher interface + typedef BlockCipher Encryption; + /// implements the BlockCipher interface + typedef BlockCipher Decryption; +}; + +/// \brief Provides Encryption and Decryption typedefs used by derived classes to +/// implement a symmetric cipher +/// \details Each class derived from this one defines two types, Encryption and Decryption, +/// both of which implement the SymmetricCipher interface. Two types of classes derive +/// from this class: stream ciphers and block cipher modes. Stream ciphers can be used +/// alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation +/// for more for information about using cipher modes and block ciphers. +struct SymmetricCipherDocumentation +{ + /// implements the SymmetricCipher interface + typedef SymmetricCipher Encryption; + /// implements the SymmetricCipher interface + typedef SymmetricCipher Decryption; +}; + +/// \brief Provides Encryption and Decryption typedefs used by derived classes to +/// implement an authenticated encryption cipher +/// \details Each class derived from this one defines two types, Encryption and Decryption, +/// both of which implement the AuthenticatedSymmetricCipher interface. +struct AuthenticatedSymmetricCipherDocumentation +{ + /// implements the AuthenticatedSymmetricCipher interface + typedef AuthenticatedSymmetricCipher Encryption; + /// implements the AuthenticatedSymmetricCipher interface + typedef AuthenticatedSymmetricCipher Decryption; +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +// Issue 340 +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/seed.cpp b/external/ours/library/crypto/src/shared/original/seed.cpp new file mode 100755 index 000000000..4e99d759d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/seed.cpp @@ -0,0 +1,113 @@ +// seed.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "seed.h" +#include "misc.h" +#include "stdcpp.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; + +const word32 s_kc[16] = { + 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, + 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b}; + +const byte s_s0[256] = { + 0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25, 0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63, 0x28, + 0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17, 0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE, 0x70, 0x8C, + 0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74, 0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01, 0x24, 0x1C, 0x73, + 0x98, 0x10, 0xCC, 0xF2, 0xD9, 0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9, 0x60, 0x50, 0xA3, 0xEB, + 0x0D, 0xB6, 0x9E, 0x4F, 0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5, 0x61, 0xC3, 0xB4, 0x41, 0x52, + 0x7D, 0x8D, 0x08, 0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1, 0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B, + 0x0E, 0xAB, 0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A, 0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE, + 0x64, 0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66, 0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0, + 0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF, 0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38, 0xF4, + 0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97, 0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89, 0x75, 0xFB, + 0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4, 0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8, 0x0F, 0x8E, 0x42, + 0x23, 0x91, 0x6C, 0xDB, 0xA4, 0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40, 0xBE, 0x3E, 0xBC, 0xC1, + 0xAA, 0xBA, 0x4E, 0x55, 0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56, 0x77, 0xA0, 0xED, 0x46, 0xB5, + 0x2B, 0x65, 0xFA, 0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2, 0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0, + 0xCD, 0x88, 0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33, 0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A, + 0x9A}; + +static const byte s_s1[256] = { + 0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8, 0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B, 0xC3, + 0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7, 0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B, 0xEF, 0x88, + 0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4, 0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98, 0x28, 0x4E, 0xF6, + 0x3E, 0xA5, 0xF9, 0x0D, 0xDF, 0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72, 0x42, 0xD4, 0x41, 0xC0, + 0x73, 0x67, 0xAC, 0x8B, 0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34, 0xD2, 0x0B, 0xEE, 0xE9, 0x5D, + 0x94, 0x18, 0xF8, 0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9, 0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A, + 0x6A, 0xB1, 0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71, 0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6, + 0x59, 0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0, 0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF, + 0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D, 0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E, 0x9F, + 0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC, 0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03, 0x64, 0x6D, + 0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09, 0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05, 0xFA, 0x01, 0xF0, + 0x2A, 0x5E, 0xA9, 0x56, 0x43, 0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79, 0x97, 0xFC, 0x1E, 0x82, + 0x21, 0x8C, 0x1B, 0x5F, 0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46, 0xED, 0x58, 0x52, 0xEB, 0x7E, + 0xDA, 0xC9, 0xFD, 0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C, 0x0E, 0x50, 0x39, 0x26, 0x32, 0x84, + 0x69, 0x93, 0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87, 0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A, + 0xB7}; + +#define SS0(x) ((s_s0[x]*0x01010101UL) & 0x3FCFF3FC) +#define SS1(x) ((s_s1[x]*0x01010101UL) & 0xFC3FCFF3) +#define SS2(x) ((s_s0[x]*0x01010101UL) & 0xF3FC3FCF) +#define SS3(x) ((s_s1[x]*0x01010101UL) & 0xCFF3FC3F) +#define G(x) (SS0(GETBYTE(x, 0)) ^ SS1(GETBYTE(x, 1)) ^ SS2(GETBYTE(x, 2)) ^ SS3(GETBYTE(x, 3))) + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void SEED::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs& /*params*/) +{ + AssertValidKeyLength(length); + + word64 key01, key23; + GetBlock get(userKey); + get(key01)(key23); + word32 *k = m_k; + ptrdiff_t kInc = 2; + + if (!IsForwardTransformation()) + { + k = k+30; + kInc = 0-kInc; + } + + for (unsigned int i=0; i>32) + word32(key23>>32) - s_kc[i]; + word32 t1 = word32(key01) - word32(key23) + s_kc[i]; + k[0] = G(t0); + k[1] = G(t1); + k+=kInc; + if (i&1) + key23 = rotlConstant<8,word64>(key23); + else + key01 = rotrConstant<8,word64>(key01); + } +} + +void SEED::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + typedef BlockGetAndPut Block; + word32 a0, a1, b0, b1, t0, t1; + Block::Get(inBlock)(a0)(a1)(b0)(b1); + + for (int i=0; i, public FixedKeyLength<16>, public FixedRounds<16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SEED";} +}; + +/// \brief SEED block cipher +/// \sa SEED +/// \since Crypto++ 5.6.0 +class SEED : public SEED_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + FixedSizeSecBlock m_k; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/serpent.cpp b/external/ours/library/crypto/src/shared/original/serpent.cpp new file mode 100755 index 000000000..351186ce8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/serpent.cpp @@ -0,0 +1,125 @@ +// serpent.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "serpent.h" +#include "secblock.h" +#include "misc.h" + +#include "serpentp.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen) +{ + FixedSizeSecBlock k0; + GetUserKey(LITTLE_ENDIAN_ORDER, k0.begin(), 8, userKey, keylen); + if (keylen < 32) + k0[keylen/4] |= word32(1) << ((keylen%4)*8); + + word32 t = k0[7]; + unsigned int i; + for (i = 0; i < 8; ++i) + k[i] = k0[i] = t = rotlConstant<11>(k0[i] ^ k0[(i + 3) % 8] ^ k0[(i + 5) % 8] ^ t ^ 0x9e3779b9 ^ i); + for (i = 8; i < 4*(rounds+1); ++i) + k[i] = t = rotlConstant<11>(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i); + k -= 20; + + word32 a,b,c,d,e; + for (i=0; i Block; + +void Serpent::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e; + + Block::Get(inBlock)(a)(b)(c)(d); + + const word32 *k = m_key; + unsigned int i=1; + + do + { + beforeS0(KX); beforeS0(S0); afterS0(LT); + afterS0(KX); afterS0(S1); afterS1(LT); + afterS1(KX); afterS1(S2); afterS2(LT); + afterS2(KX); afterS2(S3); afterS3(LT); + afterS3(KX); afterS3(S4); afterS4(LT); + afterS4(KX); afterS4(S5); afterS5(LT); + afterS5(KX); afterS5(S6); afterS6(LT); + afterS6(KX); afterS6(S7); + + if (i == 4) + break; + + ++i; + c = b; + b = e; + e = d; + d = a; + a = e; + k += 32; + beforeS0(LT); + } + while (true); + + afterS7(KX); + + Block::Put(xorBlock, outBlock)(d)(e)(b)(a); +} + +void Serpent::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e=0; + + Block::Get(inBlock)(a)(b)(c)(d); + + const word32 *k = m_key + 96; + unsigned int i=4; + + beforeI7(KX); + goto start; + + do + { + c = b; + b = d; + d = e; + k -= 32; + beforeI7(ILT); +start: + beforeI7(I7); afterI7(KX); + afterI7(ILT); afterI7(I6); afterI6(KX); + afterI6(ILT); afterI6(I5); afterI5(KX); + afterI5(ILT); afterI5(I4); afterI4(KX); + afterI4(ILT); afterI4(I3); afterI3(KX); + afterI3(ILT); afterI3(I2); afterI2(KX); + afterI2(ILT); afterI2(I1); afterI1(KX); + afterI1(ILT); afterI1(I0); afterI0(KX); + } + while (--i != 0); + + Block::Put(xorBlock, outBlock)(a)(d)(b)(e); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/serpent.h b/external/ours/library/crypto/src/shared/original/serpent.h new file mode 100755 index 000000000..bd3cedbe5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/serpent.h @@ -0,0 +1,72 @@ +// serpent.h - originally written and placed in the public domain by Wei Dai + +/// \file serpent.h +/// \brief Classes for the Serpent block cipher +/// \sa A +/// Candidate Block Cipher for the Advanced Encryption Standard + +#ifndef CRYPTOPP_SERPENT_H +#define CRYPTOPP_SERPENT_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Serpent block cipher information +/// \since Crypto++ 3.1 +struct Serpent_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8>, public FixedRounds<32> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Serpent";} +}; + +/// \brief Serpent block cipher +/// \sa Serpent on the +/// Crypto++ wiki, A +/// Candidate Block Cipher for the Advanced Encryption Standard +/// \since Crypto++ 3.1 +class Serpent : public Serpent_Info, public BlockCipherDocumentation +{ + /// \brief Serpen block cipher base implementation + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 3.1 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_key; + }; + + /// \brief Serpent encryption transformation + /// \details Enc provides the encryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 3.1 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Serpent decryption transformation + /// \details Dec provides the decryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 3.1 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Serpent::Encryption SerpentEncryption; +typedef Serpent::Decryption SerpentDecryption; + +NAMESPACE_END + +#endif // CRYPTOPP_SERPENT_H diff --git a/external/ours/library/crypto/src/shared/original/serpentp.h b/external/ours/library/crypto/src/shared/original/serpentp.h new file mode 100755 index 000000000..8df3cb8a8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/serpentp.h @@ -0,0 +1,439 @@ +// private header for Serpent and Sosemanuk + +#ifndef CRYPTOPP_SERPENTP_H +#define CRYPTOPP_SERPENTP_H + +NAMESPACE_BEGIN(CryptoPP) + +// linear transformation +#define LT(i,a,b,c,d,e) {\ + a = rotlConstant<13>(a); \ + c = rotlConstant<3>(c); \ + d = rotlConstant<7>(d ^ c ^ (a << 3)); \ + b = rotlConstant<1>(b ^ a ^ c); \ + a = rotlConstant<5>(a ^ b ^ d); \ + c = rotlConstant<22>(c ^ d ^ (b << 7));} + +// inverse linear transformation +#define ILT(i,a,b,c,d,e) {\ + c = rotrConstant<22>(c); \ + a = rotrConstant<5>(a); \ + c ^= d ^ (b << 7); \ + a ^= b ^ d; \ + b = rotrConstant<1>(b); \ + d = rotrConstant<7>(d) ^ c ^ (a << 3); \ + b ^= a ^ c; \ + c = rotrConstant<3>(c); \ + a = rotrConstant<13>(a);} + +// order of output from S-box functions +#define beforeS0(f) f(0,a,b,c,d,e) +#define afterS0(f) f(1,b,e,c,a,d) +#define afterS1(f) f(2,c,b,a,e,d) +#define afterS2(f) f(3,a,e,b,d,c) +#define afterS3(f) f(4,e,b,d,c,a) +#define afterS4(f) f(5,b,a,e,c,d) +#define afterS5(f) f(6,a,c,b,e,d) +#define afterS6(f) f(7,a,c,d,b,e) +#define afterS7(f) f(8,d,e,b,a,c) + +// order of output from inverse S-box functions +#define beforeI7(f) f(8,a,b,c,d,e) +#define afterI7(f) f(7,d,a,b,e,c) +#define afterI6(f) f(6,a,b,c,e,d) +#define afterI5(f) f(5,b,d,e,c,a) +#define afterI4(f) f(4,b,c,e,a,d) +#define afterI3(f) f(3,a,b,e,c,d) +#define afterI2(f) f(2,b,d,e,c,a) +#define afterI1(f) f(1,a,b,c,e,d) +#define afterI0(f) f(0,a,d,b,e,c) + +// The instruction sequences for the S-box functions +// come from Dag Arne Osvik's paper "Speeding up Serpent". + +#define S0(i, r0, r1, r2, r3, r4) \ + { \ + r3 ^= r0; \ + r4 = r1; \ + r1 &= r3; \ + r4 ^= r2; \ + r1 ^= r0; \ + r0 |= r3; \ + r0 ^= r4; \ + r4 ^= r3; \ + r3 ^= r2; \ + r2 |= r1; \ + r2 ^= r4; \ + r4 = ~r4; \ + r4 |= r1; \ + r1 ^= r3; \ + r1 ^= r4; \ + r3 |= r0; \ + r1 ^= r3; \ + r4 ^= r3; \ + } + +#define I0(i, r0, r1, r2, r3, r4) \ + { \ + r2 = ~r2; \ + r4 = r1; \ + r1 |= r0; \ + r4 = ~r4; \ + r1 ^= r2; \ + r2 |= r4; \ + r1 ^= r3; \ + r0 ^= r4; \ + r2 ^= r0; \ + r0 &= r3; \ + r4 ^= r0; \ + r0 |= r1; \ + r0 ^= r2; \ + r3 ^= r4; \ + r2 ^= r1; \ + r3 ^= r0; \ + r3 ^= r1; \ + r2 &= r3; \ + r4 ^= r2; \ + } + +#define S1(i, r0, r1, r2, r3, r4) \ + { \ + r0 = ~r0; \ + r2 = ~r2; \ + r4 = r0; \ + r0 &= r1; \ + r2 ^= r0; \ + r0 |= r3; \ + r3 ^= r2; \ + r1 ^= r0; \ + r0 ^= r4; \ + r4 |= r1; \ + r1 ^= r3; \ + r2 |= r0; \ + r2 &= r4; \ + r0 ^= r1; \ + r1 &= r2; \ + r1 ^= r0; \ + r0 &= r2; \ + r0 ^= r4; \ + } + +#define I1(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r1; \ + r1 ^= r3; \ + r3 &= r1; \ + r4 ^= r2; \ + r3 ^= r0; \ + r0 |= r1; \ + r2 ^= r3; \ + r0 ^= r4; \ + r0 |= r2; \ + r1 ^= r3; \ + r0 ^= r1; \ + r1 |= r3; \ + r1 ^= r0; \ + r4 = ~r4; \ + r4 ^= r1; \ + r1 |= r0; \ + r1 ^= r0; \ + r1 |= r4; \ + r3 ^= r1; \ + } + +#define S2(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r0; \ + r0 &= r2; \ + r0 ^= r3; \ + r2 ^= r1; \ + r2 ^= r0; \ + r3 |= r4; \ + r3 ^= r1; \ + r4 ^= r2; \ + r1 = r3; \ + r3 |= r4; \ + r3 ^= r0; \ + r0 &= r1; \ + r4 ^= r0; \ + r1 ^= r3; \ + r1 ^= r4; \ + r4 = ~r4; \ + } + +#define I2(i, r0, r1, r2, r3, r4) \ + { \ + r2 ^= r3; \ + r3 ^= r0; \ + r4 = r3; \ + r3 &= r2; \ + r3 ^= r1; \ + r1 |= r2; \ + r1 ^= r4; \ + r4 &= r3; \ + r2 ^= r3; \ + r4 &= r0; \ + r4 ^= r2; \ + r2 &= r1; \ + r2 |= r0; \ + r3 = ~r3; \ + r2 ^= r3; \ + r0 ^= r3; \ + r0 &= r1; \ + r3 ^= r4; \ + r3 ^= r0; \ + } + +#define S3(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r0; \ + r0 |= r3; \ + r3 ^= r1; \ + r1 &= r4; \ + r4 ^= r2; \ + r2 ^= r3; \ + r3 &= r0; \ + r4 |= r1; \ + r3 ^= r4; \ + r0 ^= r1; \ + r4 &= r0; \ + r1 ^= r3; \ + r4 ^= r2; \ + r1 |= r0; \ + r1 ^= r2; \ + r0 ^= r3; \ + r2 = r1; \ + r1 |= r3; \ + r1 ^= r0; \ + } + +#define I3(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 ^= r1; \ + r1 &= r2; \ + r1 ^= r0; \ + r0 &= r4; \ + r4 ^= r3; \ + r3 |= r1; \ + r3 ^= r2; \ + r0 ^= r4; \ + r2 ^= r0; \ + r0 |= r3; \ + r0 ^= r1; \ + r4 ^= r2; \ + r2 &= r3; \ + r1 |= r3; \ + r1 ^= r2; \ + r4 ^= r0; \ + r2 ^= r4; \ + } + +#define S4(i, r0, r1, r2, r3, r4) \ + { \ + r1 ^= r3; \ + r3 = ~r3; \ + r2 ^= r3; \ + r3 ^= r0; \ + r4 = r1; \ + r1 &= r3; \ + r1 ^= r2; \ + r4 ^= r3; \ + r0 ^= r4; \ + r2 &= r4; \ + r2 ^= r0; \ + r0 &= r1; \ + r3 ^= r0; \ + r4 |= r1; \ + r4 ^= r0; \ + r0 |= r3; \ + r0 ^= r2; \ + r2 &= r3; \ + r0 = ~r0; \ + r4 ^= r2; \ + } + +#define I4(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 &= r3; \ + r2 ^= r1; \ + r1 |= r3; \ + r1 &= r0; \ + r4 ^= r2; \ + r4 ^= r1; \ + r1 &= r2; \ + r0 = ~r0; \ + r3 ^= r4; \ + r1 ^= r3; \ + r3 &= r0; \ + r3 ^= r2; \ + r0 ^= r1; \ + r2 &= r0; \ + r3 ^= r0; \ + r2 ^= r4; \ + r2 |= r3; \ + r3 ^= r0; \ + r2 ^= r1; \ + } + +#define S5(i, r0, r1, r2, r3, r4) \ + { \ + r0 ^= r1; \ + r1 ^= r3; \ + r3 = ~r3; \ + r4 = r1; \ + r1 &= r0; \ + r2 ^= r3; \ + r1 ^= r2; \ + r2 |= r4; \ + r4 ^= r3; \ + r3 &= r1; \ + r3 ^= r0; \ + r4 ^= r1; \ + r4 ^= r2; \ + r2 ^= r0; \ + r0 &= r3; \ + r2 = ~r2; \ + r0 ^= r4; \ + r4 |= r3; \ + r2 ^= r4; \ + } + +#define I5(i, r0, r1, r2, r3, r4) \ + { \ + r1 = ~r1; \ + r4 = r3; \ + r2 ^= r1; \ + r3 |= r0; \ + r3 ^= r2; \ + r2 |= r1; \ + r2 &= r0; \ + r4 ^= r3; \ + r2 ^= r4; \ + r4 |= r0; \ + r4 ^= r1; \ + r1 &= r2; \ + r1 ^= r3; \ + r4 ^= r2; \ + r3 &= r4; \ + r4 ^= r1; \ + r3 ^= r0; \ + r3 ^= r4; \ + r4 = ~r4; \ + } + +#define S6(i, r0, r1, r2, r3, r4) \ + { \ + r2 = ~r2; \ + r4 = r3; \ + r3 &= r0; \ + r0 ^= r4; \ + r3 ^= r2; \ + r2 |= r4; \ + r1 ^= r3; \ + r2 ^= r0; \ + r0 |= r1; \ + r2 ^= r1; \ + r4 ^= r0; \ + r0 |= r3; \ + r0 ^= r2; \ + r4 ^= r3; \ + r4 ^= r0; \ + r3 = ~r3; \ + r2 &= r4; \ + r2 ^= r3; \ + } + +#define I6(i, r0, r1, r2, r3, r4) \ + { \ + r0 ^= r2; \ + r4 = r2; \ + r2 &= r0; \ + r4 ^= r3; \ + r2 = ~r2; \ + r3 ^= r1; \ + r2 ^= r3; \ + r4 |= r0; \ + r0 ^= r2; \ + r3 ^= r4; \ + r4 ^= r1; \ + r1 &= r3; \ + r1 ^= r0; \ + r0 ^= r3; \ + r0 |= r2; \ + r3 ^= r1; \ + r4 ^= r0; \ + } + +#define S7(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 &= r1; \ + r2 ^= r3; \ + r3 &= r1; \ + r4 ^= r2; \ + r2 ^= r1; \ + r1 ^= r0; \ + r0 |= r4; \ + r0 ^= r2; \ + r3 ^= r1; \ + r2 ^= r3; \ + r3 &= r0; \ + r3 ^= r4; \ + r4 ^= r2; \ + r2 &= r0; \ + r4 = ~r4; \ + r2 ^= r4; \ + r4 &= r0; \ + r1 ^= r3; \ + r4 ^= r1; \ + } + +#define I7(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 ^= r0; \ + r0 &= r3; \ + r2 = ~r2; \ + r4 |= r3; \ + r3 ^= r1; \ + r1 |= r0; \ + r0 ^= r2; \ + r2 &= r4; \ + r1 ^= r2; \ + r2 ^= r0; \ + r0 |= r2; \ + r3 &= r4; \ + r0 ^= r3; \ + r4 ^= r1; \ + r3 ^= r4; \ + r4 |= r0; \ + r3 ^= r2; \ + r4 ^= r2; \ + } + +// key xor +#define KX(r, a, b, c, d, e) {\ + a ^= k[4 * r + 0]; \ + b ^= k[4 * r + 1]; \ + c ^= k[4 * r + 2]; \ + d ^= k[4 * r + 3];} + +#define LK(r, a, b, c, d, e) {\ + a = k[(8-r)*4 + 0]; \ + b = k[(8-r)*4 + 1]; \ + c = k[(8-r)*4 + 2]; \ + d = k[(8-r)*4 + 3];} + +#define SK(r, a, b, c, d, e) {\ + k[(8-r)*4 + 4] = a; \ + k[(8-r)*4 + 5] = b; \ + k[(8-r)*4 + 6] = c; \ + k[(8-r)*4 + 7] = d;} + +void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen); + +NAMESPACE_END + +#endif // CRYPTOPP_SERPENTP_H diff --git a/external/ours/library/crypto/src/shared/original/sha.cpp b/external/ours/library/crypto/src/shared/original/sha.cpp new file mode 100755 index 000000000..30d6529f7 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha.cpp @@ -0,0 +1,1414 @@ +// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c + +// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2. Jeffrey +// Walton implemented Intel SHA extensions based on Intel articles and code +// by Sean Gulley. Jeffrey Walton implemented ARM SHA-1 and SHA-256 based +// on ARM code and code from Johannes Schneiders, Skip Hovsmith and +// Barry O'Rourke. Jeffrey Walton and Bill Schmidt implemented Power8 +// SHA-256 and SHA-512. All code is in the public domain. + +// In August 2017 JW reworked the internals to align all the +// implementations. Formerly all hashes were software based, IterHashBase +// handled endian conversions, and IterHashBase dispatched a single to +// block SHA{N}::Transform. SHA{N}::Transform then performed the single +// block hashing. It was repeated for multiple blocks. +// +// The rework added SHA{N}::HashMultipleBlocks (class) and +// SHA{N}_HashMultipleBlocks (free standing). There are also hardware +// accelerated variations. Callers enter SHA{N}::HashMultipleBlocks (class) +// and the function calls SHA{N}_HashMultipleBlocks (free standing) or +// SHA{N}_HashBlock (free standing) as a fallback. +// +// An added wrinkle is hardware is little endian, C++ is big endian, and +// callers use big endian, so SHA{N}_HashMultipleBlock accepts a ByteOrder +// for the incoming data arrangement. Hardware based SHA{N}_HashMultipleBlock +// can often perform the endian swap much easier by setting an EPI mask. +// Endian swap incurs no penalty on Intel SHA, and 4-instruction penalty on +// ARM SHA. Under C++ the full software based swap penalty is incurred due +// to use of ReverseBytes(). +// +// In May 2019 JW added Cryptogams ARMv7 and NEON implementations for SHA1, +// SHA256 and SHA512. The Cryptogams code closed a performance gap on modern +// 32-bit ARM devices. Cryptogams is Andy Polyakov's project used to create +// high speed crypto algorithms and share them with other developers. Andy's +// code runs 30% to 50% faster than C/C++ code. The Cryptogams code can be +// disabled in config_asm.h. An example of integrating Andy's code is at +// https://wiki.openssl.org/index.php/Cryptogams_SHA. + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sha.cpp" to generate MASM code + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4100 4731) +#endif + +#ifndef CRYPTOPP_IMPORTS +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "secblock.h" +#include "sha.h" +#include "misc.h" +#include "cpu.h" + +#if defined(CRYPTOPP_DISABLE_SHA_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if CRYPTOPP_SHANI_AVAILABLE +extern void SHA1_HashMultipleBlocks_SHANI(word32 *state, const word32 *data, size_t length, ByteOrder order); +extern void SHA256_HashMultipleBlocks_SHANI(word32 *state, const word32 *data, size_t length, ByteOrder order); +#endif + +#if CRYPTOGAMS_ARM_SHA1 +extern "C" void cryptogams_sha1_block_data_order(word32* state, const word32 *data, size_t blocks); +extern "C" void cryptogams_sha1_block_data_order_neon(word32* state, const word32 *data, size_t blocks); +#endif + +#if CRYPTOPP_ARM_SHA1_AVAILABLE +extern void SHA1_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order); +#endif + +#if CRYPTOPP_ARM_SHA2_AVAILABLE +extern void SHA256_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order); +#endif + +#if CRYPTOGAMS_ARM_SHA256 +extern "C" void cryptogams_sha256_block_data_order(word32* state, const word32 *data, size_t blocks); +extern "C" void cryptogams_sha256_block_data_order_neon(word32* state, const word32 *data, size_t blocks); +#endif + +#if CRYPTOPP_ARM_SHA512_AVAILABLE +extern void SHA512_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order); +#endif + +#if CRYPTOPP_POWER8_SHA_AVAILABLE +extern void SHA256_HashMultipleBlocks_POWER8(word32 *state, const word32 *data, size_t length, ByteOrder order); +extern void SHA512_HashMultipleBlocks_POWER8(word64 *state, const word64 *data, size_t length, ByteOrder order); +#endif + +#if CRYPTOGAMS_ARM_SHA512 +extern "C" void cryptogams_sha512_block_data_order(word64* state, const word64 *data, size_t blocks); +extern "C" void cryptogams_sha512_block_data_order_neon(word64* state, const word64 *data, size_t blocks); +#endif + +// We add extern to export table to sha_simd.cpp, but it +// cleared http://github.com/weidai11/cryptopp/issues/502 +extern const word32 SHA256_K[64]; +extern const word64 SHA512_K[80]; + +CRYPTOPP_ALIGN_DATA(16) +const word64 SHA512_K[80] = { + W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), + W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), + W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), + W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), + W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), + W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), + W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), + W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), + W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), + W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), + W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), + W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), + W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), + W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), + W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), + W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), + W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), + W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), + W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), + W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), + W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), + W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), + W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), + W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), + W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), + W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), + W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), + W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), + W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), + W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), + W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), + W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), + W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), + W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), + W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), + W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), + W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), + W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), + W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), + W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) +}; + +CRYPTOPP_ALIGN_DATA(16) +const word32 SHA256_K[64] = { + + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +//////////////////////////////// +// start of Steve Reid's code // +//////////////////////////////// + +ANONYMOUS_NAMESPACE_BEGIN + +#define blk0(i) (W[i] = data[i]) +#define blk1(i) (W[i&15] = rotlConstant<1>(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15])) + +#define f1(x,y,z) (z^(x&(y^z))) +#define f2(x,y,z) (x^y^z) +#define f3(x,y,z) ((x&y)|(z&(x|y))) +#define f4(x,y,z) (x^y^z) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlConstant<5>(v);w=rotlConstant<30>(w); +#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlConstant<5>(v);w=rotlConstant<30>(w); +#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlConstant<5>(v);w=rotlConstant<30>(w); +#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlConstant<5>(v);w=rotlConstant<30>(w); +#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlConstant<5>(v);w=rotlConstant<30>(w); + +void SHA1_HashBlock_CXX(word32 *state, const word32 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + + word32 W[16]; + /* Copy context->state[] to working vars */ + word32 a = state[0]; + word32 b = state[1]; + word32 c = state[2]; + word32 d = state[3]; + word32 e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +#undef blk0 +#undef blk1 +#undef f1 +#undef f2 +#undef f3 +#undef f4 +#undef R1 +#undef R2 +#undef R3 +#undef R4 + +ANONYMOUS_NAMESPACE_END + +////////////////////////////// +// end of Steve Reid's code // +////////////////////////////// + +std::string SHA1::AlgorithmProvider() const +{ +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + return "SHANI"; +#endif +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return "SSE2"; +#endif +#if CRYPTOGAMS_ARM_SHA1 + if (HasNEON()) + return "NEON"; + if (HasARMv7()) + return "ARMv7"; +#endif +#if CRYPTOPP_ARM_SHA1_AVAILABLE + if (HasSHA1()) + return "ARMv8"; +#endif + return "C++"; +} + +void SHA1::InitState(HashWordType *state) +{ + state[0] = 0x67452301; + state[1] = 0xEFCDAB89; + state[2] = 0x98BADCFE; + state[3] = 0x10325476; + state[4] = 0xC3D2E1F0; +} + +void SHA1::Transform(word32 *state, const word32 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + { + SHA1_HashMultipleBlocks_SHANI(state, data, SHA1::BLOCKSIZE, LITTLE_ENDIAN_ORDER); + return; + } +#endif +#if CRYPTOGAMS_ARM_SHA1 && 0 + if (HasNEON()) + { +# if defined(CRYPTOPP_LITTLE_ENDIAN) + word32 dataBuf[16]; + ByteReverse(dataBuf, data, SHA1::BLOCKSIZE); + cryptogams_sha1_block_data_order_neon(state, data, 1); +# else + cryptogams_sha1_block_data_order_neon(state, data, 1); +# endif + return; + } + if (HasARMv7()) + { +# if defined(CRYPTOPP_LITTLE_ENDIAN) + word32 dataBuf[16]; + ByteReverse(dataBuf, data, SHA1::BLOCKSIZE); + cryptogams_sha1_block_data_order(state, data, 1); +# else + cryptogams_sha1_block_data_order(state, data, 1); +# endif + return; + } +#endif +#if CRYPTOPP_ARM_SHA1_AVAILABLE + if (HasSHA1()) + { + SHA1_HashMultipleBlocks_ARMV8(state, data, SHA1::BLOCKSIZE, LITTLE_ENDIAN_ORDER); + return; + } +#endif + + SHA1_HashBlock_CXX(state, data); +} + +size_t SHA1::HashMultipleBlocks(const word32 *input, size_t length) +{ + CRYPTOPP_ASSERT(input); + CRYPTOPP_ASSERT(length >= SHA1::BLOCKSIZE); + +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + { + SHA1_HashMultipleBlocks_SHANI(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA1::BLOCKSIZE - 1); + } +#endif +#if CRYPTOGAMS_ARM_SHA1 + if (HasNEON()) + { + cryptogams_sha1_block_data_order_neon(m_state, input, length / SHA1::BLOCKSIZE); + return length & (SHA1::BLOCKSIZE - 1); + } + if (HasARMv7()) + { + cryptogams_sha1_block_data_order(m_state, input, length / SHA1::BLOCKSIZE); + return length & (SHA1::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_ARM_SHA1_AVAILABLE + if (HasSHA1()) + { + SHA1_HashMultipleBlocks_ARMV8(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA1::BLOCKSIZE - 1); + } +#endif + + const bool noReverse = NativeByteOrderIs(this->GetByteOrder()); + word32 *dataBuf = this->DataBuf(); + do + { + if (noReverse) + { + SHA1_HashBlock_CXX(m_state, input); + } + else + { + ByteReverse(dataBuf, input, SHA1::BLOCKSIZE); + SHA1_HashBlock_CXX(m_state, dataBuf); + } + + input += SHA1::BLOCKSIZE/sizeof(word32); + length -= SHA1::BLOCKSIZE; + } + while (length >= SHA1::BLOCKSIZE); + return length; +} + +// ************************************************************* + +ANONYMOUS_NAMESPACE_BEGIN + +#define a(i) T[(0-i)&7] +#define b(i) T[(1-i)&7] +#define c(i) T[(2-i)&7] +#define d(i) T[(3-i)&7] +#define e(i) T[(4-i)&7] +#define f(i) T[(5-i)&7] +#define g(i) T[(6-i)&7] +#define h(i) T[(7-i)&7] + +#define blk0(i) (W[i] = data[i]) +#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) (y^((x^y)&(y^z))) + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + +// for SHA256 +#define s0(x) (rotrConstant<7>(x)^rotrConstant<18>(x)^(x>>3)) +#define s1(x) (rotrConstant<17>(x)^rotrConstant<19>(x)^(x>>10)) +#define S0(x) (rotrConstant<2>(x)^rotrConstant<13>(x)^rotrConstant<22>(x)) +#define S1(x) (rotrConstant<6>(x)^rotrConstant<11>(x)^rotrConstant<25>(x)) + +void SHA256_HashBlock_CXX(word32 *state, const word32 *data) +{ + word32 W[16]={0}, T[8]; + /* Copy context->state[] to working vars */ + memcpy(T, state, sizeof(T)); + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=16) + { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + /* Add the working vars back into context.state[] */ + state[0] += a(0); + state[1] += b(0); + state[2] += c(0); + state[3] += d(0); + state[4] += e(0); + state[5] += f(0); + state[6] += g(0); + state[7] += h(0); +} + +#undef Ch +#undef Maj +#undef s0 +#undef s1 +#undef S0 +#undef S1 +#undef blk0 +#undef blk1 +#undef blk2 +#undef R + +#undef a +#undef b +#undef c +#undef d +#undef e +#undef f +#undef g +#undef h + +ANONYMOUS_NAMESPACE_END + +std::string SHA256_AlgorithmProvider() +{ +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + return "SHANI"; +#endif +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return "SSE2"; +#endif +#if CRYPTOGAMS_ARM_SHA256 + if (HasNEON()) + return "NEON"; + if (HasARMv7()) + return "ARMv7"; +#endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE + if (HasSHA2()) + return "ARMv8"; +#endif +#if (CRYPTOPP_POWER8_SHA_AVAILABLE) + if (HasSHA256()) + return "Power8"; +#endif + return "C++"; +} + +std::string SHA224::AlgorithmProvider() const +{ + return SHA256_AlgorithmProvider(); +} + +void SHA224::InitState(HashWordType *state) +{ + static const word32 s[8] = { + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; + memcpy(state, s, sizeof(s)); +} + +void SHA256::InitState(HashWordType *state) +{ + static const word32 s[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + memcpy(state, s, sizeof(s)); +} +#endif // Not CRYPTOPP_GENERATE_X64_MASM + +#if defined(CRYPTOPP_X86_ASM_AVAILABLE) + +ANONYMOUS_NAMESPACE_BEGIN + +void CRYPTOPP_FASTCALL SHA256_HashMultipleBlocks_SSE2(word32 *state, const word32 *data, size_t len) +{ + #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ + #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4] + #define G(i) H(i+1) + #define F(i) H(i+2) + #define E(i) H(i+3) + #define D(i) H(i+4) + #define C(i) H(i+5) + #define B(i) H(i+6) + #define A(i) H(i+7) + #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4 + #define Wt_2(i) Wt((i)-2) + #define Wt_15(i) Wt((i)-15) + #define Wt_7(i) Wt((i)-7) + #define K_END [BASE+8*4+16*4+0*WORD_SZ] + #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ] + #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ] + #define DATA_END [BASE+8*4+16*4+3*WORD_SZ] + #define Kt(i) WORD_REG(si)+(i)*4 +#if CRYPTOPP_BOOL_X86 + #define BASE esp+4 +#elif defined(__GNUC__) + #define BASE r8 +#else + #define BASE rsp +#endif + +#define RA0(i, edx, edi) \ + AS2( add edx, [Kt(i)] )\ + AS2( add edx, [Wt(i)] )\ + AS2( add edx, H(i) )\ + +#define RA1(i, edx, edi) + +#define RB0(i, edx, edi) + +#define RB1(i, edx, edi) \ + AS2( mov AS_REG_7d, [Wt_2(i)] )\ + AS2( mov edi, [Wt_15(i)])\ + AS2( mov ebx, AS_REG_7d )\ + AS2( shr AS_REG_7d, 10 )\ + AS2( ror ebx, 17 )\ + AS2( xor AS_REG_7d, ebx )\ + AS2( ror ebx, 2 )\ + AS2( xor ebx, AS_REG_7d )/* s1(W_t-2) */\ + AS2( add ebx, [Wt_7(i)])\ + AS2( mov AS_REG_7d, edi )\ + AS2( shr AS_REG_7d, 3 )\ + AS2( ror edi, 7 )\ + AS2( add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\ + AS2( xor AS_REG_7d, edi )\ + AS2( add edx, [Kt(i)])\ + AS2( ror edi, 11 )\ + AS2( add edx, H(i) )\ + AS2( xor AS_REG_7d, edi )/* s0(W_t-15) */\ + AS2( add AS_REG_7d, ebx )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\ + AS2( mov [Wt(i)], AS_REG_7d)\ + AS2( add edx, AS_REG_7d )\ + +#define ROUND(i, r, eax, ecx, edi, edx)\ + /* in: edi = E */\ + /* unused: eax, ecx, temp: ebx, AS_REG_7d, out: edx = T1 */\ + AS2( mov edx, F(i) )\ + AS2( xor edx, G(i) )\ + AS2( and edx, edi )\ + AS2( xor edx, G(i) )/* Ch(E,F,G) = (G^(E&(F^G))) */\ + AS2( mov AS_REG_7d, edi )\ + AS2( ror edi, 6 )\ + AS2( ror AS_REG_7d, 25 )\ + RA##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ + AS2( xor AS_REG_7d, edi )\ + AS2( ror edi, 5 )\ + AS2( xor AS_REG_7d, edi )/* S1(E) */\ + AS2( add edx, AS_REG_7d )/* T1 = S1(E) + Ch(E,F,G) + H + Wt + Kt */\ + RB##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ + /* in: ecx = A, eax = B^C, edx = T1 */\ + /* unused: edx, temp: ebx, AS_REG_7d, out: eax = A, ecx = B^C, edx = E */\ + AS2( mov ebx, ecx )\ + AS2( xor ecx, B(i) )/* A^B */\ + AS2( and eax, ecx )\ + AS2( xor eax, B(i) )/* Maj(A,B,C) = B^((A^B)&(B^C) */\ + AS2( mov AS_REG_7d, ebx )\ + AS2( ror ebx, 2 )\ + AS2( add eax, edx )/* T1 + Maj(A,B,C) */\ + AS2( add edx, D(i) )\ + AS2( mov D(i), edx )\ + AS2( ror AS_REG_7d, 22 )\ + AS2( xor AS_REG_7d, ebx )\ + AS2( ror ebx, 11 )\ + AS2( xor AS_REG_7d, ebx )\ + AS2( add eax, AS_REG_7d )/* T1 + S0(A) + Maj(A,B,C) */\ + AS2( mov H(i), eax )\ + +// Unroll the use of CRYPTOPP_BOOL_X64 in assembler math. The GAS assembler on X32 (version 2.25) +// complains "Error: invalid operands (*ABS* and *UND* sections) for `*` and `-`" +#if CRYPTOPP_BOOL_X64 +#define SWAP_COPY(i) \ + AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\ + AS1( bswap WORD_REG(bx))\ + AS2( mov [Wt(i*2+1)], WORD_REG(bx)) +#else // X86 and X32 +#define SWAP_COPY(i) \ + AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\ + AS1( bswap WORD_REG(bx))\ + AS2( mov [Wt(i)], WORD_REG(bx)) +#endif + +#if defined(__GNUC__) + #if CRYPTOPP_BOOL_X64 + FixedSizeAlignedSecBlock workspace; + #endif + __asm__ __volatile__ + ( + #if CRYPTOPP_BOOL_X64 + "lea %4, %%r8;" + #endif + INTEL_NOPREFIX +#elif defined(CRYPTOPP_GENERATE_X64_MASM) + ALIGN 8 + SHA256_HashMultipleBlocks_SSE2 PROC FRAME + rex_push_reg rsi + push_reg rdi + push_reg rbx + push_reg rbp + alloc_stack(LOCALS_SIZE+8) + .endprolog + mov rdi, r8 + lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4] +#endif + +#if CRYPTOPP_BOOL_X86 + #ifndef __GNUC__ + AS2( mov edi, [len]) + AS2( lea WORD_REG(si), [SHA256_K+48*4]) + #endif + #if !defined(_MSC_VER) || (_MSC_VER < 1400) + AS_PUSH_IF86(bx) + #endif + + AS_PUSH_IF86(bp) + AS2( mov ebx, esp) + AS2( and esp, -16) + AS2( sub WORD_REG(sp), LOCALS_SIZE) + AS_PUSH_IF86(bx) +#endif + AS2( mov STATE_SAVE, WORD_REG(cx)) + AS2( mov DATA_SAVE, WORD_REG(dx)) + AS2( lea WORD_REG(ax), [WORD_REG(di) + WORD_REG(dx)]) + AS2( mov DATA_END, WORD_REG(ax)) + AS2( mov K_END, WORD_REG(si)) + +#if CRYPTOPP_SSE2_ASM_AVAILABLE +#if CRYPTOPP_BOOL_X86 + AS2( test edi, 1) + ASJ( jnz, 2, f) + AS1( dec DWORD PTR K_END) +#endif + AS2( movdqu xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16]) + AS2( movdqu xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16]) +#endif + +#if CRYPTOPP_BOOL_X86 +#if CRYPTOPP_SSE2_ASM_AVAILABLE + ASJ( jmp, 0, f) +#endif + ASL(2) // non-SSE2 + AS2( mov esi, ecx) + AS2( lea edi, A(0)) + AS2( mov ecx, 8) +ATT_NOPREFIX + AS1( rep movsd) +INTEL_NOPREFIX + AS2( mov esi, K_END) + ASJ( jmp, 3, f) +#endif + +#if CRYPTOPP_SSE2_ASM_AVAILABLE + ASL(0) + AS2( movdqu E(0), xmm1) + AS2( movdqu A(0), xmm0) +#endif +#if CRYPTOPP_BOOL_X86 + ASL(3) +#endif + AS2( sub WORD_REG(si), 48*4) + SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3) + SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7) +#if CRYPTOPP_BOOL_X86 + SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11) + SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15) +#endif + AS2( mov edi, E(0)) // E + AS2( mov eax, B(0)) // B + AS2( xor eax, C(0)) // B^C + AS2( mov ecx, A(0)) // A + + ROUND(0, 0, eax, ecx, edi, edx) + ROUND(1, 0, ecx, eax, edx, edi) + ROUND(2, 0, eax, ecx, edi, edx) + ROUND(3, 0, ecx, eax, edx, edi) + ROUND(4, 0, eax, ecx, edi, edx) + ROUND(5, 0, ecx, eax, edx, edi) + ROUND(6, 0, eax, ecx, edi, edx) + ROUND(7, 0, ecx, eax, edx, edi) + ROUND(8, 0, eax, ecx, edi, edx) + ROUND(9, 0, ecx, eax, edx, edi) + ROUND(10, 0, eax, ecx, edi, edx) + ROUND(11, 0, ecx, eax, edx, edi) + ROUND(12, 0, eax, ecx, edi, edx) + ROUND(13, 0, ecx, eax, edx, edi) + ROUND(14, 0, eax, ecx, edi, edx) + ROUND(15, 0, ecx, eax, edx, edi) + + ASL(1) + AS2(add WORD_REG(si), 4*16) + ROUND(0, 1, eax, ecx, edi, edx) + ROUND(1, 1, ecx, eax, edx, edi) + ROUND(2, 1, eax, ecx, edi, edx) + ROUND(3, 1, ecx, eax, edx, edi) + ROUND(4, 1, eax, ecx, edi, edx) + ROUND(5, 1, ecx, eax, edx, edi) + ROUND(6, 1, eax, ecx, edi, edx) + ROUND(7, 1, ecx, eax, edx, edi) + ROUND(8, 1, eax, ecx, edi, edx) + ROUND(9, 1, ecx, eax, edx, edi) + ROUND(10, 1, eax, ecx, edi, edx) + ROUND(11, 1, ecx, eax, edx, edi) + ROUND(12, 1, eax, ecx, edi, edx) + ROUND(13, 1, ecx, eax, edx, edi) + ROUND(14, 1, eax, ecx, edi, edx) + ROUND(15, 1, ecx, eax, edx, edi) + AS2( cmp WORD_REG(si), K_END) + ATT_NOPREFIX + ASJ( jb, 1, b) + INTEL_NOPREFIX + + AS2( mov WORD_REG(dx), DATA_SAVE) + AS2( add WORD_REG(dx), 64) + AS2( mov AS_REG_7, STATE_SAVE) + AS2( mov DATA_SAVE, WORD_REG(dx)) + +#if CRYPTOPP_SSE2_ASM_AVAILABLE +#if CRYPTOPP_BOOL_X86 + AS2( test DWORD PTR K_END, 1) + ASJ( jz, 4, f) +#endif + AS2( movdqu xmm1, XMMWORD_PTR [AS_REG_7+1*16]) + AS2( movdqu xmm0, XMMWORD_PTR [AS_REG_7+0*16]) + AS2( paddd xmm1, E(0)) + AS2( paddd xmm0, A(0)) + AS2( movdqu [AS_REG_7+1*16], xmm1) + AS2( movdqu [AS_REG_7+0*16], xmm0) + AS2( cmp WORD_REG(dx), DATA_END) + ATT_NOPREFIX + ASJ( jb, 0, b) + INTEL_NOPREFIX +#endif + +#if CRYPTOPP_BOOL_X86 +#if CRYPTOPP_SSE2_ASM_AVAILABLE + ASJ( jmp, 5, f) + ASL(4) // non-SSE2 +#endif + AS2( add [AS_REG_7+0*4], ecx) // A + AS2( add [AS_REG_7+4*4], edi) // E + AS2( mov eax, B(0)) + AS2( mov ebx, C(0)) + AS2( mov ecx, D(0)) + AS2( add [AS_REG_7+1*4], eax) + AS2( add [AS_REG_7+2*4], ebx) + AS2( add [AS_REG_7+3*4], ecx) + AS2( mov eax, F(0)) + AS2( mov ebx, G(0)) + AS2( mov ecx, H(0)) + AS2( add [AS_REG_7+5*4], eax) + AS2( add [AS_REG_7+6*4], ebx) + AS2( add [AS_REG_7+7*4], ecx) + AS2( mov ecx, AS_REG_7d) + AS2( cmp WORD_REG(dx), DATA_END) + ASJ( jb, 2, b) +#if CRYPTOPP_SSE2_ASM_AVAILABLE + ASL(5) +#endif +#endif + + AS_POP_IF86(sp) + AS_POP_IF86(bp) + #if !defined(_MSC_VER) || (_MSC_VER < 1400) + AS_POP_IF86(bx) + #endif + +#ifdef CRYPTOPP_GENERATE_X64_MASM + add rsp, LOCALS_SIZE+8 + pop rbp + pop rbx + pop rdi + pop rsi + ret + SHA256_HashMultipleBlocks_SSE2 ENDP +#endif + +#ifdef __GNUC__ + ATT_PREFIX + : + : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len) + #if CRYPTOPP_BOOL_X64 + , "m" (workspace[0]) + #endif + : "memory", "cc", "%eax" + #if CRYPTOPP_BOOL_X64 + , "%rbx", "%r8", "%r10" + #endif + ); +#endif +} + +ANONYMOUS_NAMESPACE_END + +#endif // CRYPTOPP_X86_ASM_AVAILABLE + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void CRYPTOPP_FASTCALL SHA256_HashMultipleBlocks_SSE2(word32 *state, const word32 *data, size_t len); +} +#endif + +std::string SHA256::AlgorithmProvider() const +{ + return SHA256_AlgorithmProvider(); +} + +void SHA256::Transform(word32 *state, const word32 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + { + SHA256_HashMultipleBlocks_SHANI(state, data, SHA256::BLOCKSIZE, LITTLE_ENDIAN_ORDER); + return; + } +#endif +#if CRYPTOGAMS_ARM_SHA256 && 0 + if (HasNEON()) + { +# if defined(CRYPTOPP_LITTLE_ENDIAN) + word32 dataBuf[16]; + ByteReverse(dataBuf, data, SHA256::BLOCKSIZE); + cryptogams_sha256_block_data_order_neon(state, data, 1); +# else + cryptogams_sha256_block_data_order_neon(state, data, 1); +# endif + return; + } + if (HasARMv7()) + { +# if defined(CRYPTOPP_LITTLE_ENDIAN) + word32 dataBuf[16]; + ByteReverse(dataBuf, data, SHA256::BLOCKSIZE); + cryptogams_sha256_block_data_order(state, data, 1); +# else + cryptogams_sha256_block_data_order(state, data, 1); +# endif + return; + } +#endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE + if (HasSHA2()) + { + SHA256_HashMultipleBlocks_ARMV8(state, data, SHA256::BLOCKSIZE, LITTLE_ENDIAN_ORDER); + return; + } +#endif +#if CRYPTOPP_POWER8_SHA_AVAILABLE + if (HasSHA256()) + { + SHA256_HashMultipleBlocks_POWER8(state, data, SHA256::BLOCKSIZE, LITTLE_ENDIAN_ORDER); + return; + } +#endif + + SHA256_HashBlock_CXX(state, data); +} + +size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length) +{ + CRYPTOPP_ASSERT(input); + CRYPTOPP_ASSERT(length >= SHA256::BLOCKSIZE); + +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + { + SHA256_HashMultipleBlocks_SHANI(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_X64_MASM_AVAILABLE + if (HasSSE2()) + { + const size_t res = length & (SHA256::BLOCKSIZE - 1); + SHA256_HashMultipleBlocks_SSE2(m_state, input, length-res); + return res; + } +#endif +#if CRYPTOGAMS_ARM_SHA256 + if (HasNEON()) + { + cryptogams_sha256_block_data_order_neon(m_state, input, length / SHA256::BLOCKSIZE); + return length & (SHA256::BLOCKSIZE - 1); + } + if (HasARMv7()) + { + cryptogams_sha256_block_data_order(m_state, input, length / SHA256::BLOCKSIZE); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE + if (HasSHA2()) + { + SHA256_HashMultipleBlocks_ARMV8(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_POWER8_SHA_AVAILABLE + if (HasSHA256()) + { + SHA256_HashMultipleBlocks_POWER8(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif + + const bool noReverse = NativeByteOrderIs(this->GetByteOrder()); + word32 *dataBuf = this->DataBuf(); + do + { + if (noReverse) + { + SHA256_HashBlock_CXX(m_state, input); + } + else + { + ByteReverse(dataBuf, input, SHA256::BLOCKSIZE); + SHA256_HashBlock_CXX(m_state, dataBuf); + } + + input += SHA256::BLOCKSIZE/sizeof(word32); + length -= SHA256::BLOCKSIZE; + } + while (length >= SHA256::BLOCKSIZE); + return length; +} + +size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length) +{ + CRYPTOPP_ASSERT(input); + CRYPTOPP_ASSERT(length >= SHA256::BLOCKSIZE); + +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + { + SHA256_HashMultipleBlocks_SHANI(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_X64_MASM_AVAILABLE + if (HasSSE2()) + { + const size_t res = length & (SHA256::BLOCKSIZE - 1); + SHA256_HashMultipleBlocks_SSE2(m_state, input, length-res); + return res; + } +#endif +#if CRYPTOGAMS_ARM_SHA256 + if (HasNEON()) + { + cryptogams_sha256_block_data_order_neon(m_state, input, length / SHA256::BLOCKSIZE); + return length & (SHA256::BLOCKSIZE - 1); + } + if (HasARMv7()) + { + cryptogams_sha256_block_data_order(m_state, input, length / SHA256::BLOCKSIZE); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE + if (HasSHA2()) + { + SHA256_HashMultipleBlocks_ARMV8(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif +#if CRYPTOPP_POWER8_SHA_AVAILABLE + if (HasSHA256()) + { + SHA256_HashMultipleBlocks_POWER8(m_state, input, length, BIG_ENDIAN_ORDER); + return length & (SHA256::BLOCKSIZE - 1); + } +#endif + + const bool noReverse = NativeByteOrderIs(this->GetByteOrder()); + word32 *dataBuf = this->DataBuf(); + do + { + if (noReverse) + { + SHA256_HashBlock_CXX(m_state, input); + } + else + { + ByteReverse(dataBuf, input, SHA256::BLOCKSIZE); + SHA256_HashBlock_CXX(m_state, dataBuf); + } + + input += SHA256::BLOCKSIZE/sizeof(word32); + length -= SHA256::BLOCKSIZE; + } + while (length >= SHA256::BLOCKSIZE); + return length; +} + +// ************************************************************* + +std::string SHA512_AlgorithmProvider() +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return "SSE2"; +#endif +#if CRYPTOGAMS_ARM_SHA512 + if (HasNEON()) + return "NEON"; + if (HasARMv7()) + return "ARMv7"; +#endif +#if (CRYPTOPP_POWER8_SHA_AVAILABLE) + if (HasSHA512()) + return "Power8"; +#endif + return "C++"; +} + +std::string SHA384::AlgorithmProvider() const +{ + return SHA512_AlgorithmProvider(); +} + +std::string SHA512::AlgorithmProvider() const +{ + return SHA512_AlgorithmProvider(); +} + +void SHA384::InitState(HashWordType *state) +{ + const word64 s[8] = { + W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), + W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), + W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), + W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; + memcpy(state, s, sizeof(s)); +} + +void SHA512::InitState(HashWordType *state) +{ + const word64 s[8] = { + W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), + W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), + W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), + W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; + memcpy(state, s, sizeof(s)); +} + +#if CRYPTOPP_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86) + +ANONYMOUS_NAMESPACE_BEGIN + +// No inlining due to https://github.com/weidai11/cryptopp/issues/684 +// g++ -DNDEBUG -g2 -O3 -pthread -pipe -c sha.cpp +// sha.cpp: Assembler messages: +// sha.cpp:1155: Error: symbol `SHA512_Round' is already defined +// sha.cpp:1155: Error: symbol `SHA512_Round' is already defined + +CRYPTOPP_NOINLINE CRYPTOPP_NAKED +void CRYPTOPP_FASTCALL SHA512_HashBlock_SSE2(word64 *state, const word64 *data) +{ +#ifdef __GNUC__ + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS_PUSH_IF86( bx) + AS2( mov ebx, eax) +#else + AS1( push ebx) + AS1( push esi) + AS1( push edi) + AS2( lea ebx, SHA512_K) +#endif + + AS2( mov eax, esp) + AS2( and esp, 0xfffffff0) + AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state + AS_PUSH_IF86( ax) + AS2( xor eax, eax) + + AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying + AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8 + + AS2( movdqu xmm0, [ecx+0*16]) + AS2( movdq2q mm4, xmm0) + AS2( movdqu [edi+0*16], xmm0) + AS2( movdqu xmm0, [ecx+1*16]) + AS2( movdqu [edi+1*16], xmm0) + AS2( movdqu xmm0, [ecx+2*16]) + AS2( movdq2q mm5, xmm0) + AS2( movdqu [edi+2*16], xmm0) + AS2( movdqu xmm0, [ecx+3*16]) + AS2( movdqu [edi+3*16], xmm0) + ASJ( jmp, 0, f) + +#define SSE2_S0_S1(r, a, b, c) \ + AS2( movq mm6, r)\ + AS2( psrlq r, a)\ + AS2( movq mm7, r)\ + AS2( psllq mm6, 64-c)\ + AS2( pxor mm7, mm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor mm7, r)\ + AS2( psllq mm6, c-b)\ + AS2( pxor mm7, mm6)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, mm7)\ + AS2( psllq mm6, b-a)\ + AS2( pxor r, mm6) + +#define SSE2_s0(r, a, b, c) \ + AS2( movdqu xmm6, r)\ + AS2( psrlq r, a)\ + AS2( movdqu xmm7, r)\ + AS2( psllq xmm6, 64-c)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor xmm7, r)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, xmm7)\ + AS2( psllq xmm6, c-a)\ + AS2( pxor r, xmm6) + +#define SSE2_s1(r, a, b, c) \ + AS2( movdqu xmm6, r)\ + AS2( psrlq r, a)\ + AS2( movdqu xmm7, r)\ + AS2( psllq xmm6, 64-c)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor xmm7, r)\ + AS2( psllq xmm6, c-b)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, xmm7) + ASL(SHA512_Round) + + // k + w is in mm0, a is in mm4, e is in mm5 + AS2( paddq mm0, [edi+7*8]) // h + AS2( movq mm2, [edi+5*8]) // f + AS2( movq mm3, [edi+6*8]) // g + AS2( pxor mm2, mm3) + AS2( pand mm2, mm5) + SSE2_S0_S1(mm5,14,18,41) + AS2( pxor mm2, mm3) + AS2( paddq mm0, mm2) // h += Ch(e,f,g) + AS2( paddq mm5, mm0) // h += S1(e) + AS2( movq mm2, [edi+1*8]) // b + AS2( movq mm1, mm2) + AS2( por mm2, mm4) + AS2( pand mm2, [edi+2*8]) // c + AS2( pand mm1, mm4) + AS2( por mm1, mm2) + AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c) + AS2( paddq mm5, [edi+3*8]) // e = d + h + AS2( movq [edi+3*8], mm5) + AS2( movq [edi+11*8], mm5) + SSE2_S0_S1(mm4,28,34,39) // S0(a) + AS2( paddq mm4, mm1) // a = temp + S0(a) + AS2( movq [edi-8], mm4) + AS2( movq [edi+7*8], mm4) + AS1( ret) + + // first 16 rounds + ASL(0) + AS2( movq mm0, [edx+eax*8]) + AS2( movq [esi+eax*8], mm0) + AS2( movq [esi+eax*8+16*8], mm0) + AS2( paddq mm0, [ebx+eax*8]) + ASC( call, SHA512_Round) + + AS1( inc eax) + AS2( sub edi, 8) + AS2( test eax, 7) + ASJ( jnz, 0, b) + AS2( add edi, 8*8) + AS2( cmp eax, 16) + ASJ( jne, 0, b) + + // rest of the rounds + AS2( movdqu xmm0, [esi+(16-2)*8]) + ASL(1) + // data expansion, W[i-2] already in xmm0 + AS2( movdqu xmm3, [esi]) + AS2( paddq xmm3, [esi+(16-7)*8]) + AS2( movdqu xmm2, [esi+(16-15)*8]) + SSE2_s1(xmm0, 6, 19, 61) + AS2( paddq xmm0, xmm3) + SSE2_s0(xmm2, 1, 7, 8) + AS2( paddq xmm0, xmm2) + AS2( movdq2q mm0, xmm0) + AS2( movhlps xmm1, xmm0) + AS2( paddq mm0, [ebx+eax*8]) + AS2( movlps [esi], xmm0) + AS2( movlps [esi+8], xmm1) + AS2( movlps [esi+8*16], xmm0) + AS2( movlps [esi+8*17], xmm1) + // 2 rounds + ASC( call, SHA512_Round) + AS2( sub edi, 8) + AS2( movdq2q mm0, xmm1) + AS2( paddq mm0, [ebx+eax*8+8]) + ASC( call, SHA512_Round) + // update indices and loop + AS2( add esi, 16) + AS2( add eax, 2) + AS2( sub edi, 8) + AS2( test eax, 7) + ASJ( jnz, 1, b) + // do housekeeping every 8 rounds + AS2( mov esi, 0xf) + AS2( and esi, eax) + AS2( lea esi, [esp+4+20*8+8+esi*8]) + AS2( add edi, 8*8) + AS2( cmp eax, 80) + ASJ( jne, 1, b) + +#define SSE2_CombineState(i) \ + AS2( movdqu xmm0, [edi+i*16])\ + AS2( paddq xmm0, [ecx+i*16])\ + AS2( movdqu [ecx+i*16], xmm0) + + SSE2_CombineState(0) + SSE2_CombineState(1) + SSE2_CombineState(2) + SSE2_CombineState(3) + + AS_POP_IF86( sp) + AS1( emms) + +#if defined(__GNUC__) + AS_POP_IF86( bx) + ATT_PREFIX + : + : "a" (SHA512_K), "c" (state), "d" (data) + : "%esi", "%edi", "memory", "cc" + ); +#else + AS1( pop edi) + AS1( pop esi) + AS1( pop ebx) + AS1( ret) +#endif +} + +ANONYMOUS_NAMESPACE_END + +#endif // CRYPTOPP_SSE2_ASM_AVAILABLE + +ANONYMOUS_NAMESPACE_BEGIN + +#define a(i) T[(0-i)&7] +#define b(i) T[(1-i)&7] +#define c(i) T[(2-i)&7] +#define d(i) T[(3-i)&7] +#define e(i) T[(4-i)&7] +#define f(i) T[(5-i)&7] +#define g(i) T[(6-i)&7] +#define h(i) T[(7-i)&7] + +#define blk0(i) (W[i]=data[i]) +#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) (y^((x^y)&(y^z))) + +#define s0(x) (rotrConstant<1>(x)^rotrConstant<8>(x)^(x>>7)) +#define s1(x) (rotrConstant<19>(x)^rotrConstant<61>(x)^(x>>6)) +#define S0(x) (rotrConstant<28>(x)^rotrConstant<34>(x)^rotrConstant<39>(x)) +#define S1(x) (rotrConstant<14>(x)^rotrConstant<18>(x)^rotrConstant<41>(x)) + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+\ + (j?blk2(i):blk0(i));d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)); + +void SHA512_HashBlock_CXX(word64 *state, const word64 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + + word64 W[16]={0}, T[8]; + + /* Copy context->state[] to working vars */ + std::memcpy(T, state, sizeof(T)); + + /* 80 operations, partially loop unrolled */ + for (unsigned int j=0; j<80; j+=16) + { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + + state[0] += a(0); + state[1] += b(0); + state[2] += c(0); + state[3] += d(0); + state[4] += e(0); + state[5] += f(0); + state[6] += g(0); + state[7] += h(0); +} + +ANONYMOUS_NAMESPACE_END + +void SHA512::Transform(word64 *state, const word64 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + +#if CRYPTOPP_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86) + if (HasSSE2()) + { + SHA512_HashBlock_SSE2(state, data); + return; + } +#endif +#if CRYPTOGAMS_ARM_SHA512 + if (HasNEON()) + { +# if (CRYPTOPP_LITTLE_ENDIAN) + word64 dataBuf[16]; + ByteReverse(dataBuf, data, SHA512::BLOCKSIZE); + cryptogams_sha512_block_data_order_neon(state, dataBuf, 1); +# else + cryptogams_sha512_block_data_order_neon(state, data, 1); +# endif + return; + } + if (HasARMv7()) + { +# if (CRYPTOPP_LITTLE_ENDIAN) + word64 dataBuf[16]; + ByteReverse(dataBuf, data, SHA512::BLOCKSIZE); + cryptogams_sha512_block_data_order(state, dataBuf, 1); +# else + cryptogams_sha512_block_data_order(state, data, 1); +# endif + return; + } +#endif +#if CRYPTOPP_POWER8_SHA_AVAILABLE + if (HasSHA512()) + { + SHA512_HashMultipleBlocks_POWER8(state, data, SHA512::BLOCKSIZE, BIG_ENDIAN_ORDER); + return; + } +#endif + + SHA512_HashBlock_CXX(state, data); +} + +#undef Ch +#undef Maj + +#undef s0 +#undef s1 +#undef S0 +#undef S1 + +#undef blk0 +#undef blk1 +#undef blk2 + +#undef R + +#undef a +#undef b +#undef c +#undef d +#undef e +#undef f +#undef g +#undef h + +NAMESPACE_END + +#endif // Not CRYPTOPP_GENERATE_X64_MASM +#endif // Not CRYPTOPP_IMPORTS diff --git a/external/ours/library/crypto/src/shared/original/sha.h b/external/ours/library/crypto/src/shared/original/sha.h new file mode 100755 index 000000000..a819bd92b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha.h @@ -0,0 +1,210 @@ +// sha.h - originally written and placed in the public domain by Wei Dai + +/// \file sha.h +/// \brief Classes for SHA-1 and SHA-2 family of message digests +/// \since SHA1 since Crypto++ 1.0, SHA2 since Crypto++ 4.0, ARMv8 SHA since +/// Crypto++ 6.0, Intel SHA since Crypto++ 6.0, Power8 SHA since Crypto++ 6.1 + +#ifndef CRYPTOPP_SHA_H +#define CRYPTOPP_SHA_H + +#include "config.h" +#include "iterhash.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_SHA_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SHA-1 message digest +/// \sa SHA-1 +/// \since SHA1 since Crypto++ 1.0, SHA2 since Crypto++ 4.0, ARMv8 SHA since +/// Crypto++ 6.0, Intel SHA since Crypto++ 6.0 +class CRYPTOPP_DLL SHA1 : public IteratedHashWithStaticTransform +{ +public: + /// \brief Initialize state array + /// \param state the state of the hash + /// \details InitState sets a state array to SHA1 initial values + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array must be 16-byte aligned for SSE2. + static void CRYPTOPP_API InitState(HashWordType *state); + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + /// \details Transform operates the hash on data. When the call is invoked + /// digest holds initial state. Upon return digest holds the hash + /// or updated state. + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array and data must be 16-byte aligned for SSE2. + static void CRYPTOPP_API Transform(HashWordType *digest, const HashWordType *data); + /// \brief The algorithm name + /// \return C-style string "SHA-1" + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "SHA-1";} + // Algorithm class + std::string AlgorithmProvider() const; + +protected: + size_t HashMultipleBlocks(const HashWordType *input, size_t length); +}; + +/// \brief SHA-256 message digest +/// \sa SHA-256 +/// \since SHA2 since Crypto++ 4.0, ARMv8 SHA since Crypto++ 6.0, +/// Intel SHA since Crypto++ 6.0, Power8 SHA since Crypto++ 6.1 +class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform +{ +public: + /// \brief Initialize state array + /// \param state the state of the hash + /// \details InitState sets a state array to SHA256 initial values + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array must be 16-byte aligned for SSE2. + static void CRYPTOPP_API InitState(HashWordType *state); + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + /// \details Transform operates the hash on data. When the call is invoked + /// digest holds initial state. Upon return digest holds the hash + /// or updated state. + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array and data must be 16-byte aligned for SSE2. + static void CRYPTOPP_API Transform(HashWordType *digest, const HashWordType *data); + /// \brief The algorithm name + /// \return C-style string "SHA-256" + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "SHA-256";} + + // Algorithm class + std::string AlgorithmProvider() const; + +protected: + size_t HashMultipleBlocks(const HashWordType *input, size_t length); +}; + +/// \brief SHA-224 message digest +/// \sa SHA-224 +/// \since SHA2 since Crypto++ 4.0, ARMv8 SHA since Crypto++ 6.0, +/// Intel SHA since Crypto++ 6.0, Power8 SHA since Crypto++ 6.1 +class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform +{ +public: + /// \brief Initialize state array + /// \param state the state of the hash + /// \details InitState sets a state array to SHA224 initial values + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array must be 16-byte aligned for SSE2. + static void CRYPTOPP_API InitState(HashWordType *state); + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + /// \details Transform operates the hash on data. When the call is invoked + /// digest holds initial state. Upon return digest holds the hash + /// or updated state. + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array and data must be 16-byte aligned for SSE2. + static void CRYPTOPP_API Transform(HashWordType *digest, const HashWordType *data) {SHA256::Transform(digest, data);} + /// \brief The algorithm name + /// \return C-style string "SHA-224" + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "SHA-224";} + + // Algorithm class + std::string AlgorithmProvider() const; + +protected: + size_t HashMultipleBlocks(const HashWordType *input, size_t length); +}; + +/// \brief SHA-512 message digest +/// \sa SHA-512 +/// \since SHA2 since Crypto++ 4.0, Power8 SHA since Crypto++ 6.1 +class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform +{ +public: + /// \brief Initialize state array + /// \param state the state of the hash + /// \details InitState sets a state array to SHA512 initial values + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array must be 16-byte aligned for SSE2. + static void CRYPTOPP_API InitState(HashWordType *state); + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + /// \details Transform operates the hash on data. When the call is invoked + /// digest holds initial state. Upon return digest holds the hash + /// or updated state. + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array and data must be 16-byte aligned for SSE2. + static void CRYPTOPP_API Transform(HashWordType *digest, const HashWordType *data); + /// \brief The algorithm name + /// \return C-style string "SHA-512" + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "SHA-512";} + + // Algorithm class + std::string AlgorithmProvider() const; +}; + +/// \brief SHA-384 message digest +/// \sa SHA-384 +/// \since SHA2 since Crypto++ 4.0, Power8 SHA since Crypto++ 6.1 +class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform +{ +public: + /// \brief Initialize state array + /// \param state the state of the hash + /// \details InitState sets a state array to SHA384 initial values + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array must be 16-byte aligned for SSE2. + static void CRYPTOPP_API InitState(HashWordType *state); + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + /// \details Transform operates the hash on data. When the call is invoked + /// digest holds initial state. Upon return digest holds the hash + /// or updated state. + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState and Transform. External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + /// \note On Intel platforms the state array and data must be 16-byte aligned for SSE2. + static void CRYPTOPP_API Transform(HashWordType *digest, const HashWordType *data) {SHA512::Transform(digest, data);} + /// \brief The algorithm name + /// \return C-style string "SHA-384" + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "SHA-384";} + + // Algorithm class + std::string AlgorithmProvider() const; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/sha1_armv4.h b/external/ours/library/crypto/src/shared/original/sha1_armv4.h new file mode 100755 index 000000000..7cdb6dab3 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha1_armv4.h @@ -0,0 +1,23 @@ +/* Header file for use with Cryptogam's ARMv4 SHA1. */ +/* Also see http://www.openssl.org/~appro/cryptogams/ */ +/* https://wiki.openssl.org/index.php/Cryptogams_SHA. */ + +#ifndef CRYPTOGAMS_SHA1_ARMV4_H +#define CRYPTOGAMS_SHA1_ARMV4_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Crypto++ modified sha1_block_data_order to pass caps as a parameter. */ +/* Also see https://github.com/weidai11/cryptopp/issues/846. */ +void cryptogams_sha1_block_data_order(void *state, const void *data, size_t blocks); + +/* Cryptogams arm caps */ +#define CRYPTOGAMS_ARMV7_NEON (1<<0) + +#ifdef __cplusplus +} +#endif + +#endif /* CRYPTOGAMS_SHA1_ARMV4_H */ diff --git a/external/ours/library/crypto/src/shared/original/sha256_armv4.h b/external/ours/library/crypto/src/shared/original/sha256_armv4.h new file mode 100755 index 000000000..a577b5b09 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha256_armv4.h @@ -0,0 +1,23 @@ +/* Header file for use with Cryptogam's ARMv4 SHA1. */ +/* Also see http://www.openssl.org/~appro/cryptogams/ */ +/* https://wiki.openssl.org/index.php/Cryptogams_SHA. */ + +#ifndef CRYPTOGAMS_SHA256_ARMV4_H +#define CRYPTOGAMS_SHA256_ARMV4_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Crypto++ modified cryptogams_sha256_block_data_order to pass caps as a parameter. */ +/* Also see https://github.com/weidai11/cryptopp/issues/846. */ +void cryptogams_sha256_block_data_order(void *state, const void *data, size_t blocks); + +/* Cryptogams arm caps */ +#define CRYPTOGAMS_ARMV7_NEON (1<<0) + +#ifdef __cplusplus +} +#endif + +#endif /* CRYPTOGAMS_SHA256_ARMV4_H */ diff --git a/external/ours/library/crypto/src/shared/original/sha3.cpp b/external/ours/library/crypto/src/shared/original/sha3.cpp new file mode 100755 index 000000000..35de1b135 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha3.cpp @@ -0,0 +1,71 @@ +// sha3.cpp - modified by Wei Dai from Ronny Van Keer's public domain +// Keccak-simple.c. All modifications here are placed in the +// public domain by Wei Dai. +// Keccack core function moved to keccakc.cpp in AUG 2018 +// by Jeffrey Walton. Separating the core file allows both +// SHA3 and Keccack to share the core implementation. + +/* +The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, +Michael Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "pch.h" +#include "sha3.h" + +NAMESPACE_BEGIN(CryptoPP) + +// The Keccak core function +extern void KeccakF1600(word64 *state); + +NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void SHA3::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); + if (length == 0) { return; } + + size_t spaceLeft; + while (length >= (spaceLeft = r() - m_counter)) + { + if (spaceLeft) + xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft); + KeccakF1600(m_state); + input += spaceLeft; + length -= spaceLeft; + m_counter = 0; + } + + if (length) + xorbuf(m_state.BytePtr() + m_counter, input, length); + m_counter += (unsigned int)length; +} + +void SHA3::Restart() +{ + memset(m_state, 0, m_state.SizeInBytes()); + m_counter = 0; +} + +void SHA3::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + ThrowIfInvalidTruncatedSize(size); + + m_state.BytePtr()[m_counter] ^= 0x06; + m_state.BytePtr()[r()-1] ^= 0x80; + KeccakF1600(m_state); + std::memcpy(hash, m_state, size); + Restart(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/sha3.h b/external/ours/library/crypto/src/shared/original/sha3.h new file mode 100755 index 000000000..f02b7d44b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha3.h @@ -0,0 +1,106 @@ +// sha3.h - originally written and placed in the public domain by Wei Dai + +/// \file sha3.h +/// \brief Classes for SHA3 message digests +/// \details The Crypto++ implementation conforms to the FIPS 202 version of SHA3 using F1600 with XOF d=0x06. +/// Previous behavior (XOF d=0x01) is available in Keccak classes. +/// \sa SHA-3, +/// SHA-3 STANDARD (FIPS 202). +/// \since Crypto++ 5.6.2 + +#ifndef CRYPTOPP_SHA3_H +#define CRYPTOPP_SHA3_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SHA3 message digest base class +/// \details The Crypto++ implementation conforms to FIPS 202 version of SHA3 using F1600 with XOF d=0x06. +/// Previous behavior (XOF d=0x01) is available in Keccak classes. +/// \details SHA3 is the base class for SHA3_224, SHA3_256, SHA3_384 and SHA3_512. +/// Library users should instantiate a derived class, and only use SHA3 +/// as a base class reference or pointer. +/// \sa Keccak, SHA3_224, SHA3_256, SHA3_384 and SHA3_512. +/// \since Crypto++ 5.6.2 +class SHA3 : public HashTransformation +{ +protected: + /// \brief Construct a SHA3 + /// \param digestSize the digest size, in bytes + /// \details SHA3 is the base class for SHA3_224, SHA3_256, SHA3_384 and SHA3_512. + /// Library users should instantiate a derived class, and only use SHA3 + /// as a base class reference or pointer. + /// \details This constructor was moved to protected at Crypto++ 8.1 + /// because users were attempting to create Keccak objects with it. + /// \since Crypto++ 5.6.2 + SHA3(unsigned int digestSize) : m_digestSize(digestSize) {Restart();} + +public: + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + void Update(const byte *input, size_t length); + void Restart(); + void TruncatedFinal(byte *hash, size_t size); + +protected: + inline unsigned int r() const {return BlockSize();} + + FixedSizeSecBlock m_state; + unsigned int m_digestSize, m_counter; +}; + +/// \brief SHA3 message digest template +/// \tparam T_DigestSize the size of the digest, in bytes +/// \since Crypto++ 5.6.2 +template +class SHA3_Final : public SHA3 +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize); + CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * DIGESTSIZE); + static std::string StaticAlgorithmName() + { return "SHA3-" + IntToString(DIGESTSIZE * 8); } + + /// \brief Construct a SHA3-X message digest + SHA3_Final() : SHA3(DIGESTSIZE) {} + + /// \brief Provides the block size of the compression function + /// \return block size of the compression function, in bytes + /// \details BlockSize() will return 0 if the hash is not block based + /// or does not have an equivalent block size. For example, Keccak + /// and SHA-3 do not have a block size, but they do have an equivalent + /// block size called rate expressed as r. + unsigned int BlockSize() const { return BLOCKSIZE; } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } + +private: +#if !defined(__BORLANDC__) + // ensure there was no underflow in the math + CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); +#endif +}; + +/// \brief SHA3-224 message digest +/// \since Crypto++ 5.6.2 +class SHA3_224 : public SHA3_Final<28> {}; + +/// \brief SHA3-256 message digest +/// \since Crypto++ 5.6.2 +class SHA3_256 : public SHA3_Final<32> {}; + +/// \brief SHA3-384 message digest +/// \since Crypto++ 5.6.2 +class SHA3_384 : public SHA3_Final<48> {}; + +/// \brief SHA3-512 message digest +/// \since Crypto++ 5.6.2 +class SHA3_512 : public SHA3_Final<64> {}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/sha512_armv4.h b/external/ours/library/crypto/src/shared/original/sha512_armv4.h new file mode 100755 index 000000000..b914577f0 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha512_armv4.h @@ -0,0 +1,23 @@ +/* Header file for use with Cryptogam's ARMv4 SHA512. */ +/* Also see http://www.openssl.org/~appro/cryptogams/ */ +/* https://wiki.openssl.org/index.php/Cryptogams_SHA. */ + +#ifndef CRYPTOGAMS_SHA512_ARMV4_H +#define CRYPTOGAMS_SHA512_ARMV4_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Crypto++ modified cryptogams_sha512_block_data_order to pass caps as a parameter. */ +/* Also see https://github.com/weidai11/cryptopp/issues/846. */ +void cryptogams_sha512_block_data_order(void *state, const void *data, size_t blocks); + +/* Cryptogams arm caps */ +#define CRYPTOGAMS_ARMV7_NEON (1<<0) + +#ifdef __cplusplus +} +#endif + +#endif /* CRYPTOGAMS_SHA512_ARMV4_H */ diff --git a/external/ours/library/crypto/src/shared/original/sha_simd.cpp b/external/ours/library/crypto/src/shared/original/sha_simd.cpp new file mode 100755 index 000000000..18bdf1923 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sha_simd.cpp @@ -0,0 +1,1506 @@ +// sha_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics to gain access to SHA-NI and +// ARMv8a SHA instructions. A separate source file is needed +// because additional CXXFLAGS are required to enable the +// appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "sha.h" +#include "misc.h" + +#if defined(CRYPTOPP_DISABLE_SHA_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +#if (CRYPTOPP_SHANI_AVAILABLE) +# include +# include +#endif + +// Android makes available with ARMv7-a +#if (CRYPTOPP_BOOL_ARMV8) +# if (CRYPTOPP_ARM_NEON_HEADER) +# include +# endif +# if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +# endif +#endif + +#if CRYPTOPP_POWER8_SHA_AVAILABLE +# include "ppc_simd.h" +#endif + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char SHA_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +// ***************** SHA key tables ******************** + +extern const word32 SHA256_K[64]; +extern const word64 SHA512_K[80]; + +// ***************** SIGILL probes ******************** + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); + + static jmp_buf s_jmpSIGILL; + static void SigIllHandler(int) + { + longjmp(s_jmpSIGILL, 1); + } +} +#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY + +#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) +bool CPU_ProbeSHA1() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (CRYPTOPP_ARM_SHA1_AVAILABLE) +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + unsigned int w[] = {1,2,3,4, 5,6,7,8, 9,10,11,12}; + uint32x4_t data1 = vld1q_u32(w+0); + uint32x4_t data2 = vld1q_u32(w+4); + uint32x4_t data3 = vld1q_u32(w+8); + + uint32x4_t r1 = vsha1cq_u32 (data1, 0, data2); + uint32x4_t r2 = vsha1mq_u32 (data1, 0, data2); + uint32x4_t r3 = vsha1pq_u32 (data1, 0, data2); + uint32x4_t r4 = vsha1su0q_u32 (data1, data2, data3); + uint32x4_t r5 = vsha1su1q_u32 (data1, data2); + + result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3) | vgetq_lane_u32(r5,0)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +# else + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + unsigned int w[] = {1,2,3,4, 5,6,7,8, 9,10,11,12}; + uint32x4_t data1 = vld1q_u32(w+0); + uint32x4_t data2 = vld1q_u32(w+4); + uint32x4_t data3 = vld1q_u32(w+8); + + uint32x4_t r1 = vsha1cq_u32 (data1, 0, data2); + uint32x4_t r2 = vsha1mq_u32 (data1, 0, data2); + uint32x4_t r3 = vsha1pq_u32 (data1, 0, data2); + uint32x4_t r4 = vsha1su0q_u32 (data1, data2, data3); + uint32x4_t r5 = vsha1su1q_u32 (data1, data2); + + result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3) | vgetq_lane_u32(r5,0)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_SHA1_AVAILABLE +} + +bool CPU_ProbeSHA256() +{ +#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif (CRYPTOPP_ARM_SHA2_AVAILABLE) +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + unsigned int w[] = {1,2,3,4, 5,6,7,8, 9,10,11,12}; + uint32x4_t data1 = vld1q_u32(w+0); + uint32x4_t data2 = vld1q_u32(w+4); + uint32x4_t data3 = vld1q_u32(w+8); + + uint32x4_t r1 = vsha256hq_u32 (data1, data2, data3); + uint32x4_t r2 = vsha256h2q_u32 (data1, data2, data3); + uint32x4_t r3 = vsha256su0q_u32 (data1, data2); + uint32x4_t r4 = vsha256su1q_u32 (data1, data2, data3); + + result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +#else + + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } + + if (setjmp(s_jmpSIGILL)) + result = false; + else + { + unsigned int w[] = {1,2,3,4, 5,6,7,8, 9,10,11,12}; + uint32x4_t data1 = vld1q_u32(w+0); + uint32x4_t data2 = vld1q_u32(w+4); + uint32x4_t data3 = vld1q_u32(w+8); + + uint32x4_t r1 = vsha256hq_u32 (data1, data2, data3); + uint32x4_t r2 = vsha256h2q_u32 (data1, data2, data3); + uint32x4_t r3 = vsha256su0q_u32 (data1, data2); + uint32x4_t r4 = vsha256su1q_u32 (data1, data2, data3); + + result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3)); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_ARM_SHA2_AVAILABLE +} +#endif // ARM32 or ARM64 + +// ***************** Intel x86 SHA ******************** + +///////////////////////////////////// +// start of Walton and Gulley code // +///////////////////////////////////// + +#if CRYPTOPP_SHANI_AVAILABLE +// Based on http://software.intel.com/en-us/articles/intel-sha-extensions and code by Sean Gulley. +void SHA1_HashMultipleBlocks_SHANI(word32 *state, const word32 *data, size_t length, ByteOrder order) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + CRYPTOPP_ASSERT(length >= SHA1::BLOCKSIZE); + + __m128i ABCD, ABCD_SAVE, E0, E0_SAVE, E1; + __m128i MASK, MSG0, MSG1, MSG2, MSG3; + + // Load initial values + ABCD = _mm_loadu_si128(CONST_M128_CAST(state)); + E0 = _mm_set_epi32(state[4], 0, 0, 0); + ABCD = _mm_shuffle_epi32(ABCD, 0x1B); + + // IA-32 SHA is little endian, SHA::Transform is big endian, + // and SHA::HashMultipleBlocks can be either. ByteOrder + // allows us to avoid extra endian reversals. It saves 1.0 cpb. + MASK = order == BIG_ENDIAN_ORDER ? // Data arrangement + _mm_set_epi8(0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15) : + _mm_set_epi8(3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12) ; + + while (length >= SHA1::BLOCKSIZE) + { + // Save current hash + ABCD_SAVE = ABCD; + E0_SAVE = E0; + + // Rounds 0-3 + MSG0 = _mm_loadu_si128(CONST_M128_CAST(data+0)); + MSG0 = _mm_shuffle_epi8(MSG0, MASK); + E0 = _mm_add_epi32(E0, MSG0); + E1 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); + + // Rounds 4-7 + MSG1 = _mm_loadu_si128(CONST_M128_CAST(data+4)); + MSG1 = _mm_shuffle_epi8(MSG1, MASK); + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + + // Rounds 8-11 + MSG2 = _mm_loadu_si128(CONST_M128_CAST(data+8)); + MSG2 = _mm_shuffle_epi8(MSG2, MASK); + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 12-15 + MSG3 = _mm_loadu_si128(CONST_M128_CAST(data+12)); + MSG3 = _mm_shuffle_epi8(MSG3, MASK); + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 16-19 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 20-23 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 24-27 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 28-31 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 32-35 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 36-39 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 40-43 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 44-47 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 48-51 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 52-55 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 56-59 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 60-63 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 64-67 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 68-71 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 72-75 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3); + + // Rounds 76-79 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); + + // Add values back to state + E0 = _mm_sha1nexte_epu32(E0, E0_SAVE); + ABCD = _mm_add_epi32(ABCD, ABCD_SAVE); + + data += SHA1::BLOCKSIZE/sizeof(word32); + length -= SHA1::BLOCKSIZE; + } + + // Save state + ABCD = _mm_shuffle_epi32(ABCD, 0x1B); + _mm_storeu_si128(M128_CAST(state), ABCD); + state[4] = _mm_extract_epi32(E0, 3); +} + +// Based on http://software.intel.com/en-us/articles/intel-sha-extensions and code by Sean Gulley. +void SHA256_HashMultipleBlocks_SHANI(word32 *state, const word32 *data, size_t length, ByteOrder order) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + CRYPTOPP_ASSERT(length >= SHA256::BLOCKSIZE); + + __m128i STATE0, STATE1; + __m128i MSG, TMP, MASK; + __m128i TMSG0, TMSG1, TMSG2, TMSG3; + __m128i ABEF_SAVE, CDGH_SAVE; + + // Load initial values + TMP = _mm_loadu_si128(M128_CAST(&state[0])); + STATE1 = _mm_loadu_si128(M128_CAST(&state[4])); + + // IA-32 SHA is little endian, SHA::Transform is big endian, + // and SHA::HashMultipleBlocks can be either. ByteOrder + // allows us to avoid extra endian reversals. It saves 1.0 cpb. + MASK = order == BIG_ENDIAN_ORDER ? // Data arrangement + _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3) : + _mm_set_epi8(15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0) ; + + TMP = _mm_shuffle_epi32(TMP, 0xB1); // CDAB + STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); // EFGH + STATE0 = _mm_alignr_epi8(TMP, STATE1, 8); // ABEF + STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0); // CDGH + + while (length >= SHA256::BLOCKSIZE) + { + // Save current hash + ABEF_SAVE = STATE0; + CDGH_SAVE = STATE1; + + // Rounds 0-3 + MSG = _mm_loadu_si128(CONST_M128_CAST(data+0)); + TMSG0 = _mm_shuffle_epi8(MSG, MASK); + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(W64LIT(0xE9B5DBA5B5C0FBCF), W64LIT(0x71374491428A2F98))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Rounds 4-7 + TMSG1 = _mm_loadu_si128(CONST_M128_CAST(data+4)); + TMSG1 = _mm_shuffle_epi8(TMSG1, MASK); + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(W64LIT(0xAB1C5ED5923F82A4), W64LIT(0x59F111F13956C25B))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1); + + // Rounds 8-11 + TMSG2 = _mm_loadu_si128(CONST_M128_CAST(data+8)); + TMSG2 = _mm_shuffle_epi8(TMSG2, MASK); + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(W64LIT(0x550C7DC3243185BE), W64LIT(0x12835B01D807AA98))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2); + + // Rounds 12-15 + TMSG3 = _mm_loadu_si128(CONST_M128_CAST(data+12)); + TMSG3 = _mm_shuffle_epi8(TMSG3, MASK); + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(W64LIT(0xC19BF1749BDC06A7), W64LIT(0x80DEB1FE72BE5D74))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4); + TMSG0 = _mm_add_epi32(TMSG0, TMP); + TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3); + + // Rounds 16-19 + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(W64LIT(0x240CA1CC0FC19DC6), W64LIT(0xEFBE4786E49B69C1))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4); + TMSG1 = _mm_add_epi32(TMSG1, TMP); + TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0); + + // Rounds 20-23 + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(W64LIT(0x76F988DA5CB0A9DC), W64LIT(0x4A7484AA2DE92C6F))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4); + TMSG2 = _mm_add_epi32(TMSG2, TMP); + TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1); + + // Rounds 24-27 + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(W64LIT(0xBF597FC7B00327C8), W64LIT(0xA831C66D983E5152))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4); + TMSG3 = _mm_add_epi32(TMSG3, TMP); + TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2); + + // Rounds 28-31 + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(W64LIT(0x1429296706CA6351), W64LIT(0xD5A79147C6E00BF3))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4); + TMSG0 = _mm_add_epi32(TMSG0, TMP); + TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3); + + // Rounds 32-35 + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(W64LIT(0x53380D134D2C6DFC), W64LIT(0x2E1B213827B70A85))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4); + TMSG1 = _mm_add_epi32(TMSG1, TMP); + TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0); + + // Rounds 36-39 + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(W64LIT(0x92722C8581C2C92E), W64LIT(0x766A0ABB650A7354))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4); + TMSG2 = _mm_add_epi32(TMSG2, TMP); + TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1); + + // Rounds 40-43 + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(W64LIT(0xC76C51A3C24B8B70), W64LIT(0xA81A664BA2BFE8A1))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4); + TMSG3 = _mm_add_epi32(TMSG3, TMP); + TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2); + + // Rounds 44-47 + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(W64LIT(0x106AA070F40E3585), W64LIT(0xD6990624D192E819))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4); + TMSG0 = _mm_add_epi32(TMSG0, TMP); + TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3); + + // Rounds 48-51 + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(W64LIT(0x34B0BCB52748774C), W64LIT(0x1E376C0819A4C116))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4); + TMSG1 = _mm_add_epi32(TMSG1, TMP); + TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0); + + // Rounds 52-55 + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(W64LIT(0x682E6FF35B9CCA4F), W64LIT(0x4ED8AA4A391C0CB3))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4); + TMSG2 = _mm_add_epi32(TMSG2, TMP); + TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Rounds 56-59 + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(W64LIT(0x8CC7020884C87814), W64LIT(0x78A5636F748F82EE))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4); + TMSG3 = _mm_add_epi32(TMSG3, TMP); + TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Rounds 60-63 + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(W64LIT(0xC67178F2BEF9A3F7), W64LIT(0xA4506CEB90BEFFFA))); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Add values back to state + STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE); + STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE); + + data += SHA256::BLOCKSIZE/sizeof(word32); + length -= SHA256::BLOCKSIZE; + } + + TMP = _mm_shuffle_epi32(STATE0, 0x1B); // FEBA + STATE1 = _mm_shuffle_epi32(STATE1, 0xB1); // DCHG + STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0); // DCBA + STATE1 = _mm_alignr_epi8(STATE1, TMP, 8); // ABEF + + // Save state + _mm_storeu_si128(M128_CAST(&state[0]), STATE0); + _mm_storeu_si128(M128_CAST(&state[4]), STATE1); +} +#endif // CRYPTOPP_SHANI_AVAILABLE + +/////////////////////////////////// +// end of Walton and Gulley code // +/////////////////////////////////// + +// ***************** ARMV8 SHA ******************** + +///////////////////////////////////////////////////////////// +// start of Walton, Schneiders, O'Rourke and Hovsmith code // +///////////////////////////////////////////////////////////// + +#if CRYPTOPP_ARM_SHA1_AVAILABLE +void SHA1_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + CRYPTOPP_ASSERT(length >= SHA1::BLOCKSIZE); + + uint32x4_t C0, C1, C2, C3; + uint32x4_t ABCD, ABCD_SAVED; + uint32x4_t MSG0, MSG1, MSG2, MSG3; + uint32x4_t TMP0, TMP1; + uint32_t E0, E0_SAVED, E1; + + // Load initial values + C0 = vdupq_n_u32(0x5A827999); + C1 = vdupq_n_u32(0x6ED9EBA1); + C2 = vdupq_n_u32(0x8F1BBCDC); + C3 = vdupq_n_u32(0xCA62C1D6); + + ABCD = vld1q_u32(&state[0]); + E0 = state[4]; + + while (length >= SHA1::BLOCKSIZE) + { + // Save current hash + ABCD_SAVED = ABCD; + E0_SAVED = E0; + + MSG0 = vld1q_u32(data + 0); + MSG1 = vld1q_u32(data + 4); + MSG2 = vld1q_u32(data + 8); + MSG3 = vld1q_u32(data + 12); + + if (order == BIG_ENDIAN_ORDER) // Data arrangement + { + MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0))); + MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1))); + MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2))); + MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3))); + } + + TMP0 = vaddq_u32(MSG0, C0); + TMP1 = vaddq_u32(MSG1, C0); + + // Rounds 0-3 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C0); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 4-7 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C0); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 8-11 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C0); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 12-15 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C1); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 16-19 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C1); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 20-23 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C1); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 24-27 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C1); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 28-31 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C1); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 32-35 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C2); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 36-39 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C2); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 40-43 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C2); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 44-47 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C2); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 48-51 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C2); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 52-55 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C3); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 56-59 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C3); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 60-63 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C3); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 64-67 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C3); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 68-71 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C3); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + + // Rounds 72-75 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + + // Rounds 76-79 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + + E0 += E0_SAVED; + ABCD = vaddq_u32(ABCD_SAVED, ABCD); + + data += SHA1::BLOCKSIZE/sizeof(word32); + length -= SHA1::BLOCKSIZE; + } + + // Save state + vst1q_u32(&state[0], ABCD); + state[4] = E0; +} +#endif // CRYPTOPP_ARM_SHA1_AVAILABLE + +#if CRYPTOPP_ARM_SHA2_AVAILABLE +void SHA256_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + CRYPTOPP_ASSERT(length >= SHA256::BLOCKSIZE); + + uint32x4_t STATE0, STATE1, ABEF_SAVE, CDGH_SAVE; + uint32x4_t MSG0, MSG1, MSG2, MSG3; + uint32x4_t TMP0, TMP1, TMP2; + + // Load initial values + STATE0 = vld1q_u32(&state[0]); + STATE1 = vld1q_u32(&state[4]); + + while (length >= SHA256::BLOCKSIZE) + { + // Save current hash + ABEF_SAVE = STATE0; + CDGH_SAVE = STATE1; + + // Load message + MSG0 = vld1q_u32(data + 0); + MSG1 = vld1q_u32(data + 4); + MSG2 = vld1q_u32(data + 8); + MSG3 = vld1q_u32(data + 12); + + if (order == BIG_ENDIAN_ORDER) // Data arrangement + { + MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0))); + MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1))); + MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2))); + MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3))); + } + + TMP0 = vaddq_u32(MSG0, vld1q_u32(&SHA256_K[0x00])); + + // Rounds 0-3 + MSG0 = vsha256su0q_u32(MSG0, MSG1); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&SHA256_K[0x04])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3); + + // Rounds 4-7 + MSG1 = vsha256su0q_u32(MSG1, MSG2); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&SHA256_K[0x08])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0); + + // Rounds 8-11 + MSG2 = vsha256su0q_u32(MSG2, MSG3); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&SHA256_K[0x0c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1); + + // Rounds 12-15 + MSG3 = vsha256su0q_u32(MSG3, MSG0); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG0, vld1q_u32(&SHA256_K[0x10])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2); + + // Rounds 16-19 + MSG0 = vsha256su0q_u32(MSG0, MSG1); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&SHA256_K[0x14])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3); + + // Rounds 20-23 + MSG1 = vsha256su0q_u32(MSG1, MSG2); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&SHA256_K[0x18])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0); + + // Rounds 24-27 + MSG2 = vsha256su0q_u32(MSG2, MSG3); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&SHA256_K[0x1c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1); + + // Rounds 28-31 + MSG3 = vsha256su0q_u32(MSG3, MSG0); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG0, vld1q_u32(&SHA256_K[0x20])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2); + + // Rounds 32-35 + MSG0 = vsha256su0q_u32(MSG0, MSG1); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&SHA256_K[0x24])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3); + + // Rounds 36-39 + MSG1 = vsha256su0q_u32(MSG1, MSG2); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&SHA256_K[0x28])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0); + + // Rounds 40-43 + MSG2 = vsha256su0q_u32(MSG2, MSG3); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&SHA256_K[0x2c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1); + + // Rounds 44-47 + MSG3 = vsha256su0q_u32(MSG3, MSG0); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG0, vld1q_u32(&SHA256_K[0x30])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2); + + // Rounds 48-51 + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&SHA256_K[0x34])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + + // Rounds 52-55 + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&SHA256_K[0x38])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + + // Rounds 56-59 + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&SHA256_K[0x3c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + + // Rounds 60-63 + TMP2 = STATE0; + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + + // Add back to state + STATE0 = vaddq_u32(STATE0, ABEF_SAVE); + STATE1 = vaddq_u32(STATE1, CDGH_SAVE); + + data += SHA256::BLOCKSIZE/sizeof(word32); + length -= SHA256::BLOCKSIZE; + } + + // Save state + vst1q_u32(&state[0], STATE0); + vst1q_u32(&state[4], STATE1); +} +#endif // CRYPTOPP_ARM_SHA2_AVAILABLE + +/////////////////////////////////////////////////////////// +// end of Walton, Schneiders, O'Rourke and Hovsmith code // +/////////////////////////////////////////////////////////// + +// ***************** Power8 SHA ******************** + +////////////////////////////////////////////////// +// start Gustavo, Serra, Scalet and Walton code // +////////////////////////////////////////////////// + +#if CRYPTOPP_POWER8_SHA_AVAILABLE + +// Indexes into the S[] array +enum {A=0, B=1, C, D, E, F, G, H}; + +inline +uint32x4_p VecLoad32(const word32* data, int offset) +{ +#if (CRYPTOPP_LITTLE_ENDIAN) + const uint8x16_p mask = {3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12}; + const uint32x4_p val = VecLoad(offset, data); + return (uint32x4_p)VecPermute(val, val, mask); +#else + return VecLoad(offset, data); +#endif +} + +template inline +void VecStore32(const T data, word32 dest[4]) +{ + VecStore(data, dest); +} + +inline +uint32x4_p VectorCh(const uint32x4_p x, const uint32x4_p y, const uint32x4_p z) +{ + // The trick below is due to Andy Polyakov and Jack Lloyd + return vec_sel(z,y,x); +} + +inline +uint32x4_p VectorMaj(const uint32x4_p x, const uint32x4_p y, const uint32x4_p z) +{ + // The trick below is due to Andy Polyakov and Jack Lloyd + return vec_sel(y, z, VecXor(x, y)); +} + +inline +uint32x4_p Vector_sigma0(const uint32x4_p val) +{ + return VecSHA256<0,0>(val); +} + +inline +uint32x4_p Vector_sigma1(const uint32x4_p val) +{ + return VecSHA256<0,0xf>(val); +} + +inline +uint32x4_p VectorSigma0(const uint32x4_p val) +{ + return VecSHA256<1,0>(val); +} + +inline +uint32x4_p VectorSigma1(const uint32x4_p val) +{ + return VecSHA256<1,0xf>(val); +} + +inline +uint32x4_p VectorPack(const uint32x4_p a, const uint32x4_p b, + const uint32x4_p c, const uint32x4_p d) +{ + const uint8x16_p m1 = {0,1,2,3, 16,17,18,19, 0,0,0,0, 0,0,0,0}; + const uint8x16_p m2 = {0,1,2,3, 4,5,6,7, 16,17,18,19, 20,21,22,23}; + return VecPermute(VecPermute(a,b,m1), VecPermute(c,d,m1), m2); +} + +template inline +void SHA256_ROUND1(uint32x4_p W[16], uint32x4_p S[8], const uint32x4_p K, const uint32x4_p M) +{ + uint32x4_p T1, T2; + + W[R] = M; + T1 = S[H] + VectorSigma1(S[E]) + VectorCh(S[E],S[F],S[G]) + K + M; + T2 = VectorSigma0(S[A]) + VectorMaj(S[A],S[B],S[C]); + + S[H] = S[G]; S[G] = S[F]; S[F] = S[E]; + S[E] = S[D] + T1; + S[D] = S[C]; S[C] = S[B]; S[B] = S[A]; + S[A] = T1 + T2; +} + +template inline +void SHA256_ROUND2(uint32x4_p W[16], uint32x4_p S[8], const uint32x4_p K) +{ + // Indexes into the W[] array + enum {IDX0=(R+0)&0xf, IDX1=(R+1)&0xf, IDX9=(R+9)&0xf, IDX14=(R+14)&0xf}; + + const uint32x4_p s0 = Vector_sigma0(W[IDX1]); + const uint32x4_p s1 = Vector_sigma1(W[IDX14]); + + uint32x4_p T1 = (W[IDX0] += s0 + s1 + W[IDX9]); + T1 += S[H] + VectorSigma1(S[E]) + VectorCh(S[E],S[F],S[G]) + K; + uint32x4_p T2 = VectorSigma0(S[A]) + VectorMaj(S[A],S[B],S[C]); + + S[H] = S[G]; S[G] = S[F]; S[F] = S[E]; + S[E] = S[D] + T1; + S[D] = S[C]; S[C] = S[B]; S[B] = S[A]; + S[A] = T1 + T2; +} + +void SHA256_HashMultipleBlocks_POWER8(word32 *state, const word32 *data, size_t length, ByteOrder order) +{ + CRYPTOPP_ASSERT(state); CRYPTOPP_ASSERT(data); + CRYPTOPP_ASSERT(length >= SHA256::BLOCKSIZE); + CRYPTOPP_UNUSED(order); + + const uint32_t* k = reinterpret_cast(SHA256_K); + const uint32_t* m = reinterpret_cast(data); + + uint32x4_p abcd = VecLoad(state+0); + uint32x4_p efgh = VecLoad(state+4); + uint32x4_p W[16], S[8], vm, vk; + + size_t blocks = length / SHA256::BLOCKSIZE; + while (blocks--) + { + unsigned int offset=0; + + S[A] = abcd; S[E] = efgh; + S[B] = VecShiftLeftOctet<4>(S[A]); + S[F] = VecShiftLeftOctet<4>(S[E]); + S[C] = VecShiftLeftOctet<4>(S[B]); + S[G] = VecShiftLeftOctet<4>(S[F]); + S[D] = VecShiftLeftOctet<4>(S[C]); + S[H] = VecShiftLeftOctet<4>(S[G]); + + // Rounds 0-16 + vk = VecLoad(offset, k); + vm = VecLoad32(m, offset); + SHA256_ROUND1<0>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<1>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<2>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<3>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad32(m, offset); + SHA256_ROUND1<4>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<5>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<6>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<7>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad32(m, offset); + SHA256_ROUND1<8>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<9>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<10>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<11>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad32(m, offset); + SHA256_ROUND1<12>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<13>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<14>(W,S, vk,vm); + + vk = VecShiftLeftOctet<4>(vk); + vm = VecShiftLeftOctet<4>(vm); + SHA256_ROUND1<15>(W,S, vk,vm); + + m += 16; // 32-bit words, not bytes + + // Rounds 16-64 + for (unsigned int i=16; i<64; i+=16) + { + vk = VecLoad(offset, k); + SHA256_ROUND2<0>(W,S, vk); + SHA256_ROUND2<1>(W,S, VecShiftLeftOctet<4>(vk)); + SHA256_ROUND2<2>(W,S, VecShiftLeftOctet<8>(vk)); + SHA256_ROUND2<3>(W,S, VecShiftLeftOctet<12>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA256_ROUND2<4>(W,S, vk); + SHA256_ROUND2<5>(W,S, VecShiftLeftOctet<4>(vk)); + SHA256_ROUND2<6>(W,S, VecShiftLeftOctet<8>(vk)); + SHA256_ROUND2<7>(W,S, VecShiftLeftOctet<12>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA256_ROUND2<8>(W,S, vk); + SHA256_ROUND2<9>(W,S, VecShiftLeftOctet<4>(vk)); + SHA256_ROUND2<10>(W,S, VecShiftLeftOctet<8>(vk)); + SHA256_ROUND2<11>(W,S, VecShiftLeftOctet<12>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA256_ROUND2<12>(W,S, vk); + SHA256_ROUND2<13>(W,S, VecShiftLeftOctet<4>(vk)); + SHA256_ROUND2<14>(W,S, VecShiftLeftOctet<8>(vk)); + SHA256_ROUND2<15>(W,S, VecShiftLeftOctet<12>(vk)); + offset+=16; + } + + abcd += VectorPack(S[A],S[B],S[C],S[D]); + efgh += VectorPack(S[E],S[F],S[G],S[H]); + } + + VecStore32(abcd, state+0); + VecStore32(efgh, state+4); +} + +inline +void VecStore64(const uint64x2_p val, word64* data) +{ + VecStore(val, data); +} + +inline +uint64x2_p VecLoad64(const word64* data, int offset) +{ +#if (CRYPTOPP_LITTLE_ENDIAN) + const uint8x16_p mask = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}; + return VecPermute(VecLoad(offset, data), mask); +#else + return VecLoad(offset, data); +#endif +} + +inline +uint64x2_p VectorCh(const uint64x2_p x, const uint64x2_p y, const uint64x2_p z) +{ + // The trick below is due to Andy Polyakov and Jack Lloyd + return vec_sel(z,y,x); +} + +inline +uint64x2_p VectorMaj(const uint64x2_p x, const uint64x2_p y, const uint64x2_p z) +{ + // The trick below is due to Andy Polyakov and Jack Lloyd + return vec_sel(y, z, VecXor(x, y)); +} + +inline +uint64x2_p Vector_sigma0(const uint64x2_p val) +{ + return VecSHA512<0,0>(val); +} + +inline +uint64x2_p Vector_sigma1(const uint64x2_p val) +{ + return VecSHA512<0,0xf>(val); +} + +inline +uint64x2_p VectorSigma0(const uint64x2_p val) +{ + return VecSHA512<1,0>(val); +} + +inline +uint64x2_p VectorSigma1(const uint64x2_p val) +{ + return VecSHA512<1,0xf>(val); +} + +inline +uint64x2_p VectorPack(const uint64x2_p x, const uint64x2_p y) +{ + const uint8x16_p m = {0,1,2,3, 4,5,6,7, 16,17,18,19, 20,21,22,23}; + return VecPermute(x,y,m); +} + +template inline +void SHA512_ROUND1(uint64x2_p W[16], uint64x2_p S[8], const uint64x2_p K, const uint64x2_p M) +{ + uint64x2_p T1, T2; + + W[R] = M; + T1 = S[H] + VectorSigma1(S[E]) + VectorCh(S[E],S[F],S[G]) + K + M; + T2 = VectorSigma0(S[A]) + VectorMaj(S[A],S[B],S[C]); + + S[H] = S[G]; S[G] = S[F]; S[F] = S[E]; + S[E] = S[D] + T1; + S[D] = S[C]; S[C] = S[B]; S[B] = S[A]; + S[A] = T1 + T2; +} + +template inline +void SHA512_ROUND2(uint64x2_p W[16], uint64x2_p S[8], const uint64x2_p K) +{ + // Indexes into the W[] array + enum {IDX0=(R+0)&0xf, IDX1=(R+1)&0xf, IDX9=(R+9)&0xf, IDX14=(R+14)&0xf}; + + const uint64x2_p s0 = Vector_sigma0(W[IDX1]); + const uint64x2_p s1 = Vector_sigma1(W[IDX14]); + + uint64x2_p T1 = (W[IDX0] += s0 + s1 + W[IDX9]); + T1 += S[H] + VectorSigma1(S[E]) + VectorCh(S[E],S[F],S[G]) + K; + uint64x2_p T2 = VectorSigma0(S[A]) + VectorMaj(S[A],S[B],S[C]); + + S[H] = S[G]; S[G] = S[F]; S[F] = S[E]; + S[E] = S[D] + T1; + S[D] = S[C]; S[C] = S[B]; S[B] = S[A]; + S[A] = T1 + T2; +} + +void SHA512_HashMultipleBlocks_POWER8(word64 *state, const word64 *data, size_t length, ByteOrder order) +{ + CRYPTOPP_ASSERT(state); CRYPTOPP_ASSERT(data); + CRYPTOPP_ASSERT(length >= SHA512::BLOCKSIZE); + CRYPTOPP_UNUSED(order); + + const uint64_t* k = reinterpret_cast(SHA512_K); + const uint64_t* m = reinterpret_cast(data); + + uint64x2_p ab = VecLoad(state+0); + uint64x2_p cd = VecLoad(state+2); + uint64x2_p ef = VecLoad(state+4); + uint64x2_p gh = VecLoad(state+6); + uint64x2_p W[16], S[8], vm, vk; + + size_t blocks = length / SHA512::BLOCKSIZE; + while (blocks--) + { + unsigned int offset=0; + + S[A] = ab; S[C] = cd; + S[E] = ef; S[G] = gh; + S[B] = VecShiftLeftOctet<8>(S[A]); + S[D] = VecShiftLeftOctet<8>(S[C]); + S[F] = VecShiftLeftOctet<8>(S[E]); + S[H] = VecShiftLeftOctet<8>(S[G]); + + // Rounds 0-16 + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<0>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<1>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<2>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<3>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<4>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<5>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<6>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<7>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<8>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<9>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<10>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<11>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<12>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<13>(W,S, vk,vm); + + vk = VecLoad(offset, k); + vm = VecLoad64(m, offset); + SHA512_ROUND1<14>(W,S, vk,vm); + offset+=16; + + vk = VecShiftLeftOctet<8>(vk); + vm = VecShiftLeftOctet<8>(vm); + SHA512_ROUND1<15>(W,S, vk,vm); + + m += 16; // 64-bit words, not bytes + + // Rounds 16-80 + for (unsigned int i=16; i<80; i+=16) + { + vk = VecLoad(offset, k); + SHA512_ROUND2<0>(W,S, vk); + SHA512_ROUND2<1>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<2>(W,S, vk); + SHA512_ROUND2<3>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<4>(W,S, vk); + SHA512_ROUND2<5>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<6>(W,S, vk); + SHA512_ROUND2<7>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<8>(W,S, vk); + SHA512_ROUND2<9>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<10>(W,S, vk); + SHA512_ROUND2<11>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<12>(W,S, vk); + SHA512_ROUND2<13>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + + vk = VecLoad(offset, k); + SHA512_ROUND2<14>(W,S, vk); + SHA512_ROUND2<15>(W,S, VecShiftLeftOctet<8>(vk)); + offset+=16; + } + + ab += VectorPack(S[A],S[B]); + cd += VectorPack(S[C],S[D]); + ef += VectorPack(S[E],S[F]); + gh += VectorPack(S[G],S[H]); + } + + VecStore64(ab, state+0); + VecStore64(cd, state+2); + VecStore64(ef, state+4); + VecStore64(gh, state+6); +} + +#endif // CRYPTOPP_POWER8_SHA_AVAILABLE + +//////////////////////////////////////////////// +// end Gustavo, Serra, Scalet and Walton code // +//////////////////////////////////////////////// + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/shacal2.cpp b/external/ours/library/crypto/src/shared/original/shacal2.cpp new file mode 100755 index 000000000..37ba9899f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shacal2.cpp @@ -0,0 +1,172 @@ +// shacal2.cpp - written by Kevin Springle, 2003 +// +// Portions of this code were derived from +// Wei Dai's implementation of SHA-2 +// +// Jack Lloyd and the Botan team allowed Crypto++ to use parts of +// Botan's implementation under the same license as Crypto++ +// is released. The code for SHACAL2_Enc_ProcessAndXorBlock_SHANI +// below is Botan's x86_encrypt_blocks with minor tweaks. Many thanks +// to the Botan team. Also see http://github.com/randombit/botan/. +// +// The original code and all modifications are in the public domain. + +#include "pch.h" +#include "config.h" +#include "shacal2.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +// SHACAL-2 function and round definitions + +#define S0(x) (rotrConstant<2>(x)^rotrConstant<13>(x)^rotrConstant<22>(x)) +#define S1(x) (rotrConstant<6>(x)^rotrConstant<11>(x)^rotrConstant<25>(x)) +#define s0(x) (rotrConstant<7>(x)^rotrConstant<18>(x)^(x>>3)) +#define s1(x) (rotrConstant<17>(x)^rotrConstant<19>(x)^(x>>10)) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +/* R is the SHA-256 round function. */ +/* This macro increments the k argument as a side effect. */ +#define R(a,b,c,d,e,f,g,h,k) \ + h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c); + +/* P is the inverse of the SHA-256 round function. */ +/* This macro decrements the k argument as a side effect. */ +#define P(a,b,c,d,e,f,g,h,k) \ + h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k; + +#if CRYPTOPP_SHANI_AVAILABLE +extern void SHACAL2_Enc_ProcessAndXorBlock_SHANI(const word32* subKeys, + const byte *inBlock, const byte *xorBlock, byte *outBlock); +#endif + +std::string SHACAL2::Base::AlgorithmProvider() const +{ +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + return "SHANI"; +#endif + return "C++"; +} + +void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) +{ + AssertValidKeyLength(keylen); + + word32 *rk = m_key; + unsigned int i; + + // 32-bit GCC 5.4 hack... m_key.size() returns 0. Note: this surfaced after changing + // m_key to FixedSizeAlignedSecBlock at commit 1ab1e08ac5b5a0d63374de0c. + GetUserKey(BIG_ENDIAN_ORDER, rk, 64, userKey, keylen); + for (i = 0; i < 48; i++, rk++) + { + rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]); + rk[0] += K[i]; + } + for (i = 48; i < 64; i++, rk++) + { + rk[0] += K[i]; + } +} + +typedef BlockGetAndPut Block; + +void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ +#if CRYPTOPP_SHANI_AVAILABLE + if (HasSHA()) + { + SHACAL2_Enc_ProcessAndXorBlock_SHANI(m_key, inBlock, xorBlock, outBlock); + return; + } +#endif + + word32 a, b, c, d, e, f, g, h; + const word32 *rk = m_key; + + /* + * map byte array block to cipher state: + */ + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + + // Perform SHA-256 transformation. + + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=8) + { + R(a,b,c,d,e,f,g,h,rk); + R(h,a,b,c,d,e,f,g,rk); + R(g,h,a,b,c,d,e,f,rk); + R(f,g,h,a,b,c,d,e,rk); + R(e,f,g,h,a,b,c,d,rk); + R(d,e,f,g,h,a,b,c,rk); + R(c,d,e,f,g,h,a,b,rk); + R(b,c,d,e,f,g,h,a,rk); + } + + /* + * map cipher state to byte array block: + */ + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e, f, g, h; + const word32 *rk = m_key + 64; + + /* + * map byte array block to cipher state: + */ + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + + // Perform inverse SHA-256 transformation. + + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=8) + { + P(b,c,d,e,f,g,h,a,rk); + P(c,d,e,f,g,h,a,b,rk); + P(d,e,f,g,h,a,b,c,rk); + P(e,f,g,h,a,b,c,d,rk); + P(f,g,h,a,b,c,d,e,rk); + P(g,h,a,b,c,d,e,f,rk); + P(h,a,b,c,d,e,f,g,rk); + P(a,b,c,d,e,f,g,h,rk); + } + + /* + * map cipher state to byte array block: + */ + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +// The SHACAL-2 round constants are identical to the SHA-256 round constants. +const word32 SHACAL2::Base::K[64] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/shacal2.h b/external/ours/library/crypto/src/shared/original/shacal2.h new file mode 100755 index 000000000..ca0c482ce --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shacal2.h @@ -0,0 +1,66 @@ +// shacal.h - originally written and placed in the public domain by Wei Dai + +/// \file shacal2.h +/// \brief Classes for the SHACAL-2 block cipher +/// \since Crypto++ 5.2, Intel SHA since Crypto++ 6.0 + +#ifndef CRYPTOPP_SHACAL2_H +#define CRYPTOPP_SHACAL2_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SHACAL2 block cipher information +struct SHACAL2_Info : public FixedBlockSize<32>, public VariableKeyLength<16, 16, 64> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SHACAL-2";} +}; + +/// \brief SHACAL2 block cipher +/// \since Crypto++ 5.2, Intel SHA since Crypto++ 6.0 +/// \sa SHACAL-2 +class SHACAL2 : public SHACAL2_Info, public BlockCipherDocumentation +{ + /// \brief SHACAL2 block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + std::string AlgorithmProvider() const; + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeAlignedSecBlock m_key; + + static const word32 K[64]; + }; + + /// \brief SHACAL2 block cipher transformation functions + /// \details Encryption transformation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief SHACAL2 block cipher transformation functions + /// \details Decryption transformation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SHACAL2::Encryption SHACAL2Encryption; +typedef SHACAL2::Decryption SHACAL2Decryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/shacal2_simd.cpp b/external/ours/library/crypto/src/shared/original/shacal2_simd.cpp new file mode 100755 index 000000000..5114601b7 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shacal2_simd.cpp @@ -0,0 +1,94 @@ +// shacla2_simd.cpp - written and placed in the public domain by +// Jeffrey Walton and Jack Lloyd +// +// Jack Lloyd and the Botan team allowed Crypto++ to use parts of +// Botan's implementation under the same license as Crypto++ +// is released. The code for SHACAL2_Enc_ProcessAndXorBlock_SHANI +// below is Botan's x86_encrypt_blocks with minor tweaks. Many thanks +// to the Botan team. Also see http://github.com/randombit/botan/. +// +// This source file uses intrinsics to gain access to SHA-NI and +// ARMv8a SHA instructions. A separate source file is needed because +// additional CXXFLAGS are required to enable the appropriate instruction +// sets in some build configurations. + +#include "pch.h" +#include "config.h" +#include "sha.h" +#include "misc.h" + +#if (CRYPTOPP_SHANI_AVAILABLE) +# include +# include +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char SHACAL2_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#if CRYPTOPP_SHANI_AVAILABLE +void SHACAL2_Enc_ProcessAndXorBlock_SHANI(const word32* subKeys, const byte *inBlock, const byte *xorBlock, byte *outBlock) +{ + CRYPTOPP_ASSERT(subKeys); + CRYPTOPP_ASSERT(inBlock); + CRYPTOPP_ASSERT(outBlock); + + const __m128i MASK1 = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); + const __m128i MASK2 = _mm_set_epi8(0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15); + + __m128i B0 = _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(inBlock + 0)), MASK1); + __m128i B1 = _mm_shuffle_epi8(_mm_loadu_si128(CONST_M128_CAST(inBlock + 16)), MASK2); + + __m128i TMP = _mm_alignr_epi8(B0, B1, 8); + B1 = _mm_blend_epi16(B1, B0, 0xF0); + B0 = TMP; + +#if 0 + // SSE2 + SSSE3, but 0.2 cpb slower on a Celeraon J3455 + const __m128i MASK1 = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); + const __m128i MASK2 = _mm_set_epi8(0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15); + + __m128i B0 = _mm_loadu_si128(CONST_M128_CAST(inBlock + 0)); + __m128i B1 = _mm_loadu_si128(CONST_M128_CAST(inBlock + 16)); + + __m128i TMP = _mm_shuffle_epi8(_mm_unpacklo_epi64(B0, B1), MASK2); + B1 = _mm_shuffle_epi8(_mm_unpackhi_epi64(B0, B1), MASK2); + B0 = TMP; +#endif + + const byte* keys = reinterpret_cast(subKeys); + for (size_t i = 0; i != 8; ++i) + { + const __m128i RK0 = _mm_load_si128(CONST_M128_CAST(keys + 32*i)); + const __m128i RK2 = _mm_load_si128(CONST_M128_CAST(keys + 32*i+16)); + const __m128i RK1 = _mm_srli_si128(RK0, 8); + const __m128i RK3 = _mm_srli_si128(RK2, 8); + + B1 = _mm_sha256rnds2_epu32(B1, B0, RK0); + B0 = _mm_sha256rnds2_epu32(B0, B1, RK1); + B1 = _mm_sha256rnds2_epu32(B1, B0, RK2); + B0 = _mm_sha256rnds2_epu32(B0, B1, RK3); + } + + TMP = _mm_shuffle_epi8(_mm_unpackhi_epi64(B0, B1), MASK1); + B1 = _mm_shuffle_epi8(_mm_unpacklo_epi64(B0, B1), MASK1); + B0 = TMP; + + if (xorBlock) + { + _mm_storeu_si128(M128_CAST(outBlock + 0), + _mm_xor_si128(B0, _mm_loadu_si128(CONST_M128_CAST(xorBlock + 0)))); + + _mm_storeu_si128(M128_CAST(outBlock + 16), + _mm_xor_si128(B1, _mm_loadu_si128(CONST_M128_CAST(xorBlock + 16)))); + } + else + { + _mm_storeu_si128(M128_CAST(outBlock + 0), B0); + _mm_storeu_si128(M128_CAST(outBlock + 16), B1); + } +} +#endif + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/shake.cpp b/external/ours/library/crypto/src/shared/original/shake.cpp new file mode 100755 index 000000000..65e082355 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shake.cpp @@ -0,0 +1,85 @@ +// shake.cpp - modified by Wei Dai from Ronny Van Keer's public domain +// sha3-simple.c. All modifications here are placed in the +// public domain by Wei Dai. +// Keccack core function moved to keccakc.cpp in AUG 2018 +// by Jeffrey Walton. Separating the core file allows both +// SHA3 and Keccack to share the core implementation. + +/* +The SHAKE sponge function, designed by Guido Bertoni, Joan Daemen, +Michael Peeters and Gilles Van Assche. For more information, feedback or +questions, please refer to our website: http://keccak.noekeon.org/ + +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "pch.h" +#include "shake.h" + +NAMESPACE_BEGIN(CryptoPP) + +// The Keccak core function +extern void KeccakF1600(word64 *state); + +void SHAKE::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); + if (length == 0) { return; } + + size_t spaceLeft; + while (length >= (spaceLeft = r() - m_counter)) + { + if (spaceLeft) + xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft); + KeccakF1600(m_state); + input += spaceLeft; + length -= spaceLeft; + m_counter = 0; + } + + if (length) + xorbuf(m_state.BytePtr() + m_counter, input, length); + m_counter += (unsigned int)length; +} + +void SHAKE::Restart() +{ + memset(m_state, 0, m_state.SizeInBytes()); + m_counter = 0; +} + +void SHAKE::ThrowIfInvalidTruncatedSize(size_t size) const +{ + if (size > UINT_MAX) + throw InvalidArgument(std::string("HashTransformation: can't truncate a ") + + IntToString(UINT_MAX) + " byte digest to " + IntToString(size) + " bytes"); +} + +void SHAKE::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + ThrowIfInvalidTruncatedSize(size); + + m_state.BytePtr()[m_counter] ^= 0x1F; + m_state.BytePtr()[r()-1] ^= 0x80; + + // FIPS 202, Algorithm 8, pp 18-19. + while (size > 0) + { + KeccakF1600(m_state); + + const size_t segmentLen = STDMIN(size, (size_t)BlockSize()); + std::memcpy(hash, m_state, segmentLen); + + hash += segmentLen; + size -= segmentLen; + } + + Restart(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/shake.h b/external/ours/library/crypto/src/shared/original/shake.h new file mode 100755 index 000000000..0eaab43b2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shake.h @@ -0,0 +1,161 @@ +// shake.h - written and placed in the public domain by Jeffrey Walton + +/// \file shake.h +/// \brief Classes for SHAKE message digests +/// \details The library provides byte oriented SHAKE128 and SHAKE256 using F1600. +/// FIPS 202 allows nearly unlimited output sizes, but Crypto++ limits the output +/// size to UINT_MAX due underlying data types. +/// \sa Keccak, SHA3, SHAKE128, SHAKE256, +/// FIPS 202, +/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +/// \since Crypto++ 8.1 + +#ifndef CRYPTOPP_SHAKE_H +#define CRYPTOPP_SHAKE_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SHAKE message digest base class +/// \details SHAKE is the base class for SHAKE128 and SHAKE258. +/// Library users should instantiate a derived class, and only use SHAKE +/// as a base class reference or pointer. +/// \sa Keccak, SHA3, SHAKE128, SHAKE256, +/// FIPS 202, +/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +/// \since Crypto++ 8.1 +class SHAKE : public HashTransformation +{ +protected: + /// \brief Construct a SHAKE + /// \param digestSize the digest size, in bytes + /// \details SHAKE is the base class for SHAKE128 and SHAKE256. + /// Library users should instantiate a derived class, and only use SHAKE + /// as a base class reference or pointer. + /// \details This constructor was moved to protected at Crypto++ 8.1 + /// because users were attempting to create Keccak objects with it. + /// \since Crypto++ 8.1 + SHAKE(unsigned int digestSize) : m_digestSize(digestSize) {Restart();} + +public: + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + void Update(const byte *input, size_t length); + void Restart(); + void TruncatedFinal(byte *hash, size_t size); + +protected: + inline unsigned int r() const {return BlockSize();} + + // SHAKE-128 and SHAKE-256 effectively allow unlimited + // output length. However, we use an unsigned int so + // we are limited in practice to UINT_MAX. + void ThrowIfInvalidTruncatedSize(size_t size) const; + + FixedSizeSecBlock m_state; + unsigned int m_digestSize, m_counter; +}; + +/// \brief SHAKE message digest template +/// \tparam T_Strength the strength of the digest +/// \since Crypto++ 8.1 +template +class SHAKE_Final : public SHAKE +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = (T_Strength == 128 ? 32 : 64)); + CRYPTOPP_CONSTANT(BLOCKSIZE = (T_Strength == 128 ? 1344/8 : 1088/8)); + static std::string StaticAlgorithmName() + { return "SHAKE-" + IntToString(T_Strength); } + + /// \brief Construct a SHAKE-X message digest + /// \details SHAKE128 and SHAKE256 don't need the output size in advance + /// because the output size does not affect the digest. TruncatedFinal + /// produces the correct digest for any output size. However, cSHAKE + /// requires the output size in advance because the algoirthm uses + /// output size as a parameter to the hash function. + SHAKE_Final(unsigned int outputSize=DIGESTSIZE) : SHAKE(outputSize) {} + + /// \brief Provides the block size of the compression function + /// \return block size of the compression function, in bytes + /// \details BlockSize() will return 0 if the hash is not block based + /// or does not have an equivalent block size. For example, Keccak + /// and SHA-3 do not have a block size, but they do have an equivalent + /// to block size called rate expressed as r. + unsigned int BlockSize() const { return BLOCKSIZE; } + + std::string AlgorithmName() const { return StaticAlgorithmName(); } + +private: +#if !defined(__BORLANDC__) + // ensure there was no underflow in the math + CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); +#endif +}; + +/// \brief SHAKE128 message digest +/// \details The library provides byte oriented SHAKE128 using F1600. +/// FIPS 202 allows nearly unlimited output sizes, but Crypto++ limits +/// the output size to UINT_MAX due underlying data types. +/// \sa Keccak, SHA3, SHAKE256, +/// FIPS 202, +/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +/// \since Crypto++ 8.1 +class SHAKE128 : public SHAKE_Final<128> +{ +public: + /// \brief Construct a SHAKE128 message digest + /// \details SHAKE128 and SHAKE256 don't need the output size in advance + /// because the output size does not affect the digest. TruncatedFinal + /// produces the correct digest for any output size. However, cSHAKE + /// requires the output size in advance because the algoirthm uses + /// output size as a parameter to the hash function. + /// \since Crypto++ 8.1 + SHAKE128() {} + + /// \brief Construct a SHAKE128 message digest + /// \details SHAKE128 and SHAKE256 don't need the output size in advance + /// because the output size does not affect the digest. TruncatedFinal + /// produces the correct digest for any output size. However, cSHAKE + /// requires the output size in advance because the algoirthm uses + /// output size as a parameter to the hash function. + /// \since Crypto++ 8.1 + SHAKE128(unsigned int outputSize) : SHAKE_Final<128>(outputSize) {} +}; + +/// \brief SHAKE256 message digest +/// \details The library provides byte oriented SHAKE256 using F1600. +/// FIPS 202 allows nearly unlimited output sizes, but Crypto++ limits +/// the output size to UINT_MAX due underlying data types. +/// \sa Keccak, SHA3, SHAKE128, +/// FIPS 202, +/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +/// \since Crypto++ 8.1 +class SHAKE256 : public SHAKE_Final<256> +{ +public: + /// \brief Construct a SHAKE256 message digest + /// \details SHAKE128 and SHAKE256 don't need the output size in advance + /// because the output size does not affect the digest. TruncatedFinal + /// produces the correct digest for any output size. However, cSHAKE + /// requires the output size in advance because the algoirthm uses + /// output size as a parameter to the hash function. + /// \since Crypto++ 8.1 + SHAKE256() {} + + /// \brief Construct a SHAKE256 message digest + /// \details SHAKE128 and SHAKE256 don't need the output size in advance + /// because the output size does not affect the digest. TruncatedFinal + /// produces the correct digest for any output size. However, cSHAKE + /// requires the output size in advance because the algoirthm uses + /// output size as a parameter to the hash function. + /// \since Crypto++ 8.1 + SHAKE256(unsigned int outputSize) : SHAKE_Final<256>(outputSize) {} +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/shark.cpp b/external/ours/library/crypto/src/shared/original/shark.cpp new file mode 100755 index 000000000..6e3b8da3f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shark.cpp @@ -0,0 +1,163 @@ +// shark.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "shark.h" +#include "misc.h" +#include "modes.h" +#include "gf256.h" + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wmissing-braces" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +static word64 SHARKTransform(word64 a) +{ + static const byte iG[8][8] = { + 0xe7, 0x30, 0x90, 0x85, 0xd0, 0x4b, 0x91, 0x41, + 0x53, 0x95, 0x9b, 0xa5, 0x96, 0xbc, 0xa1, 0x68, + 0x02, 0x45, 0xf7, 0x65, 0x5c, 0x1f, 0xb6, 0x52, + 0xa2, 0xca, 0x22, 0x94, 0x44, 0x63, 0x2a, 0xa2, + 0xfc, 0x67, 0x8e, 0x10, 0x29, 0x75, 0x85, 0x71, + 0x24, 0x45, 0xa2, 0xcf, 0x2f, 0x22, 0xc1, 0x0e, + 0xa1, 0xf1, 0x71, 0x40, 0x91, 0x27, 0x18, 0xa5, + 0x56, 0xf4, 0xaf, 0x32, 0xd2, 0xa4, 0xdc, 0x71, + }; + + word64 result=0; + GF256 gf256(0xf5); + for (unsigned int i=0; i<8; i++) + for(unsigned int j=0; j<8; j++) + result ^= word64(gf256.Multiply(iG[i][j], GF256::Element(a>>(56-8*j)))) << (56-8*i); + return result; +} + +void SHARK::Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keyLen); + + m_rounds = GetRoundsAndThrowIfInvalid(params, this); + m_roundKeys.New(m_rounds+1); + + // concatenate key enought times to fill a + for (unsigned int i=0; i<(m_rounds+1)*8; i++) + ((byte *)m_roundKeys.begin())[i] = key[i%keyLen]; + + SHARK::Encryption e; + e.InitForKeySetup(); + byte IV[8] = {0,0,0,0,0,0,0,0}; + CFB_Mode_ExternalCipher::Encryption cfb(e, IV); + + cfb.ProcessString((byte *)m_roundKeys.begin(), (m_rounds+1)*8); + + ConditionalByteReverse(BIG_ENDIAN_ORDER, m_roundKeys.begin(), m_roundKeys.begin(), (m_rounds+1)*8); + + m_roundKeys[m_rounds] = SHARKTransform(m_roundKeys[m_rounds]); + + if (!IsForwardTransformation()) + { + unsigned int i; + + // transform encryption round keys into decryption round keys + for (i=0; i())); + word64 tmp = *(word64 *)(void *)inBlock ^ m_roundKeys[0]; + + ByteOrder order = GetNativeByteOrder(); + tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)] + ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)] + ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)] + ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)] + ^ m_roundKeys[1]; + + for(unsigned int i=2; i(xorBlock, outBlock) + (sbox[GETBYTE(tmp, 7)]) + (sbox[GETBYTE(tmp, 6)]) + (sbox[GETBYTE(tmp, 5)]) + (sbox[GETBYTE(tmp, 4)]) + (sbox[GETBYTE(tmp, 3)]) + (sbox[GETBYTE(tmp, 2)]) + (sbox[GETBYTE(tmp, 1)]) + (sbox[GETBYTE(tmp, 0)]); + + CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf())); + *(word64 *)(void *)outBlock ^= m_roundKeys[m_rounds]; +} + +void SHARK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf())); + word64 tmp = *(word64 *)(void *)inBlock ^ m_roundKeys[0]; + + ByteOrder order = GetNativeByteOrder(); + tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)] + ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)] + ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)] + ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)] + ^ m_roundKeys[1]; + + for(unsigned int i=2; i(xorBlock, outBlock) + (sbox[GETBYTE(tmp, 7)]) + (sbox[GETBYTE(tmp, 6)]) + (sbox[GETBYTE(tmp, 5)]) + (sbox[GETBYTE(tmp, 4)]) + (sbox[GETBYTE(tmp, 3)]) + (sbox[GETBYTE(tmp, 2)]) + (sbox[GETBYTE(tmp, 1)]) + (sbox[GETBYTE(tmp, 0)]); + + CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf())); + *(word64 *)(void *)outBlock ^= m_roundKeys[m_rounds]; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/shark.h b/external/ours/library/crypto/src/shared/original/shark.h new file mode 100755 index 000000000..09459adc8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/shark.h @@ -0,0 +1,77 @@ +// shark.h - originally written and placed in the public domain by Wei Dai + +/// \file shark.h +/// \brief Classes for the SHARK block cipher +/// \since Crypto++ 2.1 + +#ifndef CRYPTOPP_SHARK_H +#define CRYPTOPP_SHARK_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SHARK block cipher information +/// \since Crypto++ 2.1 +struct SHARK_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<6, 2> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SHARK-E";} +}; + +/// \brief SHARK block cipher +/// SHARK-E +/// \since Crypto++ 2.1 +class SHARK : public SHARK_Info, public BlockCipherDocumentation +{ + /// \brief SHARK block cipher default operation + /// \since Crypto++ 2.1 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶m); + + protected: + unsigned int m_rounds; + SecBlock m_roundKeys; + }; + + /// \brief SHARK block cipher encryption operation + /// \since Crypto++ 2.1 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + // used by Base to do key setup + void InitForKeySetup(); + + private: + static const byte sbox[256]; + static const word64 cbox[8][256]; + }; + + /// \brief SHARK block cipher decryption operation + /// \since Crypto++ 2.1 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + private: + static const byte sbox[256]; + static const word64 cbox[8][256]; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SHARK::Encryption SHARKEncryption; +typedef SHARK::Decryption SHARKDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/sharkbox.cpp b/external/ours/library/crypto/src/shared/original/sharkbox.cpp new file mode 100755 index 000000000..1a50c1714 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sharkbox.cpp @@ -0,0 +1,4166 @@ +#include "pch.h" +#include "shark.h" + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wmissing-braces" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +const byte SHARK::Enc::sbox[256] = { +177, 206, 195, 149, 90, 173, 231, 2, 77, 68, 251, 145, 12, 135, 161, 80, +203, 103, 84, 221, 70, 143, 225, 78, 240, 253, 252, 235, 249, 196, 26, 110, + 94, 245, 204, 141, 28, 86, 67, 254, 7, 97, 248, 117, 89, 255, 3, 34, +138, 209, 19, 238, 136, 0, 14, 52, 21, 128, 148, 227, 237, 181, 83, 35, + 75, 71, 23, 167, 144, 53, 171, 216, 184, 223, 79, 87, 154, 146, 219, 27, + 60, 200, 153, 4, 142, 224, 215, 125, 133, 187, 64, 44, 58, 69, 241, 66, +101, 32, 65, 24, 114, 37, 147, 112, 54, 5, 242, 11, 163, 121, 236, 8, + 39, 49, 50, 182, 124, 176, 10, 115, 91, 123, 183, 129, 210, 13, 106, 38, +158, 88, 156, 131, 116, 179, 172, 48, 122, 105, 119, 15, 174, 33, 222, 208, + 46, 151, 16, 164, 152, 168, 212, 104, 45, 98, 41, 109, 22, 73, 118, 199, +232, 193, 150, 55, 229, 202, 244, 233, 99, 18, 194, 166, 20, 188, 211, 40, +175, 47, 230, 36, 82, 198, 160, 9, 189, 140, 207, 93, 17, 95, 1, 197, +159, 61, 162, 155, 201, 59, 190, 81, 25, 31, 63, 92, 178, 239, 74, 205, +191, 186, 111, 100, 217, 243, 62, 180, 170, 220, 213, 6, 192, 126, 246, 102, +108, 132, 113, 56, 185, 29, 127, 157, 72, 139, 42, 218, 165, 51, 130, 57, +214, 120, 134, 250, 228, 43, 169, 30, 137, 96, 107, 234, 85, 76, 247, 226, +}; + +const byte SHARK::Dec::sbox[256] = { + 53, 190, 7, 46, 83, 105, 219, 40, 111, 183, 118, 107, 12, 125, 54, 139, +146, 188, 169, 50, 172, 56, 156, 66, 99, 200, 30, 79, 36, 229, 247, 201, + 97, 141, 47, 63, 179, 101, 127, 112, 175, 154, 234, 245, 91, 152, 144, 177, +135, 113, 114, 237, 55, 69, 104, 163, 227, 239, 92, 197, 80, 193, 214, 202, + 90, 98, 95, 38, 9, 93, 20, 65, 232, 157, 206, 64, 253, 8, 23, 74, + 15, 199, 180, 62, 18, 252, 37, 75, 129, 44, 4, 120, 203, 187, 32, 189, +249, 41, 153, 168, 211, 96, 223, 17, 151, 137, 126, 250, 224, 155, 31, 210, +103, 226, 100, 119, 132, 43, 158, 138, 241, 109, 136, 121, 116, 87, 221, 230, + 57, 123, 238, 131, 225, 88, 242, 13, 52, 248, 48, 233, 185, 35, 84, 21, + 68, 11, 77, 102, 58, 3, 162, 145, 148, 82, 76, 195, 130, 231, 128, 192, +182, 14, 194, 108, 147, 236, 171, 67, 149, 246, 216, 70, 134, 5, 140, 176, +117, 0, 204, 133, 215, 61, 115, 122, 72, 228, 209, 89, 173, 184, 198, 208, +220, 161, 170, 2, 29, 191, 181, 159, 81, 196, 165, 16, 34, 207, 1, 186, +143, 49, 124, 174, 150, 218, 240, 86, 71, 212, 235, 78, 217, 19, 142, 73, + 85, 22, 255, 59, 244, 164, 178, 6, 160, 167, 251, 27, 110, 60, 51, 205, + 24, 94, 106, 213, 166, 33, 222, 254, 42, 28, 243, 10, 26, 25, 39, 45, +}; + +const word64 SHARK::Enc::cbox[8][256] = { +/* box 0 */ +W64LIT(0x060d838f16f3a365), +W64LIT(0xa68857ee5cae56f6), +W64LIT(0xebf516353c2c4d89), +W64LIT(0x652174be88e85bdc), +W64LIT(0x0d4e9a8086c17921), +W64LIT(0x27ba7d33cffa58a1), +W64LIT(0x88d9e104a237b530), +W64LIT(0x693b8755a4fbe816), +W64LIT(0xdac9591826b254a0), +W64LIT(0x45c2e369fb336af3), +W64LIT(0xa96e1fb87b3e4ef4), +W64LIT(0xb7578f1435eb7ef0), +W64LIT(0x839af80b32056f74), +W64LIT(0xae37f55cc71f277a), +W64LIT(0xa4208538fdff37d5), +W64LIT(0x35991e74ad3cdb6f), +W64LIT(0xba191594b32a07d1), +W64LIT(0x5344d1772e572b7b), +W64LIT(0xe7efe5de103ffe43), +W64LIT(0xa3796fdc41de5e5b), +W64LIT(0x2cf9643c5fc882e5), +W64LIT(0xffdbf6fd48196d22), +W64LIT(0x33949dfbbbcf780a), +W64LIT(0x7d15679dd0cec8bd), +W64LIT(0x5f5e229c024498b1), +W64LIT(0x1223634762c683ce), +W64LIT(0xdcc4da973041f7c5), +W64LIT(0x0b43190f9032da44), +W64LIT(0xc05598eddfc5a6e2), +W64LIT(0x9e5fd31a7753f4b8), +W64LIT(0x9afa8243c0f136fe), +W64LIT(0xcc4f6b06f3d61528), +W64LIT(0xdf38612a3bc25c0d), +W64LIT(0x43cf60e6edc0c996), +W64LIT(0xcfb3d0bbf855bee0), +W64LIT(0x96e071a8ece28534), +W64LIT(0x21b7febcd909fbc4), +W64LIT(0x8ed4628bb4c41655), +W64LIT(0x30682646b04cd3c2), +W64LIT(0xb5ff5dc294ba1fd3), +W64LIT(0x75aac52f4b7fb931), +W64LIT(0xe809ad8837afe641), +W64LIT(0x0eb2213d8d42d2e9), +W64LIT(0x9852509561a057dd), +W64LIT(0xaa92a40570bde53c), +W64LIT(0x7b18e412c63d6bd8), +W64LIT(0xa7dc3e85f67c9c1d), +W64LIT(0xd8618bce87e33583), +W64LIT(0xe34ab487a79d3c05), +W64LIT(0x20e397d773db312f), +W64LIT(0x05f138321d7008ad), +W64LIT(0x17d25b757fb68b63), +W64LIT(0x8a7133d20366d413), +W64LIT(0x0000000000000000), +W64LIT(0xeaa17f5e96fe8762), +W64LIT(0xc101f18675176c09), +W64LIT(0xbebc44cd0488c597), +W64LIT(0xdb9d30738c609e4b), +W64LIT(0xabc6cd6eda6f2fd7), +W64LIT(0x5aaf1aae1f34901c), +W64LIT(0xb00e65f089ca177e), +W64LIT(0xd47b7825abf08649), +W64LIT(0x924520f15b404772), +W64LIT(0x1686321ed5644188), +W64LIT(0x618425e73f4a999a), +W64LIT(0xe21eddec0d4ff6ee), +W64LIT(0xd787c398a0732d81), +W64LIT(0x1f6df9c7e407faef), +W64LIT(0x79b036c4676c0afb), +W64LIT(0x0fe6485627901802), +W64LIT(0x9cf701ccd602959b), +W64LIT(0xbfe82da6ae5a0f7c), +W64LIT(0x990639fecb729d36), +W64LIT(0xca42e889e525b64d), +W64LIT(0xb3f2de4d8249bcb6), +W64LIT(0x4033db5be643625e), +W64LIT(0x4167b2304c91a8b5), +W64LIT(0x108bb191c397e2ed), +W64LIT(0x1834132358269361), +W64LIT(0x541d3b93927642f5), +W64LIT(0x90edf227fa112651), +W64LIT(0x1dc52b1145569bcc), +W64LIT(0xe6bb8cb5baed34a8), +W64LIT(0xd276fbaabd03252c), +W64LIT(0x313c4f2d1a9e1929), +W64LIT(0xfd73242be9480c01), +W64LIT(0x9baeeb286a23fc15), +W64LIT(0xc9be5334eea61d85), +W64LIT(0xc70c720963e4cf6c), +W64LIT(0x3eda077b3d0e012b), +W64LIT(0x97b418c346304fdf), +W64LIT(0x32c0f490111db2e1), +W64LIT(0x2ba08ed8e3e9eb6b), +W64LIT(0x8b255ab9a9b41ef8), +W64LIT(0x91b99b4c50c3ecba), +W64LIT(0xfe8f9f96e2cba7c9), +W64LIT(0x3a7f56228aacc36d), +W64LIT(0xb15a0c9b2318dd95), +W64LIT(0x5953a11314b73bd4), +W64LIT(0xf3c10516640adee8), +W64LIT(0xedf895ba2adfeeec), +W64LIT(0xadcb4ee1cc9c8cb2), +W64LIT(0xde6c0841911096e6), +W64LIT(0x84c312ef8e2406fa), +W64LIT(0xa83a76d3d1ec841f), +W64LIT(0x1c91427aef845127), +W64LIT(0x3665a5c9a6bf70a7), +W64LIT(0xf6303d24797ad645), +W64LIT(0xcd1b026d5904dfc3), +W64LIT(0x1bc8a89e53a538a9), +W64LIT(0x7ee9dc20db4d6375), +W64LIT(0x51ec03a18f064a58), +W64LIT(0xc4f0c9b4686764a4), +W64LIT(0xdd90b3fc9a933d2e), +W64LIT(0x7a4c8d796cefa133), +W64LIT(0x73a746a05d8c1a54), +W64LIT(0x0759eae4bc21698e), +W64LIT(0xc8ea3a5f4474d76e), +W64LIT(0x38d784f42bfda24e), +W64LIT(0x231f2c6a78589ae7), +W64LIT(0xc3a92350d4460d2a), +W64LIT(0x72f32fcbf75ed0bf), +W64LIT(0xbd40ff700f0b6e5f), +W64LIT(0x157a89a3dee7ea40), +W64LIT(0x873fa95285a7ad32), +W64LIT(0x4d7d41db60821b7f), +W64LIT(0x1e3990ac4ed53004), +W64LIT(0x0a1770643ae010af), +W64LIT(0x9311499af1928d99), +W64LIT(0x64751dd5223a9137), +W64LIT(0xfa2acecf5569658f), +W64LIT(0x7c410ef67a1c0256), +W64LIT(0x56b5e945332723d6), +W64LIT(0x6f3604dab2084b73), +W64LIT(0xe95dc4e39d7d2caa), +W64LIT(0x13770a2cc8144925), +W64LIT(0xbc14961ba5d9a4b4), +W64LIT(0xb9e5ae29b8a9ac19), +W64LIT(0xf169d7c0c55bbfcb), +W64LIT(0x2446c68ec479f369), +W64LIT(0x806643b63986c4bc), +W64LIT(0x7fbdb54b719fa99e), +W64LIT(0x04a55159b7a2c246), +W64LIT(0xee042e07215c4524), +W64LIT(0x5bfb73c5b5e65af7), +W64LIT(0x0c1af3eb2c13b3ca), +W64LIT(0xa22d06b7eb0c94b0), +W64LIT(0xb8b1c742127b66f2), +W64LIT(0x285c3565e86a40a3), +W64LIT(0x3b2b3f49207e0986), +W64LIT(0x3c72d5ad9c5f6008), +W64LIT(0x770217f9ea2ed812), +W64LIT(0xfc274d40439ac6ea), +W64LIT(0x4fd5930dc1d37a5c), +W64LIT(0x2e51b6eafe99e3c6), +W64LIT(0x6b93558305aa8935), +W64LIT(0x19607a48f2f4598a), +W64LIT(0x08bfa2b29bb1718c), +W64LIT(0x3f8e6e1097dccbc0), +W64LIT(0x3983ed9f812f68a5), +W64LIT(0xac9f278a664e4659), +W64LIT(0x82ce916098d7a59f), +W64LIT(0xc2fd4a3b7e94c7c1), +W64LIT(0x66ddcf03836bf014), +W64LIT(0xe1e2665106cc5d26), +W64LIT(0x74feac44e1ad73da), +W64LIT(0x8d28d936bf47bd9d), +W64LIT(0x62789e5a34c93252), +W64LIT(0x81322add93540e57), +W64LIT(0xcb1681e24ff77ca6), +W64LIT(0x2512afe56eab3982), +W64LIT(0xd18a4017b6808ee4), +W64LIT(0x705bfd1d560fb19c), +W64LIT(0x4b70c2547671b81a), +W64LIT(0x49d81082d720d939), +W64LIT(0xe0b60f3aac1e97cd), +W64LIT(0x4e81fa666b01b0b7), +W64LIT(0x951cca15e7612efc), +W64LIT(0x463e58d4f0b0c13b), +W64LIT(0x632cf7319e1bf8b9), +W64LIT(0x5ca2992109c73379), +W64LIT(0xf764544fd3a81cae), +W64LIT(0x6ac73ce8af7843de), +W64LIT(0x9f0bba71dd813e53), +W64LIT(0x85977b8424f6cc11), +W64LIT(0x5807c878be65f13f), +W64LIT(0x686fee3e0e2922fd), +W64LIT(0x78e45fafcdbec010), +W64LIT(0x6ccabf67b98be0bb), +W64LIT(0x11dfd8fa69452806), +W64LIT(0xcee7b9d05287740b), +W64LIT(0x50b86aca25d480b3), +W64LIT(0x5df6f04aa315f992), +W64LIT(0x5e0a4bf7a896525a), +W64LIT(0x03fcbbbd0b83abc8), +W64LIT(0x8f800be01e16dcbe), +W64LIT(0xd32292c117d1efc7), +W64LIT(0xe5473708b16e9f60), +W64LIT(0x224b4501d28a500c), +W64LIT(0xfb7ea7a4ffbbaf64), +W64LIT(0x3d26bcc6368daae3), +W64LIT(0x866bc0392f7567d9), +W64LIT(0x3731cca20c6dba4c), +W64LIT(0xb603e67f9f39b41b), +W64LIT(0xa1d1bd0ae08f3f78), +W64LIT(0xd935e2a52d31ff68), +W64LIT(0xaf639c376dcded91), +W64LIT(0x0154696baad2caeb), +W64LIT(0xecacfcd1800d2407), +W64LIT(0xf03dbeab6f897520), +W64LIT(0x02a8d2d6a1516123), +W64LIT(0xf498eff2d82bb766), +W64LIT(0x710f9476fcdd7b77), +W64LIT(0xf8821c19f43804ac), +W64LIT(0xf9d675725eeace47), +W64LIT(0x1a9cc1f5f977f242), +W64LIT(0x5210b81c8485e190), +W64LIT(0x6d9ed60c13592a50), +W64LIT(0xf2956c7dced81403), +W64LIT(0xbb4d7cff19f8cd3a), +W64LIT(0x4c2928b0ca50d194), +W64LIT(0x6e626db118da8198), +W64LIT(0xe4135e631bbc558b), +W64LIT(0x9da368a77cd05f70), +W64LIT(0xa574ec53572dfd3e), +W64LIT(0x09ebcbd93163bb67), +W64LIT(0x4a24ab3fdca372f1), +W64LIT(0x429b098d4712037d), +W64LIT(0x57e1802e99f5e93d), +W64LIT(0xef50476c8b8e8fcf), +W64LIT(0xa085d4614a5df593), +W64LIT(0x34cd771f07ee1184), +W64LIT(0xc6581b62c9360587), +W64LIT(0x2dad0d57f51a480e), +W64LIT(0x898d886f08e57fdb), +W64LIT(0xd6d3aaf30aa1e76a), +W64LIT(0x76567e9240fc12f9), +W64LIT(0xb4ab34a93e68d538), +W64LIT(0xb2a6b726289b765d), +W64LIT(0x8c7cb05d15957776), +W64LIT(0x554952f838a4881e), +W64LIT(0xd52f114e01224ca2), +W64LIT(0x60d04c8c95985371), +W64LIT(0x6789a66829b93aff), +W64LIT(0x2f05df81544b292d), +W64LIT(0x476a31bf5a620bd0), +W64LIT(0xf5cc869972f97d8d), +W64LIT(0x488c79e97df213d2), +W64LIT(0x44968a0251e1a018), +W64LIT(0x26ee14586528924a), +W64LIT(0xd0de297c1c52440f), +W64LIT(0xc5a4a0dfc2b5ae4f), +W64LIT(0x29085c0e42b88a48), +W64LIT(0x142ee0c8743520ab), +W64LIT(0x2af4e7b3493b2180), +W64LIT(0x9448a37e4db3e417), +/* box 1 */ +W64LIT(0xe2795ba105ba30ce), +W64LIT(0x65b5d634f5e0fbdd), +W64LIT(0x2d7d7f1464dd8c55), +W64LIT(0xeefbf778add1c20b), +W64LIT(0x1eb0fbd1f11968e7), +W64LIT(0xe6073f45ce30cd8d), +W64LIT(0x21ffd3cdccb67e90), +W64LIT(0xdf0941cfa750a262), +W64LIT(0xc61df5b1b75ef18a), +W64LIT(0xc5c7defa9dc337c6), +W64LIT(0x2581b729073c83d3), +W64LIT(0xa5e97513167173cf), +W64LIT(0xdd3673bd381526b9), +W64LIT(0xe8baa1eef91ebb93), +W64LIT(0x3b314cf8f625eb34), +W64LIT(0x579d4bc8d5fc5df8), +W64LIT(0xbb598ec2e7681b28), +W64LIT(0xc8a06b1a80708794), +W64LIT(0x1c8fc9a36e5cec3c), +W64LIT(0xf60a5a3f0807d374), +W64LIT(0x1ace9f353a9395a4), +W64LIT(0x7e9e50387aab2cee), +W64LIT(0xb5e41069d0466d36), +W64LIT(0x8cea6ee3b92602d9), +W64LIT(0xf952ddad8af1e7fd), +W64LIT(0xb19a748d1bcc9075), +W64LIT(0x2464ae10b2e4c144), +W64LIT(0xfcc9a070f4a35829), +W64LIT(0xfa88f6e6a06c21b1), +W64LIT(0x2c98662dd105cec2), +W64LIT(0x9065a740d77aeee5), +W64LIT(0xcb7a4051aaed41d8), +W64LIT(0x55a279ba4ab9d923), +W64LIT(0x27be855b98790708), +W64LIT(0xbabc97fb52b059bf), +W64LIT(0xa19711f7ddfb8e8c), +W64LIT(0x047e64e4cb8afd43), +W64LIT(0xc386886cc90c4e5e), +W64LIT(0xc422c7c3281b7551), +W64LIT(0xfb6defdf15b46326), +W64LIT(0x01e51939b5d84297), +W64LIT(0x5cbba8be9c809432), +W64LIT(0x6f762c7b09447080), +W64LIT(0xcee13d8cd4bffe0c), +W64LIT(0x54476083ff619bb4), +W64LIT(0x6e933542bc9c3217), +W64LIT(0x4af79b520e78f353), +W64LIT(0x98996f7db49be163), +W64LIT(0xa07208ce6823cc1b), +W64LIT(0x2b3c29823012f5cd), +W64LIT(0x93bf8c0bfde728a9), +W64LIT(0x2225f886e62bb8dc), +W64LIT(0x7f7b4901cf736e79), +W64LIT(0x0000000000000000), +W64LIT(0x023f32729f4584db), +W64LIT(0xd5cabb805bf4293f), +W64LIT(0x07a44fafe1173b0f), +W64LIT(0xe95fb8d74cc6f904), +W64LIT(0x7b052de504f9933a), +W64LIT(0x6aed51a67716cf54), +W64LIT(0x68d263d4e8534b8f), +W64LIT(0xa96bd9cabe1a810a), +W64LIT(0x1d6ad09adb84aeab), +W64LIT(0x0d67b5e01db3b052), +W64LIT(0x52063615abaee22c), +W64LIT(0x8f3045a893bbc495), +W64LIT(0xd8ad0e604647996d), +W64LIT(0xaf2a8f5cead5f892), +W64LIT(0x3017af8ebf5922fe), +W64LIT(0x4034611df2dc780e), +W64LIT(0x721cfce1d2c0de2b), +W64LIT(0x28e602c91a8f3381), +W64LIT(0xe1a370ea2f27f682), +W64LIT(0x29031bf0af577116), +W64LIT(0x1914b47e100e53e8), +W64LIT(0x567852f160241f6f), +W64LIT(0x793a1f979bbc17e1), +W64LIT(0xef1eee411809809c), +W64LIT(0x6211999b14f7c0d2), +W64LIT(0x059b7ddd7e52bfd4), +W64LIT(0x43ee4a56d841be42), +W64LIT(0xf1ae1590e910e87b), +W64LIT(0x33cd84c595c4e4b2), +W64LIT(0x4b12826bbba0b1c4), +W64LIT(0xeb608aa5d3837ddf), +W64LIT(0x201acaf4796e3c07), +W64LIT(0xbf27ea262ce2e66b), +W64LIT(0x58c5cc5a570a6971), +W64LIT(0x37b3e0215e4e19f1), +W64LIT(0xab54ebb8215f05d1), +W64LIT(0x8ed55c9126638602), +W64LIT(0x9aa65d0f2bde65b8), +W64LIT(0xd7f589f2c4b1ade4), +W64LIT(0x5039046734eb66f7), +W64LIT(0x6cac073023d9b6cc), +W64LIT(0x51dc1d5e81332460), +W64LIT(0x17a92ad5272025f6), +W64LIT(0x47902eb213cb4301), +W64LIT(0x1b2b860c8f4bd733), +W64LIT(0x4f6ce68f702a4c87), +W64LIT(0xcf0424b56167bc9b), +W64LIT(0x997c76440143a3f4), +W64LIT(0x7ae034dcb121d1ad), +W64LIT(0x100d657ac6371ef9), +W64LIT(0x0ac3fa4ffca48b5d), +W64LIT(0xdeec58f61288e0f5), +W64LIT(0x265b9c622da1459f), +W64LIT(0xdcd36a848dcd642e), +W64LIT(0xe4380d3751754956), +W64LIT(0x13d74e31ecaad8b5), +W64LIT(0xfd2cb949417b1abe), +W64LIT(0x9624f1d683b5977d), +W64LIT(0x4675378ba6130196), +W64LIT(0x0b26e376497cc9ca), +W64LIT(0x41d1782447043a99), +W64LIT(0xe39c4298b0627259), +W64LIT(0xcd3b16c7fe223840), +W64LIT(0x7787813cac9261ff), +W64LIT(0x492db01924e5351f), +W64LIT(0x5afafe28c84fedaa), +W64LIT(0x8b4e214c583139d6), +W64LIT(0xccde0ffe4bfa7ad7), +W64LIT(0x76629805194a2368), +W64LIT(0x7ca1624ae5eea835), +W64LIT(0x61cbb2d03e6a069e), +W64LIT(0x48c8a920913d7788), +W64LIT(0x8068c23a114df01c), +W64LIT(0xd38bed160f3b50a7), +W64LIT(0x32289dfc201ca625), +W64LIT(0xc1b9ba1e5649ca85), +W64LIT(0xed21dc33874c0447), +W64LIT(0xa3a8238542be0a57), +W64LIT(0x5b1fe7117d97af3d), +W64LIT(0x3d701a6ea2ea92ac), +W64LIT(0x73f9e5d867189cbc), +W64LIT(0x9ed839ebe05498fb), +W64LIT(0x5920d563e2d22be6), +W64LIT(0xca9f59681f35034f), +W64LIT(0x11e87c4373ef5c6e), +W64LIT(0x97c1e8ef366dd5ea), +W64LIT(0xacf0a417c0483ede), +W64LIT(0xd26ef42fbae31230), +W64LIT(0xbcfdc16d067f2027), +W64LIT(0xbec2f31f993aa4fc), +W64LIT(0x45af1cc08c8ec7da), +W64LIT(0x31f2b6b70a816069), +W64LIT(0xd9481759f39fdbfa), +W64LIT(0xe5dd140ee4ad0bc1), +W64LIT(0xa6335e583cecb583), +W64LIT(0x38eb67b3dcb82d78), +W64LIT(0xf5d07174229a1538), +W64LIT(0x5f6183f5b61d527e), +W64LIT(0x0f58879282f63489), +W64LIT(0x164c33ec92f86761), +W64LIT(0x444a05f93956854d), +W64LIT(0x818ddb03a495b28b), +W64LIT(0x4d53d4fdef6fc85c), +W64LIT(0x8d0f77da0cfe404e), +W64LIT(0x8416a6dedac70d5f), +W64LIT(0x666ffd7fdf7d3d91), +W64LIT(0xb63e3b22fadbab7a), +W64LIT(0xf2743edbc38d2e37), +W64LIT(0xa40c6c2aa3a93158), +W64LIT(0x9f3d20d2558cda6c), +W64LIT(0xfef692026be6dcf2), +W64LIT(0x2ea7545f4e404a19), +W64LIT(0xb2405fc631515639), +W64LIT(0x23c0e1bf53f3fa4b), +W64LIT(0x83b2e9713bd03650), +W64LIT(0x0641569654cf7998), +W64LIT(0xb883a589cdf5dd64), +W64LIT(0x3ad455c143fda9a3), +W64LIT(0x925a9532483f6a3e), +W64LIT(0xaab1f28194874746), +W64LIT(0xf435684d974257af), +W64LIT(0xd1b4df64907ed47c), +W64LIT(0x390e7e8a69606fef), +W64LIT(0xd051c65d25a696eb), +W64LIT(0xb4010950659e2fa1), +W64LIT(0x0c82acd9a86bf2c5), +W64LIT(0x88940a0772acff9a), +W64LIT(0xf39127e276556ca0), +W64LIT(0xaecf96655f0dba05), +W64LIT(0x03da2b4b2a9dc64c), +W64LIT(0x3f4f281c3daf1677), +W64LIT(0x3469cb6a74d3dfbd), +W64LIT(0xf04b0ca95cc8aaec), +W64LIT(0x1f55e2e844c12a70), +W64LIT(0x4cb6cdc45ab78acb), +W64LIT(0xc05ca327e3918812), +W64LIT(0x95feda9da9285131), +W64LIT(0xb966bcb0782d9ff3), +W64LIT(0xa7d647618934f714), +W64LIT(0xd61090cb7169ef73), +W64LIT(0x71c6d7aaf85d1867), +W64LIT(0xecc4c50a329446d0), +W64LIT(0x6450cf0d4038b94a), +W64LIT(0x420b536f6d99fcd5), +W64LIT(0x75b8b34e33d7e524), +W64LIT(0xc26391557cd40cc9), +W64LIT(0xda923c12d9021db6), +W64LIT(0x4e89ffb6c5f20e10), +W64LIT(0x0919d104d6394d11), +W64LIT(0x8aab3875ede97b41), +W64LIT(0xa88ec0f30bc2c39d), +W64LIT(0xb7db221b4f03e9ed), +W64LIT(0xc7f8ec880286b31d), +W64LIT(0x2f424d66fb98088e), +W64LIT(0xe04669d39affb415), +W64LIT(0x3eaa3125887754e0), +W64LIT(0x5e849acc03c510e9), +W64LIT(0x8257f0488e0874c7), +W64LIT(0xbd18d854b3a762b0), +W64LIT(0xb3a546ff848914ae), +W64LIT(0x9ce70b997f111c20), +W64LIT(0x3c9503571732d03b), +W64LIT(0xe7e2267c7be88f1a), +W64LIT(0x63f480a2a12f8245), +W64LIT(0x602eabe98bb24409), +W64LIT(0x941bc3a41cf013a6), +W64LIT(0x678ae4466aa57f06), +W64LIT(0x1232570859729a22), +W64LIT(0x6d491e099601f45b), +W64LIT(0x5d5eb1872958d6a5), +W64LIT(0x1473019e0dbde3ba), +W64LIT(0xa24d3abcf76648c0), +W64LIT(0x85f3bfe76f1f4fc8), +W64LIT(0x08fcc83d63e10f86), +W64LIT(0x745daa77860fa7b3), +W64LIT(0x9180be7962a2ac72), +W64LIT(0x87cc8d95f05acb13), +W64LIT(0x78df06ae2e645576), +W64LIT(0x18f1ad47a5d6117f), +W64LIT(0x358cd253c10b9d2a), +W64LIT(0x0ebd9eab372e761e), +W64LIT(0xf7ef4306bddf91e3), +W64LIT(0x7023ce934d855af0), +W64LIT(0xd42fa2b9ee2c6ba8), +W64LIT(0x3656f918eb965b66), +W64LIT(0x9d0212a0cac95eb7), +W64LIT(0x2ad930bb85cab75a), +W64LIT(0x862994ac45828984), +W64LIT(0x7d447b735036eaa2), +W64LIT(0xb07f6db4ae14d2e2), +W64LIT(0x6b08489fc2ce8dc3), +W64LIT(0x9b4344369e06272f), +W64LIT(0xad15bd2e75907c49), +W64LIT(0xdb77252b6cda5f21), +W64LIT(0xea85939c665b3f48), +W64LIT(0xc945722335a8c503), +W64LIT(0x159618a7b865a12d), +W64LIT(0x69377aed5d8b0918), +W64LIT(0x8971133ec774bd0d), +W64LIT(0x53e32f2c1e76a0bb), +W64LIT(0xf8b7c4943f29a56a), +W64LIT(0xff138b3bde3e9e65), +/* box 2 */ +W64LIT(0x7c6a2eb5fdabecc6), +W64LIT(0x401cda0a752bbea0), +W64LIT(0x1925217156dc57c4), +W64LIT(0x56dec6d301d70787), +W64LIT(0x41c751ff73c6ac58), +W64LIT(0xc9067697a92cb5f9), +W64LIT(0x3391c917aaa0bc85), +W64LIT(0xae0a9a4c0e742afe), +W64LIT(0xaa8ca972162a62f4), +W64LIT(0x5aa193912935df99), +W64LIT(0x86fd9135fe27e5ba), +W64LIT(0xffca074b1d3f538e), +W64LIT(0x0e3cb65d24cdfc1b), +W64LIT(0x4384b2e07fe9885d), +W64LIT(0xc73ac0ca8de149e2), +W64LIT(0x48e5bc7645972eb4), +W64LIT(0xbe0d56b46ef9ffd6), +W64LIT(0x200e6d05c0ef5f50), +W64LIT(0xe1f17dee597f7abd), +W64LIT(0x0243e31f0c2f2405), +W64LIT(0xf4ab09dd2741f567), +W64LIT(0xe4acc52547cc204f), +W64LIT(0x348f92c3b83cc272), +W64LIT(0x53837e181f645d75), +W64LIT(0xd8da319acf4c7229), +W64LIT(0x81e3cae1ecbb9b4d), +W64LIT(0xd6e687c7eb818e32), +W64LIT(0x3dad7f4a8e6d409e), +W64LIT(0x28f70b79f053cf44), +W64LIT(0x493e3783437a3c4c), +W64LIT(0xb27203f6461b27c8), +W64LIT(0xd02357e6fff0e23d), +W64LIT(0xe8d390676f2ef851), +W64LIT(0x26cbbd24d49e335f), +W64LIT(0xee1640467b5f945e), +W64LIT(0x4aa65f6949b80ab1), +W64LIT(0xb56c58225487593f), +W64LIT(0x4ffbe7a2570b5043), +W64LIT(0x0aba85633c93b411), +W64LIT(0x78ec1d8be5f5a4cc), +W64LIT(0x501b16f215a66b88), +W64LIT(0x271036d1d27321a7), +W64LIT(0x7ff2465ff769da3b), +W64LIT(0x35541936bed1d08a), +W64LIT(0xb8c886957a8893d9), +W64LIT(0x2fe950ade2cfb1b3), +W64LIT(0xf90fd76a094e3f81), +W64LIT(0x2daab3b2eee095b6), +W64LIT(0x1abd499b5c1e6139), +W64LIT(0x0c7f554228e2d81e), +W64LIT(0x425f391579049aa5), +W64LIT(0xc3bcf3f495bf01e8), +W64LIT(0xb4b7d3d7526a4bc7), +W64LIT(0x0000000000000000), +W64LIT(0xa0362c112ab9d6e5), +W64LIT(0x91e406198c364e65), +W64LIT(0x454162c16b98e452), +W64LIT(0x139fa4126a4fe3d5), +W64LIT(0x01db8bf506ed12f8), +W64LIT(0x9a85088fb648e88c), +W64LIT(0x3ab3249e9cf13e69), +W64LIT(0xd57eef2de143b8cf), +W64LIT(0xb1ea6b1c4cd91135), +W64LIT(0x7aaffe94e9da80c9), +W64LIT(0xad92f2a604b61c03), +W64LIT(0xa3ae44fb207be018), +W64LIT(0xeb4bf88d65ecceac), +W64LIT(0xc0249b1e9f7d3715), +W64LIT(0xa8cf4a6d1a0546f1), +W64LIT(0xc6e14b3f8b0c5b1a), +W64LIT(0xce182d43bbb0cb0e), +W64LIT(0xfc526fa117fd6573), +W64LIT(0x8c471456c2b451ab), +W64LIT(0xac497953025b0efb), +W64LIT(0x0486333e185e480a), +W64LIT(0x18feaa845031453c), +W64LIT(0xa1eda7e42c54c41d), +W64LIT(0x06c5d02114716c0f), +W64LIT(0x055db8cb1eb35af2), +W64LIT(0xe5774ed0412132b7), +W64LIT(0x36cc71dcb413e677), +W64LIT(0x470281de67b7c057), +W64LIT(0x58e2708e251afb9c), +W64LIT(0xa914c1981ce85409), +W64LIT(0xb3a9880340f63530), +W64LIT(0x638adfe5bf06d70d), +W64LIT(0x0b610e963a7ea6e9), +W64LIT(0x927c6ef386f47898), +W64LIT(0xed8e28ac719da2a3), +W64LIT(0x7548c33ccbfa6e2a), +W64LIT(0xf3b5520935dd8b90), +W64LIT(0x8d9c9fa3c4594353), +W64LIT(0x31d22a08a68f9880), +W64LIT(0x0da4deb72e0fcae6), +W64LIT(0x8fdf7cbcc8766756), +W64LIT(0x5dbfc8453ba9a16e), +W64LIT(0x8e04f749ce9b75ae), +W64LIT(0x83a029fee094bf48), +W64LIT(0xa4b01f2f32e79eef), +W64LIT(0x1c7899ba486f0d36), +W64LIT(0x654f0fc4ab77bb02), +W64LIT(0x7db1a540fb46fe3e), +W64LIT(0x51c09d07134b7970), +W64LIT(0xcb459588a50391fc), +W64LIT(0x3fee9c558242649b), +W64LIT(0xfe118cbe1bd24176), +W64LIT(0x76d0abd6c13858d7), +W64LIT(0x5e27a0af316b9793), +W64LIT(0x69305a868395631c), +W64LIT(0x3b68af6b9a1c2c91), +W64LIT(0x6db669b89bcb2b16), +W64LIT(0xa72877c53825a812), +W64LIT(0xd3bb3f0cf532d4c0), +W64LIT(0x6ff58aa797e40f13), +W64LIT(0x96fa5dcd9eaa3092), +W64LIT(0x2c713847e80d874e), +W64LIT(0xc57923d581ce6de7), +W64LIT(0x2b6f6393fa91f9b9), +W64LIT(0x0922ed89365182ec), +W64LIT(0x324a42e2ac4dae7d), +W64LIT(0x16c21cd974fcb927), +W64LIT(0x956235279468066f), +W64LIT(0x7b747561ef379231), +W64LIT(0x449ae9346d75f6aa), +W64LIT(0xf570822821ace79f), +W64LIT(0x5939fb7b23f7e964), +W64LIT(0x7937967ee318b634), +W64LIT(0x84be722af208c1bf), +W64LIT(0x08f9667c30bc9014), +W64LIT(0xefcdcbb37db286a6), +W64LIT(0xa6f3fc303ec8baea), +W64LIT(0xea9073786301dc54), +W64LIT(0x62515410b9ebc5f5), +W64LIT(0xd260b4f9f3dfc638), +W64LIT(0x9e033bb1ae16a086), +W64LIT(0x38f0c78190de1a6c), +W64LIT(0xc267780193521310), +W64LIT(0x80384114ea5689b5), +W64LIT(0x9b5e837ab0a5fa74), +W64LIT(0xf73361372d83c39a), +W64LIT(0x3009a1fda0628a78), +W64LIT(0xd4a564d8e7aeaa37), +W64LIT(0xfb4c347505611b84), +W64LIT(0x5b7a18642fd8cd61), +W64LIT(0x239605efca2d69ad), +W64LIT(0xf8d45c9f0fa32d79), +W64LIT(0xbb50ee7f704aa524), +W64LIT(0x392b4c7496330894), +W64LIT(0x0fe73da82220eee3), +W64LIT(0x3717fa29b2fef48f), +W64LIT(0xf26ed9fc33309968), +W64LIT(0xd73d0c32ed6c9cca), +W64LIT(0xda99d285c363562c), +W64LIT(0xde1fe1bbdb3d1e26), +W64LIT(0x738d131ddf8b0225), +W64LIT(0x292c808cf6beddbc), +W64LIT(0xbc4eb5ab62d6dbd3), +W64LIT(0x039868ea0ac236fd), +W64LIT(0xcc5bce5cb79fef0b), +W64LIT(0xb031e0e94a3403cd), +W64LIT(0xc4a2a82087237f1f), +W64LIT(0xb72fbb3d58a87d3a), +W64LIT(0xafd111b908993806), +W64LIT(0x68ebd173857871e4), +W64LIT(0x9d9b535ba4d4967b), +W64LIT(0xe9081b9269c3eaa9), +W64LIT(0x71cef002d3a42620), +W64LIT(0x93a7e50680196a60), +W64LIT(0x891aac9ddc070b59), +W64LIT(0x155a74337e3e8fda), +W64LIT(0x4e206c5751e642bb), +W64LIT(0x9721d6389847226a), +W64LIT(0x12442fe76ca2f12d), +W64LIT(0x2553d5cede5c05a2), +W64LIT(0xa275cf0e2696f2e0), +W64LIT(0x24885e3bd8b1175a), +W64LIT(0x670cecdba7589f07), +W64LIT(0x749348c9cd177cd2), +W64LIT(0x64948431ad9aa9fa), +W64LIT(0x2ab4e866fc7ceb41), +W64LIT(0xe6ef263a4be3044a), +W64LIT(0xe734adcf4d0e16b2), +W64LIT(0x903f8dec8adb5c9d), +W64LIT(0xf02d3ae33f1fbd6d), +W64LIT(0x725698e8d96610dd), +W64LIT(0x1da3124f4e821fce), +W64LIT(0x1719972c7211abdf), +W64LIT(0x11dc470d6660c7d0), +W64LIT(0xec55a3597770b05b), +W64LIT(0xbfd6dd416814ed2e), +W64LIT(0x57054d26073a157f), +W64LIT(0x1e3b7aa544402933), +W64LIT(0x5ffc2b5a3786856b), +W64LIT(0x61c93cfab329f308), +W64LIT(0x3e3517a084af7663), +W64LIT(0xf6e8eac22b6ed162), +W64LIT(0x1007ccf8608dd528), +W64LIT(0x66d7672ea1b58dff), +W64LIT(0x8b594f82d0282f5c), +W64LIT(0x1fe0f15042ad3bcb), +W64LIT(0x4b7dd49c4f551849), +W64LIT(0x4c638f485dc966be), +W64LIT(0xcfc3a6b6bd5dd9f6), +W64LIT(0x46d90a2b615ad2af), +W64LIT(0x8565f9dff4e5d347), +W64LIT(0x94b9bed292851497), +W64LIT(0xfa97bf80038c097c), +W64LIT(0xb9130d607c658121), +W64LIT(0xdc5c02a4d7123a23), +W64LIT(0x224d8e1accc07b55), +W64LIT(0x87261ac0f8caf742), +W64LIT(0xd901ba6fc9a160d1), +W64LIT(0xab57228710c7700c), +W64LIT(0x21d5e6f0c6024da8), +W64LIT(0x98c6eb90ba67cc89), +W64LIT(0x827ba20be679adb0), +W64LIT(0x991d6065bc8ade71), +W64LIT(0x5546ae390b15317a), +W64LIT(0xa56b94da340a8c17), +W64LIT(0x071e5bd4129c7ef7), +W64LIT(0xe02af61b5f926845), +W64LIT(0x6b73b9998fba4719), +W64LIT(0xdfc46a4eddd00cde), +W64LIT(0x770b2023c7d54a2f), +W64LIT(0x7e29cdaaf184c8c3), +W64LIT(0xba8b658a76a7b7dc), +W64LIT(0x9c40d8aea2398483), +W64LIT(0x9fd8b044a8fbb27e), +W64LIT(0xdb425970c58e44d4), +W64LIT(0xe269150453bd4c40), +W64LIT(0x3c76f4bf88805266), +W64LIT(0xf1f6b11639f2af95), +W64LIT(0x549d25cc0df82382), +W64LIT(0x4db804bd5b247446), +W64LIT(0x8a82c477d6c53da4), +W64LIT(0x5258f5ed19894f8d), +W64LIT(0x6e2e015291091deb), +W64LIT(0xc1ff10eb999025ed), +W64LIT(0xbd953e5e643bc92b), +W64LIT(0xc8ddfd62afc1a701), +W64LIT(0x5c6443b03d44b396), +W64LIT(0x6c6de24d9d2639ee), +W64LIT(0x1481ffc678d39d22), +W64LIT(0xd1f8dc13f91df0c5), +W64LIT(0xca9e1e7da3ee8304), +W64LIT(0xdd878951d1ff28db), +W64LIT(0x6012b70fb5c4e1f0), +W64LIT(0x1b66c26e5af373c1), +W64LIT(0xe3b29ef155505eb8), +W64LIT(0x70157bf7d54934d8), +W64LIT(0x2e32db58e422a34b), +W64LIT(0x6aa8326c895755e1), +W64LIT(0xb6f430c85e456fc2), +W64LIT(0xfd89e4541110778b), +W64LIT(0x88c12768daea19a1), +W64LIT(0xcd8045a9b172fdf3), +/* box 3 */ +W64LIT(0x99183e616655b742), +W64LIT(0xb2872032a50d6860), +W64LIT(0x0946f63b060528ef), +W64LIT(0x36612b9a141ef07d), +W64LIT(0x0634da84dd49579b), +W64LIT(0xfc9c9e9b486c8a57), +W64LIT(0xa63fe3c0744e6fd0), +W64LIT(0xf1515758d8b46bf9), +W64LIT(0x3e82559fcd5197ff), +W64LIT(0x92e12d262bc40177), +W64LIT(0xc3bb433a5a7752c5), +W64LIT(0x21c3852a5183267a), +W64LIT(0x39130725cf528f09), +W64LIT(0x9ba7db1d2dc12998), +W64LIT(0xc58f99be873e055e), +W64LIT(0xd9d424498f32656c), +W64LIT(0x27f75fae8cca71e1), +W64LIT(0x59b91019a8fc3430), +W64LIT(0xce768af9caafb36b), +W64LIT(0x9d930199f0887e03), +W64LIT(0x63b07a7ef3706a8e), +W64LIT(0xb5167288a70e7096), +W64LIT(0x40cc1a28e967d22e), +W64LIT(0x4d01d3eb79bf3380), +W64LIT(0x9e896cdb6456afb4), +W64LIT(0x2548bad2c75eef3b), +W64LIT(0xa79a6bfeab0420bd), +W64LIT(0x9f2ce4e5bb1ce0d9), +W64LIT(0x32ea146282c3393c), +W64LIT(0x6d67defff7765a97), +W64LIT(0x83775912b31080eb), +W64LIT(0xf5da68a04e69a2b8), +W64LIT(0x1196743498d4819c), +W64LIT(0x0bf913474d91b635), +W64LIT(0x43d6776a7db90399), +W64LIT(0x444725d07fba1b6f), +W64LIT(0x6584a0fa2e393d15), +W64LIT(0x3f27dda1121bd892), +W64LIT(0xf6c005e2dab7730f), +W64LIT(0x56cb3ca673b04b44), +W64LIT(0x642128c4f1737278), +W64LIT(0xbf4ae9f135d589ce), +W64LIT(0xb038c54eee99f6ba), +W64LIT(0xf47fe09e9123edd5), +W64LIT(0x75b75cf069a7f3e4), +W64LIT(0xd419ed8a1fea84c2), +W64LIT(0x73838674b4eea47f), +W64LIT(0x498aec13ef62fac1), +W64LIT(0x20660d148ec96917), +W64LIT(0xa48006bc3fdaf10a), +W64LIT(0x2f1421ab55851663), +W64LIT(0x0a5c9b7992dbf958), +W64LIT(0xd1375a4c567d02ee), +W64LIT(0x0000000000000000), +W64LIT(0xc842507d17e6e4f0), +W64LIT(0xf3eeb2249320f523), +W64LIT(0xc9e7d843c8acab9d), +W64LIT(0xff86f3d9dcb25be0), +W64LIT(0xb4b3fab678443ffb), +W64LIT(0xb19d4d7031d3b9d7), +W64LIT(0x79df1d0d26355d27), +W64LIT(0x8eba90d123c86145), +W64LIT(0xaa57a23d3bdcc113), +W64LIT(0xcb583d3f83383547), +W64LIT(0xd871ac7750782a01), +W64LIT(0xe162ab529f2aa508), +W64LIT(0x38b68f1b1018c064), +W64LIT(0x237c60561a17b8a0), +W64LIT(0xa31154063dd9e9fc), +W64LIT(0x713c6308ff7a3aa5), +W64LIT(0x1a6f6773d54537a9), +W64LIT(0x08e37e05d94f6782), +W64LIT(0x357b46d880c021ca), +W64LIT(0x6cc256c1283c15fa), +W64LIT(0xcfd302c715e5fc06), +W64LIT(0xbdf50c8d7e411714), +W64LIT(0x7cf1aacb6fa2db0b), +W64LIT(0x5240035ee56d8205), +W64LIT(0x7b60f8716da1c3fd), +W64LIT(0x01a5883edf4a4f6d), +W64LIT(0xdd5f1bb119efac2d), +W64LIT(0x5474d9da3824d59e), +W64LIT(0x0f722cbfdb4c7f74), +W64LIT(0x17a2aeb0459dd607), +W64LIT(0x37c4a3a4cb54bf10), +W64LIT(0xc21ecb04853d1da8), +W64LIT(0x4273ff54a2f34cf4), +W64LIT(0xdace490b1becb4db), +W64LIT(0x6af68c45f5754261), +W64LIT(0x46f8c0ac342e85b5), +W64LIT(0x854383966e59d770), +W64LIT(0x81c8bc6ef8841e31), +W64LIT(0x3bace25984c611d3), +W64LIT(0x1033fc0a479ecef1), +W64LIT(0x1c5bbdf7080c6032), +W64LIT(0x7412d4ceb6edbc89), +W64LIT(0xa8e8474170485fc9), +W64LIT(0xb8dbbb4b37d69138), +W64LIT(0x079152ba020318f6), +W64LIT(0x72260e4a6ba4eb12), +W64LIT(0x905ec85a60509fad), +W64LIT(0x2dabc4d71e1188b9), +W64LIT(0xd092d27289374d83), +W64LIT(0x610f9f02b8e4f454), +W64LIT(0x02bfe57c4b949eda), +W64LIT(0x95707f9c29c71981), +W64LIT(0x6fd83b83bce2c44d), +W64LIT(0x5d322fe13e21fd71), +W64LIT(0x34decee65f8a6ea7), +W64LIT(0xcd6ce7bb5e7162dc), +W64LIT(0xfb0dcc214a6f92a1), +W64LIT(0x2eb1a9958acf590e), +W64LIT(0xdcfa938fc6a5e340), +W64LIT(0x669ecdb8bae7eca2), +W64LIT(0x151d4bcc0e0948dd), +W64LIT(0xfd3916a59726c53a), +W64LIT(0x581c982777b67b5d), +W64LIT(0x1bcaef4d0a0f78c4), +W64LIT(0xdfe0fecd527b32f7), +W64LIT(0x128c19760c0a502b), +W64LIT(0x84e60ba8b113981d), +W64LIT(0x3c3db0e386c50925), +W64LIT(0x7febc789fb7c0abc), +W64LIT(0x7d5422f5b0e89466), +W64LIT(0xd70380c88b345575), +W64LIT(0xbbc1d609a308408f), +W64LIT(0xe278c6100bf474bf), +W64LIT(0x5e2842a3aaff2cc6), +W64LIT(0x6b53047b2a3f0d0c), +W64LIT(0xf7658ddc05fd3c62), +W64LIT(0x9a025323f28b66f5), +W64LIT(0x8c0575ad685cff9f), +W64LIT(0x76ad31b2fd792253), +W64LIT(0x68496939bee1dcbb), +W64LIT(0x7e4e4fb7243645d1), +W64LIT(0xe44c1c94d6bd2324), +W64LIT(0xbeef61cfea9fc6a3), +W64LIT(0x91fb4064bf1ad0c0), +W64LIT(0x052eb7c64997862c), +W64LIT(0x4a9081517bbc2b76), +W64LIT(0x8f1f18effc822e28), +W64LIT(0x3a096a675b8c5ebe), +W64LIT(0xee1087ed4466da7c), +W64LIT(0x2652d79053803e8c), +W64LIT(0x7099eb36203075c8), +W64LIT(0xc7307cc2ccaa9b84), +W64LIT(0x5c97a7dfe16bb21c), +W64LIT(0x50ffe622aef91cdf), +W64LIT(0x8da0fd93b716b0f2), +W64LIT(0x69ece10761ab93d6), +W64LIT(0x31f07920161de88b), +W64LIT(0x13299148d3401f46), +W64LIT(0x031a6d4294ded1b7), +W64LIT(0xccc96f85813b2db1), +W64LIT(0x14b8c3f2d14307b0), +W64LIT(0x8659eed4fa8706c7), +W64LIT(0xba645e377c420fe2), +W64LIT(0x2920fb2f88cc41f8), +W64LIT(0x87fc66ea25cd49aa), +W64LIT(0x1ee4588b4398fee8), +W64LIT(0xecaf62910ff244a6), +W64LIT(0xf817a163deb14316), +W64LIT(0x45e2adeea0f05402), +W64LIT(0x806d345027ce515c), +W64LIT(0x576eb498acfa0429), +W64LIT(0xa5258e82e090be67), +W64LIT(0x892bc26b21cb79b3), +W64LIT(0x6e7db3bd63a88b20), +W64LIT(0x4e1bbea9ed61e237), +W64LIT(0xadc6f08739dfd9e5), +W64LIT(0x8b9427176a5fe769), +W64LIT(0xa1aeb17a764d7726), +W64LIT(0x4b35096fa4f6641b), +W64LIT(0x22d9e868c55df7cd), +W64LIT(0x55d151e4e76e9af3), +W64LIT(0x966a12debd19c836), +W64LIT(0x0dcdc9c390d8e1ae), +W64LIT(0xf24b3a1a4c6aba4e), +W64LIT(0x24ed32ec1814a056), +W64LIT(0xaf7915fb724b473f), +W64LIT(0x2885731157860e95), +W64LIT(0x9c3689a72fc2316e), +W64LIT(0x475d4892eb64cad8), +W64LIT(0xac6378b9e6959688), +W64LIT(0xa00b3944a907384b), +W64LIT(0xc695f4fc13e0d4e9), +W64LIT(0x3055f11ec957a7e6), +W64LIT(0x6215f2402c3a25e3), +W64LIT(0xde4576f38d317d9a), +W64LIT(0x9344a518f48e4e1a), +W64LIT(0x82d2d12c6c5acf86), +W64LIT(0xefb50fd39b2c9511), +W64LIT(0xe981d5574665c28a), +W64LIT(0x5f8dca9d75b563ab), +W64LIT(0xb60c1fca33d0a121), +W64LIT(0xfe237be703f8148d), +W64LIT(0xd6a608f6547e1a18), +W64LIT(0xb97e3375e89cde55), +W64LIT(0xd388bf301de99c34), +W64LIT(0x5b06f565e368aaea), +W64LIT(0xf0f4df6607fe2494), +W64LIT(0x1607268e9ad7996a), +W64LIT(0xaedc9dc5ad010852), +W64LIT(0xe0c7236c4060ea65), +W64LIT(0xea9bb815d2bb133d), +W64LIT(0x888e4a55fe8136de), +W64LIT(0x5aa37d5b3c22e587), +W64LIT(0xc104a64611e3cc1f), +W64LIT(0x515a6e1c71b353b2), +W64LIT(0xc42a118058744a33), +W64LIT(0x7708b98c22336d3e), +W64LIT(0x2a3a966d1c12904f), +W64LIT(0x8a31af29b515a804), +W64LIT(0xed0aeaafd0b80bcb), +W64LIT(0x2c0e4ce9c15bc7d4), +W64LIT(0x0c6841fd4f92aec3), +W64LIT(0x98bdb65fb91ff82f), +W64LIT(0x1f41d0b59cd2b185), +W64LIT(0xb322a80c7a47270d), +W64LIT(0xe6f3f9e89d29bdfe), +W64LIT(0x7ac5704fb2eb8c90), +W64LIT(0xa94dcf7faf0210a4), +W64LIT(0x787a9533f97f124a), +W64LIT(0xdb6bc135c4a6fbb6), +W64LIT(0x048b3ff896ddc941), +W64LIT(0xe8245d69992f8de7), +W64LIT(0xe3dd4e2ed4be3bd2), +W64LIT(0xcafdb5015c727a2a), +W64LIT(0xb7a997f4ec9aee4c), +W64LIT(0xe75671d64263f293), +W64LIT(0x2b9f1e53c358df22), +W64LIT(0x18d0820f9ed1a973), +W64LIT(0xabf22a03e4968e7e), +W64LIT(0xa2b4dc38e293a691), +W64LIT(0x673b458665ada3cf), +W64LIT(0xf9b2295d01fb0c7b), +W64LIT(0xd22d370ec2a3d359), +W64LIT(0x97cf9ae06253875b), +W64LIT(0x0ed7a48104063019), +W64LIT(0x482f642d3028b5ac), +W64LIT(0xc0a12e78cea98372), +W64LIT(0x4fbe3697322bad5a), +W64LIT(0x19750a31419be61e), +W64LIT(0x41699216362d9d43), +W64LIT(0xd5bc65b4c0a0cbaf), +W64LIT(0xe5e994aa09f76c49), +W64LIT(0xeb3e302b0df15c50), +W64LIT(0x94d5f7a2f68d56ec), +W64LIT(0x53e58b603a27cd68), +W64LIT(0x3d9838dd598f4648), +W64LIT(0x60aa173c67aebb39), +W64LIT(0x1dfe35c9d7462f5f), +W64LIT(0x4ca45bd5a6f57ced), +W64LIT(0xbc5084b3a10b5879), +W64LIT(0xfaa8441f9525ddcc), +W64LIT(0x334f9c5c5d897651), +/* box 4 */ +W64LIT(0xda1687a883adf27e), +W64LIT(0xe35c9378578d9f22), +W64LIT(0x303ca4531637fa40), +W64LIT(0xa088321f74b20375), +W64LIT(0xc9863f3a9acb95e9), +W64LIT(0x5fcf47c57d0b0ed4), +W64LIT(0x4aa211e4e1280b4b), +W64LIT(0xe1a4c9ba871d1289), +W64LIT(0x4926664759f03a4f), +W64LIT(0xadfb36ede3707bca), +W64LIT(0xcf7bd1891f8ef7e1), +W64LIT(0x9735559e8f882792), +W64LIT(0x5932a976f84e6cdc), +W64LIT(0x9dc792bef547818a), +W64LIT(0x06fdeeb385456208), +W64LIT(0x46ad38771ea2cf5b), +W64LIT(0x5eb36aa41543b27b), +W64LIT(0x8b2eb33cd1bcb511), +W64LIT(0x71105ff6e598ebbc), +W64LIT(0x5441ad846f8c1463), +W64LIT(0x4c5fff57646d6943), +W64LIT(0xf3485c49f633c9b1), +W64LIT(0x9cbbbfdf9d0f3d25), +W64LIT(0x22d031a067192178), +W64LIT(0xca0248992213a4ed), +W64LIT(0x19627fb263a9c18f), +W64LIT(0x9330e1efda5dc831), +W64LIT(0x1390b89219666797), +W64LIT(0x2edf18339893e568), +W64LIT(0x6c779435d3e4c590), +W64LIT(0x53c06e568281cac4), +W64LIT(0x6ff3e3966b3cf494), +W64LIT(0xfe3b58bb61f1b10e), +W64LIT(0x77edb14560dd89b4), +W64LIT(0x02f85ac2d0908dab), +W64LIT(0x12ec95f3712edb38), +W64LIT(0x85d9c06dfea6fcaa), +W64LIT(0x90b4964c6285f935), +W64LIT(0xf1b0068b26a3441a), +W64LIT(0x729428555d40dab8), +W64LIT(0x5c4b3066c5d33fd0), +W64LIT(0x5d371d07ad9b837f), +W64LIT(0xa48d866e2167ecd6), +W64LIT(0xb661139d504937ee), +W64LIT(0xa27068dda4228ede), +W64LIT(0xf8c6b608e4b4d306), +W64LIT(0x6bf657e73ee91b37), +W64LIT(0xac871b8c8b38c765), +W64LIT(0x4ea7a595b4fde4e8), +W64LIT(0x0d7304f297c278bf), +W64LIT(0xb71d3efc38018b41), +W64LIT(0xae7f414e5ba84ace), +W64LIT(0xaf036c2f33e0f661), +W64LIT(0x0000000000000000), +W64LIT(0xb89660cc7f537e55), +W64LIT(0xa675dcacf1f7617d), +W64LIT(0x610490c74426bd2f), +W64LIT(0xc18ca2d83094be5a), +W64LIT(0x2adaac42cd460acb), +W64LIT(0x7d1f76651a122fac), +W64LIT(0xc58916a9654151f9), +W64LIT(0xedabe0297897d699), +W64LIT(0x2d5b6f90204bd46c), +W64LIT(0x26d585d132cccedb), +W64LIT(0x9f3fc87c25d70c21), +W64LIT(0xc60d610add9960fd), +W64LIT(0x80a0597dc33bafa6), +W64LIT(0xd0e44088f9625466), +W64LIT(0x1d67cbc3367c2e2c), +W64LIT(0x2c2742f1480368c3), +W64LIT(0x89d6e9fe012c38ba), +W64LIT(0xe9ae54582d42393a), +W64LIT(0x3ecbd702392db3fb), +W64LIT(0xb5e5643ee89106ea), +W64LIT(0xa882affddeed28c6), +W64LIT(0x1ae60811db71f08b), +W64LIT(0x924ccc8eb215749e), +W64LIT(0xfcc30279b1613ca5), +W64LIT(0x825803bf13ab220d), +W64LIT(0xd992f00b3b75c37a), +W64LIT(0xc8fa125bf2832946), +W64LIT(0x35453d432baaa94c), +W64LIT(0xf9ba9b698cfc6fa9), +W64LIT(0x37bd6781fb3a24e7), +W64LIT(0x791ac2144fc7c00f), +W64LIT(0x16e9218224fb349b), +W64LIT(0xdb6aaac9ebe54ed1), +W64LIT(0xd8eedd6a533d7fd5), +W64LIT(0x7c635b04725a9303), +W64LIT(0x553d80e507c4a8cc), +W64LIT(0x9a46516c184a5f2d), +W64LIT(0x14117b40f46bb930), +W64LIT(0x1ee3bc608ea41f28), +W64LIT(0x27a9a8b05a847274), +W64LIT(0x4050d6c49be7ad53), +W64LIT(0x7be298d69f574da4), +W64LIT(0x6a8a7a8656a1a798), +W64LIT(0x4d23d2360c25d5ec), +W64LIT(0x1014cf31a1be5693), +W64LIT(0xb264a7ec059cd84d), +W64LIT(0xea2a23fb959a083e), +W64LIT(0xf0cc2bea4eebf8b5), +W64LIT(0x76919c240895351b), +W64LIT(0x0b8eea4112871ab7), +W64LIT(0x47d1151676ea73f4), +W64LIT(0xbdeff9dc42ce2d59), +W64LIT(0x2ba68123a50eb664), +W64LIT(0x057999103d9d530c), +W64LIT(0xe759270902587081), +W64LIT(0xef53baeba8075b32), +W64LIT(0x4fdb88f4dcb55847), +W64LIT(0x6e8fcef70374483b), +W64LIT(0x1168e250c9f6ea3c), +W64LIT(0x1b9a2570b3394c24), +W64LIT(0x706c72978dd05713), +W64LIT(0x865db7ce467ecdae), +W64LIT(0x52bc4337eac9766b), +W64LIT(0x504419f53a59fbc0), +W64LIT(0x8f2b074d84695ab2), +W64LIT(0x6078bda62c6e0180), +W64LIT(0x43d4a167233f9c57), +W64LIT(0x0ef773512f1a49bb), +W64LIT(0x0c0f2993ff8ac410), +W64LIT(0x4bde3c858960b7e4), +W64LIT(0x66855315a92b6388), +W64LIT(0xd360372b41ba6562), +W64LIT(0x584e84179006d073), +W64LIT(0x9b3a7c0d7002e382), +W64LIT(0xa5f1ab0f492f5079), +W64LIT(0x2822f6801dd68760), +W64LIT(0x445562b5ce3242f0), +W64LIT(0xaa7af53f0e7da56d), +W64LIT(0x3c338dc0e9bd3e50), +W64LIT(0x3bb24e1204b0e0f7), +W64LIT(0xd59dd998c4ff076a), +W64LIT(0x91c8bb2d0acd459a), +W64LIT(0x84a5ed0c96ee4005), +W64LIT(0x33b8d3f0aeefcb44), +W64LIT(0x57c5da27d7542567), +W64LIT(0x32c4fe91c6a777eb), +W64LIT(0x3439102243e215e3), +W64LIT(0xc7714c6bb5d1dc52), +W64LIT(0x3fb7fa6351650f54), +W64LIT(0x87219aaf2e367101), +W64LIT(0xf5b5b2fa7376abb9), +W64LIT(0x412cfba5f3af11fc), +W64LIT(0xdceb691b06e89076), +W64LIT(0xbb12176fc78b4f51), +W64LIT(0x73e8053435086617), +W64LIT(0xe220be193fc5238d), +W64LIT(0xb09cfd2ed50c55e6), +W64LIT(0xb9ea4dad171bc2fa), +W64LIT(0x9e43e51d4d9fb08e), +W64LIT(0x36c14ae093729848), +W64LIT(0xa9fe829cb6a59469), +W64LIT(0x0405b47155d5efa3), +W64LIT(0x0af2c7207acfa618), +W64LIT(0x7e9b01c6a2ca1ea8), +W64LIT(0xdd97447a6ea02cd9), +W64LIT(0x0781c3d2ed0ddea7), +W64LIT(0x7866ef75278f7ca0), +W64LIT(0xd1986de9912ae8c9), +W64LIT(0xcb7e65f84a5b1842), +W64LIT(0xcd838b4bcf1e7a4a), +W64LIT(0xab06d85e663519c2), +W64LIT(0xd4e1f4f9acb7bbc5), +W64LIT(0xfdbf2f18d929800a), +W64LIT(0xf23471289e7b751e), +W64LIT(0xbc93d4bd2a8691f6), +W64LIT(0x3d4fa0a181f582ff), +W64LIT(0xba6e3a0eafc3f3fe), +W64LIT(0x5ab6ded540965dd8), +W64LIT(0xeb560e9afdd2b491), +W64LIT(0x0976b083c217971c), +W64LIT(0xecd7cd4810df6a36), +W64LIT(0x23ac1cc10f519dd7), +W64LIT(0xbe6b8e7ffa161c5d), +W64LIT(0x7fe72ca7ca82a207), +W64LIT(0xc0f08fb958dc02f5), +W64LIT(0x7a9eb5b7f71ff10b), +W64LIT(0xa709f1cd99bfddd2), +W64LIT(0x8dd35d8f54f9d719), +W64LIT(0x8caf70ee3cb16bb6), +W64LIT(0xe4dd50aaba804185), +W64LIT(0x83242ede7be39ea2), +W64LIT(0x98be0baec8dad286), +W64LIT(0x690e0d25ee79969c), +W64LIT(0x95cd0f5c5f18aa39), +W64LIT(0x56b9f746bf1c99c8), +W64LIT(0x7469c6e6d805b8b0), +W64LIT(0x8a529e5db9f409be), +W64LIT(0xe6250a686a10cc2e), +W64LIT(0x2fa33552f0db59c7), +W64LIT(0x42a88c064b7720f8), +W64LIT(0x6d0bb954bbac793f), +W64LIT(0x181e52d30be17d20), +W64LIT(0xbf17a31e925ea0f2), +W64LIT(0x94b1223d37501696), +W64LIT(0xe8d27939450a8595), +W64LIT(0xccffa62aa756c6e5), +W64LIT(0x383639b1bc68d1f3), +W64LIT(0xee2f978ac04fe79d), +W64LIT(0xa30c45bccc6a3271), +W64LIT(0x1f9f9101e6eca387), +W64LIT(0xb1e0d04fbd44e949), +W64LIT(0x242ddf13e25c4370), +W64LIT(0x156d56219c23059f), +W64LIT(0x88aac49f69648415), +W64LIT(0x6280e764fcfe8c2b), +W64LIT(0xdf6f1eb8be30a172), +W64LIT(0xe5a17dcbd2c8fd2a), +W64LIT(0xe0d8e4dbef55ae26), +W64LIT(0x63fcca0594b63084), +W64LIT(0xa1f41f7e1cfabfda), +W64LIT(0x295edbe1759e3bcf), +W64LIT(0x67f97e74c163df27), +W64LIT(0x038477a3b8d83104), +W64LIT(0xde1333d9d6781ddd), +W64LIT(0x3ace63736cf85c58), +W64LIT(0xd619ae3b7c27366e), +W64LIT(0x5bcaf3b428dee177), +W64LIT(0xb3188a8d6dd464e2), +W64LIT(0x1c1be6a25e349283), +W64LIT(0x017c2d616848bcaf), +W64LIT(0x8e572a2cec21e61d), +W64LIT(0xf631c559cbae9abd), +W64LIT(0x81dc741cab731309), +W64LIT(0xff4775da09b90da1), +W64LIT(0xb499495f80d9ba45), +W64LIT(0x0f8b5e304752f514), +W64LIT(0x394a14d0d4206d5c), +W64LIT(0xce07fce877c64b4e), +W64LIT(0xf4c99f9b1b3e1716), +W64LIT(0xc4f53bc80d09ed56), +W64LIT(0xc208d57b884c8f5e), +W64LIT(0x080a9de2aa5f2bb3), +W64LIT(0x314089327e7f46ef), +W64LIT(0xfa3eecca34245ead), +W64LIT(0x20286b62b789acd3), +W64LIT(0x7515eb87b04d041f), +W64LIT(0x513834945211476f), +W64LIT(0x650124b611f3528c), +W64LIT(0x17950ce34cb38834), +W64LIT(0x45294fd4a67afe5f), +W64LIT(0x21544603dfc1107c), +W64LIT(0x485a4b2631b886e0), +W64LIT(0x6872204486312a33), +W64LIT(0x647d09d779bbee23), +W64LIT(0x2551f2728a14ffdf), +W64LIT(0xd765835a146f8ac1), +W64LIT(0xd21c1a4a29f2d9cd), +W64LIT(0x99c226cfa0926e29), +W64LIT(0xfb42c1ab5c6ce202), +W64LIT(0xc374f81ae00433f1), +W64LIT(0x964978ffe7c09b3d), +W64LIT(0xf74de838a3e62612), +/* box 5 */ +W64LIT(0x74b87b36b0592c6a), +W64LIT(0x3d82d75dffb4b81c), +W64LIT(0x8884246715267825), +W64LIT(0xdaf2d8a77ed4e5de), +W64LIT(0xfeb118650e53f9c7), +W64LIT(0xbd2d1aea59226b06), +W64LIT(0x26ce87f6dbabb191), +W64LIT(0x32772ecbeb66bd0a), +W64LIT(0xd4bbf82bc5104c8c), +W64LIT(0x055357720c4e03a1), +W64LIT(0xef5be62a32d0f6fd), +W64LIT(0xbe1c84c45d186aca), +W64LIT(0xacc7e4a565a1643c), +W64LIT(0x8dd7731519687b84), +W64LIT(0x11eafe4f3c830f3a), +W64LIT(0x04ef8e68a358afe5), +W64LIT(0x40ad9ca1534b930d), +W64LIT(0xe44191d4855a5c0e), +W64LIT(0x6001d20b809420f1), +W64LIT(0x73666b70173b8243), +W64LIT(0x372479b9e728beab), +W64LIT(0x45fecbd35f0590ac), +W64LIT(0x7057f55e1301838f), +W64LIT(0xff0dc17fa1455583), +W64LIT(0x0cc467b810e804da), +W64LIT(0xb9c29482fa7ac4e3), +W64LIT(0xa003831d754960e6), +W64LIT(0x8a096353be0ad5ad), +W64LIT(0xdd2cc8e1d9b64bf7), +W64LIT(0xc7dc415052bfee3e), +W64LIT(0x9f0c137421d17572), +W64LIT(0x35a93e8d4c041323), +W64LIT(0x9a5f44062d9f76d3), +W64LIT(0x71eb2c44bc172fcb), +W64LIT(0x0ff5f99614d20516), +W64LIT(0x7789e518b4632da6), +W64LIT(0xc99561dce97b476c), +W64LIT(0x5276fcc06bf29dfb), +W64LIT(0x4a0b32454bd795ba), +W64LIT(0x9274add69e2fddec), +W64LIT(0x4f5865374799961b), +W64LIT(0xb2d8e37c4df06e10), +W64LIT(0xc4eddf7e5685eff2), +W64LIT(0xb3643a66e2e6c254), +W64LIT(0xd50721316a06e0c8), +W64LIT(0x8bb5ba49111c79e9), +W64LIT(0x2bb639546455190f), +W64LIT(0xf8d3d1390627fbaa), +W64LIT(0x38d1802ff3fabbbd), +W64LIT(0xdfa18fd5729ae67f), +W64LIT(0x4ee4bc2de88f3a5f), +W64LIT(0xf72628af12f5febc), +W64LIT(0x0aa6aee4189c06b7), +W64LIT(0x0000000000000000), +W64LIT(0x9eb0ca6e8ec7d936), +W64LIT(0xcb1826e84257eae4), +W64LIT(0x187dce8520250841), +W64LIT(0xc28f16225ef1ed9f), +W64LIT(0xc333cf38f1e741db), +W64LIT(0x4220db95f8673e85), +W64LIT(0xdc9011fb76a0e7b3), +W64LIT(0x105627559395a37e), +W64LIT(0x2f59b73cc70db6ea), +W64LIT(0xe112c6a689145faf), +W64LIT(0x82228a830dba7e92), +W64LIT(0x2ee56e26681b1aae), +W64LIT(0x2a0ae04ecb43b54b), +W64LIT(0x47738ce7f4293d24), +W64LIT(0xa7dd935bd22bcecf), +W64LIT(0xd2d93177cd644ee1), +W64LIT(0xebb4684291885918), +W64LIT(0x0e49208cbbc4a952), +W64LIT(0xa550d46f79076347), +W64LIT(0x411145bbfc5d3f49), +W64LIT(0xe6ccd6e02e76f186), +W64LIT(0x4bb7eb5fe4c139fe), +W64LIT(0x5d8305567f2098ed), +W64LIT(0x95aabd90394d73c5), +W64LIT(0x25ff19d8df91b05d), +W64LIT(0x86cd04ebaee2d177), +W64LIT(0x03319e2e043a01cc), +W64LIT(0x6b1ba5f5371e8a02), +W64LIT(0x76353c021b7581e2), +W64LIT(0x64ee5c6323cc8f14), +W64LIT(0x5c3fdc4cd03634a9), +W64LIT(0x6996e2c19c32278a), +W64LIT(0x8938fd7dba30d461), +W64LIT(0x7b4d82a0a48b297c), +W64LIT(0xbfa05ddef20ec68e), +W64LIT(0x8ee6ed3b1d527a48), +W64LIT(0x61bd0b112f828cb5), +W64LIT(0x66631b5788e0229c), +W64LIT(0x55a8ec86cc9033d2), +W64LIT(0x1c9240ed837da7a4), +W64LIT(0x150570279fdba0df), +W64LIT(0x53ca25dac4e431bf), +W64LIT(0xd636bf1f6e3ce104), +W64LIT(0xcaa4fff2ed4146a0), +W64LIT(0x787c1c8ea0b128b0), +W64LIT(0xad7b3dbfcab7c878), +W64LIT(0xfc3c5f51a57f544f), +W64LIT(0xb78bb40e41be6db1), +W64LIT(0x8c6baa0fb67ed7c0), +W64LIT(0xce4b719a4e19e945), +W64LIT(0xf96f0823a93157ee), +W64LIT(0x7d2f4bfcacff2b11), +W64LIT(0x3eb34973fb8eb9d0), +W64LIT(0xe39f81922238f227), +W64LIT(0x239dd084d7e5b230), +W64LIT(0x1fa3dec38747a668), +W64LIT(0xc5510664f99343b6), +W64LIT(0xc829b8c6466deb28), +W64LIT(0x85fc9ac5aad8d0bb), +W64LIT(0xb6376d14eea8c1f5), +W64LIT(0x9d8154408afdd8fa), +W64LIT(0x3be01e01f7c0ba71), +W64LIT(0x628c953f2bb88d79), +W64LIT(0x6d796ca93f6a886f), +W64LIT(0xfa5e960dad0b5622), +W64LIT(0xe5fd48ce2a4cf04a), +W64LIT(0xe7700ffa81605dc2), +W64LIT(0x2dd4f0086c211b62), +W64LIT(0x2221099e78f31e74), +W64LIT(0xdb4e01bdd1c2499a), +W64LIT(0xf417b68116cfff70), +W64LIT(0xb506f33aea92c039), +W64LIT(0x514762ee6fc89c37), +W64LIT(0x9c3d8d5a25eb74be), +W64LIT(0x396d59355cec17f9), +W64LIT(0xccc636aee53544cd), +W64LIT(0x0b1a77feb78aaaf3), +W64LIT(0xe9392f763aa4f490), +W64LIT(0xaaa52df96dd56651), +W64LIT(0x46cf55fd5b3f9160), +W64LIT(0xa4ec0d75d611cf03), +W64LIT(0xaff67a8b619b65f0), +W64LIT(0x3415e797e312bf67), +W64LIT(0x7af15bba0b9d8538), +W64LIT(0x811314ad09807f5e), +W64LIT(0x8771ddf101f47d33), +W64LIT(0x969b23be3d777209), +W64LIT(0xd365e86d6272e2a5), +W64LIT(0x58d05224736e9b4c), +W64LIT(0xc660984afda9427a), +W64LIT(0x5414359c63869f96), +W64LIT(0xe885f66c95b258d4), +W64LIT(0x655285798cda2350), +W64LIT(0x6cc5b5b3907c242b), +W64LIT(0x6ff42b9d944625e7), +W64LIT(0xc0025116f5dd4017), +W64LIT(0xa28ec429de65cd6e), +W64LIT(0x63304c2584ae213d), +W64LIT(0x7fa20cc807d38699), +W64LIT(0x996eda2829a5771f), +W64LIT(0x1b4c50ab241f098d), +W64LIT(0x1e1f07d928510a2c), +W64LIT(0x33cbf7d14470114e), +W64LIT(0xb055a448e6dcc398), +W64LIT(0x98d2033286b3db5b), +W64LIT(0xec6a780436eaf731), +W64LIT(0xa1bf5a07da5fcca2), +W64LIT(0xbaf30aacfe40c52f), +W64LIT(0xf144e1f31a81fcd1), +W64LIT(0xe0ae1fbc2602f3eb), +W64LIT(0x14b9a93d30cd0c9b), +W64LIT(0x596c8b3edc783708), +W64LIT(0x682a3bdb33248bce), +W64LIT(0xb87e4d98556c68a7), +W64LIT(0x80afcdb7a696d31a), +W64LIT(0x5725abb267bc9e5a), +W64LIT(0x914533f89a15dc20), +W64LIT(0x5eb29b787b1a9921), +W64LIT(0x01bcd91aaf16ac44), +W64LIT(0xc1be880c5acbec53), +W64LIT(0xedd6a11e99fc5b75), +W64LIT(0x028d4734ab2cad88), +W64LIT(0x8f5a3421b244d60c), +W64LIT(0x4dd52203ecb53b93), +W64LIT(0x3f0f906954981594), +W64LIT(0xae4aa391ce8dc9b4), +W64LIT(0x3698a0a3483e12ef), +W64LIT(0xf5ab6f9bb9d95334), +W64LIT(0x082be9d0b3b0ab3f), +W64LIT(0xd1e8af59c95e4f2d), +W64LIT(0xd87f9f93d5f84856), +W64LIT(0x6e48f2873b5089a3), +W64LIT(0x2443c0c270871c19), +W64LIT(0xb1e97d5249ca6fdc), +W64LIT(0x7c9392e603e98755), +W64LIT(0x839e5399a2acd2d6), +W64LIT(0x19c1179f8f33a405), +W64LIT(0xde1d56cfdd8c4a3b), +W64LIT(0x20ac4eaad3dfb3fc), +W64LIT(0x1af089b18b09a5c9), +W64LIT(0x3a5cc71b58d61635), +W64LIT(0x444212c9f0133ce8), +W64LIT(0x72dab26ab82d2e07), +W64LIT(0x4c69fb1943a397d7), +W64LIT(0xf3c9a6c7b1ad5159), +W64LIT(0x1d2e99f72c6b0be0), +W64LIT(0xb4ba2a2045846c7d), +W64LIT(0xe22358888d2e5e63), +W64LIT(0x2887a77a606f18c3), +W64LIT(0xa8286acdc6f9cbd9), +W64LIT(0x5f0e4262d40c3565), +W64LIT(0xeee73f309dc65ab9), +W64LIT(0x9be39d1c8289da97), +W64LIT(0x1634ee099be1a113), +W64LIT(0xea08b1583e9ef55c), +W64LIT(0x9727faa49261de4d), +W64LIT(0x2c682912c337b726), +W64LIT(0xcff7a880e10f4501), +W64LIT(0x1788371334f70d57), +W64LIT(0x27725eec74bd1dd5), +W64LIT(0x3146b0e5ef5cbcc6), +W64LIT(0x099730ca1ca6077b), +W64LIT(0xf2757fdd1ebbfd1d), +W64LIT(0x6aa77cef98082646), +W64LIT(0xbb4fd3b65156696b), +W64LIT(0x569972a8c8aa321e), +W64LIT(0xa3321d337173612a), +W64LIT(0x50fbbbf4c0de3073), +W64LIT(0x5a5d1510d84236c4), +W64LIT(0xfd80864b0a69f80b), +W64LIT(0x07de1046a762ae29), +W64LIT(0xa6614a417d3d628b), +W64LIT(0xd78a6605c12a4d40), +W64LIT(0x67dfc24d27f68ed8), +W64LIT(0xbc91c3f0f634c742), +W64LIT(0xd05476436648e369), +W64LIT(0x493aac6b4fed9476), +W64LIT(0x12db606138b90ef6), +W64LIT(0xa994b3d769ef679d), +W64LIT(0x211097b07cc91fb8), +W64LIT(0x30fa69ff404a1082), +W64LIT(0x3c3e0e4750a21458), +W64LIT(0x7504a22c1f4f802e), +W64LIT(0x844043df05ce7cff), +W64LIT(0xf0f838e9b5975095), +W64LIT(0x7e1ed5d2a8c52add), +W64LIT(0x90f9eae235037064), +W64LIT(0x0662c95c0874026d), +W64LIT(0x9416648a965bdf81), +W64LIT(0xf69af1b5bde352f8), +W64LIT(0x0d78bea2bffea89e), +W64LIT(0x293b7e60cf79b487), +W64LIT(0xd9c346897aeee412), +W64LIT(0xfbe24f17021dfa66), +W64LIT(0x1367b97b97afa2b2), +W64LIT(0xab19f4e3c2c3ca15), +W64LIT(0x48867571e0fb3832), +W64LIT(0x93c874cc313971a8), +W64LIT(0x79c0c5940fa784f4), +W64LIT(0xcd7aefb44a23e889), +W64LIT(0x439c028f577192c1), +W64LIT(0x5be1cc0a77549a80), +/* box 6 */ +W64LIT(0x714d28d778656928), +W64LIT(0xc88a7c6b84f64f7c), +W64LIT(0xec43cac5ab89aaca), +W64LIT(0x777fa38110dc16a3), +W64LIT(0x0f7d5c87e4213b5c), +W64LIT(0x73f051e5f3a1ef51), +W64LIT(0xea714193c330d541), +W64LIT(0x95e5f3dae016c4f3), +W64LIT(0x63d3738095a0e173), +W64LIT(0x9825d66f8ff379d6), +W64LIT(0xe8cc38a148f45338), +W64LIT(0xa840b0c025f06bb0), +W64LIT(0x944135c35f748735), +W64LIT(0x74661caa247ad31c), +W64LIT(0xe7b16426acd56864), +W64LIT(0xd1e689df6e6f0589), +W64LIT(0xa73dec47c1d150ec), +W64LIT(0x64453ecf427bdd3e), +W64LIT(0x0ed99a9e5b43789a), +W64LIT(0x7b1b402dc05be840), +W64LIT(0x0dc025b56fe5bd25), +W64LIT(0x3f183a284e22293a), +W64LIT(0xa0aba108160a6ca1), +W64LIT(0x46be033705bd4703), +W64LIT(0x86df6e94b2b10f6e), +W64LIT(0xa216d83a9dceead8), +W64LIT(0x129e5b57edc5885b), +W64LIT(0x7e3074509c445274), +W64LIT(0x7d29cb7ba8e297cb), +W64LIT(0x1611a9330eb871a9), +W64LIT(0x486799a95efe3f99), +W64LIT(0x9fb39b205828459b), +W64LIT(0xd0424fc6d10d464f), +W64LIT(0xe968feb8f79610fe), +W64LIT(0x5d6f8fb164e08b8f), +W64LIT(0xaafdc9f2ae34edc9), +W64LIT(0x02bd79328bc48679), +W64LIT(0x9b3c6944bb55bc69), +W64LIT(0x6277b5992ac2a2b5), +W64LIT(0x877ba88d0dd34ca8), +W64LIT(0xfa5263f6a531db63), +W64LIT(0x2e9fde54974164de), +W64LIT(0xcda14816d8e9f548), +W64LIT(0x675c81e476dd1881), +W64LIT(0x2a102c30743c9d2c), +W64LIT(0x37f32be07dd82e2b), +W64LIT(0x256d70b7901da670), +W64LIT(0x4ce86bcdbd83c66b), +W64LIT(0x50afaa040b0536aa), +W64LIT(0xef5a75ee9f2f6f75), +W64LIT(0xb3913c4644ada73c), +W64LIT(0x1187e47cd9634de4), +W64LIT(0xc54a59deeb13f259), +W64LIT(0x0000000000000000), +W64LIT(0x01a4c619bf6243c6), +W64LIT(0x90cec7a7bc097ec7), +W64LIT(0xf94bdcdd91971edc), +W64LIT(0x8e347f5c814b087f), +W64LIT(0xc7f720ec60d77420), +W64LIT(0x354e52d2f61ca852), +W64LIT(0x34ea94cb497eeb94), +W64LIT(0xae723b964d49143b), +W64LIT(0xf48bf968fe72a3f9), +W64LIT(0xfc60e8a0cd88a4e8), +W64LIT(0x2909931b409a5893), +W64LIT(0xbd48a6d81feedfa6), +W64LIT(0x6cae2f077181da2f), +W64LIT(0xad6b84bd79efd184), +W64LIT(0x18c833ad55fb0933), +W64LIT(0x204644cacc021c44), +W64LIT(0x392ab17e269b56b1), +W64LIT(0x14acd001857cf7d0), +W64LIT(0x8abb8d386236f18d), +W64LIT(0xeefeb3f7204d2cb3), +W64LIT(0xf636805a75b62580), +W64LIT(0x2bb4ea29cb5edeea), +W64LIT(0xc653e6f5dfb537e6), +W64LIT(0x8d2dc077b5edcdc0), +W64LIT(0x31c1a0b6156151a0), +W64LIT(0xf8ef1ac42ef55d1a), +W64LIT(0xdbb0e125d65184e1), +W64LIT(0x82509cf051ccf69c), +W64LIT(0xe33e96424fa89196), +W64LIT(0xdf3f1341352c7d13), +W64LIT(0x8f90b9453e294bb9), +W64LIT(0x1023226566010e22), +W64LIT(0xa58095754a15d695), +W64LIT(0x2c22a7661c85e2a7), +W64LIT(0xe183ef70c46c17ef), +W64LIT(0xafd6fd8ff22b57fd), +W64LIT(0x471ac52ebadf04c5), +W64LIT(0x4d4cadd402e185ad), +W64LIT(0x916a01be036b3d01), +W64LIT(0x28ad5502fff81b55), +W64LIT(0x3657edf9c2ba6ded), +W64LIT(0xd2ff36f45ac9c036), +W64LIT(0xf1a0cd15a26d19cd), +W64LIT(0xd90d98175d950298), +W64LIT(0xf7924643cad46646), +W64LIT(0xdd826a73bee8fb6a), +W64LIT(0x9d0ee212d3ecc3e2), +W64LIT(0xb6ba083b18b21d08), +W64LIT(0x3da5431ac5e6af43), +W64LIT(0x08eb11c833fa0711), +W64LIT(0x052b347d5c1fba34), +W64LIT(0x6fb7902c45271f90), +W64LIT(0x133a9d4e52a7cb9d), +W64LIT(0x6e135635fa455c56), +W64LIT(0x725497fc4cc3ac97), +W64LIT(0xf31db42729a99fb4), +W64LIT(0x846217a639758917), +W64LIT(0x4b7e26826a58fa26), +W64LIT(0x235ffbe1f8a4d9fb), +W64LIT(0xff79578bf92e6157), +W64LIT(0xda14273c6933c727), +W64LIT(0x8b1f4b21dd54b24b), +W64LIT(0x9caa240b6c8e8024), +W64LIT(0xc1c5abba086e0bab), +W64LIT(0xde9bd5588a4e3ed5), +W64LIT(0x2d86617fa3e7a161), +W64LIT(0xbff5dfea942a59df), +W64LIT(0x66f847fdc9bf5b47), +W64LIT(0x3b97c84cad5fd0c8), +W64LIT(0x3ebcfc31f1406afc), +W64LIT(0xca3705590f32c905), +W64LIT(0x24c9b6ae2f7fe5b6), +W64LIT(0x408c88616d043888), +W64LIT(0x93d7788c88afbb78), +W64LIT(0x196cf5b4ea994af5), +W64LIT(0x9a98af5d0437ffaf), +W64LIT(0x8c89066e0a8f8e06), +W64LIT(0xab590feb1156ae0f), +W64LIT(0xd7d4028906d67a02), +W64LIT(0xe4a8db0d9873addb), +W64LIT(0xc378d28883aa8dd2), +W64LIT(0x4ff1d4e6892503d4), +W64LIT(0xd670c490b9b439c4), +W64LIT(0x65e1f8d6fd199ef8), +W64LIT(0xf2b9723e96cbdc72), +W64LIT(0xb12c4574cf692145), +W64LIT(0x569d215263bc4921), +W64LIT(0x69851b7a2d9e601b), +W64LIT(0x5e76309a50464e30), +W64LIT(0x5fd2f683ef240df6), +W64LIT(0xd8a95e0ee2f7415e), +W64LIT(0xe29a505bf0cad250), +W64LIT(0x96fc4cf1d4b0014c), +W64LIT(0x8806f40ae9f277f4), +W64LIT(0x53b6152f3fa3f315), +W64LIT(0x1c47c1c9b686f0c1), +W64LIT(0x80ede5c2da0870e5), +W64LIT(0xd5697bbb8d12fc7b), +W64LIT(0xfdc42eb972eae72e), +W64LIT(0x0bf2aee3075cc2ae), +W64LIT(0x22fb3df847c69a3d), +W64LIT(0xbadeeb97c835e3eb), +W64LIT(0xdc26ac6a018ab8ac), +W64LIT(0xbcec60c1a08c9c60), +W64LIT(0x4231f153e6c0bef1), +W64LIT(0x337cd9849ea5d7d9), +W64LIT(0x5b5d04e70c59f404), +W64LIT(0x79a6391f4b9f6e39), +W64LIT(0x5212d33680c1b0d3), +W64LIT(0xb5a3b7102c14d8b7), +W64LIT(0x7f94b249232611b2), +W64LIT(0x17b56f2ab1da326f), +W64LIT(0x59e07dd5879d727d), +W64LIT(0xebd5878a7c529687), +W64LIT(0xbb7a2d8e7757a02d), +W64LIT(0x0319bf2b34a6c5bf), +W64LIT(0x5ccb49a8db82c849), +W64LIT(0x1de307d009e4b307), +W64LIT(0x49c35fb0e19c7c5f), +W64LIT(0x55849e79571a8c9e), +W64LIT(0x7abf86347f39ab86), +W64LIT(0x9273be9537cdf8be), +W64LIT(0xe615a23f13b72ba2), +W64LIT(0x6821dd6392fc23dd), +W64LIT(0x5af9c2feb33bb7c2), +W64LIT(0x06328b5668b97f8b), +W64LIT(0x44037a058e79c17a), +W64LIT(0x83f45ae9eeaeb55a), +W64LIT(0x5739e74bdcde0ae7), +W64LIT(0xfbf6a5ef1a5398a5), +W64LIT(0xe50c1d142711ee1d), +W64LIT(0x1a754a9fde3f8f4a), +W64LIT(0x7802ff06f4fd2dff), +W64LIT(0xf52f3f714110e03f), +W64LIT(0x2674cf9ca4bb63cf), +W64LIT(0x60caccaba10624cc), +W64LIT(0xb088836d700b6283), +W64LIT(0xa6992a5e7eb3132a), +W64LIT(0xa9e476d99a922876), +W64LIT(0x6b386248a65ae662), +W64LIT(0xc2dc14913cc8ce14), +W64LIT(0x76db6598afbe5565), +W64LIT(0x32d81f9d21c7941f), +W64LIT(0x21e282d373605f82), +W64LIT(0xc0616da3b70c486d), +W64LIT(0x616e0ab21e64670a), +W64LIT(0x6d0ae91ecee399e9), +W64LIT(0x27d009851bd92009), +W64LIT(0xfedd9192464c2291), +W64LIT(0x45a7bc1c311b82bc), +W64LIT(0x54205860e878cf58), +W64LIT(0xa10f6711a9682f67), +W64LIT(0x9981107630913a10), +W64LIT(0xede70cdc14ebe90c), +W64LIT(0x70e9eecec7072aee), +W64LIT(0x1f5e7ee28220357e), +W64LIT(0x2f3b184d28232718), +W64LIT(0x41284e78d2667b4e), +W64LIT(0xa424536cf5779553), +W64LIT(0xa3b21e2322aca91e), +W64LIT(0x4e5512ff36474012), +W64LIT(0x1efab8fb3d4276b8), +W64LIT(0x89a2321356903432), +W64LIT(0xcb93c340b0508ac3), +W64LIT(0x306566afaa031266), +W64LIT(0x4adae09bd53ab9e0), +W64LIT(0xc92eba723b940cba), +W64LIT(0x094fd7d18c9844d7), +W64LIT(0xcc058e0f678bb68e), +W64LIT(0xd4cdbda23270bfbd), +W64LIT(0x0a5668fab83e8168), +W64LIT(0x510b6c1db467756c), +W64LIT(0xb86392a543f16592), +W64LIT(0x048ff264e37df9f2), +W64LIT(0x3a330e55123d930e), +W64LIT(0xb235fa5ffbcfe4fa), +W64LIT(0xb9c754bcfc932654), +W64LIT(0x3c0185037a84ec85), +W64LIT(0x0c64e3acd087fee3), +W64LIT(0xe02729697b0e5429), +W64LIT(0x07964d4fd7db3c4d), +W64LIT(0x814923db656a3323), +W64LIT(0x388e776799f91577), +W64LIT(0x6a9ca4511938a5a4), +W64LIT(0x1bd18c86615dcc8c), +W64LIT(0xb407710993769b71), +W64LIT(0x150816183a1eb416), +W64LIT(0x4395374a59a2fd37), +W64LIT(0xc4ee9fc75471b19f), +W64LIT(0x5844bbcc38ff31bb), +W64LIT(0xcf1c3124532d7331), +W64LIT(0xb71ece22a7d05ece), +W64LIT(0xaccf42a4c68d9242), +W64LIT(0x97588ae86bd2428a), +W64LIT(0x75c2dab39b1890da), +W64LIT(0x9e175d39e74a065d), +W64LIT(0xf0040b0c1d0f5a0b), +W64LIT(0xceb8f73dec4f30f7), +W64LIT(0xbe5119f32b481a19), +W64LIT(0xd35bf0ede5ab83f0), +W64LIT(0x7c8d0d621780d40d), +W64LIT(0x85c6d1bf8617cad1), +/* box 7 */ +W64LIT(0xb1c742127b66f2a4), +W64LIT(0xce916098d7a59fc1), +W64LIT(0xc312ef8e2406fa70), +W64LIT(0x956c7dced81403d5), +W64LIT(0x5a0c9b2318dd9520), +W64LIT(0xad0d57f51a480e8b), +W64LIT(0xe7b9d05287740b01), +W64LIT(0x0217f9ea2ed81268), +W64LIT(0x4d7cff19f8cd3a06), +W64LIT(0x44d1772e572b7b67), +W64LIT(0xfb73c5b5e65af72e), +W64LIT(0x91427aef84512705), +W64LIT(0x0c720963e4cf6c85), +W64LIT(0x87c398a0732d8117), +W64LIT(0xa17f5e96fe87620e), +W64LIT(0x50476c8b8e8fcf1d), +W64LIT(0xcb4ee1cc9c8cb225), +W64LIT(0x67b2304c91a8b59a), +W64LIT(0x54696baad2caebcd), +W64LIT(0xddcf03836bf01437), +W64LIT(0x46c68ec479f3690f), +W64LIT(0x8f9f96e2cba7c942), +W64LIT(0xe1802e99f5e93db9), +W64LIT(0x4e9a8086c179215a), +W64LIT(0xf0c9b4686764a427), +W64LIT(0xfd4a3b7e94c7c196), +W64LIT(0xfcbbbd0b83abc8a2), +W64LIT(0xebcbd93163bb6784), +W64LIT(0xf9643c5fc882e546), +W64LIT(0xc4da973041f7c5fc), +W64LIT(0x1af3eb2c13b3ca97), +W64LIT(0x6e1fb87b3e4ef4fb), +W64LIT(0x5e229c024498b1f0), +W64LIT(0xf516353c2c4d89c3), +W64LIT(0xcc869972f97d8da9), +W64LIT(0x8d886f08e57fdb2a), +W64LIT(0x1cca15e7612efc2f), +W64LIT(0x567e9240fc12f9a5), +W64LIT(0x43190f9032da44eb), +W64LIT(0xfeac44e1ad73daca), +W64LIT(0x07c878be65f13f8c), +W64LIT(0x618bce87e3358322), +W64LIT(0xf895ba2adfeeec72), +W64LIT(0x751dd5223a913758), +W64LIT(0x59eae4bc21698e7c), +W64LIT(0xff5dc294ba1fd3fe), +W64LIT(0x03e67f9f39b41b5c), +W64LIT(0x2292c117d1efc7c9), +W64LIT(0x8a4017b6808ee4a6), +W64LIT(0xd1bd0ae08f3f78b2), +W64LIT(0x135e631bbc558bf6), +W64LIT(0xee14586528924a60), +W64LIT(0x8857ee5cae56f6ce), +W64LIT(0x0000000000000000), +W64LIT(0x0e65f089ca177eed), +W64LIT(0x34132358269361db), +W64LIT(0x15679dd0cec8bd4e), +W64LIT(0x800be01e16dcbe9b), +W64LIT(0x949dfbbbcf780ae1), +W64LIT(0xe397d773db312fd1), +W64LIT(0xedf227fa1126513c), +W64LIT(0xb5e945332723d674), +W64LIT(0x53a11314b73bd441), +W64LIT(0x23634762c683cefd), +W64LIT(0x4b4501d28a500cbe), +W64LIT(0x473708b16e9f603b), +W64LIT(0x1770643ae010af26), +W64LIT(0xa746a05d8c1a54b6), +W64LIT(0x90b3fc9a933d2e31), +W64LIT(0x35e2a52d31ff68ef), +W64LIT(0xab34a93e68d53833), +W64LIT(0xd81082d720d939d3), +W64LIT(0xb86aca25d480b3c5), +W64LIT(0xdfd8fa694528065f), +W64LIT(0x4f6b06f3d615286e), +W64LIT(0x578f1435eb7ef091), +W64LIT(0x9af80b32056f740c), +W64LIT(0x92a40570bde53c59), +W64LIT(0xdbf6fd48196d228f), +W64LIT(0x1b026d5904dfc3a3), +W64LIT(0x3c4f2d1a9e19298e), +W64LIT(0xc8a89e53a538a979), +W64LIT(0x991e74ad3cdb6f50), +W64LIT(0x042e07215c4524d0), +W64LIT(0x8e6e1097dccbc076), +W64LIT(0xe071a8ece285348d), +W64LIT(0xd784f42bfda24e0a), +W64LIT(0x7d41db60821b7f0d), +W64LIT(0x85d4614a5df5937f), +W64LIT(0xbb8cb5baed34a899), +W64LIT(0x40ff700f0b6e5fb7), +W64LIT(0x2cf7319e1bf8b924), +W64LIT(0x3a76d3d1ec841f36), +W64LIT(0x4520f15b40477253), +W64LIT(0xf138321d7008ad13), +W64LIT(0x42e889e525b64ddf), +W64LIT(0x65a5c9a6bf70a7f2), +W64LIT(0x208538fdff37d5a1), +W64LIT(0x410ef67a1c025683), +W64LIT(0x18e412c63d6bd8ff), +W64LIT(0x72d5ad9c5f6008d4), +W64LIT(0x255ab9a9b41ef845), +W64LIT(0x93558305aa89356d), +W64LIT(0x70c2547671b81abc), +W64LIT(0x3604dab2084b73b3), +W64LIT(0x05df81544b292de4), +W64LIT(0xf2de4d8249bcb64f), +W64LIT(0x0bba71dd813e5309), +W64LIT(0xa368a77cd05f7066), +W64LIT(0x796fdc41de5e5bdd), +W64LIT(0xec03a18f064a5808), +W64LIT(0x085c0e42b88a4855), +W64LIT(0x274d40439ac6ea2d), +W64LIT(0x31cca20c6dba4c3f), +W64LIT(0x322add93540e5763), +W64LIT(0xb60f3aac1e97cd28), +W64LIT(0x7cb05d1595777639), +W64LIT(0xb036c4676c0afb90), +W64LIT(0x0a4bf7a896525a3d), +W64LIT(0x73242be9480c01e0), +W64LIT(0x5bfd1d560fb19c14), +W64LIT(0x7b7825abf08649b5), +W64LIT(0xb7febcd909fbc41c), +W64LIT(0x81fa666b01b0b7af), +W64LIT(0xd25b757fb68b63ee), +W64LIT(0x0d838f16f3a365b1), +W64LIT(0x6a31bf5a620bd02b), +W64LIT(0x26bcc6368daae319), +W64LIT(0x9ed60c13592a50dc), +W64LIT(0x581b62c936058748), +W64LIT(0x9cc1f5f977f242b4), +W64LIT(0x83ed9f812f68a5c7), +W64LIT(0x74ec53572dfd3e6c), +W64LIT(0xb3d0bbf855bee0cc), +W64LIT(0xacfcd1800d2407bf), +W64LIT(0x303d24797ad6450b), +W64LIT(0x7a89a3dee7ea4081), +W64LIT(0x69d7c0c55bbfcb77), +W64LIT(0x770a2cc814492530), +W64LIT(0x0f9476fcdd7b77d9), +W64LIT(0xaeeb286a23fc15d7), +W64LIT(0x2174be88e85bdc95), +W64LIT(0xde297c1c52440f6b), +W64LIT(0xd04c8c9598537186), +W64LIT(0x2ee0c8743520ab4c), +W64LIT(0x977b8424f6cc11bd), +W64LIT(0x10b81c8485e190aa), +W64LIT(0xa4a0dfc2b5ae4fea), +W64LIT(0x98eff2d82bb76664), +W64LIT(0xa8d2d6a15161236f), +W64LIT(0xd4628bb4c4165556), +W64LIT(0x682646b04cd3c243), +W64LIT(0x2d06b7eb0c94b010), +W64LIT(0x626db118da81987e), +W64LIT(0x2928b0ca50d194c0), +W64LIT(0x6df9c7e407faefa7), +W64LIT(0x1681e24ff77ca612), +W64LIT(0x4952f838a4881ed6), +W64LIT(0x76fbaabd03252c04), +W64LIT(0xc73ce8af7843dea0), +W64LIT(0xe82da6ae5a0f7cd8), +W64LIT(0xc10516640adee818), +W64LIT(0x968a0251e1a01889), +W64LIT(0x37f55cc71f277a87), +W64LIT(0xe5ae29b8a9ac1969), +W64LIT(0xcabf67b98be0bb11), +W64LIT(0xf4e7b3493b2180f7), +W64LIT(0xe9dc20db4d6375ec), +W64LIT(0x639c376dcded914a), +W64LIT(0x12afe56eab3982c2), +W64LIT(0xc2e369fb336af344), +W64LIT(0xa6b726289b765d82), +W64LIT(0x14961ba5d9a4b47a), +W64LIT(0xbc44cd0488c59715), +W64LIT(0xd3aaf30aa1e76ada), +W64LIT(0x28d936bf47bd9df4), +W64LIT(0xaf1aae1f34901ce3), +W64LIT(0x2f114e01224ca278), +W64LIT(0xe648562790180235), +W64LIT(0x24ab3fdca372f171), +W64LIT(0x52509561a057dd75), +W64LIT(0xc6cd6eda6f2fd794), +W64LIT(0xa08ed8e3e9eb6b3a), +W64LIT(0x09ad8837afe64161), +W64LIT(0xbdb54b719fa99e21), +W64LIT(0x8c79e97df213d21e), +W64LIT(0xcf60e6edc0c996f5), +W64LIT(0x5dc4e39d7d2caaac), +W64LIT(0x11499af1928d999e), +W64LIT(0x5fd31a7753f4b8c4), +W64LIT(0x01f18675176c0934), +W64LIT(0xc52b1145569bccc8), +W64LIT(0x9f278a664e4659e8), +W64LIT(0x3dbeab6f897520ba), +W64LIT(0xa2992109c7337952), +W64LIT(0x9b098d4712037d38), +W64LIT(0xc9591826b254a04d), +W64LIT(0x3b8755a4fbe81602), +W64LIT(0xbe5334eea61d857d), +W64LIT(0x51b6eafe99e3c629), +W64LIT(0x191594b32a07d1cb), +W64LIT(0x1f2c6a78589ae773), +W64LIT(0x3fa95285a7ad32d2), +W64LIT(0x5c3565e86a40a398), +W64LIT(0xb2213d8d42d2e9f8), +W64LIT(0xefe5de103ffe4354), +W64LIT(0x4ab487a79d3c058a), +W64LIT(0xcd771f07ee11849d), +W64LIT(0xbfa2b29bb1718c49), +W64LIT(0xba7d33cffa58a1ad), +W64LIT(0x6fee3e0e2922fdcf), +W64LIT(0x64544fd3a81caec6), +W64LIT(0xd9e104a237b530e7), +W64LIT(0xf32fcbf75ed0bf7b), +W64LIT(0x3e58d4f0b0c13be6), +W64LIT(0xb418c346304fdf40), +W64LIT(0xaac52f4b7fb93107), +W64LIT(0xdc3e85f67c9c1d03), +W64LIT(0xd5930dc1d37a5c62), +W64LIT(0x0639fecb729d36b8), +W64LIT(0xc0f490111db2e12c), +W64LIT(0x7ea7a4ffbbaf6451), +W64LIT(0xf6f04aa315f9929f), +W64LIT(0x6643b63986c4bcae), +W64LIT(0x6c0841911096e693), +W64LIT(0x8425e73f4a999a4b), +W64LIT(0x7133d20366d41388), +W64LIT(0x38612a3bc25c0d5e), +W64LIT(0xb99b4c50c3ecbaf1), +W64LIT(0x1d3b93927642f51b), +W64LIT(0x7f56228aacc36d65), +W64LIT(0x9d30738c609e4b80), +W64LIT(0x48a37e4db3e417e2), +W64LIT(0x8bb191c397e2ed92), +W64LIT(0x2acecf5569658f9c), +W64LIT(0xda077b3d0e012bbb), +W64LIT(0xa55159b7a2c246de), +W64LIT(0x33db5be643625e57), +W64LIT(0x821c19f43804acf3), +W64LIT(0x3990ac4ed530046a), +W64LIT(0xd675725eeace473e), +W64LIT(0x789e5a34c93252e9), +W64LIT(0x86321ed564418823), +W64LIT(0xfa8243c0f136fe1a), +W64LIT(0xe45fafcdbec0105d), +W64LIT(0x2b3f49207e0986a8), +W64LIT(0xa92350d4460d2a5b), +W64LIT(0x1eddec0d4ff6ee47), +W64LIT(0x89a66829b93afffa), +W64LIT(0x607a48f2f4598a16), +W64LIT(0x6bc0392f7567d91f), +W64LIT(0xea3a5f4474d76eb0), +W64LIT(0x5598eddfc5a6e2f9), +W64LIT(0x4c8d796cefa13332), +W64LIT(0xf701ccd602959bab), +W64LIT(0xe2665106cc5d26e5), +}; + +const word64 SHARK::Dec::cbox[8][256] = { +/* box 0 */ +W64LIT(0xe6126af05e55aff3), +W64LIT(0x4b6c893f310b0835), +W64LIT(0xaa4c0e84ebfc8d57), +W64LIT(0xfb9b5c7bf3b3090d), +W64LIT(0x4508a6a9ccba5ce2), +W64LIT(0xe5d1d2064dc6bde9), +W64LIT(0x348343755288edde), +W64LIT(0xb684505de46b250c), +W64LIT(0xa8cede205a1e91e8), +W64LIT(0x40b89b46f9fa6acc), +W64LIT(0x8ee1ec1afab080ba), +W64LIT(0xde77d6b7408e0a45), +W64LIT(0x9a3e184c2e455802), +W64LIT(0xbe93fad23f0955ef), +W64LIT(0x3ae76ce3af39b909), +W64LIT(0xad7ee3cf6f5ea7c6), +W64LIT(0x8b51d1f5cff0b694), +W64LIT(0x70ca8d8e3c43bf99), +W64LIT(0xccdba7f8b2a8f6c9), +W64LIT(0x4c5e6474b5a922a4), +W64LIT(0x5d31adcd541ccc32), +W64LIT(0x9b7f701e8c3456a7), +W64LIT(0x2ac9cd08ecfd593a), +W64LIT(0x8fa0844858c18e1f), +W64LIT(0x32f0c66c745bc9ea), +W64LIT(0xc58d6525cbbb888f), +W64LIT(0x8c633cbe4b529c05), +W64LIT(0xf2cd9ea68aa0774b), +W64LIT(0x2cba4811ca2e7d0e), +W64LIT(0xe2e33f4dc9649778), +W64LIT(0xf4be1bbfac73537f), +W64LIT(0x22de6787379f29d9), +W64LIT(0x0956c2dd79137e46), +W64LIT(0xe061efe978868bc7), +W64LIT(0x1cc85ed90f97a85b), +W64LIT(0x31337e9a67c8dbf0), +W64LIT(0x360193d1e36af161), +W64LIT(0x7fefca4a6383e5eb), +W64LIT(0x8535fe633241e243), +W64LIT(0xc3fee03ced68acbb), +W64LIT(0x81c4abdea570dac8), +W64LIT(0x67d6c12efb25753b), +W64LIT(0xa4282112164dd980), +W64LIT(0xcf181f0ea13be4d3), +W64LIT(0xa98fb672f86f9f4d), +W64LIT(0x5c70c59ff66dc297), +W64LIT(0xb0f7d544c2b80138), +W64LIT(0x0da79760ee2246cd), +W64LIT(0x3740fb83411bffc4), +W64LIT(0x24ade29e114c0ded), +W64LIT(0xf858e48de0201b17), +W64LIT(0x0e642f96fdb154d7), +W64LIT(0xddb46e41531d185f), +W64LIT(0x25ec8accb33d0348), +W64LIT(0x0282d0a4b1e21cbf), +W64LIT(0x1bfab3928b3582ca), +W64LIT(0xaffc336bdebcbb79), +W64LIT(0x35c22b27f0f9e37b), +W64LIT(0x03c3b8f61393121a), +W64LIT(0xb8e07fcb19da71db), +W64LIT(0x99fda0ba3dd64a18), +W64LIT(0xce59775c034aea76), +W64LIT(0x49ee599b80e9148a), +W64LIT(0xfe2b6194c6f33f23), +W64LIT(0x4edcb4d0044b3e1b), +W64LIT(0xd5a3c4ce887f68bc), +W64LIT(0xdf36bee5e2ff04e0), +W64LIT(0x171c4ca0c766caa2), +W64LIT(0x0bd41279c8f162f9), +W64LIT(0xe490ba54efb7b34c), +W64LIT(0x5b4228d472cfe806), +W64LIT(0x5355825ba9ad98e5), +W64LIT(0x9f8e25a31b056e2c), +W64LIT(0xcd9acfaa10d9f86c), +W64LIT(0x88926903dc63a48e), +W64LIT(0xb40680f9558939b3), +W64LIT(0x239f0fd595ee277c), +W64LIT(0xec8710db34d5c3af), +W64LIT(0x87b72ec783a3fefc), +W64LIT(0x632794936c144db0), +W64LIT(0x46cb1e5fdf294ef8), +W64LIT(0x83467b7a1492c677), +W64LIT(0x9c4d9d5508967c36), +W64LIT(0xd6607c389bec7aa6), +W64LIT(0x165d24f26517c407), +W64LIT(0xc4cc0d7769ca862a), +W64LIT(0xcbe94ab3360adc58), +W64LIT(0x847496319030ece6), +W64LIT(0x7a5ff7a556c3d3c5), +W64LIT(0xc03d58cafefbbea1), +W64LIT(0x76b908971a909bad), +W64LIT(0x2f79f0e7d9bd6f14), +W64LIT(0x197863363ad79e75), +W64LIT(0xda86830ad7bf32ce), +W64LIT(0x5a034086d0bee6a3), +W64LIT(0x97998f2cc0671ecf), +W64LIT(0x552607428f7ebcd1), +W64LIT(0x51d752ff184f845a), +W64LIT(0xbb23c73d0a4963c1), +W64LIT(0x2b88a55a4e8c579f), +W64LIT(0xd80453ae665d2e71), +W64LIT(0xee05c07f8537df10), +W64LIT(0x423a4be248187673), +W64LIT(0xcaa822e1947bd2fd), +W64LIT(0x1abbdbc029448c6f), +W64LIT(0x96d8e77e6216106a), +W64LIT(0x6266fcc1ce654315), +W64LIT(0x89d301517e12aa2b), +W64LIT(0x730935782fd0ad83), +W64LIT(0x8085c38c0701d46d), +W64LIT(0x6b303e1cb7763d53), +W64LIT(0x3f57510c9a798f27), +W64LIT(0x4449cefb6ecb5247), +W64LIT(0x48af31c922981a2f), +W64LIT(0x98bcc8e89fa744bd), +W64LIT(0x69b2eeb8069421ec), +W64LIT(0xebb5fd90b077e93e), +W64LIT(0x6a71564e150733f6), +W64LIT(0x116fc9b9e1b5ee96), +W64LIT(0x4a2de16d937a0690), +W64LIT(0xb9a11799bbab7f7e), +W64LIT(0x9368da9157562644), +W64LIT(0x718be5dc9e32b13c), +W64LIT(0xc82af2452599ce42), +W64LIT(0xb547e8abf7f83716), +W64LIT(0x33b1ae3ed62ac74f), +W64LIT(0x799c4f534550c1df), +W64LIT(0x3e16395e38088182), +W64LIT(0x7c2c72bc7010f7f1), +W64LIT(0xf38cf6f428d179ee), +W64LIT(0xd29129850cdd422d), +W64LIT(0x41f9f3145b8b6469), +W64LIT(0x945a37dad3f40cd5), +W64LIT(0x757ab061090389b7), +W64LIT(0x6554118a4ac76984), +W64LIT(0x7d6d1aeed261f954), +W64LIT(0x01416852a2710ea5), +W64LIT(0xb27505e0735a1d87), +W64LIT(0x77f860c5b8e19508), +W64LIT(0x78dd2701e721cf7a), +W64LIT(0xe12087bbdaf78562), +W64LIT(0x86f6469521d2f059), +W64LIT(0xef44a82d2746d1b5), +W64LIT(0xbc112a768eeb4950), +W64LIT(0xc2bf886e4f19a21e), +W64LIT(0x307216c8c5b9d555), +W64LIT(0xc96b9a1787e8c0e7), +W64LIT(0xa31acc5992eff311), +W64LIT(0xa0d974af817ce10b), +W64LIT(0xdcf50613f16c16fa), +W64LIT(0xfca9b1307711239c), +W64LIT(0x57a4d7e63e9ca06e), +W64LIT(0xc64eddd3d8289a95), +W64LIT(0xa25ba40b309efdb4), +W64LIT(0x2e3898b57bcc61b1), +W64LIT(0xf5ff73ed0e025dda), +W64LIT(0xa6aaf1b6a7afc53f), +W64LIT(0xd9453bfcc42c20d4), +W64LIT(0x9d0cf507aae77293), +W64LIT(0x290a75feff6e4b20), +W64LIT(0xa7eb99e405decb9a), +W64LIT(0xa1981cfd230defae), +W64LIT(0x12ac714ff226fc8c), +W64LIT(0x743bd833ab728712), +W64LIT(0x6c02d35733d417c2), +W64LIT(0xe9372d340195f581), +W64LIT(0xf77da349bfe04165), +W64LIT(0x68f386eaa4e52f49), +W64LIT(0x211ddf71240c3bc3), +W64LIT(0x13ed191d5057f229), +W64LIT(0xe8764566a3e4fb24), +W64LIT(0xf9198cdf425115b2), +W64LIT(0xd013f921bd3f5e92), +W64LIT(0x91ea0a35e6b43afb), +W64LIT(0x0732ed4b84a22a91), +W64LIT(0xeaf495c21206e79b), +W64LIT(0x5214ea090bdc9640), +W64LIT(0x0000000000000000), +W64LIT(0xb3346db2d12b1322), +W64LIT(0x0ce6ff324c534868), +W64LIT(0xaebd5b397ccdb5dc), +W64LIT(0x0a957a2b6a806c5c), +W64LIT(0x1f0be62f1c04ba41), +W64LIT(0x14dff456d4f5d8b8), +W64LIT(0x58819022615cfa1c), +W64LIT(0x05b03def3540362e), +W64LIT(0xe3a2571f6b1599dd), +W64LIT(0x9229b2c3f52728e1), +W64LIT(0xba62af6fa8386d64), +W64LIT(0x0673851926d32434), +W64LIT(0x641579d8e8b66721), +W64LIT(0x04f155bd9731388b), +W64LIT(0x9ecf4df1b9746089), +W64LIT(0x205cb723867d3566), +W64LIT(0x102ea1eb43c4e033), +W64LIT(0x3ba604b10d48b7ac), +W64LIT(0x50963aadba3e8aff), +W64LIT(0xac3f8b9dcd2fa963), +W64LIT(0x7b1e9ff7f4b2dd60), +W64LIT(0xf63ccb1b1d914fc0), +W64LIT(0x7eaea218c1f2eb4e), +W64LIT(0x5fb37d69e5fed08d), +W64LIT(0x56e5bfb49cedaecb), +W64LIT(0x2dfb2043685f73ab), +W64LIT(0x61a54437ddf6510f), +W64LIT(0x6fc16ba1204705d8), +W64LIT(0xe75302a2fc24a156), +W64LIT(0x3dd581a82b9b9398), +W64LIT(0xdbc7eb5875ce3c6b), +W64LIT(0x90ab626744c5345e), +W64LIT(0x59c0f870c32df4b9), +W64LIT(0x6697a97c59547b9e), +W64LIT(0xfde8d962d5602d39), +W64LIT(0xd3d041d7aeac4c88), +W64LIT(0x5ef2153b478fde28), +W64LIT(0xd4e2ac9c2a0e6619), +W64LIT(0x1e4a8e7dbe75b4e4), +W64LIT(0x72485d2a8da1a326), +W64LIT(0x437b23b0ea6978d6), +W64LIT(0x159e9c047684d61d), +W64LIT(0x0f2547c45fc05a72), +W64LIT(0xf10e265099336551), +W64LIT(0x3c94e9fa89ea9d3d), +W64LIT(0xbfd292809d785b4a), +W64LIT(0x0817aa8fdb6270e3), +W64LIT(0x60e42c657f875faa), +W64LIT(0x18390b6498a690d0), +W64LIT(0x478a760d7d58405d), +W64LIT(0x284b1dac5d1f4585), +W64LIT(0xb1b6bd1660c90f9d), +W64LIT(0xd15291731f4e5037), +W64LIT(0x4d1f0c2617d82c01), +W64LIT(0xc70fb5817a599430), +W64LIT(0x6d43bb0591a51967), +W64LIT(0x6e8003f382360b7d), +W64LIT(0x1d89368bade6a6fe), +W64LIT(0x4f9ddc82a63a30be), +W64LIT(0xedc6788996a4cd0a), +W64LIT(0xab0d66d6498d83f2), +W64LIT(0x54676f102d0fb274), +W64LIT(0xc17c30985c8ab004), +W64LIT(0x3865bc471edba5b6), +W64LIT(0x3924d415bcaaab13), +W64LIT(0x951b5f8871850270), +W64LIT(0x8a10b9a76d81b831), +W64LIT(0xbd5042242c9a47f5), +W64LIT(0xa5694940b43cd725), +W64LIT(0xff6a09c664823186), +W64LIT(0x8d2254ece92392a0), +W64LIT(0xb7c5380f461a2ba9), +W64LIT(0x82071328b6e3c8d2), +W64LIT(0xd721146a399d7403), +W64LIT(0xfada342951c207a8), +W64LIT(0x262f323aa0ae1152), +W64LIT(0xf04f4e023b426bf4), +W64LIT(0x276e5a6802df1ff7), +/* box 1 */ +W64LIT(0x3b4016dbfd16e203), +W64LIT(0x9a7574c51174530a), +W64LIT(0x90012e69c02ec8d3), +W64LIT(0xf44580e3d780e076), +W64LIT(0xf81dec2b49eca14b), +W64LIT(0x26cae3e8a6e3d7ef), +W64LIT(0x0962419e0c41f6ab), +W64LIT(0x54d1eb4070ebd951), +W64LIT(0x865e884b0188eec8), +W64LIT(0xdf76067ea406fe8a), +W64LIT(0x29849412e594fba0), +W64LIT(0x461569896869c0f2), +W64LIT(0xb5ddd6b3bbd6724e), +W64LIT(0x0c586cc89e6c413d), +W64LIT(0x6b0ad97054d904ea), +W64LIT(0xa135621eec62b109), +W64LIT(0x0eef7e47087ea461), +W64LIT(0xfaaafea4dffe4417), +W64LIT(0xe0ad344e80342331), +W64LIT(0xab4138b23d382ad0), +W64LIT(0x107390468e90fcff), +W64LIT(0xbe0885a2218561b9), +W64LIT(0xdbed22957d22c132), +W64LIT(0x2251c7037fc7e857), +W64LIT(0x33835ef8ba5e9c86), +W64LIT(0xb3f1e0d7f4e0a8aa), +W64LIT(0x3fdb32302432ddbb), +W64LIT(0xa719547aa3546bed), +W64LIT(0xe10c3df3cb3dab1f), +W64LIT(0x17feaf9f8aafae35), +W64LIT(0x9df84b1c154b01c0), +W64LIT(0x8364a51d93a5595e), +W64LIT(0x535cd49974d48b9b), +W64LIT(0x01a109bd4b09882e), +W64LIT(0xc4d0c529b0c51182), +W64LIT(0x2e09abcbe1aba96a), +W64LIT(0x1f3de7bccde7d0b0), +W64LIT(0x9317355b1d35a5a1), +W64LIT(0x6c87e6a950e65620), +W64LIT(0x8910ffb142ffc287), +W64LIT(0x40395fed275f1a16), +W64LIT(0x7b794936da49f815), +W64LIT(0xf269b68798b63a92), +W64LIT(0xfd27c17ddbc116dd), +W64LIT(0x8d8bdb5a9bdbfd3f), +W64LIT(0x1ba6c35714c3ef08), +W64LIT(0x6e30f426c6f4b37c), +W64LIT(0x7fe26ddd036dc7ad), +W64LIT(0x14e8b4ad57b4c347), +W64LIT(0xb985ba7b25ba3373), +W64LIT(0xe9cf75d08c75d59a), +W64LIT(0x626898ee5898f241), +W64LIT(0x5b9f9cba339cf51e), +W64LIT(0xb250e96abfe92084), +W64LIT(0x165fa622c1a6261b), +W64LIT(0xf5e4895e9c896858), +W64LIT(0xb76ac43c2dc49712), +W64LIT(0x02b7128f9612e55c), +W64LIT(0x1d8af5335bf535ec), +W64LIT(0x36b973ae28732b10), +W64LIT(0xa8572380e02347a2), +W64LIT(0xf6f2926c4192052a), +W64LIT(0x8c2ad2e7d0d27511), +W64LIT(0xd32e6ab63a6abfb7), +W64LIT(0xbd1e9e90fc9e0ccb), +W64LIT(0x03161b32dd1b6d72), +W64LIT(0x4dc03a98f23ad305), +W64LIT(0x81d3b79205b7bc02), +W64LIT(0x450372bbb572ad80), +W64LIT(0x2d1fb0f93cb0c418), +W64LIT(0x2a928f20388f96d2), +W64LIT(0x721b08a8d6080ebe), +W64LIT(0x92b63ce6563c2d8f), +W64LIT(0xeb78675f1a6730c6), +W64LIT(0x13658b74538b918d), +W64LIT(0x428e4d62b14dff4a), +W64LIT(0x88b1f60c09f64aa9), +W64LIT(0x75963771d2375c74), +W64LIT(0x7ad8408b9140703b), +W64LIT(0x57c7f072adf0b423), +W64LIT(0xe5971918121994a7), +W64LIT(0x5666f9cfe6f93c0d), +W64LIT(0x8f3cc9d50dc91863), +W64LIT(0x1e9cee0186ee589e), +W64LIT(0x8a06e4839fe4aff5), +W64LIT(0xb824b3c66eb3bb5d), +W64LIT(0xd1997839ac785aeb), +W64LIT(0x6752b5b8cab545d7), +W64LIT(0xb47cdf0ef0dffa60), +W64LIT(0x949a0a82190af76b), +W64LIT(0xc04be1c269e12e3a), +W64LIT(0xfc86c8c090c89ef3), +W64LIT(0xe3bb2f7c5d2f4e43), +W64LIT(0x6aabd0cd1fd08cc4), +W64LIT(0x2147dc31a2dc8525), +W64LIT(0xca3fbb6eb8bbb5e3), +W64LIT(0x48fa17ce60176493), +W64LIT(0x6444ae8a17ae28a5), +W64LIT(0x2b33869d73861efc), +W64LIT(0xd0387184e771d2c5), +W64LIT(0x7cf476efde76aadf), +W64LIT(0x63c9915313917a6f), +W64LIT(0xc929a05c65a0d891), +W64LIT(0xda4c2b28362b491c), +W64LIT(0xfe31da4f06da7baf), +W64LIT(0xc1eae87f22e8a614), +W64LIT(0x5c12a36337a3a7d4), +W64LIT(0x18b0d865c9d8827a), +W64LIT(0xe7200b97840b71fb), +W64LIT(0x4bec0cfcbd0c09e1), +W64LIT(0x0f4e77fa43772c4f), +W64LIT(0x4c613325b9335b2b), +W64LIT(0xf3c8bf3ad3bfb2bc), +W64LIT(0x87ff81f64a8166e6), +W64LIT(0xa38270917a705455), +W64LIT(0x1911d1d882d10a54), +W64LIT(0x44a27b06fe7b25ae), +W64LIT(0x049b24ebd9243fb8), +W64LIT(0xbb32a8f4b3a8d62f), +W64LIT(0x91a027d48b2740fd), +W64LIT(0x3d6c20bfb22038e7), +W64LIT(0xe681022acf02f9d5), +W64LIT(0xf17fadb545ad57e0), +W64LIT(0xcc138d0af78d6f07), +W64LIT(0x495b1e732b1eecbd), +W64LIT(0x38560de9200d8f71), +W64LIT(0xa9f62a3dab2acf8c), +W64LIT(0x47b46034236048dc), +W64LIT(0x8e9dc06846c0904d), +W64LIT(0xaccc076b3907781a), +W64LIT(0x32225745f15714a8), +W64LIT(0xd4a3556f3e55ed7d), +W64LIT(0xd7b54e5de34e800f), +W64LIT(0xddc114f132141bd6), +W64LIT(0x6d26ef141befde0e), +W64LIT(0x85489379dc9383ba), +W64LIT(0x0bd553119a5313f7), +W64LIT(0x786f520407529567), +W64LIT(0xcb9eb2d3f3b23dcd), +W64LIT(0xa223792c3179dc7b), +W64LIT(0x0a745aacd15a9bd9), +W64LIT(0x710d139a0b1363cc), +W64LIT(0x681cc24289c26998), +W64LIT(0x1a07caea5fca6726), +W64LIT(0x82c5aca0d8acd170), +W64LIT(0x25dcf8da7bf8ba9d), +W64LIT(0xc7c6de1b6dde7cf0), +W64LIT(0xc35dfaf0b4fa4348), +W64LIT(0xded70fc3ef0f76a4), +W64LIT(0x504acfaba9cfe6e9), +W64LIT(0xc571cc94fbcc99ac), +W64LIT(0x5ea5b1eca1b14288), +W64LIT(0xae7b15e4af159d46), +W64LIT(0xc888a9e12ea950bf), +W64LIT(0xf7539bd10a9b8d04), +W64LIT(0x962d180d8f181237), +W64LIT(0xe43610a559101c89), +W64LIT(0x772125fe4425b928), +W64LIT(0x84e99ac4979a0b94), +W64LIT(0xc667d7a626d7f4de), +W64LIT(0xefe343b4c3430f7e), +W64LIT(0xd5025cd2755c6553), +W64LIT(0xa6b85dc7e85de3c3), +W64LIT(0xd61447e0a8470821), +W64LIT(0x3e7a3b8d6f3b5595), +W64LIT(0x52fddd243fdd03b5), +W64LIT(0x8072be2f4ebe342c), +W64LIT(0x12c482c9188219a3), +W64LIT(0x9eee502ec8506cb2), +W64LIT(0xad6d0ed6720ef034), +W64LIT(0x59288e35a58e1042), +W64LIT(0xe21a26c11626c66d), +W64LIT(0x247df16730f132b3), +W64LIT(0xf0dea4080ea4dfce), +W64LIT(0x31344c772c4c79da), +W64LIT(0x4f77281764283659), +W64LIT(0x79ce5bb94c5b1d49), +W64LIT(0x0000000000000000), +W64LIT(0x73ba01159d018690), +W64LIT(0x74373ecc993ed45a), +W64LIT(0xbcbf972db79784e5), +W64LIT(0x4ed621aa2f21be77), +W64LIT(0xd95a301aeb30246e), +W64LIT(0x9c5942a15e4289ee), +W64LIT(0x37187a13637aa33e), +W64LIT(0x276bea55edea5fc1), +W64LIT(0x1c2bfc8e10fcbdc2), +W64LIT(0xed54513b5551ea22), +W64LIT(0x20e6d58ce9d50d0b), +W64LIT(0x3ae11f66b61f6a2d), +W64LIT(0x66f3bc0581bccdf9), +W64LIT(0x2cbeb94477b94c36), +W64LIT(0x99636ff7cc6f3e78), +W64LIT(0x953b033f52037f45), +W64LIT(0xb0e7fbe529fbc5d8), +W64LIT(0x60df8a61ce8a171d), +W64LIT(0x6f91fd9b8dfd3b52), +W64LIT(0xaae0310f7631a2fe), +W64LIT(0xbfa98c1f6a8ce997), +W64LIT(0x8ba7ed3ed4ed27db), +W64LIT(0x98c2664a8766b656), +W64LIT(0x062c36644f36dae4), +W64LIT(0x5570e2fd3be2517f), +W64LIT(0xead96ee2516eb8e8), +W64LIT(0x419856506c569238), +W64LIT(0x23f0cebe34ce6079), +W64LIT(0x309545ca6745f1f4), +W64LIT(0x5a3e950778957d30), +W64LIT(0x617e83dc85839f33), +W64LIT(0xfb0bf71994f7cc39), +W64LIT(0x3ccd2902f929b0c9), +W64LIT(0x70ac1a27401aebe2), +W64LIT(0xcea49f85619f8a5b), +W64LIT(0x39f704546b04075f), +W64LIT(0x0df96575d565c913), +W64LIT(0x08c3482347487e85), +W64LIT(0xd28f630b71633799), +W64LIT(0xecf558861e58620c), +W64LIT(0xc2fcf34dfff3cb66), +W64LIT(0x978c11b0c4119a19), +W64LIT(0x69bdcbffc2cbe1b6), +W64LIT(0xba93a149f8a15e01), +W64LIT(0x51ebc616e2c66ec7), +W64LIT(0x078d3fd9043f52ca), +W64LIT(0x58898788ee87986c), +W64LIT(0x4a4d0541f60581cf), +W64LIT(0xe86e7c6dc77c5db4), +W64LIT(0xee424a09884a8750), +W64LIT(0xcdb284b7bc84e729), +W64LIT(0x65e5a7375ca7a08b), +W64LIT(0x2fa8a276aaa22144), +W64LIT(0xa0946ba3a76b3927), +W64LIT(0xa5ae46f535468eb1), +W64LIT(0x35af689cf5684662), +W64LIT(0x28259dafae9d738e), +W64LIT(0xcf0596382a960275), +W64LIT(0xb6cbcd8166cd1f3c), +W64LIT(0x7e43646048644f83), +W64LIT(0x9bd47d785a7ddb24), +W64LIT(0x432f44dffa447764), +W64LIT(0x9f4f59938359e49c), +W64LIT(0x7d557f52957f22f1), +W64LIT(0x76802c430f2c3106), +W64LIT(0xdc601d4c791d93f8), +W64LIT(0x053a2d56922db796), +W64LIT(0x11d299fbc59974d1), +W64LIT(0xf9bce59602e52965), +W64LIT(0xd8fb39a7a039ac40), +W64LIT(0x340e6121be61ce4c), +W64LIT(0x5f04b851eab8caa6), +W64LIT(0x5db3aade7caa2ffa), +W64LIT(0x1549bd101cbd4b69), +W64LIT(0xff90d3f24dd3f381), +W64LIT(0xafda1c59e41c1568), +W64LIT(0xb146f25862f24df6), +W64LIT(0xa40f4f487e4f069f), +/* box 2 */ +W64LIT(0xa1a35cebf8f0f94c), +W64LIT(0x2c203d650f3f095d), +W64LIT(0x1a2bdaee4084a2a7), +W64LIT(0xd32404574d7bcc68), +W64LIT(0xf785bea594a9adc4), +W64LIT(0xf2eb54456206949c), +W64LIT(0x3f5e334d0475ced1), +W64LIT(0x5994299b835d1f60), +W64LIT(0x785b7989ac204794), +W64LIT(0x025da6a2cf461a41), +W64LIT(0xdf1f3a71f01a901b), +W64LIT(0x27284f018bb77637), +W64LIT(0xe1955a6d694c5310), +W64LIT(0x24a1baf2d9d261ac), +W64LIT(0xe4fbb08d9fe36a48), +W64LIT(0x8d83618ef7cff011), +W64LIT(0x2ac72276abf5279e), +W64LIT(0xf9e32621e68eebf6), +W64LIT(0xbf323fb4d3f86f69), +W64LIT(0xbb888605b8745beb), +W64LIT(0x70dafe1e7acd2f65), +W64LIT(0xd0adf1a41f1edbf3), +W64LIT(0x1e91635f2b089625), +W64LIT(0xee2791b8864818f8), +W64LIT(0x99ce23e4c56c1484), +W64LIT(0xf33f0714ff259946), +W64LIT(0xbd6f99161cbe7528), +W64LIT(0x9f293cf761a63a47), +W64LIT(0xb80173f6ea114c70), +W64LIT(0x6543ef25d54dc62a), +W64LIT(0x39b92c5ea0bfe012), +W64LIT(0x63a4f0367187e8e9), +W64LIT(0x4c0d38a02cddf62f), +W64LIT(0x07334c4239e92319), +W64LIT(0x43bff375c3d9bdc7), +W64LIT(0xca862b4a5f9a7954), +W64LIT(0x5d2e902ae8d12be2), +W64LIT(0x137e0e280b4ac78c), +W64LIT(0xf162a1b630638307), +W64LIT(0x55af17bd3e3c4313), +W64LIT(0x358212781ddebc61), +W64LIT(0x94214e93e52e452d), +W64LIT(0xc18e592edb12063e), +W64LIT(0xec7a371a490e02b9), +W64LIT(0x4963d240da72cf77), +W64LIT(0x41e255d70c9fa786), +W64LIT(0xff0439324244c535), +W64LIT(0x88ed8b6e0160c949), +W64LIT(0x6c163be39e83a301), +W64LIT(0xc534e09fb09e32bc), +W64LIT(0x806c0cf9d78da1b8), +W64LIT(0xdba583c09b96a499), +W64LIT(0x746047af11411be7), +W64LIT(0xf40c4b56c6ccba5f), +W64LIT(0x6270a367eca4e533), +W64LIT(0xd41748157492ef71), +W64LIT(0xeff3c2e91b6b1522), +W64LIT(0x0e66988472274632), +W64LIT(0x534808ae9af66dd0), +W64LIT(0x8231aa5b18cbbbf9), +W64LIT(0xb2dd52c3f3ba3ec0), +W64LIT(0xdd429cd33f5c8a5a), +W64LIT(0x4e509e02e39bec6e), +W64LIT(0x26fc1c5016947bed), +W64LIT(0xd9f8256254d0bed8), +W64LIT(0x0955d4c64bce652b), +W64LIT(0x1610e4c8fde5fed4), +W64LIT(0x6dc268b203a0aedb), +W64LIT(0x2e7d9bc7c079131c), +W64LIT(0xc3d3ff8c14541c7f), +W64LIT(0xd64aeeb7bbd4f530), +W64LIT(0xab7f7ddee15b8bfc), +W64LIT(0x144d426a32a3e495), +W64LIT(0x8e0a947da5aae78a), +W64LIT(0x798f2ad831034a4e), +W64LIT(0x3be48afc6ff9fa53), +W64LIT(0x529c5bff07d5600a), +W64LIT(0xbee66ce54edb62b3), +W64LIT(0x931202d1dcc76634), +W64LIT(0x50c1fd5dc8937a4b), +W64LIT(0xa4cdb60b0e5fc014), +W64LIT(0x57f2b11ff17a5952), +W64LIT(0x47054ac4a8558945), +W64LIT(0x5a1ddc68d13808fb), +W64LIT(0x5cfac37b75f22638), +W64LIT(0xc207acdd897711a5), +W64LIT(0x289a84d464b33ddf), +W64LIT(0xc05a0a7f46310be4), +W64LIT(0xe6a6162f50a57009), +W64LIT(0x06e71f13a4ca2ec3), +W64LIT(0x5f733688279731a3), +W64LIT(0xeb497b5870e721a0), +W64LIT(0xb667eb7298360a42), +W64LIT(0xe3c8fccfa60a4951), +W64LIT(0xe772457ecd867dd3), +W64LIT(0x6978d103682c9a59), +W64LIT(0x0def6d77204251a9), +W64LIT(0xc90fdeb90dff6ecf), +W64LIT(0xd179a2f5823dd629), +W64LIT(0x2fa9c8965d5a1ec6), +W64LIT(0x81b85fa84aaeac62), +W64LIT(0xdc96cf82a27f8780), +W64LIT(0x602d05c523e2ff72), +W64LIT(0x19a22f1d12e1b53c), +W64LIT(0xe52fe3dc02c06792), +W64LIT(0x58407aca1e7e12ba), +W64LIT(0x61f95694bec1f2a8), +W64LIT(0x48b781114751c2ad), +W64LIT(0xaaab2e8f7c788626), +W64LIT(0x04bab9b16b8c3482), +W64LIT(0x2df46e34921c0487), +W64LIT(0x1123a88ac40cddcd), +W64LIT(0xc6bd156ce2fb2527), +W64LIT(0x7f6835cb95c9648d), +W64LIT(0x83e5f90a85e8b623), +W64LIT(0x4f84cd537eb8e1b4), +W64LIT(0x294ed785f9903005), +W64LIT(0x1cccc5fde44e8c64), +W64LIT(0xcb52781bc2b9748e), +W64LIT(0x1d1896ac796d81be), +W64LIT(0xb30901926e99331a), +W64LIT(0xad9862cd4591a53f), +W64LIT(0xc8db8de890dc6315), +W64LIT(0x7bd28c7afe45500f), +W64LIT(0x0adc213519ab72b0), +W64LIT(0xa8f6882db33e9c67), +W64LIT(0xb5ee1e81ca531dd9), +W64LIT(0x201b0343b25e552e), +W64LIT(0x4036068691bcaa5c), +W64LIT(0xae11973e17f4b2a4), +W64LIT(0x9efd6fa6fc85379d), +W64LIT(0x33650d6bb91492a2), +W64LIT(0x3a30d9adf2daf789), +W64LIT(0x0c3b3e26bd615c73), +W64LIT(0xf651edf4098aa01e), +W64LIT(0x710ead4fe7ee22bf), +W64LIT(0x3138abc9765288e3), +W64LIT(0x9d749a55aee02006), +W64LIT(0x6e4b9d4151c5b940), +W64LIT(0x84d6b548bc01953a), +W64LIT(0x360be78b4fbbabfa), +W64LIT(0xa22aa918aa95eed7), +W64LIT(0xedae644bd42d0f63), +W64LIT(0x46d119953576849f), +W64LIT(0x6497bc74486ecbf0), +W64LIT(0xfbbe808329c8f1b7), +W64LIT(0x4aea27b38817d8ec), +W64LIT(0x5626e24e6c595488), +W64LIT(0x056eeae0f6af3958), +W64LIT(0x4558ec6667139304), +W64LIT(0x448cbf37fa309ede), +W64LIT(0x6f9fce10cce6b49a), +W64LIT(0xa0770fba65d3f496), +W64LIT(0x671e49871a0bdc6b), +W64LIT(0xda71d09106b5a943), +W64LIT(0x08818797d6ed68f1), +W64LIT(0xa3fefa4937b6e30d), +W64LIT(0xb080f4613cfc2481), +W64LIT(0x763de10dde0701a6), +W64LIT(0x4dd96bf1b1fefbf5), +W64LIT(0x92c6518041e46bee), +W64LIT(0x3456412980fdb1bb), +W64LIT(0x981a70b5584f195e), +W64LIT(0x3d0395efcb33d490), +W64LIT(0xba5cd55425575631), +W64LIT(0x4b3e74e21534d536), +W64LIT(0x6af124f03a498dc2), +W64LIT(0x7ebc669a08ea6957), +W64LIT(0x30ecf898eb718539), +W64LIT(0xa922db7c2e1d91bd), +W64LIT(0x7a06df2b63665dd5), +W64LIT(0xb154a730a1df295b), +W64LIT(0xfc8dccc11021d2ae), +W64LIT(0xcfe8c1aaa935400c), +W64LIT(0x97a8bb60b74b52b6), +W64LIT(0x18767c4c8fc2b8e6), +W64LIT(0x9a47d6179709031f), +W64LIT(0x0000000000000000), +W64LIT(0xac4c319cd8b2a8e5), +W64LIT(0xb9d520a7773241aa), +W64LIT(0xdecb69206d399dc1), +W64LIT(0x1f45300eb62b9bff), +W64LIT(0x10f7fbdb592fd017), +W64LIT(0x3e8a601c9956c30b), +W64LIT(0x8502e619212298e0), +W64LIT(0xf5d818075befb785), +W64LIT(0x547b44eca31f4ec9), +W64LIT(0x9ca0c90433c32ddc), +W64LIT(0xe041093cf46f5eca), +W64LIT(0xa69010a9c119da55), +W64LIT(0xc769463d7fd828fd), +W64LIT(0xc4e0b3ce2dbd3f66), +W64LIT(0x2575e9a344f16c76), +W64LIT(0x01d453519d230dda), +W64LIT(0xfa6ad3d2b4ebfc6d), +W64LIT(0xd5c31b44e9b1e2ab), +W64LIT(0xf83775707bade62c), +W64LIT(0xbcbbca47819d78f2), +W64LIT(0xd79ebde626f7f8ea), +W64LIT(0x5bc98f394c1b0521), +W64LIT(0x2246a5e17d184f6f), +W64LIT(0x12aa5d799669ca56), +W64LIT(0x5ea765d9bab43c79), +W64LIT(0x8939d83f9c43c493), +W64LIT(0x32b15e3a24379f78), +W64LIT(0xe914ddfabfa13be1), +W64LIT(0x909bf7228ea271af), +W64LIT(0x73530bed28a838fe), +W64LIT(0xd2f05706d058c1b2), +W64LIT(0xfed06a63df67c8ef), +W64LIT(0xb43a4dd057701003), +W64LIT(0xa519e55a937ccdce), +W64LIT(0x75b414fe8c62163d), +W64LIT(0xafc5c46f8ad7bf7e), +W64LIT(0x2392f6b0e03b42b5), +W64LIT(0x386d7f0f3d9cedc8), +W64LIT(0x21cf50122f7d58f4), +W64LIT(0x9b9385460a2a0ec5), +W64LIT(0x5115ae0c55b07791), +W64LIT(0x0fb2cbd5ef044be8), +W64LIT(0xea9d2809edc42c7a), +W64LIT(0xcc613459fb505797), +W64LIT(0x426ba0245efab01d), +W64LIT(0x1599113baf80e94f), +W64LIT(0x7d3593695a8f7ecc), +W64LIT(0x0389f5f35265179b), +W64LIT(0x875f40bbee6482a1), +W64LIT(0x95f51dc2780d48f7), +W64LIT(0x7ce1c038c7ac7316), +W64LIT(0xce3c92fb34164dd6), +W64LIT(0xcdb5670866735a4d), +W64LIT(0x8ab02dccce26d308), +W64LIT(0x914fa47313817c75), +W64LIT(0x8b647e9d5305ded2), +W64LIT(0xd82c7633c9f3b302), +W64LIT(0x728758bcb58b3524), +W64LIT(0xe8c08eab2282363b), +W64LIT(0x8fdec72c3889ea50), +W64LIT(0x2b13712736d62a44), +W64LIT(0x3cd7c6be5610d94a), +W64LIT(0x37dfb4dad298a620), +W64LIT(0x868b13ea73478f7b), +W64LIT(0xb7b3b82305150798), +W64LIT(0x0b08726484887f6a), +W64LIT(0x1bff89bfdda7af7d), +W64LIT(0x77e9b25c43240c7c), +W64LIT(0xf0b6f2e7ad408edd), +W64LIT(0x17c4b79960c6f30e), +W64LIT(0x8c5732df6aecfdcb), +W64LIT(0x68ac8252f50f9783), +W64LIT(0x66ca1ad68728d1b1), +W64LIT(0x6b2577a1a76a8018), +W64LIT(0xe21caf9e3b29448b), +W64LIT(0xa74443f85c3ad78f), +W64LIT(0xfd599f908d02df74), +W64LIT(0x967ce8312a685f6c), +/* box 3 */ +W64LIT(0xfa7b9775ba3af751), +W64LIT(0x03ef98cb769c2d13), +W64LIT(0x7191ce067072359e), +W64LIT(0xbab18b6bff7516a8), +W64LIT(0xe6e5ef4efbc1065e), +W64LIT(0x7bec74a3b1d0dbf4), +W64LIT(0x656b4fb907c31c4a), +W64LIT(0x4e8520f99fc86304), +W64LIT(0x8fd8df31d16dae58), +W64LIT(0x90a93fc1e60a7244), +W64LIT(0x30ad09f2b449cfc5), +W64LIT(0x8453be7e91bb5b90), +W64LIT(0x1d68a3d1c08feaad), +W64LIT(0x5c54642504b410f6), +W64LIT(0x8061383c8a9e3707), +W64LIT(0xf9940fbecca6da42), +W64LIT(0x46e1d97da982bbdf), +W64LIT(0xfc50521656f7ad77), +W64LIT(0x5e4d2704f35c2647), +W64LIT(0x8bea5973ca48c2cf), +W64LIT(0xd06323dfa34593bd), +W64LIT(0x62b651306a7a5dce), +W64LIT(0xa436b0714966d116), +W64LIT(0x4f73fb131ebc78a6), +W64LIT(0x92b07ce011e244f5), +W64LIT(0x33429139c2d5e2d6), +W64LIT(0xcee418c515565403), +W64LIT(0xd7be3d56cefcd239), +W64LIT(0x53ed83285f4789a9), +W64LIT(0xf3e9b51b0d043428), +W64LIT(0x20650e0fd8dd8a86), +W64LIT(0xb6e7f4add21aa2e4), +W64LIT(0x6d0fb63d3189c491), +W64LIT(0x0da0a42cac1bafee), +W64LIT(0x3f14eeffefba569a), +W64LIT(0x13279f361a086850), +W64LIT(0x9b225e8ea6dc878c), +W64LIT(0x6684d772715f3159), +W64LIT(0xa3ebaef824df9092), +W64LIT(0xc499a260d4f4ba69), +W64LIT(0xaa798c9693e153eb), +W64LIT(0x50021be329dba4ba), +W64LIT(0x949bb983fd2f1ed3), +W64LIT(0xdfdac4d2f8b60ae2), +W64LIT(0xf0062dd07b98193b), +W64LIT(0xafbdd13e09b024de), +W64LIT(0xb95e13a089e93bbb), +W64LIT(0x649d945386b707e8), +W64LIT(0xe4fcac6f0c2930ef), +W64LIT(0x413cc7f4c43bfa5b), +W64LIT(0x3b2668bdf49f3a0d), +W64LIT(0xe50a77858d5d2b4d), +W64LIT(0x05c45da89a517735), +W64LIT(0x3ee235156ece4d38), +W64LIT(0xfe491137a11f9bc6), +W64LIT(0xb7112f47536eb946), +W64LIT(0x07dd1e896db94184), +W64LIT(0x1ab5bd58ad36ab29), +W64LIT(0x8197e3d60bea2ca5), +W64LIT(0xab8f577c12954849), +W64LIT(0x9cff4007cb65c608), +W64LIT(0xa00436335243bd81), +W64LIT(0xfda689fcd783b6d5), +W64LIT(0xccfd5be4e2be62b2), +W64LIT(0x75a348446b575909), +W64LIT(0x17151974012d04c7), +W64LIT(0xfb8d4c9f3b4eecf3), +W64LIT(0xac5249f57f2c09cd), +W64LIT(0x9346a70a90965f57), +W64LIT(0x043286421b256c97), +W64LIT(0x27b81086b564cb02), +W64LIT(0x3569545a2e18b8f0), +W64LIT(0x6b24735edd449eb7), +W64LIT(0x2193d5e559a99124), +W64LIT(0xc7763aaba268977a), +W64LIT(0xb0cc31ce3ed7f8c2), +W64LIT(0xc939064c78ef1587), +W64LIT(0x16e3c29e80591f65), +W64LIT(0x5da2bfcf85c00b54), +W64LIT(0x5990398d9ee567c3), +W64LIT(0x67720c98f02b2afb), +W64LIT(0x54309da132fec82d), +W64LIT(0xeab39088d6aeb212), +W64LIT(0x9682faa20ac72862), +W64LIT(0xd38cbb14d5d9beae), +W64LIT(0x4c9c63d8682055b5), +W64LIT(0xd648e6bc4f88c99b), +W64LIT(0xdc355c198e2a27f1), +W64LIT(0x10c807fd6c944543), +W64LIT(0x450e41b6df1e96cc), +W64LIT(0x0b8b614f40d6f5c8), +W64LIT(0xd27a60fe54ada50c), +W64LIT(0x49583e70f2712280), +W64LIT(0x8dc19c10268598e9), +W64LIT(0x5866e2671f917c61), +W64LIT(0x79f537824638ed45), +W64LIT(0xc2b267033839e04f), +W64LIT(0xcb20456d8f072336), +W64LIT(0x2a18b4aa197f64ec), +W64LIT(0xdbe84290e3936675), +W64LIT(0x73888d27879a032f), +W64LIT(0xe8aad3a9214684a3), +W64LIT(0x6ee02ef64715e982), +W64LIT(0xa996145de57d7ef8), +W64LIT(0xc8cfdda6f99b0e25), +W64LIT(0x062bc563eccd5a26), +W64LIT(0x264ecb6c3410d0a0), +W64LIT(0xb8a8c84a089d2019), +W64LIT(0x7dc7b1c05d1d81d2), +W64LIT(0xd5a77e773914e488), +W64LIT(0x4b417d5105991431), +W64LIT(0xf62de8b39755431d), +W64LIT(0x993b1daf5134b13d), +W64LIT(0x82787b1d7d7601b6), +W64LIT(0xe321b2e66190716b), +W64LIT(0xb5086c66a4868ff7), +W64LIT(0x9ee603263c8df0b9), +W64LIT(0x349f8fb0af6ca352), +W64LIT(0x5b897aac690d5172), +W64LIT(0x7c316a2adc699a70), +W64LIT(0xd451a59db860ff2a), +W64LIT(0x706715ecf1062e3c), +W64LIT(0x838ea0f7fc021a14), +W64LIT(0x57df056a4462e53e), +W64LIT(0xcf12c32f94224fa1), +W64LIT(0xed6e8e01bb17f396), +W64LIT(0x915fe42b677e69e6), +W64LIT(0x89f31a523da0f47e), +W64LIT(0xe71334a47ab51dfc), +W64LIT(0xa860cfb76409655a), +W64LIT(0x9f10d8ccbdf9eb1b), +W64LIT(0xef77cd204cffc527), +W64LIT(0xf862d4544dd2c1e0), +W64LIT(0x8a1c82994b3cd96d), +W64LIT(0xae4b0ad488c43f7c), +W64LIT(0x98cdc645d040aa9f), +W64LIT(0x7fdef2e1aaf5b763), +W64LIT(0x4717029728f6a07d), +W64LIT(0x745593aeea2342ab), +W64LIT(0xee8116cacd8bde85), +W64LIT(0x727e56cd06ee188d), +W64LIT(0x227c4d2e2f35bc37), +W64LIT(0x977421488bb333c0), +W64LIT(0xa21d7512a5ab8b30), +W64LIT(0xbb4750817e010d0a), +W64LIT(0x6cf96dd7b0fddf33), +W64LIT(0x2801f78bee97525d), +W64LIT(0x1c9e783b41fbf10f), +W64LIT(0x9d099bed4a11ddaa), +W64LIT(0x7a1aaf4930a4c056), +W64LIT(0x32b44ad343a1f974), +W64LIT(0x3cfb763499267b89), +W64LIT(0xb2d572efc93fce73), +W64LIT(0x63408adaeb0e466c), +W64LIT(0xada4921ffe58126f), +W64LIT(0x5fbbfcee72283de5), +W64LIT(0x6ad2a8b45c308515), +W64LIT(0x0c567fc62d6fb44c), +W64LIT(0x956d62697c5b0571), +W64LIT(0x25a153a7428cfdb3), +W64LIT(0x150c5a55f6c53276), +W64LIT(0xe2d7690ce0e46ac9), +W64LIT(0xda1e997a62e77dd7), +W64LIT(0xf5c27078e1c96e0e), +W64LIT(0xc344bce9b94dfbed), +W64LIT(0x60af12119d926b7f), +W64LIT(0xa1f2edd9d337a623), +W64LIT(0xcad69e870e733894), +W64LIT(0x3770177bd9f08e41), +W64LIT(0xa5c06b9bc812cab4), +W64LIT(0x1f71e0f03767dc1c), +W64LIT(0x44f89a5c5e6a8d6e), +W64LIT(0x6159c9fb1ce670dd), +W64LIT(0x8e2e04db5019b5fa), +W64LIT(0x8805c1b8bcd4efdc), +W64LIT(0xe138f1c7967847da), +W64LIT(0x4ab7a6bb84ed0f93), +W64LIT(0x0000000000000000), +W64LIT(0x38c9f0768203171e), +W64LIT(0x1b4366b22c42b08b), +W64LIT(0x7803ec68c74cf6e7), +W64LIT(0xec9855eb3a63e834), +W64LIT(0xbe830d29e4507a3f), +W64LIT(0x2dc5aa2374c62568), +W64LIT(0xa62ff350be8ee7a7), +W64LIT(0x764cd08f1dcb741a), +W64LIT(0x8c3747faa7f1834b), +W64LIT(0x0fb9e70d5bf3995f), +W64LIT(0x55c6464bb38ad38f), +W64LIT(0xf7db3359162158bf), +W64LIT(0xd195f8352231881f), +W64LIT(0x0992226eb73ec379), +W64LIT(0x14fa81bf77b129d4), +W64LIT(0x48aee59a73053922), +W64LIT(0x2457884dc3f8e611), +W64LIT(0xffbfcadd206b8064), +W64LIT(0xb4feb78c25f29455), +W64LIT(0x864afd5f66536d21), +W64LIT(0x6f16f51cc661f220), +W64LIT(0xde2c1f3879c21140), +W64LIT(0x195a2593dbaa863a), +W64LIT(0x2e2a32e8025a087b), +W64LIT(0x432584d533d3ccea), +W64LIT(0x2c3371c9f5b23eca), +W64LIT(0xa7d928ba3ffafc05), +W64LIT(0x42d35f3fb2a7d748), +W64LIT(0x85a5659410cf4032), +W64LIT(0x0864f984364ad8db), +W64LIT(0xf21f6ef18c702f8a), +W64LIT(0xf1f0f63afaec0299), +W64LIT(0xd9f101b1147b50c4), +W64LIT(0x2fdce902832e13d9), +W64LIT(0x4d6ab832e9544e17), +W64LIT(0xe0ce2a2d170c5c78), +W64LIT(0x51f4c009a8afbf18), +W64LIT(0x68cbeb95abd8b3a4), +W64LIT(0xc15dffc84ea5cd5c), +W64LIT(0x02194321f7e836b1), +W64LIT(0x113edc17ede05ee1), +W64LIT(0x521b58c2de33920b), +W64LIT(0x9ad4856427a89c2e), +W64LIT(0x5629de80c516fe9c), +W64LIT(0x77ba0b659cbf6fb8), +W64LIT(0x238a96c4ae41a795), +W64LIT(0x12d144dc9b7c73f2), +W64LIT(0xd807da5b950f4b66), +W64LIT(0x3686cc91588495e3), +W64LIT(0x18acfe795ade9d98), +W64LIT(0x5a7fa146e8794ad0), +W64LIT(0xc680e141231c8cd8), +W64LIT(0x1e873b1ab613c7be), +W64LIT(0xf434ab9260bd75ac), +W64LIT(0xcd0b800e63ca7910), +W64LIT(0xbc9a4e0813b84c8e), +W64LIT(0x3d0dadde1852602b), +W64LIT(0x40ca1c1e454fe1f9), +W64LIT(0x0a7dbaa5c1a2ee6a), +W64LIT(0x693d307f2aaca806), +W64LIT(0x0e4f3ce7da8782fd), +W64LIT(0xbd6c95e292cc572c), +W64LIT(0x3ad0b35775eb21af), +W64LIT(0x7e28290b2b81acc1), +W64LIT(0x01f6dbea81741ba2), +W64LIT(0x87bc26b5e7277683), +W64LIT(0x393f2b9c03770cbc), +W64LIT(0xddc387f30f5e3c53), +W64LIT(0xeb454b6257daa9b0), +W64LIT(0xb323a905484bd5d1), +W64LIT(0xb13aea24bfa3e360), +W64LIT(0x315bd218353dd467), +W64LIT(0x2bee6f40980b7f4e), +W64LIT(0xe95c0843a0329f01), +W64LIT(0xc56f798a5580a1cb), +W64LIT(0xbf75d6c36524619d), +W64LIT(0x29f72c616fe349ff), +W64LIT(0xc0ab2422cfd1d6fe), +/* box 4 */ +W64LIT(0x561fc423e957943c), +W64LIT(0x014287ca69079288), +W64LIT(0x2f086129dfcd1d21), +W64LIT(0xc537d4aea044fd99), +W64LIT(0xf1e8c3bfd7c8a457), +W64LIT(0x2971998a5cdf9bfb), +W64LIT(0x23fa649a2ce9e460), +W64LIT(0x3aa9e9c356a6716a), +W64LIT(0xd6efa4e7aa3d1708), +W64LIT(0x705a24b1fda5b5eb), +W64LIT(0x101e0ce2b170a9fc), +W64LIT(0x7ca821020e814caa), +W64LIT(0x0bc97ada1931ed13), +W64LIT(0x34df1711778c59ce), +W64LIT(0xd35020ef9226d2bf), +W64LIT(0x575d43e9805006b4), +W64LIT(0x91acebec9b1db840), +W64LIT(0x549b3f423b5945d9), +W64LIT(0x99a3ed9d3925163e), +W64LIT(0x7917a50a369a891d), +W64LIT(0xe372343cb4b6dc4e), +W64LIT(0x8d40e2bdd949e8fd), +W64LIT(0xcfbc29bed0728202), +W64LIT(0x969794857108ac12), +W64LIT(0xdd26de3db30cfa1b), +W64LIT(0x115c8b28d8773b74), +W64LIT(0xe9f9c92cc480a3d5), +W64LIT(0x4dc8b21b4116d0d3), +W64LIT(0x316093194f979c79), +W64LIT(0x5124bb4a0342806e), +W64LIT(0xb31408bcdef3cea8), +W64LIT(0xc1cad76cf158aaa6), +W64LIT(0x88ff66b5e1522d4a), +W64LIT(0xa8c37e8476b28a47), +W64LIT(0x15a188ea896b6c4b), +W64LIT(0xa24883940684f5dc), +W64LIT(0xda1da1545919ee49), +W64LIT(0x22b8e35045ee76e8), +W64LIT(0x6106af9925d28e9f), +W64LIT(0xef80318f4792250f), +W64LIT(0x663dd0f0cfc79acd), +W64LIT(0x302214d326900ef1), +W64LIT(0xdfa2255c61022bfe), +W64LIT(0xe6cdb0348cad19f9), +W64LIT(0x50663c806a4512e6), +W64LIT(0x65fbac5b74ced9a0), +W64LIT(0xc4755364c9436f11), +W64LIT(0x8fc419dc0b473918), +W64LIT(0x5c9439339961eba7), +W64LIT(0x3f166dcb6ebdb4dd), +W64LIT(0xba59890715ccf25e), +W64LIT(0xf0aa4475becf36df), +W64LIT(0x03c67cabbb09436d), +W64LIT(0xb99ff5acaec5b133), +W64LIT(0xf9e7c5ce75f00a29), +W64LIT(0x6df4aa2ad6f677de), +W64LIT(0xaeba8627f5a00c9d), +W64LIT(0xa573fcfdec91e18e), +W64LIT(0x7f6e5da9b5880fc7), +W64LIT(0xca03adb6e86947b5), +W64LIT(0x74a72773acb9e2d4), +W64LIT(0x604428534cd51c17), +W64LIT(0xf8a542041cf798a1), +W64LIT(0x448533a08a29ec25), +W64LIT(0x80f060c4436a8334), +W64LIT(0x0db082799a236bc9), +W64LIT(0xfa21b965cef94944), +W64LIT(0x64b92b911dc94b28), +W64LIT(0x7118a37b94a22763), +W64LIT(0xaff801ed9ca79e15), +W64LIT(0x1dae8e9b2b53c235), +W64LIT(0x13d870490a79ea91), +W64LIT(0x8a7b9dd4335cfcaf), +W64LIT(0x1f2a75faf95d13d0), +W64LIT(0xeec2b6452e95b787), +W64LIT(0xc34e2c0d23567b43), +W64LIT(0x47434f0b3120af48), +W64LIT(0xa18eff3fbd8db6b1), +W64LIT(0x98e16a57502284b6), +W64LIT(0x37196bbacc851aa3), +W64LIT(0x8e869e166240ab90), +W64LIT(0x9fda153eba3790e4), +W64LIT(0xf515c07d86d4f368), +W64LIT(0x72dedfd02fab640e), +W64LIT(0xe230b3f6ddb14ec6), +W64LIT(0x97d5134f180f3e9a), +W64LIT(0xe1f6cf5d66b80dab), +W64LIT(0xe78f37fee5aa8b71), +W64LIT(0xa30a045e6f836754), +W64LIT(0x90ee6c26f21a2ac8), +W64LIT(0xaa4785e5a4bc5ba2), +W64LIT(0x4e0eceb0fa1f93be), +W64LIT(0x94136fe4a3067df7), +W64LIT(0x7b935e6be49458f8), +W64LIT(0x9b2716fceb2bc7db), +W64LIT(0x840d63061276d40b), +W64LIT(0xed04caee959cf4ea), +W64LIT(0xea3fb5877f89e0b8), +W64LIT(0xb56df01f5de14872), +W64LIT(0x4935b1d9100a87ec), +W64LIT(0x82749ba5916452d1), +W64LIT(0x58693af1c87dbc98), +W64LIT(0x89bde17f8855bfc2), +W64LIT(0x677f573aa6c00845), +W64LIT(0xeb7d324d168e7230), +W64LIT(0x0284fb61d20ed1e5), +W64LIT(0xb190f3dd0cfd1f4d), +W64LIT(0x684b2e22eeedb269), +W64LIT(0x2bf562eb8ed14a1e), +W64LIT(0xe0b448970fbf9f23), +W64LIT(0x396f9568edaf3207), +W64LIT(0x52e2c7e1b84bc303), +W64LIT(0x77615bd817b0a1b9), +W64LIT(0x7e2cda63dc8f9d4f), +W64LIT(0xf22ebf146cc1e73a), +W64LIT(0xc08850a6985f382e), +W64LIT(0xd9dbddffe210ad24), +W64LIT(0xbfe60d0f2dd737e9), +W64LIT(0x9a659136822c5553), +W64LIT(0x87cb1fada97f9766), +W64LIT(0x4c8a35d12811425b), +W64LIT(0x83361c6ff863c059), +W64LIT(0xd212a725fb214037), +W64LIT(0x9e9892f4d330026c), +W64LIT(0x45c7b46ae32e7ead), +W64LIT(0x5baf465a7374fff5), +W64LIT(0xdc6459f7da0b6893), +W64LIT(0xd46b5f867833c6ed), +W64LIT(0x5dd6bef9f066792f), +W64LIT(0xcb412a7c816ed53d), +W64LIT(0x75e5a0b9c5be705c), +W64LIT(0xf6d3bcd63dddb005), +W64LIT(0xfb633eafa7fedbcc), +W64LIT(0xd529d84c11345465), +W64LIT(0xc9c5d11d536004d8), +W64LIT(0xdb5f269e301e7cc1), +W64LIT(0x86899867c07805ee), +W64LIT(0x3d9296aabcb36538), +W64LIT(0x2cce1d8264c45e4c), +W64LIT(0x5aedc1901a736d7d), +W64LIT(0x2e4ae6e3b6ca8fa9), +W64LIT(0x1e68f230905a8158), +W64LIT(0xdee0a2960805b976), +W64LIT(0xcd38d2df027c53e7), +W64LIT(0x6909a9e887ea20e1), +W64LIT(0x24c11bf3c6fcf032), +W64LIT(0x18110a9313480782), +W64LIT(0xa7f7079c3e9f306b), +W64LIT(0xd8995a358b173fac), +W64LIT(0x854fe4cc7b714683), +W64LIT(0xbd62f66effd9e60c), +W64LIT(0x14e30f20e06cfec3), +W64LIT(0x6e32d6816dff34b3), +W64LIT(0x217e9ffbfee73585), +W64LIT(0xc88756d73a679650), +W64LIT(0x359d90db1e8bcb46), +W64LIT(0x2645e09214f221d7), +W64LIT(0x04fd03c2511c573f), +W64LIT(0x739c581a46acf686), +W64LIT(0xb0d2741765fa8dc5), +W64LIT(0xa0cc78f5d48a2439), +W64LIT(0x5e10c2524b6f3a42), +W64LIT(0xe50bcc9f37a45a94), +W64LIT(0x53a0402bd14c518b), +W64LIT(0x413ab7a8b2322992), +W64LIT(0x203c183197e0a70d), +W64LIT(0xcc7a55156b7bc16f), +W64LIT(0x4601c8c158273dc0), +W64LIT(0xbea48ac544d0a561), +W64LIT(0x638254f8f7dc5f7a), +W64LIT(0xa6b580565798a2e3), +W64LIT(0x3cd01160d5b4f7b0), +W64LIT(0x8c026577b04e7a75), +W64LIT(0x7ad1d9a18d93ca70), +W64LIT(0x785522c05f9d1b95), +W64LIT(0x5f5245982268a8ca), +W64LIT(0x9551e82eca01ef7f), +W64LIT(0x0000000000000000), +W64LIT(0xbb1b0ecd7ccb60d6), +W64LIT(0x094d81bbcb3f3cf6), +W64LIT(0x28331e4035d80973), +W64LIT(0xf7913b1c54da228d), +W64LIT(0x6acfd5433ce3638c), +W64LIT(0x1bd77638a84144ef), +W64LIT(0x62c0d3329edbcdf2), +W64LIT(0x81b2e70e2a6d11bc), +W64LIT(0xd7ad232dc33a8580), +W64LIT(0x05bf8408381bc5b7), +W64LIT(0x33e468789d994d9c), +W64LIT(0xfedcbaa79fe51e7b), +W64LIT(0x4f4c497a93180136), +W64LIT(0x073b7f69ea151452), +W64LIT(0x0cf205b3f324f941), +W64LIT(0x382d12a284a8a08f), +W64LIT(0x1cec0951425450bd), +W64LIT(0x55d9b888525ed751), +W64LIT(0x6cb62de0bff1e556), +W64LIT(0xd1d4db8e4028035a), +W64LIT(0x25839c39affb62ba), +W64LIT(0x4af3cd72ab03c481), +W64LIT(0xa4317b3785967306), +W64LIT(0x1a95f1f2c146d667), +W64LIT(0x926a97472014fb2d), +W64LIT(0xb7e90b7e8fef9997), +W64LIT(0xcefeae74b975108a), +W64LIT(0x3e54ea0107ba2655), +W64LIT(0xd0965c44292f91d2), +W64LIT(0xab05022fcdbbc92a), +W64LIT(0xfd1ac60c24ec5d16), +W64LIT(0xfc5841c64debcf9e), +W64LIT(0xe4494b555ea3c81c), +W64LIT(0xb6ab8cb4e6e80b1f), +W64LIT(0x3beb6e093fa1e3e2), +W64LIT(0xf36c38de05c675b2), +W64LIT(0x9c1c6995013ed389), +W64LIT(0x8b391a1e5a5b6e27), +W64LIT(0xec464d24fc9b6662), +W64LIT(0xad7cfa8c4ea94ff0), +W64LIT(0x0f347918482dba2c), +W64LIT(0x9d5eee5f68394101), +W64LIT(0x7623dc127eb73331), +W64LIT(0x32a6efb2f49edf14), +W64LIT(0x2d8c9a480dc3ccc4), +W64LIT(0xb2568f76b7f45c20), +W64LIT(0x0e76fed2212a28a4), +W64LIT(0x48773613790d1564), +W64LIT(0x129af783637e7819), +W64LIT(0x080f0671a238ae7e), +W64LIT(0x365bec70a582882b), +W64LIT(0x42fccb03093b6aff), +W64LIT(0x0a8bfd1070367f9b), +W64LIT(0xff9e3d6df6e28cf3), +W64LIT(0xe8bb4ee6ad87315d), +W64LIT(0xc7b32fcf724a2c7c), +W64LIT(0xb8dd7266c7c223bb), +W64LIT(0x9328108d491369a5), +W64LIT(0x0679f8a3831286da), +W64LIT(0x270767587df5b35f), +W64LIT(0xa981f94e1fb518cf), +W64LIT(0x6b8d528955e4f104), +W64LIT(0x1667f44132622f26), +W64LIT(0x2ab7e521e7d6d896), +W64LIT(0xac3e7d4627aedd78), +W64LIT(0x7deaa6c86786de22), +W64LIT(0x1725738b5b65bdae), +W64LIT(0x4bb14ab8c2045609), +W64LIT(0x592bbd3ba17a2e10), +W64LIT(0xc20cabc74a51e9cb), +W64LIT(0x6f70514b04f8a63b), +W64LIT(0xbc2071a496de7484), +W64LIT(0x19538d597a4f950a), +W64LIT(0xf45747b7efd361e0), +W64LIT(0x43be4cc9603cf877), +W64LIT(0xc6f1a8051b4dbef4), +W64LIT(0xb42f77d534e6dafa), +W64LIT(0x40783062db35bb1a), +/* box 5 */ +W64LIT(0xf5a96c292deb0a4e), +W64LIT(0x211c9df6ee653c51), +W64LIT(0x04de5ddcbeeef596), +W64LIT(0xe1e5b06f7457c19f), +W64LIT(0x74ca30f014a54fb6), +W64LIT(0xc296f9f7c5457d85), +W64LIT(0x7d4ee08a484d10b0), +W64LIT(0xae87f2d0bf9b13ad), +W64LIT(0x8df4bb480e89afb7), +W64LIT(0x2d8b7a67d9a2d61e), +W64LIT(0x0f3559c8bd712adb), +W64LIT(0x541bc7312f013338), +W64LIT(0x9ec4848b636d5164), +W64LIT(0x952f809f60f28e29), +W64LIT(0x28984d8cb28d6357), +W64LIT(0xd4b5f1dfc38e361f), +W64LIT(0x5674135f7076b373), +W64LIT(0xb791a330042172ec), +W64LIT(0xab94c53bd4b4a6e4), +W64LIT(0xf17731f59305ffd8), +W64LIT(0x39c7a621801e1dcf), +W64LIT(0x20d1f7c13ba47c8e), +W64LIT(0x5e3da912f95facaa), +W64LIT(0xb1202a82e5b80731), +W64LIT(0x13303fc36de4fed3), +W64LIT(0x2e29c43e5314168a), +W64LIT(0x861fbf5c0d1670fa), +W64LIT(0x6458b16af3f771f1), +W64LIT(0x3043765bdcf642c9), +W64LIT(0x12fd55f4b825be0c), +W64LIT(0x0a266e23d65e9f92), +W64LIT(0x6595db5d2636312e), +W64LIT(0x85bd010587a0b06e), +W64LIT(0x9bd7b3600842e42d), +W64LIT(0xaa59af0c0175e63b), +W64LIT(0x240faa1d854a8918), +W64LIT(0xf464061ef82a4a91), +W64LIT(0x5c527d7ca6282ce1), +W64LIT(0x03a2be598ab6c094), +W64LIT(0x40571b7776bdf8e9), +W64LIT(0xe4f687841f7874d6), +W64LIT(0x115febad32937e98), +W64LIT(0x5108f0da442e8671), +W64LIT(0x9cab50e53c1ad12f), +W64LIT(0x33e1c8025640825d), +W64LIT(0x87d2d56bd8d73025), +W64LIT(0xc0f92d999a32fdce), +W64LIT(0x62e938d8126e042c), +W64LIT(0x4a717554a0e3677b), +W64LIT(0x0beb0414039fdf4d), +W64LIT(0xd6da25b19cf9b654), +W64LIT(0x55d6ad06fac073e7), +W64LIT(0x632452efc7af44f3), +W64LIT(0xb5fe775e5b56f2a7), +W64LIT(0x892ae694b0675a21), +W64LIT(0x7a32030f7c1525b2), +W64LIT(0x5d9f174b73e96c3e), +W64LIT(0xc35b93c010843d5a), +W64LIT(0x373f95dee8ae77cb), +W64LIT(0xfb515fd6455b604a), +W64LIT(0xa9fb11558bc326af), +W64LIT(0x22be23af64d3fcc5), +W64LIT(0xa8367b625e026670), +W64LIT(0xb8a4faf8b9505837), +W64LIT(0x785dd7612362a5f9), +W64LIT(0x588c20a018c6d977), +W64LIT(0xea0eb47b77c81ed2), +W64LIT(0xa6ce489d36b20c74), +W64LIT(0x0c97e79137c7ea4f), +W64LIT(0x7c838abd9d8c506f), +W64LIT(0x57b97968a5b7f3ac), +W64LIT(0x6c110b277ade6e28), +W64LIT(0xc785ce1cae6ac8cc), +W64LIT(0x1581b6718c7d8b0e), +W64LIT(0x614b868198d8c4b8), +W64LIT(0x27ad14440ffc498c), +W64LIT(0xdb80a8177eff1cc4), +W64LIT(0x472bf8f242e5cdeb), +W64LIT(0x8a8858cd3ad19ab5), +W64LIT(0xf60bd270a75dcada), +W64LIT(0x43f5a52efc0b387d), +W64LIT(0x6ddc6110af1f2ef7), +W64LIT(0xf0ba5bc246c4bf07), +W64LIT(0x6fb3b57ef068aebc), +W64LIT(0x18db3bd76e7b219e), +W64LIT(0x903cb7740bdd3b60), +W64LIT(0x7bff6938a9d4656d), +W64LIT(0xbdb7cd13d27fed7e), +W64LIT(0x051337eb6b2fb549), +W64LIT(0x77688ea99e138f22), +W64LIT(0xd9ef7c7921889c8f), +W64LIT(0x077ce38534583502), +W64LIT(0xf318e59bcc727f93), +W64LIT(0xb34ffeecbacf877a), +W64LIT(0xe9ac0a22fd7ede46), +W64LIT(0xfc2dbc5371035548), +W64LIT(0x026fd46e5f77804b), +W64LIT(0xe53bedb3cab93409), +W64LIT(0xcc6eca08adf51781), +W64LIT(0xe028da58a1968140), +W64LIT(0x3a6518780aa8dd5b), +W64LIT(0xce011e66f28297ca), +W64LIT(0xa4a19cf369c58c3f), +W64LIT(0xc5ea1a72f11d4887), +W64LIT(0xc427704524dc0858), +W64LIT(0x4238cf1929ca78a2), +W64LIT(0x481ea13aff94e730), +W64LIT(0xdf5ef5cbc011e952), +W64LIT(0x80ae36eeec8f0527), +W64LIT(0x5ae3f4ce47b1593c), +W64LIT(0xcda3a03f7834575e), +W64LIT(0x71d9071b7f8afaff), +W64LIT(0xcadf43ba4c6c625c), +W64LIT(0x1623082806cb4b9a), +W64LIT(0x17ee621fd30a0b45), +W64LIT(0x448946abc8530d7f), +W64LIT(0x974054f13f850e62), +W64LIT(0x73b6d37520fd7ab4), +W64LIT(0xc8b097d4131be217), +W64LIT(0x9f09eebcb6ac11bb), +W64LIT(0x45442c9c1d924da0), +W64LIT(0x1b79858ee4cde10a), +W64LIT(0x0984d07a5ce85f06), +W64LIT(0x4cc0fce6417a12a6), +W64LIT(0x99b8670e57356466), +W64LIT(0xad254c89352dd339), +W64LIT(0x322ca2358381c282), +W64LIT(0xcfcc74512743d715), +W64LIT(0x6b6de8a24e865b2a), +W64LIT(0xda4dc220ab3e5c1b), +W64LIT(0x88e78ca365a61afe), +W64LIT(0x939e092d816bfbf4), +W64LIT(0xcb12298d99ad2283), +W64LIT(0xeed0e9a7c926eb44), +W64LIT(0x98750d3982f424b9), +W64LIT(0xd5789be8164f76c0), +W64LIT(0xbe15734a58c92dea), +W64LIT(0x49d3cb0d2a55a7ef), +W64LIT(0x67fa0f337941b165), +W64LIT(0x8c39d17fdb48ef68), +W64LIT(0x25c2c02a508bc9c7), +W64LIT(0x349d2b876218b75f), +W64LIT(0x70146d2caa4bba20), +W64LIT(0x1c05660bd095d408), +W64LIT(0xfe42683d2e74d503), +W64LIT(0x9a1ad957dd83a4f2), +W64LIT(0xf2d58fac19b33f4c), +W64LIT(0x81635cd9394e45f8), +W64LIT(0xb65cc907d1e03233), +W64LIT(0xdd3121a59f666919), +W64LIT(0x318e1c6c09370216), +W64LIT(0x8b4532faef10da6a), +W64LIT(0x191651e0bbba6141), +W64LIT(0x3f762f9361876812), +W64LIT(0xb96990cf6c9118e8), +W64LIT(0xb4331d698e97b278), +W64LIT(0xd822164ef449dc50), +W64LIT(0x84706b325261f0b1), +W64LIT(0x4eaf28881e0d92ed), +W64LIT(0x69023ccc11f1db61), +W64LIT(0x66376504ac80f1ba), +W64LIT(0x0849ba4d89291fd9), +W64LIT(0xff8f020afbb595dc), +W64LIT(0x50c59aed91efc6ae), +W64LIT(0x1dc80c3c055494d7), +W64LIT(0x1e6ab2658fe25443), +W64LIT(0x3d19fbfd3ef0e859), +W64LIT(0xfa9c35e1909a2095), +W64LIT(0x52aa4e83ce9846e5), +W64LIT(0x419a7140a37cb836), +W64LIT(0xa07fc12fd72b79a9), +W64LIT(0x68cf56fbc4309bbe), +W64LIT(0x01cd6a37d5c140df), +W64LIT(0x9253631a54aabb2b), +W64LIT(0xd06bac037d60c389), +W64LIT(0x295527bb674c2388), +W64LIT(0xd204786d221743c2), +W64LIT(0x0000000000000000), +W64LIT(0xf7c6b847729c8a05), +W64LIT(0xdcfc4b924aa729c6), +W64LIT(0xe38a64012b2041d4), +W64LIT(0xb28294db6f0ec7a5), +W64LIT(0x9d663ad2e9db91f0), +W64LIT(0x91f1dd43de1c7bbf), +W64LIT(0x6086ecb64d198467), +W64LIT(0x59414a97cd0799a8), +W64LIT(0xace826bee0ec93e6), +W64LIT(0xa56cf6c4bc04cce0), +W64LIT(0x727bb942f53c3a6b), +W64LIT(0x6e7edf4925a9ee63), +W64LIT(0x26607e73da3d0953), +W64LIT(0xe75439dd95ceb442), +W64LIT(0x7990bd56f6a3e526), +W64LIT(0xecbf3dc996516b0f), +W64LIT(0x76a5e49e4bd2cffd), +W64LIT(0x968d3ec6ea444ebd), +W64LIT(0x5b2e9ef9927019e3), +W64LIT(0x6aa082959b471bf5), +W64LIT(0xbb0644a133e698a3), +W64LIT(0x830c88b76639c5b3), +W64LIT(0xe2470e36fee1010b), +W64LIT(0xb0ed40b5307947ee), +W64LIT(0x355041b0b7d9f780), +W64LIT(0x8e560511843f6f23), +W64LIT(0x7f2134e4173a90fb), +W64LIT(0x2af799e2edfae31c), +W64LIT(0x4bbc1f63752227a4), +W64LIT(0xf8f3e18fcfeda0de), +W64LIT(0x0d5a8da6e206aa90), +W64LIT(0x2c4610500c6396c1), +W64LIT(0xde939ffc15d0a98d), +W64LIT(0xaf4a98e76a5a5372), +W64LIT(0x8f9b6f2651fe2ffc), +W64LIT(0x36f2ffe93d6f3714), +W64LIT(0x0ef833ff68b06a04), +W64LIT(0xe69953ea400ff49d), +W64LIT(0x23734998b112bc1a), +W64LIT(0x3ebb45a4b44628cd), +W64LIT(0x1ab4efb9310ca1d5), +W64LIT(0x2fe4ae0986d55655), +W64LIT(0xebc3de4ca2095e0d), +W64LIT(0x536724b41b59063a), +W64LIT(0x46e692c597248d34), +W64LIT(0x2b3af3d5383ba3c3), +W64LIT(0x3ba8724fdf699d84), +W64LIT(0xc13447ae4ff3bd11), +W64LIT(0x4d0d96d194bb5279), +W64LIT(0xfde0d664a4c21597), +W64LIT(0xd7174f864938f68b), +W64LIT(0x7eec5ed3c2fbd024), +W64LIT(0xbfd8197d8d086d35), +W64LIT(0x4f6242bfcbccd232), +W64LIT(0xa70322aae3734cab), +W64LIT(0xa3dd7f765d9db93d), +W64LIT(0x94e2eaa8b533cef6), +W64LIT(0x144cdc4659bccbd1), +W64LIT(0xc648a42b7bab8813), +W64LIT(0xf93e8bb81a2ce001), +W64LIT(0xbacb2e96e627d87c), +W64LIT(0xbc7aa72407beada1), +W64LIT(0xc97dfde3c6daa2c8), +W64LIT(0xa1b2ab1802ea3976), +W64LIT(0x1fa7d8525a23149c), +W64LIT(0x75075ac7c1640f69), +W64LIT(0xe861601528bf9e99), +W64LIT(0xa2101541885cf9e2), +W64LIT(0xef1d83901ce7ab9b), +W64LIT(0x06b189b2e19975dd), +W64LIT(0x380acc1655df5d10), +W64LIT(0x1092819ae7523e47), +W64LIT(0xd3c9125af7d6031d), +W64LIT(0xd1a6c634a8a18356), +W64LIT(0x5ff0c3252c9eec75), +W64LIT(0x82c1e280b3f8856c), +W64LIT(0xed7257fe43902bd0), +W64LIT(0x3cd491caeb31a886), +/* box 6 */ +W64LIT(0x94af9eb6fad9e7df), +W64LIT(0x9208ae5e03c94ddd), +W64LIT(0x1d8de8d67158480b), +W64LIT(0xfd093cd2ba147af8), +W64LIT(0xa45ceb22e6597ccf), +W64LIT(0x9bbde6e77bf113da), +W64LIT(0xe4edf4b465fffe5c), +W64LIT(0x7125622e4e8d2a2f), +W64LIT(0x1791b81b8f68430d), +W64LIT(0xb56a63d1902195c0), +W64LIT(0xa980832b30d2ee67), +W64LIT(0x4c0a7fb384862397), +W64LIT(0xed58bc0d1dc7a05b), +W64LIT(0x5955d7f05c4d0637), +W64LIT(0xd2b9b1c8806fcf4e), +W64LIT(0x06a730e8f910aa02), +W64LIT(0xb8b60bd846aa0768), +W64LIT(0x45bf370afcbe7d90), +W64LIT(0x16f6b0375ec370a1), +W64LIT(0x892276608b81afd4), +W64LIT(0xdcccc1b5d0ec08e7), +W64LIT(0xe856949162df5f58), +W64LIT(0x82592e81a41a977e), +W64LIT(0xac8eabb74fca1164), +W64LIT(0xfac9041692afe356), +W64LIT(0x3b882d75331ba3ba), +W64LIT(0xa39cd3e6cee2e561), +W64LIT(0xd077a190d7cca9e3), +W64LIT(0x9c7dde23534a8a74), +W64LIT(0x80973ed9f3b9f1d3), +W64LIT(0xce535132209cb4e9), +W64LIT(0xaa299b5fb6dabb66), +W64LIT(0x2d7e9d426dd8d31b), +W64LIT(0x8a8b6e140d89fad5), +W64LIT(0x6ca88af83fd56224), +W64LIT(0xf5db7c4713871753), +W64LIT(0xeef1a4799bcff55a), +W64LIT(0x76e55aea6636b381), +W64LIT(0x8ee24ea4a33a367a), +W64LIT(0x25acddd7c44bbeb0), +W64LIT(0x9adaeecbaa5a2076), +W64LIT(0x0e75707d5083c7a9), +W64LIT(0x2bd9adaa94c87919), +W64LIT(0x19e4c866dfeb84a4), +W64LIT(0x129f9087f070bc0e), +W64LIT(0xd9c2e929aff4f7e4), +W64LIT(0x6f01928cb9dd3725), +W64LIT(0x39463d2d64b8c517), +W64LIT(0xebff8ce5e4d70a59), +W64LIT(0xb40d6bfd418aa66c), +W64LIT(0xf21b44833b3c8efd), +W64LIT(0x3654457ce5903112), +W64LIT(0x431807e205aed792), +W64LIT(0xb10343613e92596f), +W64LIT(0x0a1c50cdfe300b06), +W64LIT(0x778252c6b79d802d), +W64LIT(0x0cbb60250720a104), +W64LIT(0xe1e3dc281ae7015f), +W64LIT(0x0f1278518128f405), +W64LIT(0x47712752ab1d1b3d), +W64LIT(0xe24ac45c9cef545e), +W64LIT(0x1ceae0faa0f37ba7), +W64LIT(0x9814fe93fdf946db), +W64LIT(0xec3fb421cc6c93f7), +W64LIT(0x833e26ad75b1a4d2), +W64LIT(0x6b68b23c176efb8a), +W64LIT(0x4904572ffb9edc94), +W64LIT(0x4bca4777ac3dba39), +W64LIT(0x2762cd8f93e8d81d), +W64LIT(0x9eb3ce7b04e9ecd9), +W64LIT(0xc2e8311727bc15ed), +W64LIT(0xea9884c9357c39f5), +W64LIT(0xfc6e34fe6bbf4954), +W64LIT(0x13f898ab21db8fa2), +W64LIT(0xb7a47389c782f36d), +W64LIT(0x7b3932e3b0bd2129), +W64LIT(0xaf27b3c3c9c24465), +W64LIT(0xb6c37ba51629c0c1), +W64LIT(0x84fe1e695d0a3d7c), +W64LIT(0x1a4dd01259e3d1a5), +W64LIT(0xab4e9373677188ca), +W64LIT(0x90c6be06546a2b70), +W64LIT(0xf37c4cafea97bd51), +W64LIT(0x647aca6d96460f8f), +W64LIT(0x4ec46febd325453a), +W64LIT(0x3e8605e94c035cb9), +W64LIT(0x0ddc6809d68b92a8), +W64LIT(0x8bec6638dc22c979), +W64LIT(0x67d3d219104e5a8e), +W64LIT(0x2abea58645634ab5), +W64LIT(0x5b9bc7a80bee609a), +W64LIT(0x936fa672d2627e71), +W64LIT(0x7d9e020b49ad8b2b), +W64LIT(0x5832dfdc8de6359b), +W64LIT(0xc7e6198b58a4eaee), +W64LIT(0xd41e8120797f654c), +W64LIT(0xf4bc746bc22c24ff), +W64LIT(0xe084d404cb4c32f3), +W64LIT(0x48635f032a35ef38), +W64LIT(0x8757061ddb02687d), +W64LIT(0x522e8f1173d63e9d), +W64LIT(0xbcdf2b68e819cbc7), +W64LIT(0xbf76331c6e119ec6), +W64LIT(0x08d24095a9936dab), +W64LIT(0x728c7a5ac8857f2e), +W64LIT(0xd110a9bc06679a4f), +W64LIT(0x1f43f88e26fb2ea6), +W64LIT(0xb2aa5b15b89a0c6e), +W64LIT(0x4aad4f5b7d968995), +W64LIT(0x9fd4c657d542df75), +W64LIT(0x323d65cc4b23fdbd), +W64LIT(0xc38f393bf6172641), +W64LIT(0xa152c3be994183cc), +W64LIT(0x9d1ad60f82e1b9d8), +W64LIT(0xe744ecc0e3f7ab5d), +W64LIT(0x38213501b513f6bb), +W64LIT(0xade9a39b9e6122c8), +W64LIT(0x37334d50343b02be), +W64LIT(0x55eeb7d55b6da733), +W64LIT(0x970686c27cd1b2de), +W64LIT(0x427f0fced405e43e), +W64LIT(0xc026214f701f7340), +W64LIT(0x40b11f9683a68293), +W64LIT(0x02ce105857a366ad), +W64LIT(0x7e371a7fcfa5de2a), +W64LIT(0xffc72c8aedb71c55), +W64LIT(0x68c1aa489166ae8b), +W64LIT(0xc68111a7890fd942), +W64LIT(0x79f722bbe71e4784), +W64LIT(0xd579890ca8d456e0), +W64LIT(0x70426a029f261983), +W64LIT(0xb0644b4def396ac3), +W64LIT(0xdb0cf971f8579149), +W64LIT(0x5489bff98ac6949f), +W64LIT(0x046920b0aeb3ccaf), +W64LIT(0x7cf90a279806b887), +W64LIT(0x050e289c7f18ff03), +W64LIT(0x651dc24147ed3c23), +W64LIT(0x5e95ef3474f69f99), +W64LIT(0x6dcf82d4ee7e5188), +W64LIT(0x8f854688729105d6), +W64LIT(0x81f036f52212c27f), +W64LIT(0xb9d103f4970134c4), +W64LIT(0x5349873da27d0d31), +W64LIT(0x20a2f54bbb5341b3), +W64LIT(0xf0d554db6c9fe850), +W64LIT(0x07c038c428bb99ae), +W64LIT(0x30f375941c809b10), +W64LIT(0x3fe10dc59da86f15), +W64LIT(0x46162f7e7ab62891), +W64LIT(0xe623e4ec325c98f1), +W64LIT(0xfea024a63c1c2ff9), +W64LIT(0x349a5524b23357bf), +W64LIT(0x35fd5d0863986413), +W64LIT(0x96618eeead7a8172), +W64LIT(0xcb5d79ae5f844bea), +W64LIT(0x21c5fd676af8721f), +W64LIT(0x5720a78d0ccec19e), +W64LIT(0xf6726433958f4252), +W64LIT(0x8d4b56d02532637b), +W64LIT(0x24cbd5fb15e08d1c), +W64LIT(0x3aef2559e2b09016), +W64LIT(0x5afccf84da455336), +W64LIT(0x51879765f5de6b9c), +W64LIT(0x2917bdf2c36b1fb4), +W64LIT(0xa7f5f356605129ce), +W64LIT(0xc1412963a1b440ec), +W64LIT(0x3d2f1d9dca0b09b8), +W64LIT(0xa53be30e37f24f63), +W64LIT(0x5ff2e718a55dac35), +W64LIT(0xa2fbdbca1f49d6cd), +W64LIT(0xf7156c1f442471fe), +W64LIT(0x7a5e3acf61161285), +W64LIT(0xca3a71828e2f7846), +W64LIT(0x1b2ad83e8848e209), +W64LIT(0xa8e78b07e179ddcb), +W64LIT(0xef96ac554a64c6f6), +W64LIT(0x0000000000000000), +W64LIT(0x6013eadd38f5c320), +W64LIT(0x3c4815b11ba03a14), +W64LIT(0x09b548b978385e07), +W64LIT(0x226ce513ecf0271e), +W64LIT(0x63baf2a9befd9621), +W64LIT(0x44d83f262d154e3c), +W64LIT(0xcdfa4946a694e1e8), +W64LIT(0x113688f37678e90f), +W64LIT(0x859916458ca10ed0), +W64LIT(0xc52809d30f078c43), +W64LIT(0x4d6d779f552d103b), +W64LIT(0x1e24f0a2f7501d0a), +W64LIT(0x0167082cd1ab33ac), +W64LIT(0x1438a06f0960160c), +W64LIT(0xf9601c6214a7b657), +W64LIT(0xa035cb9248eab060), +W64LIT(0x50e09f4924755830), +W64LIT(0xd7b79954ff77304d), +W64LIT(0xe58afc98b454cdf0), +W64LIT(0x03a9187486085501), +W64LIT(0x62ddfa856f56a58d), +W64LIT(0xc44f01ffdeacbfef), +W64LIT(0x73eb7276192e4c82), +W64LIT(0xd6d091782edc03e1), +W64LIT(0xfbae0c3a4304d0fa), +W64LIT(0x9973f6bf2c527577), +W64LIT(0x105180dfa7d3daa3), +W64LIT(0x2605c5a34243ebb1), +W64LIT(0x91a1b62a85c118dc), +W64LIT(0xc99369f608272d47), +W64LIT(0x5d3cf740f2feca98), +W64LIT(0xcf34591ef1378745), +W64LIT(0xc8f461dad98c1eeb), +W64LIT(0x0b7b58e12f9b38aa), +W64LIT(0xe32dcc704d4467f2), +W64LIT(0x754c429ee03ee680), +W64LIT(0xd3deb9e451c4fce2), +W64LIT(0x6e669aa068760489), +W64LIT(0x66b4da35c1e56922), +W64LIT(0x4fa367c7028e7696), +W64LIT(0xba781b80110961c5), +W64LIT(0x41d617ba520db13f), +W64LIT(0x335a6de09a88ce11), +W64LIT(0xdf65d9c156e45de6), +W64LIT(0xcc9d416a773fd244), +W64LIT(0x5c5bff6c2355f934), +W64LIT(0x2870b5de12c02c18), +W64LIT(0x155fa843d8cb25a0), +W64LIT(0x78902a9736b57428), +W64LIT(0xae40bbef186977c9), +W64LIT(0x88457e4c5a2a9c78), +W64LIT(0x6a0fba10c6c5c826), +W64LIT(0x7f5012531e0eed86), +W64LIT(0x8c2c5efcf49950d7), +W64LIT(0x31947db8cd2ba8bc), +W64LIT(0x2c19956ebc73e0b7), +W64LIT(0x230bed3f3d5b14b2), +W64LIT(0x69a6a26440cd9d27), +W64LIT(0x86300e310aa95bd1), +W64LIT(0xb3cd533969313fc2), +W64LIT(0x1883c04a0e40b708), +W64LIT(0xf1b25cf7bd34dbfc), +W64LIT(0x2fb08d1a3a7bb5b6), +W64LIT(0xd8a5e1057e5fc448), +W64LIT(0xddabc99901473b4b), +W64LIT(0xde02d1ed874f6e4a), +W64LIT(0xbdb8234439b2f86b), +W64LIT(0x5647afa1dd65f232), +W64LIT(0x2ed78536ebd0861a), +W64LIT(0xe9319cbdb3746cf4), +W64LIT(0xa692fb7ab1fa1a62), +W64LIT(0x742b4ab23195d52c), +W64LIT(0x95c8969a2b72d473), +W64LIT(0x6174e2f1e95ef08c), +W64LIT(0xf807144ec50c85fb), +W64LIT(0xbe113b30bfbaad6a), +W64LIT(0xda6bf15d29fca2e5), +W64LIT(0xbb1f13acc0a25269), +/* box 7 */ +W64LIT(0xc22b27f0f9e37bf9), +W64LIT(0x93fad23f0955ef09), +W64LIT(0x32ed4b84a22a91a2), +W64LIT(0x3898b57bcc61b1cc), +W64LIT(0x55825ba9ad98e5ad), +W64LIT(0xb2eeb8069421ec94), +W64LIT(0xc7eb5875ce3c6bce), +W64LIT(0x4b1dac5d1f45851f), +W64LIT(0xc16ba1204705d847), +W64LIT(0xc5380f461a2ba91a), +W64LIT(0xb908971a909bad90), +W64LIT(0x303e1cb7763d5376), +W64LIT(0xe6ff324c53486853), +W64LIT(0x6d1aeed261f95461), +W64LIT(0x0193d1e36af1616a), +W64LIT(0x51d1f5cff0b694f0), +W64LIT(0x29b2c3f52728e127), +W64LIT(0x112a768eeb4950eb), +W64LIT(0x8fb672f86f9f4d6f), +W64LIT(0xf0c66c745bc9ea5b), +W64LIT(0x3f8b9dcd2fa9632f), +W64LIT(0x65bc471edba5b6db), +W64LIT(0x4d9d5508967c3696), +W64LIT(0x3a4be24818767318), +W64LIT(0x2794936c144db014), +W64LIT(0x2af2452599ce4299), +W64LIT(0x4a8e7dbe75b4e475), +W64LIT(0x9ddc82a63a30be3a), +W64LIT(0xade29e114c0ded4c), +W64LIT(0xd1d2064dc6bde9c6), +W64LIT(0x7da349bfe04165e0), +W64LIT(0x6b9a1787e8c0e7e8), +W64LIT(0xa54437ddf6510ff6), +W64LIT(0x2254ece92392a023), +W64LIT(0x79f0e7d9bd6f14bd), +W64LIT(0x57510c9a798f2779), +W64LIT(0x346db2d12b13222b), +W64LIT(0x54118a4ac76984c7), +W64LIT(0xefca4a6383e5eb83), +W64LIT(0xca8d8e3c43bf9943), +W64LIT(0xfc336bdebcbb79bc), +W64LIT(0x3e184c2e45580245), +W64LIT(0xf495c21206e79b06), +W64LIT(0xff73ed0e025dda02), +W64LIT(0x4228d472cfe806cf), +W64LIT(0xbcc8e89fa744bda7), +W64LIT(0xab626744c5345ec5), +W64LIT(0xb6bd1660c90f9dc9), +W64LIT(0xb72ec783a3fefca3), +W64LIT(0x8be5dc9e32b13c32), +W64LIT(0x485d2a8da1a326a1), +W64LIT(0xc6788996a4cd0aa4), +W64LIT(0x40fb83411bffc41b), +W64LIT(0x08a6a9ccba5ce2ba), +W64LIT(0xf386eaa4e52f49e5), +W64LIT(0x1acc5992eff311ef), +W64LIT(0xa2571f6b1599dd15), +W64LIT(0x44a82d2746d1b546), +W64LIT(0x70c59ff66dc2976d), +W64LIT(0x8d6525cbbb888fbb), +W64LIT(0x963aadba3e8aff3e), +W64LIT(0x7c30985c8ab0048a), +W64LIT(0x607c389bec7aa6ec), +W64LIT(0xa822e1947bd2fd7b), +W64LIT(0x034086d0bee6a3be), +W64LIT(0x66fcc1ce65431565), +W64LIT(0xb37d69e5fed08dfe), +W64LIT(0x2f323aa0ae1152ae), +W64LIT(0x56c2dd79137e4613), +W64LIT(0x31adcd541ccc321c), +W64LIT(0xdff456d4f5d8b8f5), +W64LIT(0xf9f3145b8b64698b), +W64LIT(0x764566a3e4fb24e4), +W64LIT(0x0cf507aae77293e7), +W64LIT(0x59775c034aea764a), +W64LIT(0xb89b46f9fa6accfa), +W64LIT(0xe8d962d5602d3960), +W64LIT(0x17aa8fdb6270e362), +W64LIT(0x1c4ca0c766caa266), +W64LIT(0x2de16d937a06907a), +W64LIT(0x2547c45fc05a72c0), +W64LIT(0x0fb5817a59943059), +W64LIT(0x0680f9558939b389), +W64LIT(0x16395e3808818208), +W64LIT(0xac714ff226fc8c26), +W64LIT(0xa9b1307711239c11), +W64LIT(0xec8accb33d03483d), +W64LIT(0x6c893f310b08350b), +W64LIT(0xc4abdea570dac870), +W64LIT(0xba4811ca2e7d0e2e), +W64LIT(0xf155bd9731388b31), +W64LIT(0xdd2701e721cf7a21), +W64LIT(0xe94ab3360adc580a), +W64LIT(0x23c73d0a4963c149), +W64LIT(0x5cb723867d35667d), +W64LIT(0x5042242c9a47f59a), +W64LIT(0x198cdf425115b251), +W64LIT(0x0a75feff6e4b206e), +W64LIT(0xfda0ba3dd64a18d6), +W64LIT(0xcede205a1e91e81e), +W64LIT(0xd041d7aeac4c88ac), +W64LIT(0xe42c657f875faa87), +W64LIT(0x36bee5e2ff04e0ff), +W64LIT(0x6fc9b9e1b5ee96b5), +W64LIT(0x998f2cc0671ecf67), +W64LIT(0xd301517e12aa2b12), +W64LIT(0xaea218c1f2eb4ef2), +W64LIT(0xda342951c207a8c2), +W64LIT(0x61efe978868bc786), +W64LIT(0x7f701e8c3456a734), +W64LIT(0x0be62f1c04ba4104), +W64LIT(0x9129850cdd422ddd), +W64LIT(0xd6c12efb25753b25), +W64LIT(0xe33f4dc964977864), +W64LIT(0x1579d8e8b66721b6), +W64LIT(0xf860c5b8e19508e1), +W64LIT(0x7496319030ece630), +W64LIT(0x88a55a4e8c579f8c), +W64LIT(0xcf4df1b974608974), +W64LIT(0x10b9a76d81b83181), +W64LIT(0x0e26509933655133), +W64LIT(0x43bb0591a51967a5), +W64LIT(0x926903dc63a48e63), +W64LIT(0x9c4f534550c1df50), +W64LIT(0x3bd833ab72871272), +W64LIT(0xa4d7e63e9ca06e9c), +W64LIT(0xb46e41531d185f1d), +W64LIT(0x126af05e55aff355), +W64LIT(0x24d415bcaaab13aa), +W64LIT(0x1e9ff7f4b2dd60b2), +W64LIT(0x05c07f8537df1037), +W64LIT(0x467b7a1492c67792), +W64LIT(0x2087bbdaf78562f7), +W64LIT(0x819022615cfa1c5c), +W64LIT(0xcd9ea68aa0774ba0), +W64LIT(0xa79760ee2246cd22), +W64LIT(0x8343755288edde88), +W64LIT(0x58e48de0201b1720), +W64LIT(0x7216c8c5b9d555b9), +W64LIT(0x372d340195f58195), +W64LIT(0xa11799bbab7f7eab), +W64LIT(0x9f0fd595ee277cee), +W64LIT(0x676f102d0fb2740f), +W64LIT(0x9e9c047684d61d84), +W64LIT(0x49cefb6ecb5247cb), +W64LIT(0xd41279c8f162f9f1), +W64LIT(0x1f0c2617d82c01d8), +W64LIT(0x97a97c59547b9e54), +W64LIT(0xe76ce3af39b90939), +W64LIT(0xc3b8f61393121a93), +W64LIT(0x5ba40b309efdb49e), +W64LIT(0xea0a35e6b43afbb4), +W64LIT(0x5a37dad3f40cd5f4), +W64LIT(0x14ea090bdc9640dc), +W64LIT(0x5e6474b5a922a4a9), +W64LIT(0xfee03ced68acbb68), +W64LIT(0x071328b6e3c8d2e3), +W64LIT(0x5302a2fc24a15624), +W64LIT(0x85c38c0701d46d01), +W64LIT(0x3d58cafefbbea1fb), +W64LIT(0x84505de46b250c6b), +W64LIT(0x642f96fdb154d7b1), +W64LIT(0xbf886e4f19a21e19), +W64LIT(0x02d35733d417c2d4), +W64LIT(0x68da915756264456), +W64LIT(0x8710db34d5c3afd5), +W64LIT(0x0d66d6498d83f28d), +W64LIT(0x7b23b0ea6978d669), +W64LIT(0x1b5f887185027085), +W64LIT(0x3ccb1b1d914fc091), +W64LIT(0x0453ae665d2e715d), +W64LIT(0xcb1e5fdf294ef829), +W64LIT(0xf6469521d2f059d2), +W64LIT(0xb03def3540362e40), +W64LIT(0x633cbe4b529c0552), +W64LIT(0xf7d544c2b80138b8), +W64LIT(0x7ab061090389b703), +W64LIT(0x0000000000000000), +W64LIT(0xdba7f8b2a8f6c9a8), +W64LIT(0x35fe633241e24341), +W64LIT(0x21146a399d74039d), +W64LIT(0xd581a82b9b93989b), +W64LIT(0x0935782fd0ad83d0), +W64LIT(0x5ff7a556c3d3c5c3), +W64LIT(0xaf31c922981a2f98), +W64LIT(0x90ba54efb7b34cb7), +W64LIT(0x5291731f4e50374e), +W64LIT(0xc0f870c32df4b92d), +W64LIT(0x7ee3cf6f5ea7c65e), +W64LIT(0xe07fcb19da71dbda), +W64LIT(0x4eddd3d8289a9528), +W64LIT(0x13f921bd3f5e923f), +W64LIT(0xf50613f16c16fa6c), +W64LIT(0x981cfd230defae0d), +W64LIT(0x4c0e84ebfc8d57fc), +W64LIT(0x82d0a4b1e21cbfe2), +W64LIT(0x89368bade6a6fee6), +W64LIT(0xd292809d785b4a78), +W64LIT(0x47e8abf7f83716f8), +W64LIT(0x8e25a31b056e2c05), +W64LIT(0xd752ff184f845a4f), +W64LIT(0xcc0d7769ca862aca), +W64LIT(0x694940b43cd7253c), +W64LIT(0x2ea1eb43c4e033c4), +W64LIT(0xde6787379f29d99f), +W64LIT(0x181f0ea13be4d33b), +W64LIT(0x416852a2710ea571), +W64LIT(0x62af6fa8386d6438), +W64LIT(0xa0844858c18e1fc1), +W64LIT(0x337e9a67c8dbf0c8), +W64LIT(0x2c72bc7010f7f110), +W64LIT(0xbd5b397ccdb5dccd), +W64LIT(0xd8e77e6216106a16), +W64LIT(0x86830ad7bf32cebf), +W64LIT(0x4f4e023b426bf442), +W64LIT(0xe5bfb49cedaecbed), +W64LIT(0x8a760d7d58405d58), +W64LIT(0xe2ac9c2a0e66190e), +W64LIT(0xb5fd90b077e93e77), +W64LIT(0xdcb4d0044b3e1b4b), +W64LIT(0x453bfcc42c20d42c), +W64LIT(0xed191d5057f22957), +W64LIT(0xe1ec1afab080bab0), +W64LIT(0xee599b80e9148ae9), +W64LIT(0x2607428f7ebcd17e), +W64LIT(0x5d24f26517c40717), +W64LIT(0x6a09c66482318682), +W64LIT(0xa604b10d48b7ac48), +W64LIT(0xbe1bbfac73537f73), +W64LIT(0x282112164dd9804d), +W64LIT(0x7505e0735a1d875a), +W64LIT(0x73851926d32434d3), +W64LIT(0xd974af817ce10b7c), +W64LIT(0xeb99e405decb9ade), +W64LIT(0x9b5c7bf3b3090db3), +W64LIT(0xfab3928b3582ca35), +W64LIT(0x8003f382360b7d36), +W64LIT(0x94e9fa89ea9d3dea), +W64LIT(0xb1ae3ed62ac74f2a), +W64LIT(0x9acfaa10d9f86cd9), +W64LIT(0x390b6498a690d0a6), +W64LIT(0xf2153b478fde288f), +W64LIT(0x71564e150733f607), +W64LIT(0xa3c4ce887f68bc7f), +W64LIT(0xaaf1b6a7afc53faf), +W64LIT(0x1ddf71240c3bc30c), +W64LIT(0x77d6b7408e0a458e), +W64LIT(0x2b6194c6f33f23f3), +W64LIT(0xc9cd08ecfd593afd), +W64LIT(0xc85ed90f97a85b97), +W64LIT(0x8cf6f428d179eed1), +W64LIT(0x957a2b6a806c5c80), +W64LIT(0xbbdbc029448c6f44), +W64LIT(0x7863363ad79e75d7), +W64LIT(0x6e5a6802df1ff7df), +W64LIT(0xfb2043685f73ab5f), +}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/simeck.cpp b/external/ours/library/crypto/src/shared/original/simeck.cpp new file mode 100755 index 000000000..a1a5316e1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simeck.cpp @@ -0,0 +1,154 @@ +// simeck.cpp - written and placed in the public domain by Gangqiang Yang and Jeffrey Walton. +// Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang, +// Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong + +#include "pch.h" +#include "config.h" + +#include "simeck.h" +#include "misc.h" +#include "cpu.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::rotlConstant; +using CryptoPP::rotrConstant; + +/// \brief SIMECK encryption round +/// \tparam T word type +/// \param key the key for the round or iteration +/// \param left the first value +/// \param right the second value +/// \details SIMECK_Encryption serves as the key schedule, encryption and +/// decryption functions. +template +inline void SIMECK_Encryption(const T key, T& left, T& right) +{ + const T temp = left; + left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key; + right = temp; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +std::string SIMECK32::Base::AlgorithmProvider() const +{ + return "C++"; +} + +void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + CRYPTOPP_UNUSED(keyLength); + + GetBlock kblock(userKey); + kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]); + + word16 constant = 0xFFFC; + word32 sequence = 0x9A42BB1F; + for (unsigned int i = 0; i < ROUNDS; ++i) + { + m_rk[i] = m_t[0]; + + constant &= 0xFFFC; + constant |= sequence & 1; + sequence >>= 1; + + SIMECK_Encryption(static_cast(constant), m_t[1], m_t[0]); + + // rotate the LFSR of m_t + m_t[4] = m_t[1]; + m_t[1] = m_t[2]; + m_t[2] = m_t[3]; + m_t[3] = m_t[4]; + } +} + +void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[1])(m_t[0]); + + for (int idx = 0; idx < ROUNDS; ++idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[1])(m_t[0]); +} + +void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[0])(m_t[1]); + + for (int idx = ROUNDS - 1; idx >= 0; --idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[0])(m_t[1]); +} + +std::string SIMECK64::Base::AlgorithmProvider() const +{ + return "C++"; +} + +void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + CRYPTOPP_UNUSED(keyLength); + + GetBlock kblock(userKey); + kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]); + + word64 constant = W64LIT(0xFFFFFFFC); + word64 sequence = W64LIT(0x938BCA3083F); + for (unsigned int i = 0; i < ROUNDS; ++i) + { + m_rk[i] = m_t[0]; + + constant &= W64LIT(0xFFFFFFFC); + constant |= sequence & 1; + sequence >>= 1; + + SIMECK_Encryption(static_cast(constant), m_t[1], m_t[0]); + + // rotate the LFSR of m_t + m_t[4] = m_t[1]; + m_t[1] = m_t[2]; + m_t[2] = m_t[3]; + m_t[3] = m_t[4]; + } +} + +void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[1])(m_t[0]); + + for (int idx = 0; idx < ROUNDS; ++idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[1])(m_t[0]); +} + +void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[0])(m_t[1]); + + for (int idx = ROUNDS - 1; idx >= 0; --idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[0])(m_t[1]); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/simeck.h b/external/ours/library/crypto/src/shared/original/simeck.h new file mode 100755 index 000000000..3449c7f84 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simeck.h @@ -0,0 +1,162 @@ +// simeck.h - written and placed in the public domain by Gangqiang Yang and Jeffrey Walton. +// Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang, +// Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong + +/// \file simeck.h +/// \brief Classes for the SIMECK block cipher +/// \sa SIMECK, +/// The Simeck +/// Family of Lightweight Block Ciphers +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_SIMECK_H +#define CRYPTOPP_SIMECK_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SIMECK block cipher information +/// \since Crypto++ 8.0 +struct SIMECK32_Info : public FixedBlockSize<4>, public FixedKeyLength<8>, public FixedRounds<32> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "SIMECK-32"; + } +}; + +/// \brief SIMECK block cipher information +/// \since Crypto++ 8.0 +struct SIMECK64_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public FixedRounds<44> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "SIMECK-64"; + } +}; + +/// \brief SIMECK 32-bit block cipher +/// \details SIMECK32 provides 32-bit block size. The valid key size is 64-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa SIMECK64, SIMECK, +/// The Simeck Family of +/// Lightweight Block Ciphers +/// \since Crypto++ 8.0 +class CRYPTOPP_NO_VTABLE SIMECK32 : public SIMECK32_Info, public BlockCipherDocumentation +{ +public: + /// \brief SIMECK block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + std::string AlgorithmProvider() const; + + FixedSizeSecBlock m_rk; + mutable FixedSizeSecBlock m_t; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SIMECK32::Encryption SIMECK32Encryption; +typedef SIMECK32::Decryption SIMECK32Decryption; + +/// \brief SIMECK 64-bit block cipher +/// \details SIMECK64 provides 64-bit block size. The valid key size is 128-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa SIMECK32, SIMECK, +/// The Simeck Family of +/// Lightweight Block Ciphers +/// \since Crypto++ 8.0 +class CRYPTOPP_NO_VTABLE SIMECK64 : public SIMECK64_Info, public BlockCipherDocumentation +{ +public: + /// \brief SIMECK block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + std::string AlgorithmProvider() const; + + FixedSizeSecBlock m_rk; + mutable FixedSizeSecBlock m_t; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + +#if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + +#if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SIMECK64::Encryption SIMECK64Encryption; +typedef SIMECK64::Decryption SIMECK64Decryption; + +NAMESPACE_END + +#endif // CRYPTOPP_SIMECK_H diff --git a/external/ours/library/crypto/src/shared/original/simon.cpp b/external/ours/library/crypto/src/shared/original/simon.cpp new file mode 100755 index 000000000..a0eacea4c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simon.cpp @@ -0,0 +1,505 @@ +// simon.h - written and placed in the public domain by Jeffrey Walton + +#include "pch.h" +#include "config.h" + +#include "simon.h" +#include "misc.h" +#include "cpu.h" + +// Uncomment for benchmarking C++ against SSE or NEON. +// Do so in both simon.cpp and simon_simd.cpp. +// #undef CRYPTOPP_SSSE3_AVAILABLE +// #undef CRYPTOPP_SSE41_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlConstant; +using CryptoPP::rotrConstant; + +/// \brief Round transformation helper +/// \tparam W word type +/// \param v value +template +inline W f(const W v) +{ + return (rotlConstant<1>(v) & rotlConstant<8>(v)) ^ rotlConstant<2>(v); +} + +/// \brief Round transformation +/// \tparam W word type +/// \param x value +/// \param y value +/// \param k value +/// \param l value +template +inline void R2(W& x, W& y, const W k, const W l) +{ + y ^= f(x); y ^= k; + x ^= f(y); x ^= l; +} + +/// \brief Forward transformation +/// \tparam W word type +/// \tparam R number of rounds +/// \param c output array +/// \param p input array +/// \param k subkey array +template +inline void SIMON_Encrypt(W c[2], const W p[2], const W k[R]) +{ + c[0]=p[0]; c[1]=p[1]; + + for (int i = 0; i < static_cast(R-1); i += 2) + R2(c[0], c[1], k[i], k[i + 1]); + + if (R & 1) + { + c[1] ^= f(c[0]); c[1] ^= k[R-1]; + W t = c[0]; c[0] = c[1]; c[1] = t; + } +} + +/// \brief Reverse transformation +/// \tparam W word type +/// \tparam R number of rounds +/// \param p output array +/// \param c input array +/// \param k subkey array +template +inline void SIMON_Decrypt(W p[2], const W c[2], const W k[R]) +{ + p[0]=c[0]; p[1]=c[1]; + unsigned int rounds = R; + + if (R & 1) + { + const W t = p[1]; p[1] = p[0]; p[0] = t; + p[1] ^= k[R - 1]; p[1] ^= f(p[0]); + rounds--; + } + + for (int i = static_cast(rounds - 2); i >= 0; i -= 2) + R2(p[1], p[0], k[i + 1], k[i]); +} + +/// \brief Subkey generation function +/// \details Used for SIMON-64 with 96-bit key and 42 rounds. A template was +/// not worthwhile because all instantiations would need specialization. +/// \param key empty subkey array +/// \param k user key array +inline void SIMON64_ExpandKey_3W(word32 key[42], const word32 k[3]) +{ + const word32 c = 0xfffffffc; + word64 z = W64LIT(0x7369f885192c0ef5); + + key[0] = k[2]; key[1] = k[1]; key[2] = k[0]; + for (size_t i = 3; i<42; ++i) + { + key[i] = static_cast(c ^ (z & 1) ^ key[i - 3] ^ + rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1])); + z >>= 1; + } +} + +/// \brief Subkey generation function +/// \details Used for SIMON-64 with 128-bit key and 44 rounds. A template was +/// not worthwhile because all instantiations would need specialization. +/// \param key empty subkey array +/// \param k user key array +inline void SIMON64_ExpandKey_4W(word32 key[44], const word32 k[4]) +{ + const word32 c = 0xfffffffc; + word64 z = W64LIT(0xfc2ce51207a635db); + + key[0] = k[3]; key[1] = k[2]; key[2] = k[1]; key[3] = k[0]; + for (size_t i = 4; i<44; ++i) + { + key[i] = static_cast(c ^ (z & 1) ^ key[i - 4] ^ + rotrConstant<3>(key[i - 1]) ^ key[i - 3] ^ rotrConstant<4>(key[i - 1]) ^ + rotrConstant<1>(key[i - 3])); + z >>= 1; + } +} + +/// \brief Subkey generation function +/// \details Used for SIMON-128 with 128-bit key and 68 rounds. A template was +/// not worthwhile because all instantiations would need specialization. +/// \param key empty subkey array +/// \param k user key array +inline void SIMON128_ExpandKey_2W(word64 key[68], const word64 k[2]) +{ + const word64 c = W64LIT(0xfffffffffffffffc); + word64 z = W64LIT(0x7369f885192c0ef5); + + key[0] = k[1]; key[1] = k[0]; + for (size_t i=2; i<66; ++i) + { + key[i] = c ^ (z & 1) ^ key[i - 2] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]); + z>>=1; + } + + key[66] = c ^ 1 ^ key[64] ^ rotrConstant<3>(key[65]) ^ rotrConstant<4>(key[65]); + key[67] = c^key[65] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]); +} + +/// \brief Subkey generation function +/// \details Used for SIMON-128 with 192-bit key and 69 rounds. A template was +/// not worthwhile because all instantiations would need specialization. +/// \param key empty subkey array +/// \param k user key array +inline void SIMON128_ExpandKey_3W(word64 key[69], const word64 k[3]) +{ + const word64 c = W64LIT(0xfffffffffffffffc); + word64 z = W64LIT(0xfc2ce51207a635db); + + key[0]=k[2]; key[1]=k[1]; key[2]=k[0]; + for (size_t i=3; i<67; ++i) + { + key[i] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]); + z>>=1; + } + + key[67] = c^key[64] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]); + key[68] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[67]) ^ rotrConstant<4>(key[67]); +} + +/// \brief Subkey generation function +/// \details Used for SIMON-128 with 256-bit key and 72 rounds. A template was +/// not worthwhile because all instantiations would need specialization. +/// \param key empty subkey array +/// \param k user key array +inline void SIMON128_ExpandKey_4W(word64 key[72], const word64 k[4]) +{ + const word64 c = W64LIT(0xfffffffffffffffc); + word64 z = W64LIT(0xfdc94c3a046d678b); + + key[0]=k[3]; key[1]=k[2]; key[2]=k[1]; key[3]=k[0]; + for (size_t i=4; i<68; ++i) + { + key[i] = c ^ (z & 1) ^ key[i - 4] ^ rotrConstant<3>(key[i - 1]) ^ key[i - 3] ^ rotrConstant<4>(key[i - 1]) ^ rotrConstant<1>(key[i - 3]); + z>>=1; + } + + key[68] = c^key[64] ^ rotrConstant<3>(key[67]) ^ key[65] ^ rotrConstant<4>(key[67]) ^ rotrConstant<1>(key[65]); + key[69] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[68]) ^ key[66] ^ rotrConstant<4>(key[68]) ^ rotrConstant<1>(key[66]); + key[70] = c^key[66] ^ rotrConstant<3>(key[69]) ^ key[67] ^ rotrConstant<4>(key[69]) ^ rotrConstant<1>(key[67]); + key[71] = c^key[67] ^ rotrConstant<3>(key[70]) ^ key[68] ^ rotrConstant<4>(key[70]) ^ rotrConstant<1>(key[68]); +} + +ANONYMOUS_NAMESPACE_END + +/////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) +extern size_t SIMON128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SIMON128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOPP_SSSE3_AVAILABLE) +extern size_t SIMON128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SIMON128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +extern size_t SIMON128_Enc_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SIMON128_Dec_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +std::string SIMON64::Base::AlgorithmProvider() const +{ + return "C++"; +} + +unsigned int SIMON64::Base::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +void SIMON64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16); + CRYPTOPP_UNUSED(params); + + // Building the key schedule table requires {3,4} words workspace. + // Encrypting and decrypting requires 4 words workspace. + m_kwords = keyLength/sizeof(word32); + m_wspace.New(4U); + + // Do the endian gyrations from the paper and align pointers + typedef GetBlock KeyBlock; + KeyBlock kblk(userKey); + + switch (m_kwords) + { + case 3: + m_rkeys.New((m_rounds = 42)); + kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SIMON64_ExpandKey_3W(m_rkeys, m_wspace); + break; + case 4: + m_rkeys.New((m_rounds = 44)); + kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SIMON64_ExpandKey_4W(m_rkeys, m_wspace); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void SIMON64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do the endian gyrations from the paper and align pointers + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 42: + SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 44: + SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +void SIMON64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do the endian gyrations from the paper and align pointers + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 42: + SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 44: + SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +/////////////////////////////////////////////////////////// + +std::string SIMON128::Base::AlgorithmProvider() const +{ +#if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS) +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return "SSSE3"; +# endif +# if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; +# endif +# if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return "Altivec"; +# endif +#endif + return "C++"; +} + +unsigned int SIMON128::Base::OptimalDataAlignment() const +{ +#if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS) +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return 16; // load __m128i +# endif +# if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return 8; // load uint64x2_t +# endif +# if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return 16; // load uint64x2_p +# endif +#endif + return GetAlignmentOf(); +} + +void SIMON128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32); + CRYPTOPP_UNUSED(params); + + // Building the key schedule table requires {2,3,4} words workspace. + // Encrypting and decrypting requires 4 words workspace. + m_kwords = keyLength/sizeof(word64); + m_wspace.New(4U); + + // Do the endian gyrations from the paper and align pointers + typedef GetBlock KeyBlock; + KeyBlock kblk(userKey); + + switch (m_kwords) + { + case 2: + m_rkeys.New((m_rounds = 68)); + kblk(m_wspace[1])(m_wspace[0]); + SIMON128_ExpandKey_2W(m_rkeys, m_wspace); + break; + case 3: + m_rkeys.New((m_rounds = 69)); + kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SIMON128_ExpandKey_3W(m_rkeys, m_wspace); + break; + case 4: + m_rkeys.New((m_rounds = 72)); + kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SIMON128_ExpandKey_4W(m_rkeys, m_wspace); + break; + default: + CRYPTOPP_ASSERT(0); + } + +#if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS + + // Pre-splat the round keys for Altivec forward transformation +#if CRYPTOPP_ALTIVEC_AVAILABLE + if (IsForwardTransformation() && HasAltivec()) + { + AlignedSecBlock presplat(m_rkeys.size()*2); + for (size_t i=0, j=0; i InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 68: + SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 69: + SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 72: + SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +void SIMON128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do the endian gyrations from the paper and align pointers + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 68: + SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 69: + SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 72: + SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +#if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS) +size_t SIMON128::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return SIMON128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return SIMON128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return SIMON128_Enc_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SIMON128::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return SIMON128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return SIMON128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return SIMON128_Dec_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/simon.h b/external/ours/library/crypto/src/shared/original/simon.h new file mode 100755 index 000000000..107aae541 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simon.h @@ -0,0 +1,206 @@ +// simon.h - written and placed in the public domain by Jeffrey Walton + +/// \file simon.h +/// \brief Classes for the Simon block cipher +/// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, +/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. +/// \sa The SIMON and SPECK Families of +/// Lightweight Block Ciphers, +/// The Simon and Speck GitHub and +/// SIMON on the Crypto++ wiki. +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_SIMON_H +#define CRYPTOPP_SIMON_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || \ + CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 || \ + CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 +# ifndef CRYPTOPP_DISABLE_SIMON_SIMD +# define CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS 1 +# endif +#endif + +// Yet another SunStudio/SunCC workaround. Failed self tests +// in SSE code paths on i386 for SunStudio 12.3 and below. +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) +# undef CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SIMON block cipher information +/// \tparam L block size of the cipher, in bytes +/// \tparam D default key length, in bytes +/// \tparam N minimum key length, in bytes +/// \tparam M maximum key length, in bytes +/// \since Crypto++ 6.0 +template +struct SIMON_Info : public FixedBlockSize, VariableKeyLength +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize(Keylength) + return "SIMON-" + IntToString(L*8); + } +}; + +/// \brief SIMON block cipher base class +/// \tparam W the word type +/// \details User code should use SIMON64 or SIMON128 +/// \sa SIMON64, SIMON128, SIMON on the Crypto++ wiki +/// \since Crypto++ 6.0 +template +struct SIMON_Base +{ + virtual ~SIMON_Base() {} + SIMON_Base() : m_kwords(0), m_rounds(0) {} + + typedef SecBlock > AlignedSecBlock; + mutable AlignedSecBlock m_wspace; // workspace + AlignedSecBlock m_rkeys; // round keys + unsigned int m_kwords; // number of key words + unsigned int m_rounds; // number of rounds +}; + +/// \brief SIMON 64-bit block cipher +/// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, +/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. +/// \details SIMON64 provides 64-bit block size. The valid key sizes are 96-bit and 128-bit. +/// \sa SIMON64, SIMON128, The SIMON and SIMON +/// Families of Lightweight Block Ciphers, +/// The Simon and Speck GitHub, SIMON on the +/// Crypto++ wiki +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE SIMON64 : public SIMON_Info<8, 12, 12, 16>, public BlockCipherDocumentation +{ +public: + /// \brief SIMON64 block cipher base implementation + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : protected SIMON_Base, public BlockCipherImpl > + { + public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details AlgorithmName returns the algorithm's name as a + /// member function. + std::string AlgorithmName() const { + return StaticAlgorithmName() + (m_kwords == 0 ? "" : + "(" + IntToString(m_kwords*sizeof(word32)*8) + ")"); + } + + std::string AlgorithmProvider() const; + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const; + + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief SIMON64 encryption transformation + /// \details Enc provides the encryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief SIMON64 decryption transformation + /// \details Dec provides the decryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief SIMON 128-bit block cipher +/// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, +/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. +/// \details SIMON128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit. +/// \sa SIMON64, SIMON128, The SIMON and SIMON +/// Families of Lightweight Block Ciphers, +/// The Simon and Speck GitHub, SIMON on the +/// Crypto++ wiki +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE SIMON128 : public SIMON_Info<16, 16, 16, 32>, public BlockCipherDocumentation +{ +public: + /// \brief SIMON128 block cipher base implementation + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : protected SIMON_Base, public BlockCipherImpl > + { + public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details AlgorithmName returns the algorithm's name as a + /// member function. + std::string AlgorithmName() const { + return StaticAlgorithmName() + (m_kwords == 0 ? "" : + "(" + IntToString(m_kwords*sizeof(word64)*8) + ")"); + } + + std::string AlgorithmProvider() const; + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const; + + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief SIMON128 encryption transformation + /// \details Enc provides the encryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief SIMON128 decryption transformation + /// \details Dec provides the decryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SIMON_H diff --git a/external/ours/library/crypto/src/shared/original/simon128_simd.cpp b/external/ours/library/crypto/src/shared/original/simon128_simd.cpp new file mode 100755 index 000000000..5a0aaddf2 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simon128_simd.cpp @@ -0,0 +1,862 @@ +// simon_simd.cpp - written and placed in the public domain by Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// SSSE3, ARM NEON and ARMv8a, and Altivec instructions. A separate +// source file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#include "simon.h" +#include "misc.h" + +// Uncomment for benchmarking C++ against SSE or NEON. +// Do so in both simon.cpp and simon_simd.cpp. +// #undef CRYPTOPP_SSSE3_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_SSSE3_AVAILABLE) +# include "adv_simd.h" +# include +# include +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include "adv_simd.h" +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if defined(_M_ARM64) +# include "adv_simd.h" +#endif + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +# include "adv_simd.h" +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char SIMON128_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::vec_swap; // SunCC + +// *************************** ARM NEON ************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +// Missing from Microsoft's ARM A-32 implementation +#if defined(_MSC_VER) && !defined(_M_ARM64) +inline uint64x2_t vld1q_dup_u64(const uint64_t* ptr) +{ + return vmovq_n_u64(*ptr); +} +#endif + +template +inline T UnpackHigh64(const T& a, const T& b) +{ + const uint64x1_t x(vget_high_u64((uint64x2_t)a)); + const uint64x1_t y(vget_high_u64((uint64x2_t)b)); + return (T)vcombine_u64(x, y); +} + +template +inline T UnpackLow64(const T& a, const T& b) +{ + const uint64x1_t x(vget_low_u64((uint64x2_t)a)); + const uint64x1_t y(vget_low_u64((uint64x2_t)b)); + return (T)vcombine_u64(x, y); +} + +template +inline uint64x2_t RotateLeft64(const uint64x2_t& val) +{ + const uint64x2_t a(vshlq_n_u64(val, R)); + const uint64x2_t b(vshrq_n_u64(val, 64 - R)); + return vorrq_u64(a, b); +} + +template +inline uint64x2_t RotateRight64(const uint64x2_t& val) +{ + const uint64x2_t a(vshlq_n_u64(val, 64 - R)); + const uint64x2_t b(vshrq_n_u64(val, R)); + return vorrq_u64(a, b); +} + +#if defined(__aarch32__) || defined(__aarch64__) +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +inline uint64x2_t RotateLeft64<8>(const uint64x2_t& val) +{ + const uint8_t maskb[16] = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 }; + const uint8x16_t mask = vld1q_u8(maskb); + + return vreinterpretq_u64_u8( + vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +inline uint64x2_t RotateRight64<8>(const uint64x2_t& val) +{ + const uint8_t maskb[16] = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 }; + const uint8x16_t mask = vld1q_u8(maskb); + + return vreinterpretq_u64_u8( + vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); +} +#endif + +inline uint64x2_t SIMON128_f(const uint64x2_t& val) +{ + return veorq_u64(RotateLeft64<2>(val), + vandq_u64(RotateLeft64<1>(val), RotateLeft64<8>(val))); +} + +inline void SIMON128_Enc_Block(uint64x2_t &block0, uint64x2_t &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + + for (size_t i = 0; i < static_cast(rounds & ~1)-1; i += 2) + { + const uint64x2_t rk1 = vld1q_dup_u64(subkeys+i); + y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk1); + + const uint64x2_t rk2 = vld1q_dup_u64(subkeys+i+1); + x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk2); + } + + if (rounds & 1) + { + const uint64x2_t rk = vld1q_dup_u64(subkeys+rounds-1); + + y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk); + std::swap(x1, y1); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); +} + +inline void SIMON128_Enc_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, + uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + uint64x2_t x2 = UnpackHigh64(block2, block3); + uint64x2_t y2 = UnpackLow64(block2, block3); + uint64x2_t x3 = UnpackHigh64(block4, block5); + uint64x2_t y3 = UnpackLow64(block4, block5); + + for (size_t i = 0; i < static_cast(rounds & ~1) - 1; i += 2) + { + const uint64x2_t rk1 = vld1q_dup_u64(subkeys+i); + y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk1); + y2 = veorq_u64(veorq_u64(y2, SIMON128_f(x2)), rk1); + y3 = veorq_u64(veorq_u64(y3, SIMON128_f(x3)), rk1); + + const uint64x2_t rk2 = vld1q_dup_u64(subkeys+i+1); + x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk2); + x2 = veorq_u64(veorq_u64(x2, SIMON128_f(y2)), rk2); + x3 = veorq_u64(veorq_u64(x3, SIMON128_f(y3)), rk2); + } + + if (rounds & 1) + { + const uint64x2_t rk = vld1q_dup_u64(subkeys + rounds - 1); + + y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk); + y2 = veorq_u64(veorq_u64(y2, SIMON128_f(x2)), rk); + y3 = veorq_u64(veorq_u64(y3, SIMON128_f(x3)), rk); + std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); + block2 = UnpackLow64(y2, x2); + block3 = UnpackHigh64(y2, x2); + block4 = UnpackLow64(y3, x3); + block5 = UnpackHigh64(y3, x3); +} + +inline void SIMON128_Dec_Block(uint64x2_t &block0, uint64x2_t &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + + if (rounds & 1) + { + std::swap(x1, y1); + const uint64x2_t rk = vld1q_dup_u64(subkeys + rounds - 1); + + y1 = veorq_u64(veorq_u64(y1, rk), SIMON128_f(x1)); + rounds--; + } + + for (int i = static_cast(rounds-2); i >= 0; i -= 2) + { + const uint64x2_t rk1 = vld1q_dup_u64(subkeys+i+1); + x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk1); + + const uint64x2_t rk2 = vld1q_dup_u64(subkeys+i); + y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk2); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); +} + +inline void SIMON128_Dec_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, + uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + uint64x2_t x2 = UnpackHigh64(block2, block3); + uint64x2_t y2 = UnpackLow64(block2, block3); + uint64x2_t x3 = UnpackHigh64(block4, block5); + uint64x2_t y3 = UnpackLow64(block4, block5); + + if (rounds & 1) + { + std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); + const uint64x2_t rk = vld1q_dup_u64(subkeys + rounds - 1); + + y1 = veorq_u64(veorq_u64(y1, rk), SIMON128_f(x1)); + y2 = veorq_u64(veorq_u64(y2, rk), SIMON128_f(x2)); + y3 = veorq_u64(veorq_u64(y3, rk), SIMON128_f(x3)); + rounds--; + } + + for (int i = static_cast(rounds-2); i >= 0; i -= 2) + { + const uint64x2_t rk1 = vld1q_dup_u64(subkeys + i + 1); + x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk1); + x2 = veorq_u64(veorq_u64(x2, SIMON128_f(y2)), rk1); + x3 = veorq_u64(veorq_u64(x3, SIMON128_f(y3)), rk1); + + const uint64x2_t rk2 = vld1q_dup_u64(subkeys + i); + y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk2); + y2 = veorq_u64(veorq_u64(y2, SIMON128_f(x2)), rk2); + y3 = veorq_u64(veorq_u64(y3, SIMON128_f(x3)), rk2); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); + block2 = UnpackLow64(y2, x2); + block3 = UnpackHigh64(y2, x2); + block4 = UnpackLow64(y3, x3); + block5 = UnpackHigh64(y3, x3); +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// ***************************** IA-32 ***************************** // + +#if (CRYPTOPP_SSSE3_AVAILABLE) + +// GCC double casts, https://www.spinics.net/lists/gcchelp/msg47735.html +#ifndef DOUBLE_CAST +# define DOUBLE_CAST(x) ((double *)(void *)(x)) +#endif +#ifndef CONST_DOUBLE_CAST +# define CONST_DOUBLE_CAST(x) ((const double *)(const void *)(x)) +#endif + +inline void Swap128(__m128i& a,__m128i& b) +{ +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) + // __m128i is an unsigned long long[2], and support for swapping it was not added until C++11. + // SunCC 12.1 - 12.3 fail to consume the swap; while SunCC 12.4 consumes it without -std=c++11. + vec_swap(a, b); +#else + std::swap(a, b); +#endif +} + +template +inline __m128i RotateLeft64(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, R); +#else + return _mm_or_si128( + _mm_slli_epi64(val, R), _mm_srli_epi64(val, 64-R)); +#endif +} + +template +inline __m128i RotateRight64(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, 64-R); +#else + return _mm_or_si128( + _mm_slli_epi64(val, 64-R), _mm_srli_epi64(val, R)); +#endif +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +__m128i RotateLeft64<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, 8); +#else + const __m128i mask = _mm_set_epi8(14,13,12,11, 10,9,8,15, 6,5,4,3, 2,1,0,7); + return _mm_shuffle_epi8(val, mask); +#endif +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +__m128i RotateRight64<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, 64-8); +#else + const __m128i mask = _mm_set_epi8(8,15,14,13, 12,11,10,9, 0,7,6,5, 4,3,2,1); + return _mm_shuffle_epi8(val, mask); +#endif +} + +inline __m128i SIMON128_f(const __m128i& v) +{ + return _mm_xor_si128(RotateLeft64<2>(v), + _mm_and_si128(RotateLeft64<1>(v), RotateLeft64<8>(v))); +} + +inline void SIMON128_Enc_Block(__m128i &block0, __m128i &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + + for (size_t i = 0; i < static_cast(rounds & ~1)-1; i += 2) + { + // Round keys are pre-splated in forward direction + const __m128i rk1 = _mm_load_si128(CONST_M128_CAST(subkeys+i*2)); + y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk1); + + const __m128i rk2 = _mm_load_si128(CONST_M128_CAST(subkeys+(i+1)*2)); + x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk2); + } + + if (rounds & 1) + { + // Round keys are pre-splated in forward direction + const __m128i rk = _mm_load_si128(CONST_M128_CAST(subkeys+(rounds-1)*2)); + + y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk); + Swap128(x1, y1); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); +} + +inline void SIMON128_Enc_6_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + __m128i x2 = _mm_unpackhi_epi64(block2, block3); + __m128i y2 = _mm_unpacklo_epi64(block2, block3); + __m128i x3 = _mm_unpackhi_epi64(block4, block5); + __m128i y3 = _mm_unpacklo_epi64(block4, block5); + + for (size_t i = 0; i < static_cast(rounds & ~1) - 1; i += 2) + { + // Round keys are pre-splated in forward direction + const __m128i rk1 = _mm_load_si128(CONST_M128_CAST(subkeys+i*2)); + y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk1); + y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON128_f(x2)), rk1); + y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON128_f(x3)), rk1); + + // Round keys are pre-splated in forward direction + const __m128i rk2 = _mm_load_si128(CONST_M128_CAST(subkeys+(i+1)*2)); + x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk2); + x2 = _mm_xor_si128(_mm_xor_si128(x2, SIMON128_f(y2)), rk2); + x3 = _mm_xor_si128(_mm_xor_si128(x3, SIMON128_f(y3)), rk2); + } + + if (rounds & 1) + { + // Round keys are pre-splated in forward direction + const __m128i rk = _mm_load_si128(CONST_M128_CAST(subkeys+(rounds-1)*2)); + y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk); + y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON128_f(x2)), rk); + y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON128_f(x3)), rk); + Swap128(x1, y1); Swap128(x2, y2); Swap128(x3, y3); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); + block2 = _mm_unpacklo_epi64(y2, x2); + block3 = _mm_unpackhi_epi64(y2, x2); + block4 = _mm_unpacklo_epi64(y3, x3); + block5 = _mm_unpackhi_epi64(y3, x3); +} + +inline void SIMON128_Dec_Block(__m128i &block0, __m128i &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + + if (rounds & 1) + { + const __m128i rk = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + rounds - 1))); + + Swap128(x1, y1); + y1 = _mm_xor_si128(_mm_xor_si128(y1, rk), SIMON128_f(x1)); + rounds--; + } + + for (int i = static_cast(rounds-2); i >= 0; i -= 2) + { + const __m128i rk1 = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i+1))); + x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk1); + + const __m128i rk2 = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); + y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk2); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); +} + +inline void SIMON128_Dec_6_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + __m128i x2 = _mm_unpackhi_epi64(block2, block3); + __m128i y2 = _mm_unpacklo_epi64(block2, block3); + __m128i x3 = _mm_unpackhi_epi64(block4, block5); + __m128i y3 = _mm_unpacklo_epi64(block4, block5); + + if (rounds & 1) + { + const __m128i rk = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + rounds - 1))); + + Swap128(x1, y1); Swap128(x2, y2); Swap128(x3, y3); + y1 = _mm_xor_si128(_mm_xor_si128(y1, rk), SIMON128_f(x1)); + y2 = _mm_xor_si128(_mm_xor_si128(y2, rk), SIMON128_f(x2)); + y3 = _mm_xor_si128(_mm_xor_si128(y3, rk), SIMON128_f(x3)); + rounds--; + } + + for (int i = static_cast(rounds-2); i >= 0; i -= 2) + { + const __m128i rk1 = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + i + 1))); + x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk1); + x2 = _mm_xor_si128(_mm_xor_si128(x2, SIMON128_f(y2)), rk1); + x3 = _mm_xor_si128(_mm_xor_si128(x3, SIMON128_f(y3)), rk1); + + const __m128i rk2 = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + i))); + y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk2); + y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON128_f(x2)), rk2); + y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON128_f(x3)), rk2); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); + block2 = _mm_unpacklo_epi64(y2, x2); + block3 = _mm_unpackhi_epi64(y2, x2); + block4 = _mm_unpacklo_epi64(y3, x3); + block5 = _mm_unpackhi_epi64(y3, x3); +} + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// ***************************** Altivec ***************************** // + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + +// Altivec uses native 64-bit types on 64-bit environments, or 32-bit types +// in 32-bit environments. Speck128 will use the appropriate type for the +// environment. Functions like VecAdd64 have two overloads, one for each +// environment. The 32-bit overload treats uint32x4_p like a 64-bit type, +// and does things like perform a add with carry or subtract with borrow. + +// Speck128 on Power8 performed as expected because of 64-bit environment. +// Performance sucked on old PowerPC machines because of 32-bit environments. +// At Crypto++ 8.3 we added an implementation that operated on 32-bit words. +// Native 64-bit Speck128 performance dropped from about 4.1 to 6.3 cpb, but +// 32-bit Speck128 improved from 66.5 cpb to 10.4 cpb. Overall it was a +// good win even though we lost some performance in 64-bit environments. + +using CryptoPP::uint8x16_p; +using CryptoPP::uint32x4_p; +#if defined(_ARCH_PWR8) +using CryptoPP::uint64x2_p; +#endif + +using CryptoPP::VecAdd64; +using CryptoPP::VecSub64; +using CryptoPP::VecAnd64; +using CryptoPP::VecOr64; +using CryptoPP::VecXor64; +using CryptoPP::VecRotateLeft64; +using CryptoPP::VecRotateRight64; +using CryptoPP::VecSplatElement64; +using CryptoPP::VecLoad; +using CryptoPP::VecLoadAligned; +using CryptoPP::VecPermute; + +#if defined(_ARCH_PWR8) +#define simon128_t uint64x2_p +#else +#define simon128_t uint32x4_p +#endif + +inline simon128_t SIMON128_f(const simon128_t val) +{ + return (simon128_t)VecXor64(VecRotateLeft64<2>(val), + VecAnd64(VecRotateLeft64<1>(val), VecRotateLeft64<8>(val))); +} + +inline void SIMON128_Enc_Block(uint32x4_p &block, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + simon128_t x1 = (simon128_t)VecPermute(block, block, m1); + simon128_t y1 = (simon128_t)VecPermute(block, block, m2); + + for (size_t i = 0; i < static_cast(rounds & ~1)-1; i += 2) + { + // Round keys are pre-splated in forward direction + const word32* ptr1 = reinterpret_cast(subkeys+i*2); + const simon128_t rk1 = (simon128_t)VecLoadAligned(ptr1); + const word32* ptr2 = reinterpret_cast(subkeys+(i+1)*2); + const simon128_t rk2 = (simon128_t)VecLoadAligned(ptr2); + + y1 = VecXor64(VecXor64(y1, SIMON128_f(x1)), rk1); + x1 = VecXor64(VecXor64(x1, SIMON128_f(y1)), rk2); + } + + if (rounds & 1) + { + // Round keys are pre-splated in forward direction + const word32* ptr = reinterpret_cast(subkeys+(rounds-1)*2); + const simon128_t rk = (simon128_t)VecLoadAligned(ptr); + + y1 = VecXor64(VecXor64(y1, SIMON128_f(x1)), rk); + + std::swap(x1, y1); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + //const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + //const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block = (uint32x4_p)VecPermute(x1, y1, m3); +} + +inline void SIMON128_Dec_Block(uint32x4_p &block, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + simon128_t x1 = (simon128_t)VecPermute(block, block, m1); + simon128_t y1 = (simon128_t)VecPermute(block, block, m2); + + if (rounds & 1) + { + std::swap(x1, y1); + + const word32* ptr = reinterpret_cast(subkeys+rounds-1); + const simon128_t tk = (simon128_t)VecLoad(ptr); + const simon128_t rk = (simon128_t)VecSplatElement64<0>(tk); + + y1 = VecXor64(VecXor64(y1, rk), SIMON128_f(x1)); + rounds--; + } + + for (int i = static_cast(rounds-2); i >= 0; i -= 2) + { + const word32* ptr = reinterpret_cast(subkeys+i); + const simon128_t tk = (simon128_t)VecLoad(ptr); + const simon128_t rk1 = (simon128_t)VecSplatElement64<1>(tk); + const simon128_t rk2 = (simon128_t)VecSplatElement64<0>(tk); + + x1 = VecXor64(VecXor64(x1, SIMON128_f(y1)), rk1); + y1 = VecXor64(VecXor64(y1, SIMON128_f(x1)), rk2); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + //const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + //const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block = (uint32x4_p)VecPermute(x1, y1, m3); +} + +inline void SIMON128_Enc_6_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, uint32x4_p &block4, + uint32x4_p &block5, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + simon128_t x1 = (simon128_t)VecPermute(block0, block1, m1); + simon128_t y1 = (simon128_t)VecPermute(block0, block1, m2); + simon128_t x2 = (simon128_t)VecPermute(block2, block3, m1); + simon128_t y2 = (simon128_t)VecPermute(block2, block3, m2); + simon128_t x3 = (simon128_t)VecPermute(block4, block5, m1); + simon128_t y3 = (simon128_t)VecPermute(block4, block5, m2); + + for (size_t i = 0; i < static_cast(rounds & ~1)-1; i += 2) + { + // Round keys are pre-splated in forward direction + const word32* ptr1 = reinterpret_cast(subkeys+i*2); + const simon128_t rk1 = (simon128_t)VecLoadAligned(ptr1); + + const word32* ptr2 = reinterpret_cast(subkeys+(i+1)*2); + const simon128_t rk2 = (simon128_t)VecLoadAligned(ptr2); + + y1 = VecXor64(VecXor64(y1, SIMON128_f(x1)), rk1); + y2 = VecXor64(VecXor64(y2, SIMON128_f(x2)), rk1); + y3 = VecXor64(VecXor64(y3, SIMON128_f(x3)), rk1); + + x1 = VecXor64(VecXor64(x1, SIMON128_f(y1)), rk2); + x2 = VecXor64(VecXor64(x2, SIMON128_f(y2)), rk2); + x3 = VecXor64(VecXor64(x3, SIMON128_f(y3)), rk2); + } + + if (rounds & 1) + { + // Round keys are pre-splated in forward direction + const word32* ptr = reinterpret_cast(subkeys+(rounds-1)*2); + const simon128_t rk = (simon128_t)VecLoadAligned(ptr); + + y1 = VecXor64(VecXor64(y1, SIMON128_f(x1)), rk); + y2 = VecXor64(VecXor64(y2, SIMON128_f(x2)), rk); + y3 = VecXor64(VecXor64(y3, SIMON128_f(x3)), rk); + + std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = (uint32x4_p)VecPermute(x1, y1, m3); + block1 = (uint32x4_p)VecPermute(x1, y1, m4); + block2 = (uint32x4_p)VecPermute(x2, y2, m3); + block3 = (uint32x4_p)VecPermute(x2, y2, m4); + block4 = (uint32x4_p)VecPermute(x3, y3, m3); + block5 = (uint32x4_p)VecPermute(x3, y3, m4); +} + +inline void SIMON128_Dec_6_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, uint32x4_p &block4, + uint32x4_p &block5, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + simon128_t x1 = (simon128_t)VecPermute(block0, block1, m1); + simon128_t y1 = (simon128_t)VecPermute(block0, block1, m2); + simon128_t x2 = (simon128_t)VecPermute(block2, block3, m1); + simon128_t y2 = (simon128_t)VecPermute(block2, block3, m2); + simon128_t x3 = (simon128_t)VecPermute(block4, block5, m1); + simon128_t y3 = (simon128_t)VecPermute(block4, block5, m2); + + if (rounds & 1) + { + std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); + + const word32* ptr = reinterpret_cast(subkeys+rounds-1); + const simon128_t tk = (simon128_t)VecLoad(ptr); + const simon128_t rk = (simon128_t)VecSplatElement64<0>(tk); + + y1 = VecXor64(VecXor64(y1, rk), SIMON128_f(x1)); + y2 = VecXor64(VecXor64(y2, rk), SIMON128_f(x2)); + y3 = VecXor64(VecXor64(y3, rk), SIMON128_f(x3)); + rounds--; + } + + for (int i = static_cast(rounds-2); i >= 0; i -= 2) + { + const word32* ptr = reinterpret_cast(subkeys+i); + const simon128_t tk = (simon128_t)VecLoad(ptr); + const simon128_t rk1 = (simon128_t)VecSplatElement64<1>(tk); + const simon128_t rk2 = (simon128_t)VecSplatElement64<0>(tk); + + x1 = VecXor64(VecXor64(x1, SIMON128_f(y1)), rk1); + x2 = VecXor64(VecXor64(x2, SIMON128_f(y2)), rk1); + x3 = VecXor64(VecXor64(x3, SIMON128_f(y3)), rk1); + + y1 = VecXor64(VecXor64(y1, SIMON128_f(x1)), rk2); + y2 = VecXor64(VecXor64(y2, SIMON128_f(x2)), rk2); + y3 = VecXor64(VecXor64(y3, SIMON128_f(x3)), rk2); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = (uint32x4_p)VecPermute(x1, y1, m3); + block1 = (uint32x4_p)VecPermute(x1, y1, m4); + block2 = (uint32x4_p)VecPermute(x2, y2, m3); + block3 = (uint32x4_p)VecPermute(x2, y2, m4); + block4 = (uint32x4_p)VecPermute(x3, y3, m3); + block5 = (uint32x4_p)VecPermute(x3, y3, m4); +} + +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +// *************************** ARM NEON **************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) +size_t SIMON128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_NEON(SIMON128_Enc_Block, SIMON128_Enc_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SIMON128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_NEON(SIMON128_Dec_Block, SIMON128_Dec_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// ***************************** IA-32 ***************************** // + +#if (CRYPTOPP_SSSE3_AVAILABLE) +size_t SIMON128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_SSE(SIMON128_Enc_Block, SIMON128_Enc_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SIMON128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_SSE(SIMON128_Dec_Block, SIMON128_Dec_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// ***************************** Altivec ***************************** // + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +size_t SIMON128_Enc_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x1_ALTIVEC(SIMON128_Enc_Block, SIMON128_Enc_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SIMON128_Dec_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x1_ALTIVEC(SIMON128_Dec_Block, SIMON128_Dec_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/simple.cpp b/external/ours/library/crypto/src/shared/original/simple.cpp new file mode 100755 index 000000000..b897cc129 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simple.cpp @@ -0,0 +1,13 @@ +// simple.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "simple.h" + +NAMESPACE_BEGIN(CryptoPP) + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/simple.h b/external/ours/library/crypto/src/shared/original/simple.h new file mode 100755 index 000000000..d3047e228 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/simple.h @@ -0,0 +1,506 @@ +// simple.h - originally written and placed in the public domain by Wei Dai + +/// \file simple.h +/// \brief Classes providing basic library services. + +#ifndef CRYPTOPP_SIMPLE_H +#define CRYPTOPP_SIMPLE_H + +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4127 4189) +#endif + +#include "cryptlib.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Base class for identifying alogorithm +/// \tparam BASE base class from which to derive +/// \tparam DERIVED class which to clone +template +class CRYPTOPP_NO_VTABLE ClonableImpl : public BASE +{ +public: + /// \brief Create a copy of this object + /// \return a copy of this object + /// \details The caller is responsible for freeing the object. + Clonable * Clone() const {return new DERIVED(*static_cast(this));} +}; + +/// \brief Base class information +/// \tparam BASE an Algorithm derived class +/// \tparam ALGORITHM_INFO an Algorithm derived class +/// \details AlgorithmImpl provides StaticAlgorithmName from the template parameter BASE +template +class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE +{ +public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static member function. + /// The name is taken from information provided by BASE. + static std::string CRYPTOPP_API StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();} + /// \brief The algorithm name + /// \return the algorithm name + /// \details AlgorithmName returns the algorithm's name as a member function. + /// The name is acquired by calling StaticAlgorithmName. + std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();} +}; + +/// \brief Exception thrown when an invalid key length is encountered +class CRYPTOPP_DLL InvalidKeyLength : public InvalidArgument +{ +public: + /// \brief Construct an InvalidKeyLength + /// \param algorithm the Algorithm associated with the exception + /// \param length the key size associated with the exception + explicit InvalidKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid key length") {} +}; + +/// \brief Exception thrown when an invalid number of rounds is encountered +class CRYPTOPP_DLL InvalidRounds : public InvalidArgument +{ +public: + /// \brief Construct an InvalidRounds + /// \param algorithm the Algorithm associated with the exception + /// \param rounds the number of rounds associated with the exception + explicit InvalidRounds(const std::string &algorithm, unsigned int rounds) : InvalidArgument(algorithm + ": " + IntToString(rounds) + " is not a valid number of rounds") {} +}; + +/// \brief Exception thrown when an invalid block size is encountered +class CRYPTOPP_DLL InvalidBlockSize : public InvalidArgument +{ +public: + /// \brief Construct an InvalidBlockSize + /// \param algorithm the Algorithm associated with the exception + /// \param length the block size associated with the exception + explicit InvalidBlockSize(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid block size") {} +}; + +/// \brief Exception thrown when an invalid derived key length is encountered +class CRYPTOPP_DLL InvalidDerivedKeyLength : public InvalidArgument +{ +public: + /// \brief Construct an InvalidDerivedKeyLength + /// \param algorithm the Algorithm associated with the exception + /// \param length the size associated with the exception + explicit InvalidDerivedKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid derived key length") {} +}; + +/// \brief Exception thrown when an invalid personalization string length is encountered +class CRYPTOPP_DLL InvalidPersonalizationLength : public InvalidArgument +{ +public: + /// \brief Construct an InvalidPersonalizationLength + /// \param algorithm the Algorithm associated with the exception + /// \param length the personalization size associated with the exception + explicit InvalidPersonalizationLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid salt length") {} +}; + +/// \brief Exception thrown when an invalid salt length is encountered +class CRYPTOPP_DLL InvalidSaltLength : public InvalidArgument +{ +public: + /// \brief Construct an InvalidSaltLength + /// \param algorithm the Algorithm associated with the exception + /// \param length the salt size associated with the exception + explicit InvalidSaltLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid salt length") {} +}; + +// ***************************** + +/// \brief Base class for bufferless filters +/// \tparam T the class or type +template +class CRYPTOPP_NO_VTABLE Bufferless : public T +{ +public: + /// \brief Flushes data buffered by this object, without signal propagation + /// \param hardFlush indicates whether all data should be flushed + /// \param blocking specifies whether the object should block when processing input + /// \note hardFlush must be used with care + bool IsolatedFlush(bool hardFlush, bool blocking) + {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); return false;} +}; + +/// \brief Base class for unflushable filters +/// \tparam T the class or type +template +class CRYPTOPP_NO_VTABLE Unflushable : public T +{ +public: + /// \brief Flush buffered input and/or output, with signal propagation + /// \param completeFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the Flush() + /// signal should be passed + /// \param blocking specifies whether the object should block when processing + /// input + /// \details propagation count includes this object. Setting propagation to + /// 1 means this object only. Setting propagation to -1 + /// means unlimited propagation. + /// \note Hard flushes must be used with care. It means try to process and + /// output everything, even if there may not be enough data to complete the + /// action. For example, hard flushing a HexDecoder would cause an error if + /// you do it after inputing an odd number of hex encoded characters. + /// \note For some types of filters, like ZlibDecompressor, hard flushes can + /// only be done at "synchronization points". These synchronization points + /// are positions in the data stream that are created by hard flushes on the + /// corresponding reverse filters, in this example ZlibCompressor. This is + /// useful when zlib compressed data is moved across a network in packets + /// and compression state is preserved across packets, as in the SSH2 protocol. + bool Flush(bool completeFlush, int propagation=-1, bool blocking=true) + {return ChannelFlush(DEFAULT_CHANNEL, completeFlush, propagation, blocking);} + + /// \brief Flushes data buffered by this object, without signal propagation + /// \param hardFlush indicates whether all data should be flushed + /// \param blocking specifies whether the object should block when processing input + /// \note hardFlush must be used with care + bool IsolatedFlush(bool hardFlush, bool blocking) + {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); CRYPTOPP_ASSERT(false); return false;} + + /// \brief Flush buffered input and/or output on a channel + /// \param channel the channel to flush the data + /// \param hardFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the ChannelFlush() + /// signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true of the Flush was successful + /// \details propagation count includes this object. Setting propagation to + /// 1 means this object only. Setting propagation to -1 means + /// unlimited propagation. + bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) + { + if (hardFlush && !InputBufferIsEmpty()) + throw CannotFlush("Unflushable: this object has buffered input that cannot be flushed"); + else + { + BufferedTransformation *attached = this->AttachedTransformation(); + return attached && propagation ? attached->ChannelFlush(channel, hardFlush, propagation-1, blocking) : false; + } + } + +protected: + virtual bool InputBufferIsEmpty() const {return false;} +}; + +/// \brief Base class for input rejecting filters +/// \tparam T the class or type +/// \details T should be a BufferedTransformation derived class +template +class CRYPTOPP_NO_VTABLE InputRejecting : public T +{ +public: + struct InputRejected : public NotImplemented + {InputRejected() : NotImplemented("BufferedTransformation: this object doesn't allow input") {}}; + + /// \name INPUT + //@{ + + /// \brief Input a byte array for processing + /// \param inString the byte array to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \throw InputRejected + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + /// \details Internally, the default implementation throws InputRejected. + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();} + //@} + + /// \name SIGNALS + //@{ + + /// \brief Flushes data buffered by this object, without signal propagation + /// \param hardFlush indicates whether all data should be flushed + /// \param blocking specifies whether the object should block when processing input + /// \note hardFlush must be used with care + bool IsolatedFlush(bool hardFlush, bool blocking) + {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); return false;} + + /// \brief Marks the end of a series of messages, without signal propagation + /// \param blocking specifies whether the object should block when completing the processing on + /// the current series of messages + /// \return true if the message was successful, false otherwise + bool IsolatedMessageSeriesEnd(bool blocking) + {CRYPTOPP_UNUSED(blocking); throw InputRejected();} + + /// \brief Input multiple bytes for processing on a channel. + /// \param channel the channel to process the data. + /// \param inString the byte buffer to process. + /// \param length the size of the string, in bytes. + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + size_t ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking) + {CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); + CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();} + + /// \brief Marks the end of a series of messages on a channel + /// \param channel the channel to signal the end of a series of messages + /// \param messageEnd the number of attached transformations the ChannelMessageSeriesEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true if the message was successful, false otherwise + /// \details Each object that receives the signal will perform its processing, decrement + /// propagation, and then pass the signal on to attached transformations if the value is not 0. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note There should be a MessageEnd() immediately before MessageSeriesEnd(). + bool ChannelMessageSeriesEnd(const std::string& channel, int messageEnd, bool blocking) + {CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();} + //@} +}; + +/// \brief Interface for custom flush signals propagation +/// \tparam T BufferedTransformation derived class +template +class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T +{ +public: + /// \name SIGNALS + //@{ + + /// \brief Flush buffered input and/or output, with signal propagation + /// \param hardFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the Flush() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note Hard flushes must be used with care. It means try to process and output everything, even if + /// there may not be enough data to complete the action. For example, hard flushing a HexDecoder + /// would cause an error if you do it after inputing an odd number of hex encoded characters. + /// \note For some types of filters, like ZlibDecompressor, hard flushes can only + /// be done at "synchronization points". These synchronization points are positions in the data + /// stream that are created by hard flushes on the corresponding reverse filters, in this + /// example ZlibCompressor. This is useful when zlib compressed data is moved across a + /// network in packets and compression state is preserved across packets, as in the SSH2 protocol. + virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0; + + //@} + +private: + bool IsolatedFlush(bool hardFlush, bool blocking) + {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); CRYPTOPP_ASSERT(false); return false;} +}; + +/// \brief Interface for custom flush signals +/// \tparam T BufferedTransformation derived class +template +class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation +{ +public: + /// \brief Initialize or reinitialize this object, with signal propagation + /// \param parameters a set of NameValuePairs to initialize or reinitialize this object + /// \param propagation the number of attached transformations the Initialize() signal should be passed + /// \details Initialize() is used to initialize or reinitialize an object using a variable number of + /// arbitrarily typed arguments. The function avoids the need for multiple constructors providing + /// all possible combintations of configurable parameters. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1) =0; + +private: + void IsolatedInitialize(const NameValuePairs ¶meters) + {CRYPTOPP_UNUSED(parameters); CRYPTOPP_ASSERT(false);} +}; + +/// \brief Multiple channels support for custom signal processing +/// \tparam T the class or type +/// \details T should be a BufferedTransformation derived class +template +class CRYPTOPP_NO_VTABLE Multichannel : public CustomFlushPropagation +{ +public: + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) + {return this->ChannelFlush(DEFAULT_CHANNEL, hardFlush, propagation, blocking);} + + /// \brief Marks the end of a series of messages, with signal propagation + /// \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \details Each object that receives the signal will perform its processing, decrement + /// propagation, and then pass the signal on to attached transformations if the value is not 0. + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + /// \note There should be a MessageEnd() immediately before MessageSeriesEnd(). + bool MessageSeriesEnd(int propagation=-1, bool blocking=true) + {return this->ChannelMessageSeriesEnd(DEFAULT_CHANNEL, propagation, blocking);} + + /// \brief Request space which can be written into by the caller + /// \param size the requested size of the buffer + /// \details The purpose of this method is to help avoid extra memory allocations. + /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, + /// size is the requested size of the buffer. When the call returns, size is the size of + /// the array returned to the caller. + /// \details The base class implementation sets size to 0 and returns NULL. + /// \note Some objects, like ArraySink, cannot create a space because its fixed. In the case of + /// an ArraySink, the pointer to the array is returned and the size is remaining size. + byte * CreatePutSpace(size_t &size) + {return this->ChannelCreatePutSpace(DEFAULT_CHANNEL, size);} + + /// \brief Input multiple bytes for processing + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + /// \details Derived classes must implement Put2(). + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + {return this->ChannelPut2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);} + + /// \brief Input multiple bytes that may be modified by callee. + /// \param inString the byte buffer to process. + /// \param length the size of the string, in bytes. + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + /// \details Internally, PutModifiable2() calls Put2(). + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) + {return this->ChannelPutModifiable2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);} + + // void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) + // {PropagateMessageSeriesEnd(propagation, channel);} + + /// \brief Request space which can be written into by the caller + /// \param channel the channel to process the data + /// \param size the requested size of the buffer + /// \return a pointer to a memory block with length size + /// \details The purpose of this method is to help avoid extra memory allocations. + /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made, + /// size is the requested size of the buffer. When the call returns, size is the size of + /// the array returned to the caller. + /// \details The base class implementation sets size to 0 and returns NULL. + /// \note Some objects, like ArraySink(), cannot create a space because its fixed. In the case of + /// an ArraySink(), the pointer to the array is returned and the size is remaining size. + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) + {CRYPTOPP_UNUSED(channel); size = 0; return NULLPTR;} + + /// \brief Input multiple bytes that may be modified by callee on a channel + /// \param channel the channel to process the data. + /// \param inString the byte buffer to process + /// \param length the size of the string, in bytes + /// \return true if all bytes were processed, false otherwise. + bool ChannelPutModifiable(const std::string &channel, byte *inString, size_t length) + {this->ChannelPut(channel, inString, length); return false;} + + /// \brief Input multiple bytes for processing on a channel. + /// \param channel the channel to process the data. + /// \param begin the byte buffer to process. + /// \param length the size of the string, in bytes. + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one. + /// \param blocking specifies whether the object should block when processing input. + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) =0; + + /// \brief Input multiple bytes that may be modified by callee on a channel + /// \param channel the channel to process the data + /// \param begin the byte buffer to process + /// \param length the size of the string, in bytes + /// \param messageEnd means how many filters to signal MessageEnd() to, including this one + /// \param blocking specifies whether the object should block when processing input + /// \return the number of bytes that remain to be processed (i.e., bytes not processed) + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + {return ChannelPut2(channel, begin, length, messageEnd, blocking);} + + /// \brief Flush buffered input and/or output on a channel + /// \param channel the channel to flush the data + /// \param hardFlush is used to indicate whether all data should be flushed + /// \param propagation the number of attached transformations the ChannelFlush() signal should be passed + /// \param blocking specifies whether the object should block when processing input + /// \return true of the Flush was successful + /// \details propagation count includes this object. Setting propagation to 1 means this + /// object only. Setting propagation to -1 means unlimited propagation. + virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) =0; +}; + +/// \brief Provides auto signaling support +/// \tparam T BufferedTransformation derived class +template +class CRYPTOPP_NO_VTABLE AutoSignaling : public T +{ +public: + /// \brief Construct an AutoSignaling + /// \param propagation the propagation count + AutoSignaling(int propagation=-1) : m_autoSignalPropagation(propagation) {} + + /// \brief Set propagation of automatically generated and transferred signals + /// \param propagation then new value + /// \details Setting propagation to 0 means do not automatically generate signals. Setting + /// propagation to -1 means unlimited propagation. + void SetAutoSignalPropagation(int propagation) + {m_autoSignalPropagation = propagation;} + + /// \brief Retrieve automatic signal propagation value + /// \return the number of attached transformations the signal is propagated to. 0 indicates + /// the signal is only witnessed by this object + int GetAutoSignalPropagation() const + {return m_autoSignalPropagation;} + +private: + int m_autoSignalPropagation; +}; + +/// \brief Acts as a Source for pre-existing, static data +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Store : public AutoSignaling > +{ +public: + /// \brief Construct a Store + Store() : m_messageEnd(false) {} + + void IsolatedInitialize(const NameValuePairs ¶meters) + { + m_messageEnd = false; + StoreInitialize(parameters); + } + + unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;} + bool GetNextMessage(); + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; + +protected: + virtual void StoreInitialize(const NameValuePairs ¶meters) =0; + + bool m_messageEnd; +}; + +/// \brief Implementation of BufferedTransformation's attachment interface +/// \details Sink is a cornerstone of the Pipeline trinitiy. Data flows from +/// Sources, through Filters, and then terminates in Sinks. The difference +/// between a Source and Filter is a Source \a pumps data, while a Filter does +/// not. The difference between a Filter and a Sink is a Filter allows an +/// attached transformation, while a Sink does not. +/// \details A Sink doesnot produce any retrievable output. +/// \details See the discussion of BufferedTransformation in cryptlib.h for +/// more details. +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Sink : public BufferedTransformation +{ +public: + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) + {CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(transferBytes); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking); transferBytes = 0; return 0;} + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const + {CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(end); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking); return 0;} +}; + +/// \brief Acts as an input discarding Filter or Sink +/// \details The BitBucket discards all input and returns 0 to the caller +/// to indicate all data was processed. +class CRYPTOPP_DLL BitBucket : public Bufferless +{ +public: + std::string AlgorithmName() const {return "BitBucket";} + void IsolatedInitialize(const NameValuePairs ¶ms) + {CRYPTOPP_UNUSED(params);} + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); return 0;} +}; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/siphash.h b/external/ours/library/crypto/src/shared/original/siphash.h new file mode 100755 index 000000000..4ffe1b50d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/siphash.h @@ -0,0 +1,313 @@ +// siphash.h - written and placed in public domain by Jeffrey Walton. + +/// \file siphash.h +/// \brief Classes for SipHash message authentication code +/// \details SipHash computes a 64-bit or 128-bit message authentication code from a variable-length +/// message and 128-bit secret key. It was designed to be efficient even for short inputs, with +/// performance comparable to non-cryptographic hash functions. +/// \details To create a SipHash-2-4 object with a 64-bit MAC use code similar to the following. +///
  SecByteBlock key(16);
+///   prng.GenerateBlock(key, key.size());
+///
+///   SipHash<2,4,false> hash(key, key.size());
+///   hash.Update(...);
+///   hash.Final(...);
+/// \details To create a SipHash-2-4 object with a 128-bit MAC use code similar to the following. +///
  SecByteBlock key(16);
+///   prng.GenerateBlock(key, key.size());
+///
+///   SipHash<2,4,true> hash(key, key.size());
+///   hash.Update(...);
+///   hash.Final(...);
+/// \sa Jean-Philippe Aumasson and Daniel J. Bernstein SipHash: +/// a fast short-input PRF +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_SIPHASH_H +#define CRYPTOPP_SIPHASH_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SipHash message authentication code information +/// \tparam T_128bit flag indicating 128-bit (true) versus 64-bit (false) digest size +template +class SipHash_Info : public FixedKeyLength<16> +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SipHash";} + CRYPTOPP_CONSTANT(DIGESTSIZE = (T_128bit ? 16 : 8)); +}; + +/// \brief SipHash message authentication code base class +/// \tparam C the number of compression rounds +/// \tparam D the number of finalization rounds +/// \tparam T_128bit flag indicating 128-bit (true) versus 64-bit (false) digest size +template +class SipHash_Base : public MessageAuthenticationCode, public SipHash_Info +{ +public: + static std::string StaticAlgorithmName() { + return std::string(SipHash_Info::StaticAlgorithmName())+"-"+IntToString(C)+"-"+IntToString(D); + } + + virtual ~SipHash_Base() {} + + SipHash_Base() : m_idx(0) {} + + virtual unsigned int DigestSize() const + {return SipHash_Info::DIGESTSIZE;} + virtual size_t MinKeyLength() const + {return SipHash_Info::MIN_KEYLENGTH;} + virtual size_t MaxKeyLength() const + {return SipHash_Info::MAX_KEYLENGTH;} + virtual size_t DefaultKeyLength() const + {return SipHash_Info::DEFAULT_KEYLENGTH;} + virtual size_t GetValidKeyLength(size_t keylength) const + {CRYPTOPP_UNUSED(keylength); return SipHash_Info::DEFAULT_KEYLENGTH;} + virtual IV_Requirement IVRequirement() const + {return SimpleKeyingInterface::NOT_RESYNCHRONIZABLE;} + virtual unsigned int IVSize() const + {return 0;} + virtual unsigned int OptimalBlockSize() const + {return sizeof(word64);} + virtual unsigned int OptimalDataAlignment () const + {return GetAlignmentOf();} + + virtual void Update(const byte *input, size_t length); + virtual void TruncatedFinal(byte *digest, size_t digestSize); + +protected: + + virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + virtual void Restart(); + + inline void SIPROUND() + { + m_v[0] += m_v[1]; + m_v[1] = rotlConstant<13>(m_v[1]); + m_v[1] ^= m_v[0]; + m_v[0] = rotlConstant<32>(m_v[0]); + m_v[2] += m_v[3]; + m_v[3] = rotlConstant<16>(m_v[3]); + m_v[3] ^= m_v[2]; + m_v[0] += m_v[3]; + m_v[3] = rotlConstant<21>(m_v[3]); + m_v[3] ^= m_v[0]; + m_v[2] += m_v[1]; + m_v[1] = rotlConstant<17>(m_v[1]); + m_v[1] ^= m_v[2]; + m_v[2] = rotlConstant<32>(m_v[2]); + } + +private: + FixedSizeSecBlock m_v; + FixedSizeSecBlock m_k; + FixedSizeSecBlock m_b; + + // Tail bytes + FixedSizeSecBlock m_acc; + size_t m_idx; +}; + +/// \brief SipHash message authentication code +/// \tparam C the number of compression rounds +/// \tparam D the number of finalization rounds +/// \tparam T_128bit flag indicating 128-bit (true) versus 64-bit (false) digest size +/// \details SipHash computes a 64-bit or 128-bit message authentication code from a variable-length +/// message and 128-bit secret key. It was designed to be efficient even for short inputs, with +/// performance comparable to non-cryptographic hash functions. +/// \details To create a SipHash-2-4 object with a 64-bit MAC use code similar to the following. +///
  SecByteBlock key(16);
+///   prng.GenerateBlock(key, key.size());
+///
+///   SipHash<2,4,false> hash(key, key.size());
+///   hash.Update(...);
+///   hash.Final(...);
+/// \details To create a SipHash-2-4 object with a 128-bit MAC use code similar to the following. +///
  SecByteBlock key(16);
+///   prng.GenerateBlock(key, key.size());
+///
+///   SipHash<2,4,true> hash(key, key.size());
+///   hash.Update(...);
+///   hash.Final(...);
+/// \sa Jean-Philippe Aumasson and Daniel J. Bernstein SipHash: +/// a fast short-input PRF +/// \since Crypto++ 6.0 +template +class SipHash : public SipHash_Base +{ +public: + /// \brief Create a SipHash + SipHash() + {this->UncheckedSetKey(NULLPTR, 0, g_nullNameValuePairs);} + /// \brief Create a SipHash + /// \param key a byte array used to key the cipher + /// \param length the size of the byte array, in bytes + SipHash(const byte *key, unsigned int length) + {this->ThrowIfInvalidKeyLength(length); + this->UncheckedSetKey(key, length, g_nullNameValuePairs);} +}; + +template +void SipHash_Base::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT((input && length) || !length); + if (!length) return; + + if (m_idx) + { + size_t head = STDMIN(size_t(8U-m_idx), length); + memcpy(m_acc+m_idx, input, head); + m_idx += head; input += head; length -= head; + + if (m_idx == 8) + { + word64 m = GetWord(true, LITTLE_ENDIAN_ORDER, m_acc); + m_v[3] ^= m; + for (unsigned int i = 0; i < C; ++i) + SIPROUND(); + + m_v[0] ^= m; + m_b[0] += 8; + + m_idx = 0; + } + } + + while (length >= 8) + { + word64 m = GetWord(false, LITTLE_ENDIAN_ORDER, input); + m_v[3] ^= m; + for (unsigned int i = 0; i < C; ++i) + SIPROUND(); + + m_v[0] ^= m; + m_b[0] += 8; + + input += 8; + length -= 8; + } + + CRYPTOPP_ASSERT(length < 8); + size_t tail = length % 8; + if (tail) + { + memcpy(m_acc+m_idx, input, tail); + m_idx += tail; + } +} + +template +void SipHash_Base::TruncatedFinal(byte *digest, size_t digestSize) +{ + CRYPTOPP_ASSERT(digest); // Pointer is valid + + ThrowIfInvalidTruncatedSize(digestSize); + + // The high octet holds length and is digested mod 256 + m_b[0] += m_idx; m_b[0] <<= 56U; + switch (m_idx) + { + case 7: + m_b[0] |= ((word64)m_acc[6]) << 48; + // fall through + case 6: + m_b[0] |= ((word64)m_acc[5]) << 40; + // fall through + case 5: + m_b[0] |= ((word64)m_acc[4]) << 32; + // fall through + case 4: + m_b[0] |= ((word64)m_acc[3]) << 24; + // fall through + case 3: + m_b[0] |= ((word64)m_acc[2]) << 16; + // fall through + case 2: + m_b[0] |= ((word64)m_acc[1]) << 8; + // fall through + case 1: + m_b[0] |= ((word64)m_acc[0]); + // fall through + case 0: + break; + } + + m_v[3] ^= m_b[0]; + + for (unsigned int i=0; i::DIGESTSIZE)); + Restart(); +} + +template +void SipHash_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + if (key && length) + { + m_k[0] = GetWord(false, LITTLE_ENDIAN_ORDER, key); + m_k[1] = GetWord(false, LITTLE_ENDIAN_ORDER, key+8); + } + else + { + // Avoid Coverity finding + m_k[0] = m_k[1] = 0; + } + Restart(); +} + +template +void SipHash_Base::Restart () +{ + m_v[0] = W64LIT(0x736f6d6570736575); + m_v[1] = W64LIT(0x646f72616e646f6d); + m_v[2] = W64LIT(0x6c7967656e657261); + m_v[3] = W64LIT(0x7465646279746573); + + m_v[3] ^= m_k[1]; + m_v[2] ^= m_k[0]; + m_v[1] ^= m_k[1]; + m_v[0] ^= m_k[0]; + + if (T_128bit) + { + m_v[1] ^= 0xee; + } + + m_idx = 0; + m_b[0] = 0; +} + +NAMESPACE_END + +#endif // CRYPTOPP_SIPHASH_H diff --git a/external/ours/library/crypto/src/shared/original/skipjack.cpp b/external/ours/library/crypto/src/shared/original/skipjack.cpp new file mode 100755 index 000000000..d3f59ff71 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/skipjack.cpp @@ -0,0 +1,202 @@ +// skipjack.cpp - modified by Wei Dai from Paulo Barreto's skipjack32.c, +// which is public domain according to his web site. + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "skipjack.h" + +/* + * Optimized implementation of SKIPJACK algorithm + * + * originally written by Panu Rissanen 1998.06.24 + * optimized by Mark Tillotson 1998.06.25 + * optimized by Paulo Barreto 1998.06.30 + */ + +NAMESPACE_BEGIN(CryptoPP) + +/** + * The F-table byte permutation (see description of the G-box permutation) + */ +const byte SKIPJACK::Base::fTable[256] = { + 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, + 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, + 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, + 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, + 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, + 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, + 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, + 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, + 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, + 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, + 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, + 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, + 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, + 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, + 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, + 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 +}; + +/** + * The key-dependent permutation G on V^16 is a four-round Feistel network. + * The round function is a fixed byte-substitution table (permutation on V^8), + * the F-table. Each round of G incorporates a single byte from the key. + */ +#define g(tab, w, i, j, k, l) \ +{ \ + w ^= (word)tab[i*256 + (w & 0xff)] << 8; \ + w ^= (word)tab[j*256 + (w >> 8)]; \ + w ^= (word)tab[k*256 + (w & 0xff)] << 8; \ + w ^= (word)tab[l*256 + (w >> 8)]; \ +} + +#define g0(tab, w) g(tab, w, 0, 1, 2, 3) +#define g1(tab, w) g(tab, w, 4, 5, 6, 7) +#define g2(tab, w) g(tab, w, 8, 9, 0, 1) +#define g3(tab, w) g(tab, w, 2, 3, 4, 5) +#define g4(tab, w) g(tab, w, 6, 7, 8, 9) + +/** + * The inverse of the G permutation. + */ +#define h(tab, w, i, j, k, l) \ +{ \ + w ^= (word)tab[l*256 + (w >> 8)]; \ + w ^= (word)tab[k*256 + (w & 0xff)] << 8; \ + w ^= (word)tab[j*256 + (w >> 8)]; \ + w ^= (word)tab[i*256 + (w & 0xff)] << 8; \ +} + +#define h0(tab, w) h(tab, w, 0, 1, 2, 3) +#define h1(tab, w) h(tab, w, 4, 5, 6, 7) +#define h2(tab, w) h(tab, w, 8, 9, 0, 1) +#define h3(tab, w) h(tab, w, 2, 3, 4, 5) +#define h4(tab, w) h(tab, w, 6, 7, 8, 9) + +/** + * Preprocess a user key into a table to save an XOR at each F-table access. + */ +void SKIPJACK::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + /* tab[i][c] = fTable[c ^ key[i]] */ + int i; + for (i = 0; i < 10; i++) { + byte *t = tab+i*256, k = key[9-i]; + int c; + for (c = 0; c < 256; c++) { + t[c] = fTable[c ^ k]; + } + } +} + +typedef BlockGetAndPut Block; + +/** + * Encrypt a single block of data. + */ +void SKIPJACK::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 w1, w2, w3, w4; + Block::Get(inBlock)(w4)(w3)(w2)(w1); + + /* stepping rule A: */ + g0(tab, w1); w4 ^= w1 ^ 1; + g1(tab, w4); w3 ^= w4 ^ 2; + g2(tab, w3); w2 ^= w3 ^ 3; + g3(tab, w2); w1 ^= w2 ^ 4; + g4(tab, w1); w4 ^= w1 ^ 5; + g0(tab, w4); w3 ^= w4 ^ 6; + g1(tab, w3); w2 ^= w3 ^ 7; + g2(tab, w2); w1 ^= w2 ^ 8; + + /* stepping rule B: */ + w2 ^= w1 ^ 9; g3(tab, w1); + w1 ^= w4 ^ 10; g4(tab, w4); + w4 ^= w3 ^ 11; g0(tab, w3); + w3 ^= w2 ^ 12; g1(tab, w2); + w2 ^= w1 ^ 13; g2(tab, w1); + w1 ^= w4 ^ 14; g3(tab, w4); + w4 ^= w3 ^ 15; g4(tab, w3); + w3 ^= w2 ^ 16; g0(tab, w2); + + /* stepping rule A: */ + g1(tab, w1); w4 ^= w1 ^ 17; + g2(tab, w4); w3 ^= w4 ^ 18; + g3(tab, w3); w2 ^= w3 ^ 19; + g4(tab, w2); w1 ^= w2 ^ 20; + g0(tab, w1); w4 ^= w1 ^ 21; + g1(tab, w4); w3 ^= w4 ^ 22; + g2(tab, w3); w2 ^= w3 ^ 23; + g3(tab, w2); w1 ^= w2 ^ 24; + + /* stepping rule B: */ + w2 ^= w1 ^ 25; g4(tab, w1); + w1 ^= w4 ^ 26; g0(tab, w4); + w4 ^= w3 ^ 27; g1(tab, w3); + w3 ^= w2 ^ 28; g2(tab, w2); + w2 ^= w1 ^ 29; g3(tab, w1); + w1 ^= w4 ^ 30; g4(tab, w4); + w4 ^= w3 ^ 31; g0(tab, w3); + w3 ^= w2 ^ 32; g1(tab, w2); + + Block::Put(xorBlock, outBlock)(w4)(w3)(w2)(w1); +} + +/** + * Decrypt a single block of data. + */ +void SKIPJACK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 w1, w2, w3, w4; + Block::Get(inBlock)(w4)(w3)(w2)(w1); + + /* stepping rule A: */ + h1(tab, w2); w3 ^= w2 ^ 32; + h0(tab, w3); w4 ^= w3 ^ 31; + h4(tab, w4); w1 ^= w4 ^ 30; + h3(tab, w1); w2 ^= w1 ^ 29; + h2(tab, w2); w3 ^= w2 ^ 28; + h1(tab, w3); w4 ^= w3 ^ 27; + h0(tab, w4); w1 ^= w4 ^ 26; + h4(tab, w1); w2 ^= w1 ^ 25; + + /* stepping rule B: */ + w1 ^= w2 ^ 24; h3(tab, w2); + w2 ^= w3 ^ 23; h2(tab, w3); + w3 ^= w4 ^ 22; h1(tab, w4); + w4 ^= w1 ^ 21; h0(tab, w1); + w1 ^= w2 ^ 20; h4(tab, w2); + w2 ^= w3 ^ 19; h3(tab, w3); + w3 ^= w4 ^ 18; h2(tab, w4); + w4 ^= w1 ^ 17; h1(tab, w1); + + /* stepping rule A: */ + h0(tab, w2); w3 ^= w2 ^ 16; + h4(tab, w3); w4 ^= w3 ^ 15; + h3(tab, w4); w1 ^= w4 ^ 14; + h2(tab, w1); w2 ^= w1 ^ 13; + h1(tab, w2); w3 ^= w2 ^ 12; + h0(tab, w3); w4 ^= w3 ^ 11; + h4(tab, w4); w1 ^= w4 ^ 10; + h3(tab, w1); w2 ^= w1 ^ 9; + + /* stepping rule B: */ + w1 ^= w2 ^ 8; h2(tab, w2); + w2 ^= w3 ^ 7; h1(tab, w3); + w3 ^= w4 ^ 6; h0(tab, w4); + w4 ^= w1 ^ 5; h4(tab, w1); + w1 ^= w2 ^ 4; h3(tab, w2); + w2 ^= w3 ^ 3; h2(tab, w3); + w3 ^= w4 ^ 2; h1(tab, w4); + w4 ^= w1 ^ 1; h0(tab, w1); + + Block::Put(xorBlock, outBlock)(w4)(w3)(w2)(w1); +} + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/skipjack.h b/external/ours/library/crypto/src/shared/original/skipjack.h new file mode 100755 index 000000000..f158005aa --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/skipjack.h @@ -0,0 +1,80 @@ +// skipjack.h - originally written and placed in the public domain by Wei Dai + +/// \file skipjack.h +/// \brief Classes for the SKIPJACK block cipher +/// \details The Crypto++ implementation conforms to SKIPJACK and KEA +/// Algorithm Specifications published by NIST in May 1998. The library passes +/// known answer tests available in NIST SP800-17, Table 6, pp. 140-42. +/// \sa SKIPJACK +/// and KEA Algorithm Specifications (May 1998), +/// SKIPJACK on the +// Crypto++ wiki + +#ifndef CRYPTOPP_SKIPJACK_H +#define CRYPTOPP_SKIPJACK_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SKIPJACK block cipher information +struct SKIPJACK_Info : public FixedBlockSize<8>, public FixedKeyLength<10> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "SKIPJACK";} +}; + +/// \brief SKIPJACK block cipher +/// \details The Crypto++ implementation conforms to SKIPJACK and KEA +/// Algorithm Specifications published by NIST in May 1998. The library passes +/// known answer tests available in NIST SP800-17, Table 6, pp. 140-42. +/// \sa SKIPJACK +/// and KEA Algorithm Specifications (May 1998), +/// SKIPJACK on the +/// Crypto++ wiki +class SKIPJACK : public SKIPJACK_Info, public BlockCipherDocumentation +{ + /// \brief SKIPJACK block cipher default operation + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + protected: + static const byte fTable[256]; + + FixedSizeSecBlock tab; + }; + + /// \brief SKIPJACK block cipher encryption operation + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Se[256]; + static const word32 Te[4][256]; + }; + + /// \brief SKIPJACK block cipher decryption operation + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Sd[256]; + static const word32 Td[4][256]; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SKIPJACK::Encryption SKIPJACKEncryption; +typedef SKIPJACK::Decryption SKIPJACKDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/sm3.cpp b/external/ours/library/crypto/src/shared/original/sm3.cpp new file mode 100755 index 000000000..bf01dd53f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sm3.cpp @@ -0,0 +1,255 @@ +// sm3.cpp - written and placed in the public domain by Jeffrey Walton and Han Lulu +// Based on the specification provided by Sean Shen and Xiaodong Lee. +// Based on code by Krzysztof Kwiatkowski and Jack Lloyd. +// Also see https://tools.ietf.org/html/draft-shen-sm3-hash. +// +// We understand future ARMv8 enhancements are supposed +// to include SM3 and SM4 related instructions so the function +// is stubbed for an eventual SM3_HashMultipleBlocks_ARMV8. + +#include "pch.h" +#include "config.h" + +#include "sm3.h" +#include "misc.h" +#include "cpu.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::rotlConstant; + +using CryptoPP::SM3; +using CryptoPP::GetBlock; +using CryptoPP::BigEndian; + +inline word32 P0(word32 X) +{ + return X ^ rotlConstant<9>(X) ^ rotlConstant<17>(X); +} + +inline word32 P1(word32 X) +{ + return X ^ rotlConstant<15>(X) ^ rotlConstant<23>(X); +} + +inline word32 EE(word32 W0, word32 W7, word32 W13, word32 W3, word32 W10) +{ + return P1(W0 ^ W7 ^ rotlConstant<15>(W13)) ^ rotlConstant<7>(W3) ^ W10; +} + +inline word32 FF(word32 X, word32 Y, word32 Z) +{ + return (X & Y) | ((X | Y) & Z); +} + +inline word32 GG(word32 X, word32 Y, word32 Z) +{ + return ((Z ^ (X & (Y ^ Z)))); +} + +inline void R1(word32 A, word32& B, word32 C, word32& D, word32 E, word32& F, + word32 G, word32& H, word32 TJ, word32 Wi, word32 Wj) +{ + const word32 A12 = rotlConstant<12>(A); + const word32 TT0 = rotlConstant<7>(A12 + E + TJ); + const word32 TT1 = (A ^ B ^ C) + D + (TT0 ^ A12) + Wj; + const word32 TT2 = (E ^ F ^ G) + H + TT0 + Wi; + + B = rotlConstant<9>(B); D = TT1; + F = rotlConstant<19>(F); H = P0(TT2); +} + +inline void R2(word32 A, word32& B, word32 C, word32& D, word32 E, word32& F, + word32 G, word32& H, word32 TJ, word32 Wi, word32 Wj) +{ + const word32 A12 = rotlConstant<12>(A); + const word32 TT0 = rotlConstant<7>(A12 + E + TJ); + const word32 TT1 = FF(A, B, C) + D + (TT0 ^ A12) + Wj; + const word32 TT2 = GG(E, F, G) + H + TT0 + Wi; + + B = rotlConstant<9>(B); D = TT1; + F = rotlConstant<19>(F); H = P0(TT2); +} + +// Krzysztof Kwiatkowski did a very nice job with this function. +size_t SM3_HashMultipleBlocks_CXX(word32 *state, const word32 *data, size_t length) +{ + CRYPTOPP_ASSERT(data); + + word32 A = state[0], B = state[1], C = state[2], D = state[3]; + word32 E = state[4], F = state[5], G = state[6], H = state[7]; + + while (length >= SM3::BLOCKSIZE) + { + // Reverse bytes on LittleEndian; align pointer on BigEndian + typedef GetBlock InBlock; + InBlock iblk(data); + + word32 W00, W01, W02, W03, W04, W05, W06, W07, W08, W09, W10, W11, W12, W13, W14, W15; + iblk(W00)(W01)(W02)(W03)(W04)(W05)(W06)(W07)(W08)(W09)(W10)(W11)(W12)(W13)(W14)(W15); + + R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04); + W00 = EE(W00, W07, W13, W03, W10); + R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05); + W01 = EE(W01, W08, W14, W04, W11); + R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06); + W02 = EE(W02, W09, W15, W05, W12); + R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07); + W03 = EE(W03, W10, W00, W06, W13); + R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08); + W04 = EE(W04, W11, W01, W07, W14); + R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09); + W05 = EE(W05, W12, W02, W08, W15); + R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10); + W06 = EE(W06, W13, W03, W09, W00); + R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11); + W07 = EE(W07, W14, W04, W10, W01); + R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12); + W08 = EE(W08, W15, W05, W11, W02); + R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13); + W09 = EE(W09, W00, W06, W12, W03); + R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14); + W10 = EE(W10, W01, W07, W13, W04); + R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15); + W11 = EE(W11, W02, W08, W14, W05); + R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00); + W12 = EE(W12, W03, W09, W15, W06); + R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01); + W13 = EE(W13, W04, W10, W00, W07); + R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02); + W14 = EE(W14, W05, W11, W01, W08); + R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03); + W15 = EE(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); + W00 = EE(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); + W01 = EE(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); + W02 = EE(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); + W03 = EE(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); + W04 = EE(W04, W11, W01, W07, W14); + R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); + W05 = EE(W05, W12, W02, W08, W15); + R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); + W06 = EE(W06, W13, W03, W09, W00); + R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); + W07 = EE(W07, W14, W04, W10, W01); + R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); + W08 = EE(W08, W15, W05, W11, W02); + R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); + W09 = EE(W09, W00, W06, W12, W03); + R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); + W10 = EE(W10, W01, W07, W13, W04); + R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); + W11 = EE(W11, W02, W08, W14, W05); + R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); + W12 = EE(W12, W03, W09, W15, W06); + R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); + W13 = EE(W13, W04, W10, W00, W07); + R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); + W14 = EE(W14, W05, W11, W01, W08); + R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); + W15 = EE(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04); + W00 = EE(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05); + W01 = EE(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06); + W02 = EE(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07); + W03 = EE(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08); + W04 = EE(W04, W11, W01, W07, W14); + R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09); + W05 = EE(W05, W12, W02, W08, W15); + R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10); + W06 = EE(W06, W13, W03, W09, W00); + R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11); + W07 = EE(W07, W14, W04, W10, W01); + R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12); + W08 = EE(W08, W15, W05, W11, W02); + R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13); + W09 = EE(W09, W00, W06, W12, W03); + R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14); + W10 = EE(W10, W01, W07, W13, W04); + R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15); + W11 = EE(W11, W02, W08, W14, W05); + R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00); + W12 = EE(W12, W03, W09, W15, W06); + R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01); + W13 = EE(W13, W04, W10, W00, W07); + R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02); + W14 = EE(W14, W05, W11, W01, W08); + R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03); + W15 = EE(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); + W00 = EE(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); + W01 = EE(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); + W02 = EE(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); + W03 = EE(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); + R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); + R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); + R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); + R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); + R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); + R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); + R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); + R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); + R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); + R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); + R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); + + A = (state[0] ^= A); + B = (state[1] ^= B); + C = (state[2] ^= C); + D = (state[3] ^= D); + E = (state[4] ^= E); + F = (state[5] ^= F); + G = (state[6] ^= G); + H = (state[7] ^= H); + + data += SM3::BLOCKSIZE/sizeof(word32); + length -= SM3::BLOCKSIZE; + } + + return length; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void SM3::InitState(HashWordType *state) +{ + const word32 s[] = { + 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, + 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e + }; + + std::memcpy(state, s, sizeof(s)); +} + +void SM3::Transform(word32 *state, const word32 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + + SM3_HashMultipleBlocks_CXX(state, data, SM3::BLOCKSIZE); +} + +size_t SM3::HashMultipleBlocks(const HashWordType *input, size_t length) +{ + const size_t res = length & (SM3::BLOCKSIZE - 1); + SM3_HashMultipleBlocks_CXX(m_state, input, length-res); + return res; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/sm3.h b/external/ours/library/crypto/src/shared/original/sm3.h new file mode 100755 index 000000000..746ccc580 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sm3.h @@ -0,0 +1,61 @@ +// sm3.h - written and placed in the public domain by Jeffrey Walton and Han Lulu +// Based on the specification provided by Sean Shen and Xiaodong Lee. +// Based on code by Krzysztof Kwiatkowski and Jack Lloyd. +// Also see https://tools.ietf.org/html/draft-shen-sm3-hash. + +/// \file sm3.h +/// \brief Classes for the SM3 hash function +/// \details SM3 is a hash function designed by Xiaoyun Wang, et al. The hash is part of the +/// Chinese State Cryptography Administration portfolio. +/// \sa SM3 Hash Function and +/// Reference implementation using OpenSSL. +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_SM3_H +#define CRYPTOPP_SM3_H + +#include "config.h" +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SM3 hash function +/// \details SM3 is a hash function designed by Xiaoyun Wang, et al. The hash is part of the +/// Chinese State Cryptography Administration portfolio. +/// \sa SM3 Hash Function +/// \since Crypto++ 6.0 +class SM3 : public IteratedHashWithStaticTransform +{ +public: + /// \brief Initialize state array + /// \param state the state of the hash + /// \details InitState sets a state array to SM3 initial values + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState() and Transform(). External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + static void InitState(HashWordType *state); + + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + /// \details Transform() operates the hash on data. When the call is invoked + /// digest holds initial or current state. Upon return digest holds + /// the hash or updated state. + /// \details Hashes which derive from IteratedHashWithStaticTransform provide static + /// member functions InitState() and Transform(). External classes, like SEAL and MDC, + /// can initialize state with a user provided key and operate the hash on the data + /// with the user supplied state. + static void Transform(HashWordType *digest, const HashWordType *data); + + /// \brief The algorithm name + /// \return C-style string "SM3" + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "SM3"; } + +protected: + size_t HashMultipleBlocks(const HashWordType *input, size_t length); +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SM3_H diff --git a/external/ours/library/crypto/src/shared/original/sm4.cpp b/external/ours/library/crypto/src/shared/original/sm4.cpp new file mode 100755 index 000000000..ad7f32224 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sm4.cpp @@ -0,0 +1,212 @@ +// sm4.cpp - written and placed in the public domain by Jeffrey Walton and Han Lulu +// +// We understand future ARMv8 enhancements are supposed +// to include SM3 and SM4 related instructions so the function +// is stubbed for an eventual SM4_Round_ARMV8. + +#include "pch.h" +#include "config.h" + +#include "sm4.h" +#include "misc.h" +#include "cpu.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4307) +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::rotlConstant; + +CRYPTOPP_ALIGN_DATA(4) +const byte S[256] = +{ + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, + 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, + 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, + 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, + 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, + 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, + 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, + 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, + 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, + 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, + 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, + 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, + 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, + 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, + 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, + 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48 +}; + +const word32 CK[32] = +{ + 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, + 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9, + 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, + 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9, + 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229, + 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299, + 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209, + 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 +}; + +inline word32 SM4_H(word32 x) +{ + return (S[GETBYTE(x, 3)] << 24) | (S[GETBYTE(x, 2)] << 16) | (S[GETBYTE(x, 1)] << 8) | (S[GETBYTE(x, 0)]); +} + +inline word32 SM4_G(word32 x) +{ + const word32 t = SM4_H(x); + return t ^ rotlConstant<13>(t) ^ rotlConstant<23>(t); +} + +inline word32 SM4_F(word32 x) +{ + const word32 t = SM4_H(x); + return t ^ rotlConstant<2>(t) ^ rotlConstant<10>(t) ^ rotlConstant<18>(t) ^ rotlConstant<24>(t); +} + +template +inline void SM4_Round(word32 wspace[4], const word32 rkeys[32]) +{ + if (FWD) + { + wspace[0] ^= SM4_F(wspace[1] ^ wspace[2] ^ wspace[3] ^ rkeys[R+0]); + wspace[1] ^= SM4_F(wspace[0] ^ wspace[2] ^ wspace[3] ^ rkeys[R+1]); + wspace[2] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[3] ^ rkeys[R+2]); + wspace[3] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[2] ^ rkeys[R+3]); + } + else + { + wspace[0] ^= SM4_F(wspace[1] ^ wspace[2] ^ wspace[3] ^ rkeys[R-0]); + wspace[1] ^= SM4_F(wspace[0] ^ wspace[2] ^ wspace[3] ^ rkeys[R-1]); + wspace[2] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[3] ^ rkeys[R-2]); + wspace[3] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[2] ^ rkeys[R-3]); + } +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if CRYPTOPP_SM4_ADVANCED_PROCESS_BLOCKS +# if defined(CRYPTOPP_AESNI_AVAILABLE) +extern size_t SM4_Enc_AdvancedProcessBlocks_AESNI(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +# endif +#endif + +std::string SM4::Enc::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_AESNI_AVAILABLE) + if (HasAESNI()) + return "AESNI"; +#endif + return "C++"; +} + +void SM4::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(keyLength == 16); + CRYPTOPP_UNUSED(params); + + m_rkeys.New(32); + m_wspace.New(5); + + GetUserKey(BIG_ENDIAN_ORDER, m_wspace.begin(), 4, userKey, keyLength); + m_wspace[0] ^= 0xa3b1bac6; m_wspace[1] ^= 0x56aa3350; + m_wspace[2] ^= 0x677d9197; m_wspace[3] ^= 0xb27022dc; + + size_t i=0; + do + { + m_rkeys[i] = (m_wspace[0] ^= SM4_G(m_wspace[1] ^ m_wspace[2] ^ m_wspace[3] ^ CK[i])); i++; + m_rkeys[i] = (m_wspace[1] ^= SM4_G(m_wspace[2] ^ m_wspace[3] ^ m_wspace[0] ^ CK[i])); i++; + m_rkeys[i] = (m_wspace[2] ^= SM4_G(m_wspace[3] ^ m_wspace[0] ^ m_wspace[1] ^ CK[i])); i++; + m_rkeys[i] = (m_wspace[3] ^= SM4_G(m_wspace[0] ^ m_wspace[1] ^ m_wspace[2] ^ CK[i])); i++; + } + while (i < 32); +} + +void SM4::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Reverse bytes on LittleEndian; align pointer on BigEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1])(m_wspace[2])(m_wspace[3]); + + // Timing attack countermeasure, see comments in Rijndael for more details. + // The hardening does not materially affect benchmarks. SM4 runs at + // 30.5 cpb on a Core i5 Skylake with and without the code below. + const int cacheLineSize = GetCacheLineSize(); + volatile word32 _u = 0; + word32 u = _u; + + for (unsigned int i=0; i(m_wspace, m_rkeys); + SM4_Round< 4, true>(m_wspace, m_rkeys); + SM4_Round< 8, true>(m_wspace, m_rkeys); + SM4_Round<12, true>(m_wspace, m_rkeys); + SM4_Round<16, true>(m_wspace, m_rkeys); + SM4_Round<20, true>(m_wspace, m_rkeys); + SM4_Round<24, true>(m_wspace, m_rkeys); + SM4_Round<28, true>(m_wspace, m_rkeys); + + // Reverse bytes on LittleEndian; align pointer on BigEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); +} + +void SM4::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Reverse bytes on LittleEndian; align pointer on BigEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1])(m_wspace[2])(m_wspace[3]); + + // Timing attack countermeasure, see comments in Rijndael for more details. + // The hardening does not materially affect benchmarks. SM4 runs at + // 30.5 cpb on a Core i5 Skylake with and without the code below. + const int cacheLineSize = GetCacheLineSize(); + volatile word32 _u = 0; + word32 u = _u; + + for (unsigned int i=0; i(m_wspace, m_rkeys); + SM4_Round<27, false>(m_wspace, m_rkeys); + SM4_Round<23, false>(m_wspace, m_rkeys); + SM4_Round<19, false>(m_wspace, m_rkeys); + SM4_Round<15, false>(m_wspace, m_rkeys); + SM4_Round<11, false>(m_wspace, m_rkeys); + SM4_Round< 7, false>(m_wspace, m_rkeys); + SM4_Round< 3, false>(m_wspace, m_rkeys); + + // Reverse bytes on LittleEndian; align pointer on BigEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); +} + +#if CRYPTOPP_SM4_ADVANCED_PROCESS_BLOCKS +size_t SM4::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if defined(CRYPTOPP_AESNI_AVAILABLE) + if (HasAESNI()) { + return SM4_Enc_AdvancedProcessBlocks_AESNI(m_rkeys, 32, + inBlocks, xorBlocks, outBlocks, length, flags); + } +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SM4_ADVANCED_PROCESS_BLOCKS + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/sm4.h b/external/ours/library/crypto/src/shared/original/sm4.h new file mode 100755 index 000000000..67f76052f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sm4.h @@ -0,0 +1,96 @@ +// sm4.h - written and placed in the public domain by Jeffrey Walton and Han Lulu + +/// \file sm4.h +/// \brief Classes for the SM4 block cipher +/// \details SM4 is a block cipher designed by Xiaoyun Wang, et al. The block cipher is part of the +/// Chinese State Cryptography Administration portfolio. The cipher was formely known as SMS4. +/// \details SM4 encryption is accelerated on machines with AES-NI. Decryption is not acclerated because +/// it is not profitable. Thanks to Markku-Juhani Olavi Saarinen for help and the code. +/// \sa SMS4 Encryption Algorithm for Wireless Networks, +/// Reference implementation using OpenSSL and +/// Markku-Juhani Olavi Saarinen GitHub. +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_SM4_H +#define CRYPTOPP_SM4_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +#if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86) +# ifndef CRYPTOPP_DISABLE_SM4_SIMD +# define CRYPTOPP_SM4_ADVANCED_PROCESS_BLOCKS 1 +# endif +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SM4 block cipher information +/// \since Crypto++ 6.0 +struct SM4_Info : public FixedBlockSize<16>, FixedKeyLength<16> +{ + static const std::string StaticAlgorithmName() + { + return "SM4"; + } +}; + +/// \brief Classes for the SM4 block cipher +/// \details SM4 is a block cipher designed by Xiaoyun Wang, et al. The block cipher is part of the +/// Chinese State Cryptography Administration portfolio. The cipher was formely known as SMS4. +/// \sa SMS4 Encryption Algorithm for Wireless Networks +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE SM4 : public SM4_Info, public BlockCipherDocumentation +{ +public: + /// \brief SM4 block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + + SecBlock > m_rkeys; + mutable SecBlock > m_wspace; + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key + /// sizes are supported. + /// \details SM4 encryption is accelerated on machines with AES-NI. Decryption is + /// not acclerated because it is not profitable. Thanks to Markku-Juhani Olavi + /// Saarinen. + /// \since Crypto++ 6.0, AESNI encryption since Crypto++ 8.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + std::string AlgorithmProvider() const; + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_SM4_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key + /// sizes are supported. + /// \details SM4 encryption is accelerated on machines with AES-NI. Decryption is + /// not acclerated because it is not profitable. Thanks to Markku-Juhani Olavi + /// Saarinen. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SM4_H diff --git a/external/ours/library/crypto/src/shared/original/sm4_simd.cpp b/external/ours/library/crypto/src/shared/original/sm4_simd.cpp new file mode 100755 index 000000000..d19e05924 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sm4_simd.cpp @@ -0,0 +1,323 @@ +// sm4_simd.cpp - written and placed in the public domain by +// Markku-Juhani O. Saarinen and Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// AESNI, ARM NEON and ARMv8a, and Power7 Altivec instructions. A separate +// source file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. +// +// AES-NI based on Markku-Juhani O. Saarinen work at https://github.com/mjosaarinen/sm4ni. +// +// ARMv8 is upcoming. + +#include "pch.h" +#include "config.h" + +#include "sm4.h" +#include "misc.h" + +// Uncomment for benchmarking C++ against SSE. +// Do so in both simon.cpp and simon_simd.cpp. +// #undef CRYPTOPP_AESNI_AVAILABLE + +#if (CRYPTOPP_AESNI_AVAILABLE) +# include "adv_simd.h" +# include +# include +# include +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char SM4_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; + +#if (CRYPTOPP_AESNI_AVAILABLE) + +template +inline __m128i ShiftLeft(const __m128i& val) +{ + return _mm_slli_epi32(val, R); +} + +template +inline __m128i ShiftRight(const __m128i& val) +{ + return _mm_srli_epi32(val, R); +} + +template +inline __m128i ShiftLeft64(const __m128i& val) +{ + return _mm_slli_epi64(val, R); +} + +template +inline __m128i ShiftRight64(const __m128i& val) +{ + return _mm_srli_epi64(val, R); +} + +template +inline __m128i RotateLeft(const __m128i& val) +{ + return _mm_or_si128( + _mm_slli_epi32(val, R), _mm_srli_epi32(val, 32-R)); +} + +template +inline __m128i RotateRight(const __m128i& val) +{ + return _mm_or_si128( + _mm_slli_epi32(val, 32-R), _mm_srli_epi32(val, R)); +} + +template <> +inline __m128i RotateLeft<8>(const __m128i& val) +{ + const __m128i r08 = _mm_set_epi32(0x0E0D0C0F, 0x0A09080B, 0x06050407, 0x02010003); + return _mm_shuffle_epi8(val, r08); +} + +template <> +inline __m128i RotateLeft<16>(const __m128i& val) +{ + const __m128i mask = _mm_set_epi32(0x0D0C0F0E, 0x09080B0A, 0x05040706, 0x01000302); + return _mm_shuffle_epi8(val, mask); +} + +template <> +inline __m128i RotateLeft<24>(const __m128i& val) +{ + const __m128i mask = _mm_set_epi32(0x0C0F0E0D, 0x080B0A09, 0x04070605, 0x00030201); + return _mm_shuffle_epi8(val, mask); +} + +/// \brief Unpack XMM words +/// \tparam IDX the element from each XMM word +/// \param a the first XMM word +/// \param b the second XMM word +/// \param c the third XMM word +/// \param d the fourth XMM word +/// \details UnpackXMM selects the IDX element from a, b, c, d and returns a concatenation +/// equivalent to a[IDX] || b[IDX] || c[IDX] || d[IDX]. +template +inline __m128i UnpackXMM(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(a); CRYPTOPP_UNUSED(b); + CRYPTOPP_UNUSED(c); CRYPTOPP_UNUSED(d); + CRYPTOPP_ASSERT(0); + return _mm_setzero_si128(); +} + +template <> +inline __m128i UnpackXMM<0>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + const __m128i r1 = _mm_unpacklo_epi32(a, b); + const __m128i r2 = _mm_unpacklo_epi32(c, d); + return _mm_unpacklo_epi64(r1, r2); +} + +template <> +inline __m128i UnpackXMM<1>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + const __m128i r1 = _mm_unpacklo_epi32(a, b); + const __m128i r2 = _mm_unpacklo_epi32(c, d); + return _mm_unpackhi_epi64(r1, r2); +} + +template <> +inline __m128i UnpackXMM<2>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + const __m128i r1 = _mm_unpackhi_epi32(a, b); + const __m128i r2 = _mm_unpackhi_epi32(c, d); + return _mm_unpacklo_epi64(r1, r2); +} + +template <> +inline __m128i UnpackXMM<3>(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + const __m128i r1 = _mm_unpackhi_epi32(a, b); + const __m128i r2 = _mm_unpackhi_epi32(c, d); + return _mm_unpackhi_epi64(r1, r2); +} + +/// \brief Unpack a XMM word +/// \tparam IDX the element from each XMM word +/// \param v the first XMM word +/// \details UnpackXMM selects the IDX element from v and returns a concatenation +/// equivalent to v[IDX] || v[IDX] || v[IDX] || v[IDX]. +template +inline __m128i UnpackXMM(const __m128i& v) +{ + // Should not be instantiated + CRYPTOPP_UNUSED(v); CRYPTOPP_ASSERT(0); + return _mm_setzero_si128(); +} + +template <> +inline __m128i UnpackXMM<0>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); +} + +template <> +inline __m128i UnpackXMM<1>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); +} + +template <> +inline __m128i UnpackXMM<2>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(11,10,9,8, 11,10,9,8, 11,10,9,8, 11,10,9,8)); +} + +template <> +inline __m128i UnpackXMM<3>(const __m128i& v) +{ + // Splat to all lanes + return _mm_shuffle_epi8(v, _mm_set_epi8(15,14,13,12, 15,14,13,12, 15,14,13,12, 15,14,13,12)); +} + +template +inline __m128i RepackXMM(const __m128i& a, const __m128i& b, const __m128i& c, const __m128i& d) +{ + return UnpackXMM(a, b, c, d); +} + +template +inline __m128i RepackXMM(const __m128i& v) +{ + return UnpackXMM(v); +} + +inline void SM4_Encrypt(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys) +{ + // nibble mask + const __m128i c0f = _mm_set_epi32(0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F); + + // flip all bytes in all 32-bit words + const __m128i flp = _mm_set_epi32(0x0C0D0E0F, 0x08090A0B, 0x04050607, 0x00010203); + + // inverse shift rows + const __m128i shr = _mm_set_epi32(0x0306090C, 0x0F020508, 0x0B0E0104, 0x070A0D00); + + // Affine transform 1 (low and high hibbles) + const __m128i m1l = _mm_set_epi32(0xC7C1B4B2, 0x22245157, 0x9197E2E4, 0x74720701); + const __m128i m1h = _mm_set_epi32(0xF052B91B, 0xF95BB012, 0xE240AB09, 0xEB49A200); + + // Affine transform 2 (low and high hibbles) + const __m128i m2l = _mm_set_epi32(0xEDD14478, 0x172BBE82, 0x5B67F2CE, 0xA19D0834); + const __m128i m2h = _mm_set_epi32(0x11CDBE62, 0xCC1063BF, 0xAE7201DD, 0x73AFDC00); + + __m128i t0 = UnpackXMM<0>(block0, block1, block2, block3); + __m128i t1 = UnpackXMM<1>(block0, block1, block2, block3); + __m128i t2 = UnpackXMM<2>(block0, block1, block2, block3); + __m128i t3 = UnpackXMM<3>(block0, block1, block2, block3); + + t0 = _mm_shuffle_epi8(t0, flp); + t1 = _mm_shuffle_epi8(t1, flp); + t2 = _mm_shuffle_epi8(t2, flp); + t3 = _mm_shuffle_epi8(t3, flp); + + const unsigned int ROUNDS = 32; + for (unsigned int i = 0; i < ROUNDS; i++) + { + const __m128i k = _mm_shuffle_epi32(_mm_castps_si128( + _mm_load_ss((const float*)(subkeys+i))), _MM_SHUFFLE(0,0,0,0)); + + __m128i x, y; + x = _mm_xor_si128(t1, _mm_xor_si128(t2, _mm_xor_si128(t3, k))); + + y = _mm_and_si128(x, c0f); // inner affine + y = _mm_shuffle_epi8(m1l, y); + x = _mm_and_si128(ShiftRight64<4>(x), c0f); + x = _mm_xor_si128(_mm_shuffle_epi8(m1h, x), y); + + x = _mm_shuffle_epi8(x, shr); // inverse MixColumns + x = _mm_aesenclast_si128(x, c0f); // AESNI instruction + + y = _mm_andnot_si128(x, c0f); // outer affine + y = _mm_shuffle_epi8(m2l, y); + x = _mm_and_si128(ShiftRight64<4>(x), c0f); + x = _mm_xor_si128(_mm_shuffle_epi8(m2h, x), y); + + // 4 parallel L1 linear transforms + y = _mm_xor_si128(x, RotateLeft<8>(x)); + y = _mm_xor_si128(y, RotateLeft<16>(x)); + y = _mm_xor_si128(ShiftLeft<2>(y), ShiftRight<30>(y)); + x = _mm_xor_si128(x, _mm_xor_si128(y, RotateLeft<24>(x))); + + // rotate registers + x = _mm_xor_si128(x, t0); + t0 = t1; t1 = t2; + t2 = t3; t3 = x; + } + + t0 = _mm_shuffle_epi8(t0, flp); + t1 = _mm_shuffle_epi8(t1, flp); + t2 = _mm_shuffle_epi8(t2, flp); + t3 = _mm_shuffle_epi8(t3, flp); + + block0 = RepackXMM<0>(t3,t2,t1,t0); + block1 = RepackXMM<1>(t3,t2,t1,t0); + block2 = RepackXMM<2>(t3,t2,t1,t0); + block3 = RepackXMM<3>(t3,t2,t1,t0); +} + +inline void SM4_Enc_4_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys, unsigned int /*rounds*/) +{ + SM4_Encrypt(block0, block1, block2, block3, subkeys); +} + +inline void SM4_Dec_4_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, const word32 *subkeys, unsigned int /*rounds*/) +{ + SM4_Encrypt(block0, block1, block2, block3, subkeys); +} + +inline void SM4_Enc_Block(__m128i &block0, + const word32 *subkeys, unsigned int /*rounds*/) +{ + __m128i t1 = _mm_setzero_si128(); + __m128i t2 = _mm_setzero_si128(); + __m128i t3 = _mm_setzero_si128(); + + SM4_Encrypt(block0, t1, t2, t3, subkeys); +} + +inline void SM4_Dec_Block(__m128i &block0, + const word32 *subkeys, unsigned int /*rounds*/) +{ + __m128i t1 = _mm_setzero_si128(); + __m128i t2 = _mm_setzero_si128(); + __m128i t3 = _mm_setzero_si128(); + + SM4_Encrypt(block0, t1, t2, t3, subkeys); +} + +#endif // CRYPTOPP_AESNI_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_AESNI_AVAILABLE) +size_t SM4_Enc_AdvancedProcessBlocks_AESNI(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_4x1_SSE(SM4_Enc_Block, SM4_Enc_4_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_AESNI_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/smartptr.h b/external/ours/library/crypto/src/shared/original/smartptr.h index f5c0b41bd..04cb9a420 100755 --- a/external/ours/library/crypto/src/shared/original/smartptr.h +++ b/external/ours/library/crypto/src/shared/original/smartptr.h @@ -1,195 +1,257 @@ -#ifndef CRYPTOPP_SMARTPTR_H -#define CRYPTOPP_SMARTPTR_H - -#include "config.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -template class member_ptr -{ -public: - explicit member_ptr(T *p = nullptr) : m_p(p) {} - - ~member_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return m_p; } - - const T* get() const { return m_p; } - T* get() { return m_p; } - - T* release() - { - T *old_p = m_p; - m_p = 0; - return old_p; - } - - void reset(T *p = 0); - -protected: - member_ptr(const member_ptr& rhs); // copy not allowed - void operator=(const member_ptr& rhs); // assignment not allowed - - T *m_p; -}; - -template member_ptr::~member_ptr() {delete m_p;} -template void member_ptr::reset(T *p) {delete m_p; m_p = p;} - -// ******************************************************** - -template class value_ptr : public member_ptr -{ -public: - value_ptr(const T &obj) : member_ptr(new T(obj)) {} - value_ptr(T *p = nullptr) : member_ptr(p) {} - value_ptr(const value_ptr& rhs) - : member_ptr(rhs.m_p ? new T(*rhs.m_p) : nullptr) {} - - value_ptr& operator=(const value_ptr& rhs); - bool operator==(const value_ptr& rhs) - { - return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); - } -}; - -template value_ptr& value_ptr::operator=(const value_ptr& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? new T(*rhs.m_p) : nullptr; - delete old_p; - return *this; -} - -// ******************************************************** - -template class clonable_ptr : public member_ptr -{ -public: - clonable_ptr(const T &obj) : member_ptr(obj.Clone()) {} - clonable_ptr(T *p = nullptr) : member_ptr(p) {} - clonable_ptr(const clonable_ptr& rhs) - : member_ptr(rhs.m_p ? rhs.m_p->Clone() : nullptr) {} - - clonable_ptr& operator=(const clonable_ptr& rhs); -}; - -template clonable_ptr& clonable_ptr::operator=(const clonable_ptr& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? rhs.m_p->Clone() : nullptr; - delete old_p; - return *this; -} - -// ******************************************************** - -template class counted_ptr -{ -public: - explicit counted_ptr(T *p = 0); - counted_ptr(const counted_ptr& rhs); - - ~counted_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return m_p; } - - const T* get() const { return m_p; } - T* get() { return m_p; } - - counted_ptr & operator=(const counted_ptr& rhs); - -private: - T *m_p; -}; - -template counted_ptr::counted_ptr(T *p) - : m_p(p) -{ - if (m_p) - m_p->m_referenceCount = 1; -} - -template counted_ptr::counted_ptr(const counted_ptr& rhs) - : m_p(rhs.m_p) -{ - if (m_p) - m_p->m_referenceCount++; -} - -template counted_ptr::~counted_ptr() -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; -} - -template counted_ptr & counted_ptr::operator=(const counted_ptr& rhs) -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; - m_p = rhs.m_p; - if (m_p) - m_p->m_referenceCount++; - return *this; -} - -// ******************************************************** - -template class vector_member_ptrs -{ -public: - vector_member_ptrs(unsigned int size=0) - : _size(size) {ptr = new member_ptr[_size];} - ~vector_member_ptrs() - {delete [] ptr;} - - member_ptr& operator[](unsigned int index) - {assert(index<_size); return ptr[index];} - const member_ptr& operator[](unsigned int index) const - {assert(index<_size); return ptr[index];} - - unsigned int size() const {return _size;} - void resize(unsigned int newSize) - { - member_ptr *newPtr = new member_ptr[newSize]; - for (unsigned int i=0; i &c); // copy not allowed - void operator=(const vector_member_ptrs &x); // assignment not allowed - - unsigned int _size; - member_ptr *ptr; -}; - -// ******************************************************** - -// derive from this class for a temporary variable -// that can be used during base/member initialization -template -class ConstructorTemp -{ -protected: - ConstructorTemp(const ConstructorTemp ©) : m_temp(nullptr) {} - ConstructorTemp(T *t = nullptr) : m_temp(t) {} - ConstructorTemp(const T &t) : m_temp(new T(t)) {} - member_ptr m_temp; -}; - -NAMESPACE_END - -#endif +// smartptr.h - originally written and placed in the public domain by Wei Dai + +/// \file smartptr.h +/// \brief Classes for automatic resource management + +#ifndef CRYPTOPP_SMARTPTR_H +#define CRYPTOPP_SMARTPTR_H + +#include "config.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Manages resources for a single object +/// \tparam T class or type +/// \details \p simple_ptr is used frequently in the library to manage resources and +/// ensure cleanup under the RAII pattern (Resource Acquisition Is Initialization). +template class simple_ptr +{ +public: + simple_ptr(T *p = NULLPTR) : m_p(p) {} + ~simple_ptr() + { + delete m_p; + m_p = NULLPTR; + } + + T *m_p; +}; + +/// \brief Pointer that overloads operator -> +/// \tparam T class or type +/// \details member_ptr is used frequently in the library to avoid the issues related to +/// std::auto_ptr in C++11 (deprecated) and std::unique_ptr in C++03 (non-existent). +/// \bug Issue 48: "Use of auto_ptr +/// causes dirty compile under C++11" +template class member_ptr +{ +public: + explicit member_ptr(T *p = NULLPTR) : m_p(p) {} + + ~member_ptr(); + + const T& operator*() const { return *m_p; } + T& operator*() { return *m_p; } + + const T* operator->() const { return m_p; } + T* operator->() { return m_p; } + + const T* get() const { return m_p; } + T* get() { return m_p; } + + T* release() + { + T *old_p = m_p; + m_p = NULLPTR; + return old_p; + } + + void reset(T *p = NULLPTR); + +protected: + member_ptr(const member_ptr& rhs); // copy not allowed + void operator=(const member_ptr& rhs); // assignment not allowed + + T *m_p; +}; + +template member_ptr::~member_ptr() {delete m_p;} +template void member_ptr::reset(T *p) {delete m_p; m_p = p;} + +// ******************************************************** + +/// \brief Value pointer +/// \tparam T class or type +template class value_ptr : public member_ptr +{ +public: + value_ptr(const T &obj) : member_ptr(new T(obj)) {} + value_ptr(T *p = NULLPTR) : member_ptr(p) {} + value_ptr(const value_ptr& rhs) + : member_ptr(rhs.m_p ? new T(*rhs.m_p) : NULLPTR) {} + + value_ptr& operator=(const value_ptr& rhs); + bool operator==(const value_ptr& rhs) + { + return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); + } +}; + +template value_ptr& value_ptr::operator=(const value_ptr& rhs) +{ + T *old_p = this->m_p; + this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULLPTR; + delete old_p; + return *this; +} + +// ******************************************************** + +/// \brief A pointer which can be copied and cloned +/// \tparam T class or type +/// \details \p T should adhere to the \p Clonable interface +template class clonable_ptr : public member_ptr +{ +public: + clonable_ptr(const T &obj) : member_ptr(obj.Clone()) {} + clonable_ptr(T *p = NULLPTR) : member_ptr(p) {} + clonable_ptr(const clonable_ptr& rhs) + : member_ptr(rhs.m_p ? rhs.m_p->Clone() : NULLPTR) {} + + clonable_ptr& operator=(const clonable_ptr& rhs); +}; + +template clonable_ptr& clonable_ptr::operator=(const clonable_ptr& rhs) +{ + T *old_p = this->m_p; + this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULLPTR; + delete old_p; + return *this; +} + +// ******************************************************** + +/// \brief Reference counted pointer +/// \tparam T class or type +/// \details users should declare \p m_referenceCount as std::atomic +/// (or similar) under C++ 11 +template class counted_ptr +{ +public: + explicit counted_ptr(T *p = NULLPTR); + counted_ptr(const T &r) : m_p(0) {attach(r);} + counted_ptr(const counted_ptr& rhs); + + ~counted_ptr(); + + const T& operator*() const { return *m_p; } + T& operator*() { return *m_p; } + + const T* operator->() const { return m_p; } + T* operator->() { return get(); } + + const T* get() const { return m_p; } + T* get(); + + void attach(const T &p); + + counted_ptr & operator=(const counted_ptr& rhs); + +private: + T *m_p; +}; + +template counted_ptr::counted_ptr(T *p) + : m_p(p) +{ + if (m_p) + m_p->m_referenceCount = 1; +} + +template counted_ptr::counted_ptr(const counted_ptr& rhs) + : m_p(rhs.m_p) +{ + if (m_p) + m_p->m_referenceCount++; +} + +template counted_ptr::~counted_ptr() +{ + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; +} + +template void counted_ptr::attach(const T &r) +{ + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; + if (r.m_referenceCount == 0) + { + m_p = r.clone(); + m_p->m_referenceCount = 1; + } + else + { + m_p = const_cast(&r); + m_p->m_referenceCount++; + } +} + +template T* counted_ptr::get() +{ + if (m_p && m_p->m_referenceCount > 1) + { + T *temp = m_p->clone(); + m_p->m_referenceCount--; + m_p = temp; + m_p->m_referenceCount = 1; + } + return m_p; +} + +template counted_ptr & counted_ptr::operator=(const counted_ptr& rhs) +{ + if (m_p != rhs.m_p) + { + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; + m_p = rhs.m_p; + if (m_p) + m_p->m_referenceCount++; + } + return *this; +} + +// ******************************************************** + +/// \brief Manages resources for an array of objects +/// \tparam T class or type +template class vector_member_ptrs +{ +public: + /// Construct an arry of \p T + /// \param size the size of the array, in elements + /// \details If \p T is a Plain Old Dataype (POD), then the array is uninitialized. + vector_member_ptrs(size_t size=0) + : m_size(size), m_ptr(new member_ptr[size]) {} + ~vector_member_ptrs() + {delete [] this->m_ptr;} + + member_ptr& operator[](size_t index) + {CRYPTOPP_ASSERT(indexm_size); return this->m_ptr[index];} + const member_ptr& operator[](size_t index) const + {CRYPTOPP_ASSERT(indexm_size); return this->m_ptr[index];} + + size_t size() const {return this->m_size;} + void resize(size_t newSize) + { + member_ptr *newPtr = new member_ptr[newSize]; + for (size_t i=0; im_size && im_ptr[i].release()); + delete [] this->m_ptr; + this->m_size = newSize; + this->m_ptr = newPtr; + } + +private: + vector_member_ptrs(const vector_member_ptrs &c); // copy not allowed + void operator=(const vector_member_ptrs &x); // assignment not allowed + + size_t m_size; + member_ptr *m_ptr; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/sosemanuk.cpp b/external/ours/library/crypto/src/shared/original/sosemanuk.cpp new file mode 100755 index 000000000..82cf8c92b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sosemanuk.cpp @@ -0,0 +1,728 @@ +// sosemanuk.cpp - originally written and placed in the public domain by Wei Dai + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sosemanuk.cpp" to generate MASM code + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4702 4731) +#endif + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "sosemanuk.h" +#include "serpentp.h" +#include "secblock.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +std::string SosemanukPolicy::AlgorithmProvider() const +{ +#ifndef CRYPTOPP_DISABLE_SOSEMANUK_ASM +# if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return "SSE2"; +# endif +#endif + return "C++"; +} + +void SosemanukPolicy::CipherSetKey(const NameValuePairs ¶ms, const byte *userKey, size_t keylen) +{ + CRYPTOPP_UNUSED(params); + Serpent_KeySchedule(m_key, 24, userKey, keylen); +} + +void SosemanukPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) +{ + CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(iv), CRYPTOPP_UNUSED(length); + CRYPTOPP_ASSERT(length==16); + + word32 a, b, c, d, e; + + typedef BlockGetAndPut Block; + Block::Get(iv)(a)(b)(c)(d); + + const word32 *k = m_key; + unsigned int i=1; + + do + { + beforeS0(KX); beforeS0(S0); afterS0(LT); + afterS0(KX); afterS0(S1); afterS1(LT); + if (i == 3) // after 18th round + { + m_state[4] = b; + m_state[5] = e; + m_state[10] = c; + m_state[11] = a; + } + afterS1(KX); afterS1(S2); afterS2(LT); + afterS2(KX); afterS2(S3); afterS3(LT); + if (i == 2) // after 12th round + { + m_state[6] = c; + m_state[7] = d; + m_state[8] = b; + m_state[9] = e; + } + afterS3(KX); afterS3(S4); afterS4(LT); + afterS4(KX); afterS4(S5); afterS5(LT); + afterS5(KX); afterS5(S6); afterS6(LT); + afterS6(KX); afterS6(S7); afterS7(LT); + + if (i == 3) + break; + + ++i; + c = b; + b = e; + e = d; + d = a; + a = e; + k += 32; + } + while (true); + + afterS7(KX); + + m_state[0] = a; + m_state[1] = b; + m_state[2] = e; + m_state[3] = d; + +#define XMUX(c, x, y) (x ^ (y & (0 - (c & 1)))) + m_state[11] += XMUX(m_state[10], m_state[1], m_state[8]); + m_state[10] = rotlConstant<7>(m_state[10] * 0x54655307); +} + +extern "C" { +word32 s_sosemanukMulTables[512] = { +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM) + 0x00000000, 0xE19FCF12, 0x6B973724, 0x8A08F836, + 0xD6876E48, 0x3718A15A, 0xBD10596C, 0x5C8F967E, + 0x05A7DC90, 0xE4381382, 0x6E30EBB4, 0x8FAF24A6, + 0xD320B2D8, 0x32BF7DCA, 0xB8B785FC, 0x59284AEE, + 0x0AE71189, 0xEB78DE9B, 0x617026AD, 0x80EFE9BF, + 0xDC607FC1, 0x3DFFB0D3, 0xB7F748E5, 0x566887F7, + 0x0F40CD19, 0xEEDF020B, 0x64D7FA3D, 0x8548352F, + 0xD9C7A351, 0x38586C43, 0xB2509475, 0x53CF5B67, + 0x146722BB, 0xF5F8EDA9, 0x7FF0159F, 0x9E6FDA8D, + 0xC2E04CF3, 0x237F83E1, 0xA9777BD7, 0x48E8B4C5, + 0x11C0FE2B, 0xF05F3139, 0x7A57C90F, 0x9BC8061D, + 0xC7479063, 0x26D85F71, 0xACD0A747, 0x4D4F6855, + 0x1E803332, 0xFF1FFC20, 0x75170416, 0x9488CB04, + 0xC8075D7A, 0x29989268, 0xA3906A5E, 0x420FA54C, + 0x1B27EFA2, 0xFAB820B0, 0x70B0D886, 0x912F1794, + 0xCDA081EA, 0x2C3F4EF8, 0xA637B6CE, 0x47A879DC, + 0x28CE44DF, 0xC9518BCD, 0x435973FB, 0xA2C6BCE9, + 0xFE492A97, 0x1FD6E585, 0x95DE1DB3, 0x7441D2A1, + 0x2D69984F, 0xCCF6575D, 0x46FEAF6B, 0xA7616079, + 0xFBEEF607, 0x1A713915, 0x9079C123, 0x71E60E31, + 0x22295556, 0xC3B69A44, 0x49BE6272, 0xA821AD60, + 0xF4AE3B1E, 0x1531F40C, 0x9F390C3A, 0x7EA6C328, + 0x278E89C6, 0xC61146D4, 0x4C19BEE2, 0xAD8671F0, + 0xF109E78E, 0x1096289C, 0x9A9ED0AA, 0x7B011FB8, + 0x3CA96664, 0xDD36A976, 0x573E5140, 0xB6A19E52, + 0xEA2E082C, 0x0BB1C73E, 0x81B93F08, 0x6026F01A, + 0x390EBAF4, 0xD89175E6, 0x52998DD0, 0xB30642C2, + 0xEF89D4BC, 0x0E161BAE, 0x841EE398, 0x65812C8A, + 0x364E77ED, 0xD7D1B8FF, 0x5DD940C9, 0xBC468FDB, + 0xE0C919A5, 0x0156D6B7, 0x8B5E2E81, 0x6AC1E193, + 0x33E9AB7D, 0xD276646F, 0x587E9C59, 0xB9E1534B, + 0xE56EC535, 0x04F10A27, 0x8EF9F211, 0x6F663D03, + 0x50358817, 0xB1AA4705, 0x3BA2BF33, 0xDA3D7021, + 0x86B2E65F, 0x672D294D, 0xED25D17B, 0x0CBA1E69, + 0x55925487, 0xB40D9B95, 0x3E0563A3, 0xDF9AACB1, + 0x83153ACF, 0x628AF5DD, 0xE8820DEB, 0x091DC2F9, + 0x5AD2999E, 0xBB4D568C, 0x3145AEBA, 0xD0DA61A8, + 0x8C55F7D6, 0x6DCA38C4, 0xE7C2C0F2, 0x065D0FE0, + 0x5F75450E, 0xBEEA8A1C, 0x34E2722A, 0xD57DBD38, + 0x89F22B46, 0x686DE454, 0xE2651C62, 0x03FAD370, + 0x4452AAAC, 0xA5CD65BE, 0x2FC59D88, 0xCE5A529A, + 0x92D5C4E4, 0x734A0BF6, 0xF942F3C0, 0x18DD3CD2, + 0x41F5763C, 0xA06AB92E, 0x2A624118, 0xCBFD8E0A, + 0x97721874, 0x76EDD766, 0xFCE52F50, 0x1D7AE042, + 0x4EB5BB25, 0xAF2A7437, 0x25228C01, 0xC4BD4313, + 0x9832D56D, 0x79AD1A7F, 0xF3A5E249, 0x123A2D5B, + 0x4B1267B5, 0xAA8DA8A7, 0x20855091, 0xC11A9F83, + 0x9D9509FD, 0x7C0AC6EF, 0xF6023ED9, 0x179DF1CB, + 0x78FBCCC8, 0x996403DA, 0x136CFBEC, 0xF2F334FE, + 0xAE7CA280, 0x4FE36D92, 0xC5EB95A4, 0x24745AB6, + 0x7D5C1058, 0x9CC3DF4A, 0x16CB277C, 0xF754E86E, + 0xABDB7E10, 0x4A44B102, 0xC04C4934, 0x21D38626, + 0x721CDD41, 0x93831253, 0x198BEA65, 0xF8142577, + 0xA49BB309, 0x45047C1B, 0xCF0C842D, 0x2E934B3F, + 0x77BB01D1, 0x9624CEC3, 0x1C2C36F5, 0xFDB3F9E7, + 0xA13C6F99, 0x40A3A08B, 0xCAAB58BD, 0x2B3497AF, + 0x6C9CEE73, 0x8D032161, 0x070BD957, 0xE6941645, + 0xBA1B803B, 0x5B844F29, 0xD18CB71F, 0x3013780D, + 0x693B32E3, 0x88A4FDF1, 0x02AC05C7, 0xE333CAD5, + 0xBFBC5CAB, 0x5E2393B9, 0xD42B6B8F, 0x35B4A49D, + 0x667BFFFA, 0x87E430E8, 0x0DECC8DE, 0xEC7307CC, + 0xB0FC91B2, 0x51635EA0, 0xDB6BA696, 0x3AF46984, + 0x63DC236A, 0x8243EC78, 0x084B144E, 0xE9D4DB5C, + 0xB55B4D22, 0x54C48230, 0xDECC7A06, 0x3F53B514, +#else + 0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835, + 0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679, + 0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD, + 0xD320B2D4, 0x32BF7DC7, 0xB8B785F2, 0x59284AE1, + 0x0AE71199, 0xEB78DE8A, 0x617026BF, 0x80EFE9AC, + 0xDC607FD5, 0x3DFFB0C6, 0xB7F748F3, 0x566887E0, + 0x0F40CD01, 0xEEDF0212, 0x64D7FA27, 0x85483534, + 0xD9C7A34D, 0x38586C5E, 0xB250946B, 0x53CF5B78, + 0x1467229B, 0xF5F8ED88, 0x7FF015BD, 0x9E6FDAAE, + 0xC2E04CD7, 0x237F83C4, 0xA9777BF1, 0x48E8B4E2, + 0x11C0FE03, 0xF05F3110, 0x7A57C925, 0x9BC80636, + 0xC747904F, 0x26D85F5C, 0xACD0A769, 0x4D4F687A, + 0x1E803302, 0xFF1FFC11, 0x75170424, 0x9488CB37, + 0xC8075D4E, 0x2998925D, 0xA3906A68, 0x420FA57B, + 0x1B27EF9A, 0xFAB82089, 0x70B0D8BC, 0x912F17AF, + 0xCDA081D6, 0x2C3F4EC5, 0xA637B6F0, 0x47A879E3, + 0x28CE449F, 0xC9518B8C, 0x435973B9, 0xA2C6BCAA, + 0xFE492AD3, 0x1FD6E5C0, 0x95DE1DF5, 0x7441D2E6, + 0x2D699807, 0xCCF65714, 0x46FEAF21, 0xA7616032, + 0xFBEEF64B, 0x1A713958, 0x9079C16D, 0x71E60E7E, + 0x22295506, 0xC3B69A15, 0x49BE6220, 0xA821AD33, + 0xF4AE3B4A, 0x1531F459, 0x9F390C6C, 0x7EA6C37F, + 0x278E899E, 0xC611468D, 0x4C19BEB8, 0xAD8671AB, + 0xF109E7D2, 0x109628C1, 0x9A9ED0F4, 0x7B011FE7, + 0x3CA96604, 0xDD36A917, 0x573E5122, 0xB6A19E31, + 0xEA2E0848, 0x0BB1C75B, 0x81B93F6E, 0x6026F07D, + 0x390EBA9C, 0xD891758F, 0x52998DBA, 0xB30642A9, + 0xEF89D4D0, 0x0E161BC3, 0x841EE3F6, 0x65812CE5, + 0x364E779D, 0xD7D1B88E, 0x5DD940BB, 0xBC468FA8, + 0xE0C919D1, 0x0156D6C2, 0x8B5E2EF7, 0x6AC1E1E4, + 0x33E9AB05, 0xD2766416, 0x587E9C23, 0xB9E15330, + 0xE56EC549, 0x04F10A5A, 0x8EF9F26F, 0x6F663D7C, + 0x50358897, 0xB1AA4784, 0x3BA2BFB1, 0xDA3D70A2, + 0x86B2E6DB, 0x672D29C8, 0xED25D1FD, 0x0CBA1EEE, + 0x5592540F, 0xB40D9B1C, 0x3E056329, 0xDF9AAC3A, + 0x83153A43, 0x628AF550, 0xE8820D65, 0x091DC276, + 0x5AD2990E, 0xBB4D561D, 0x3145AE28, 0xD0DA613B, + 0x8C55F742, 0x6DCA3851, 0xE7C2C064, 0x065D0F77, + 0x5F754596, 0xBEEA8A85, 0x34E272B0, 0xD57DBDA3, + 0x89F22BDA, 0x686DE4C9, 0xE2651CFC, 0x03FAD3EF, + 0x4452AA0C, 0xA5CD651F, 0x2FC59D2A, 0xCE5A5239, + 0x92D5C440, 0x734A0B53, 0xF942F366, 0x18DD3C75, + 0x41F57694, 0xA06AB987, 0x2A6241B2, 0xCBFD8EA1, + 0x977218D8, 0x76EDD7CB, 0xFCE52FFE, 0x1D7AE0ED, + 0x4EB5BB95, 0xAF2A7486, 0x25228CB3, 0xC4BD43A0, + 0x9832D5D9, 0x79AD1ACA, 0xF3A5E2FF, 0x123A2DEC, + 0x4B12670D, 0xAA8DA81E, 0x2085502B, 0xC11A9F38, + 0x9D950941, 0x7C0AC652, 0xF6023E67, 0x179DF174, + 0x78FBCC08, 0x9964031B, 0x136CFB2E, 0xF2F3343D, + 0xAE7CA244, 0x4FE36D57, 0xC5EB9562, 0x24745A71, + 0x7D5C1090, 0x9CC3DF83, 0x16CB27B6, 0xF754E8A5, + 0xABDB7EDC, 0x4A44B1CF, 0xC04C49FA, 0x21D386E9, + 0x721CDD91, 0x93831282, 0x198BEAB7, 0xF81425A4, + 0xA49BB3DD, 0x45047CCE, 0xCF0C84FB, 0x2E934BE8, + 0x77BB0109, 0x9624CE1A, 0x1C2C362F, 0xFDB3F93C, + 0xA13C6F45, 0x40A3A056, 0xCAAB5863, 0x2B349770, + 0x6C9CEE93, 0x8D032180, 0x070BD9B5, 0xE69416A6, + 0xBA1B80DF, 0x5B844FCC, 0xD18CB7F9, 0x301378EA, + 0x693B320B, 0x88A4FD18, 0x02AC052D, 0xE333CA3E, + 0xBFBC5C47, 0x5E239354, 0xD42B6B61, 0x35B4A472, + 0x667BFF0A, 0x87E43019, 0x0DECC82C, 0xEC73073F, + 0xB0FC9146, 0x51635E55, 0xDB6BA660, 0x3AF46973, + 0x63DC2392, 0x8243EC81, 0x084B14B4, 0xE9D4DBA7, + 0xB55B4DDE, 0x54C482CD, 0xDECC7AF8, 0x3F53B5EB, +#endif + 0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE, + 0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998, + 0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32, + 0xA04452AA, 0xB84B1267, 0x905AD299, 0x88559254, + 0x29F05F31, 0x31FF1FFC, 0x19EEDF02, 0x01E19FCF, + 0x49CCF657, 0x51C3B69A, 0x79D27664, 0x61DD36A9, + 0xE988A4FD, 0xF187E430, 0xD99624CE, 0xC1996403, + 0x89B40D9B, 0x91BB4D56, 0xB9AA8DA8, 0xA1A5CD65, + 0x5249BE62, 0x4A46FEAF, 0x62573E51, 0x7A587E9C, + 0x32751704, 0x2A7A57C9, 0x026B9737, 0x1A64D7FA, + 0x923145AE, 0x8A3E0563, 0xA22FC59D, 0xBA208550, + 0xF20DECC8, 0xEA02AC05, 0xC2136CFB, 0xDA1C2C36, + 0x7BB9E153, 0x63B6A19E, 0x4BA76160, 0x53A821AD, + 0x1B854835, 0x038A08F8, 0x2B9BC806, 0x339488CB, + 0xBBC11A9F, 0xA3CE5A52, 0x8BDF9AAC, 0x93D0DA61, + 0xDBFDB3F9, 0xC3F2F334, 0xEBE333CA, 0xF3EC7307, + 0xA492D5C4, 0xBC9D9509, 0x948C55F7, 0x8C83153A, + 0xC4AE7CA2, 0xDCA13C6F, 0xF4B0FC91, 0xECBFBC5C, + 0x64EA2E08, 0x7CE56EC5, 0x54F4AE3B, 0x4CFBEEF6, + 0x04D6876E, 0x1CD9C7A3, 0x34C8075D, 0x2CC74790, + 0x8D628AF5, 0x956DCA38, 0xBD7C0AC6, 0xA5734A0B, + 0xED5E2393, 0xF551635E, 0xDD40A3A0, 0xC54FE36D, + 0x4D1A7139, 0x551531F4, 0x7D04F10A, 0x650BB1C7, + 0x2D26D85F, 0x35299892, 0x1D38586C, 0x053718A1, + 0xF6DB6BA6, 0xEED42B6B, 0xC6C5EB95, 0xDECAAB58, + 0x96E7C2C0, 0x8EE8820D, 0xA6F942F3, 0xBEF6023E, + 0x36A3906A, 0x2EACD0A7, 0x06BD1059, 0x1EB25094, + 0x569F390C, 0x4E9079C1, 0x6681B93F, 0x7E8EF9F2, + 0xDF2B3497, 0xC724745A, 0xEF35B4A4, 0xF73AF469, + 0xBF179DF1, 0xA718DD3C, 0x8F091DC2, 0x97065D0F, + 0x1F53CF5B, 0x075C8F96, 0x2F4D4F68, 0x37420FA5, + 0x7F6F663D, 0x676026F0, 0x4F71E60E, 0x577EA6C3, + 0xE18D0321, 0xF98243EC, 0xD1938312, 0xC99CC3DF, + 0x81B1AA47, 0x99BEEA8A, 0xB1AF2A74, 0xA9A06AB9, + 0x21F5F8ED, 0x39FAB820, 0x11EB78DE, 0x09E43813, + 0x41C9518B, 0x59C61146, 0x71D7D1B8, 0x69D89175, + 0xC87D5C10, 0xD0721CDD, 0xF863DC23, 0xE06C9CEE, + 0xA841F576, 0xB04EB5BB, 0x985F7545, 0x80503588, + 0x0805A7DC, 0x100AE711, 0x381B27EF, 0x20146722, + 0x68390EBA, 0x70364E77, 0x58278E89, 0x4028CE44, + 0xB3C4BD43, 0xABCBFD8E, 0x83DA3D70, 0x9BD57DBD, + 0xD3F81425, 0xCBF754E8, 0xE3E69416, 0xFBE9D4DB, + 0x73BC468F, 0x6BB30642, 0x43A2C6BC, 0x5BAD8671, + 0x1380EFE9, 0x0B8FAF24, 0x239E6FDA, 0x3B912F17, + 0x9A34E272, 0x823BA2BF, 0xAA2A6241, 0xB225228C, + 0xFA084B14, 0xE2070BD9, 0xCA16CB27, 0xD2198BEA, + 0x5A4C19BE, 0x42435973, 0x6A52998D, 0x725DD940, + 0x3A70B0D8, 0x227FF015, 0x0A6E30EB, 0x12617026, + 0x451FD6E5, 0x5D109628, 0x750156D6, 0x6D0E161B, + 0x25237F83, 0x3D2C3F4E, 0x153DFFB0, 0x0D32BF7D, + 0x85672D29, 0x9D686DE4, 0xB579AD1A, 0xAD76EDD7, + 0xE55B844F, 0xFD54C482, 0xD545047C, 0xCD4A44B1, + 0x6CEF89D4, 0x74E0C919, 0x5CF109E7, 0x44FE492A, + 0x0CD320B2, 0x14DC607F, 0x3CCDA081, 0x24C2E04C, + 0xAC977218, 0xB49832D5, 0x9C89F22B, 0x8486B2E6, + 0xCCABDB7E, 0xD4A49BB3, 0xFCB55B4D, 0xE4BA1B80, + 0x17566887, 0x0F59284A, 0x2748E8B4, 0x3F47A879, + 0x776AC1E1, 0x6F65812C, 0x477441D2, 0x5F7B011F, + 0xD72E934B, 0xCF21D386, 0xE7301378, 0xFF3F53B5, + 0xB7123A2D, 0xAF1D7AE0, 0x870CBA1E, 0x9F03FAD3, + 0x3EA637B6, 0x26A9777B, 0x0EB8B785, 0x16B7F748, + 0x5E9A9ED0, 0x4695DE1D, 0x6E841EE3, 0x768B5E2E, + 0xFEDECC7A, 0xE6D18CB7, 0xCEC04C49, 0xD6CF0C84, + 0x9EE2651C, 0x86ED25D1, 0xAEFCE52F, 0xB6F3A5E2 +}; +} + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +unsigned int SosemanukPolicy::GetAlignment() const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE +#ifdef __INTEL_COMPILER + if (HasSSE2() && !IsP4()) // Intel compiler produces faster code for this algorithm on the P4 +#else + if (HasSSE2()) +#endif + return 16; + else +#endif + return GetAlignmentOf(); +} + +unsigned int SosemanukPolicy::GetOptimalBlockSize() const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE +#ifdef __INTEL_COMPILER + if (HasSSE2() && !IsP4()) // Intel compiler produces faster code for this algorithm on the P4 +#else + if (HasSSE2()) +#endif + return 4*BYTES_PER_ITERATION; + else +#endif + return BYTES_PER_ITERATION; +} +#endif + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Sosemanuk_OperateKeystream(size_t iterationCount, const byte *input, byte *output, word32 *state); +} +#endif + +void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE + Sosemanuk_OperateKeystream(iterationCount, input, output, m_state.data()); + return; +#endif + +#if CRYPTOPP_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM) +#ifdef CRYPTOPP_GENERATE_X64_MASM + ALIGN 8 + Sosemanuk_OperateKeystream PROC FRAME + rex_push_reg rsi + push_reg rdi + alloc_stack(80*4*2+12*4+8*WORD_SZ + 2*16+8) + save_xmm128 xmm6, 02f0h + save_xmm128 xmm7, 0300h + .endprolog + mov rdi, r8 + mov rax, r9 +#else +#ifdef __INTEL_COMPILER + if (HasSSE2() && !IsP4()) // Intel compiler produces faster code for this algorithm on the P4 +#else + if (HasSSE2()) +#endif + { +#ifdef __GNUC__ + #if CRYPTOPP_BOOL_X64 + FixedSizeAlignedSecBlock workspace; + #endif + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS_PUSH_IF86( bx) +#else + word32 *state = m_state; + AS2( mov WORD_REG(ax), state) + AS2( mov WORD_REG(di), output) + AS2( mov WORD_REG(dx), input) + AS2( mov WORD_REG(cx), iterationCount) +#endif +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#if defined(__GNUC__) && CRYPTOPP_BOOL_X64 + #define SSE2_workspace %5 +#else + #define SSE2_workspace WORD_REG(sp) +#endif + +#define SSE2_output WORD_PTR [SSE2_workspace+1*WORD_SZ] +#define SSE2_input WORD_PTR [SSE2_workspace+2*WORD_SZ] +#define SSE2_wordsLeft WORD_PTR [SSE2_workspace+3*WORD_SZ] +#define SSE2_diEnd WORD_PTR [SSE2_workspace+4*WORD_SZ] +#define SSE2_pMulTables WORD_PTR [SSE2_workspace+5*WORD_SZ] +#define SSE2_state WORD_PTR [SSE2_workspace+6*WORD_SZ] +#define SSE2_wordsLeft2 WORD_PTR [SSE2_workspace+7*WORD_SZ] +#define SSE2_stateCopy SSE2_workspace + 8*WORD_SZ +#define SSE2_uvStart SSE2_stateCopy + 12*4 + +#if (CRYPTOPP_BOOL_X86) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM) + AS_PUSH_IF86( bp) + AS2( mov AS_REG_6, esp) + AS2( and esp, -16) + AS2( sub esp, 80*4*2+12*4+8*WORD_SZ) // 80 v's, 80 u's, 12 state, 8 locals + AS2( mov [esp], AS_REG_6) +#endif + AS2( mov SSE2_output, WORD_REG(di)) + AS2( mov SSE2_input, WORD_REG(dx)) + AS2( mov SSE2_state, WORD_REG(ax)) +#ifndef _MSC_VER + AS2( mov SSE2_pMulTables, WORD_REG(si)) +#endif + AS2( lea WORD_REG(cx), [4*WORD_REG(cx)+WORD_REG(cx)]) + AS2( lea WORD_REG(si), [4*WORD_REG(cx)]) + AS2( mov SSE2_wordsLeft, WORD_REG(si)) + AS2( movdqa xmm0, [WORD_REG(ax)+0*16]) // copy state to stack to save a register + AS2( movdqa [SSE2_stateCopy+0*16], xmm0) + AS2( movdqa xmm0, [WORD_REG(ax)+1*16]) + AS2( movdqa [SSE2_stateCopy+1*16], xmm0) + AS2( movq xmm0, QWORD PTR [WORD_REG(ax)+2*16]) + AS2( movq QWORD PTR [SSE2_stateCopy+2*16], xmm0) + AS2( psrlq xmm0, 32) + AS2( movd AS_REG_6d, xmm0) // s(9) + AS2( mov ecx, [WORD_REG(ax)+10*4]) + AS2( mov edx, [WORD_REG(ax)+11*4]) + AS2( pcmpeqb xmm7, xmm7) // all ones + +#define s(i) SSE2_stateCopy + ASM_MOD(i,10)*4 +#define u(j) WORD_REG(di) + (ASM_MOD(j,4)*20 + (j/4)) * 4 +#define v(j) WORD_REG(di) + (ASM_MOD(j,4)*20 + (j/4)) * 4 + 80*4 + +#define R10 ecx +#define R11 edx +#define R20 edx +#define R21 ecx +// workaround bug in GAS 2.15 +#define R20r WORD_REG(dx) +#define R21r WORD_REG(cx) + +#define SSE2_STEP(i, j) \ + AS2( mov eax, [s(i+0)])\ + AS2( mov [v(i)], eax)\ + AS2( rol eax, 8)\ + AS2( lea AS_REG_7, [AS_REG_6 + R2##j##r])\ + AS2( xor AS_REG_7d, R1##j)\ + AS2( mov [u(i)], AS_REG_7d)\ + AS2( mov AS_REG_7d, 1)\ + AS2( and AS_REG_7d, R2##j)\ + AS1( neg AS_REG_7d)\ + AS2( and AS_REG_7d, AS_REG_6d)\ + AS2( xor AS_REG_6d, eax)\ + AS2( movzx eax, al)\ + AS2( xor AS_REG_6d, [WORD_REG(si)+WORD_REG(ax)*4])\ + AS2( mov eax, [s(i+3)])\ + AS2( xor AS_REG_7d, [s(i+2)])\ + AS2( add R1##j, AS_REG_7d)\ + AS2( movzx AS_REG_7d, al)\ + AS2( shr eax, 8)\ + AS2( xor AS_REG_6d, [WORD_REG(si)+1024+AS_REG_7*4])\ + AS2( xor AS_REG_6d, eax)\ + AS2( imul R2##j, AS_HEX(54655307))\ + AS2( rol R2##j, 7)\ + AS2( mov [s(i+0)], AS_REG_6d)\ + + ASL(2) // outer loop, each iteration of this processes 80 words + AS2( lea WORD_REG(di), [SSE2_uvStart]) // start of v and u + AS2( mov WORD_REG(ax), 80) + AS2( cmp WORD_REG(si), 80) + AS2( cmovg WORD_REG(si), WORD_REG(ax)) + AS2( mov SSE2_wordsLeft2, WORD_REG(si)) + AS2( lea WORD_REG(si), [WORD_REG(di)+WORD_REG(si)]) // use to end first inner loop + AS2( mov SSE2_diEnd, WORD_REG(si)) +#ifdef _MSC_VER + AS2( lea WORD_REG(si), s_sosemanukMulTables) +#else + AS2( mov WORD_REG(si), SSE2_pMulTables) +#endif + + ASL(0) // first inner loop, 20 words each, 4 iterations + SSE2_STEP(0, 0) + SSE2_STEP(1, 1) + SSE2_STEP(2, 0) + SSE2_STEP(3, 1) + SSE2_STEP(4, 0) + SSE2_STEP(5, 1) + SSE2_STEP(6, 0) + SSE2_STEP(7, 1) + SSE2_STEP(8, 0) + SSE2_STEP(9, 1) + SSE2_STEP(10, 0) + SSE2_STEP(11, 1) + SSE2_STEP(12, 0) + SSE2_STEP(13, 1) + SSE2_STEP(14, 0) + SSE2_STEP(15, 1) + SSE2_STEP(16, 0) + SSE2_STEP(17, 1) + SSE2_STEP(18, 0) + SSE2_STEP(19, 1) + // loop + AS2( add WORD_REG(di), 5*4) + AS2( cmp WORD_REG(di), SSE2_diEnd) + ASJ( jne, 0, b) + + AS2( mov WORD_REG(ax), SSE2_input) + AS2( mov AS_REG_7, SSE2_output) + AS2( lea WORD_REG(di), [SSE2_uvStart]) // start of v and u + AS2( mov WORD_REG(si), SSE2_wordsLeft2) + + ASL(1) // second inner loop, 16 words each, 5 iterations + AS2( movdqa xmm0, [WORD_REG(di)+0*20*4]) + AS2( movdqa xmm2, [WORD_REG(di)+2*20*4]) + AS2( movdqa xmm3, [WORD_REG(di)+3*20*4]) + AS2( movdqa xmm1, [WORD_REG(di)+1*20*4]) + // S2 + AS2( movdqa xmm4, xmm0) + AS2( pand xmm0, xmm2) + AS2( pxor xmm0, xmm3) + AS2( pxor xmm2, xmm1) + AS2( pxor xmm2, xmm0) + AS2( por xmm3, xmm4) + AS2( pxor xmm3, xmm1) + AS2( pxor xmm4, xmm2) + AS2( movdqa xmm1, xmm3) + AS2( por xmm3, xmm4) + AS2( pxor xmm3, xmm0) + AS2( pand xmm0, xmm1) + AS2( pxor xmm4, xmm0) + AS2( pxor xmm1, xmm3) + AS2( pxor xmm1, xmm4) + AS2( pxor xmm4, xmm7) + // xor with v + AS2( pxor xmm2, [WORD_REG(di)+80*4]) + AS2( pxor xmm3, [WORD_REG(di)+80*5]) + AS2( pxor xmm1, [WORD_REG(di)+80*6]) + AS2( pxor xmm4, [WORD_REG(di)+80*7]) + // exit loop early if less than 16 words left to output + // this is necessary because block size is 20 words, and we output 16 words in each iteration of this loop + AS2( cmp WORD_REG(si), 16) + ASJ( jl, 4, f) + // unpack + AS2( movdqa xmm6, xmm2) + AS2( punpckldq xmm2, xmm3) + AS2( movdqa xmm5, xmm1) + AS2( punpckldq xmm1, xmm4) + AS2( movdqa xmm0, xmm2) + AS2( punpcklqdq xmm2, xmm1) + AS2( punpckhqdq xmm0, xmm1) + AS2( punpckhdq xmm6, xmm3) + AS2( punpckhdq xmm5, xmm4) + AS2( movdqa xmm3, xmm6) + AS2( punpcklqdq xmm6, xmm5) + AS2( punpckhqdq xmm3, xmm5) + + // output keystream + AS_XMM_OUTPUT4(SSE2_Sosemanuk_Output, WORD_REG(ax), AS_REG_7, 2,0,6,3, 1, 0,1,2,3, 4) + + // loop + AS2( add WORD_REG(di), 4*4) + AS2( sub WORD_REG(si), 16) + ASJ( jnz, 1, b) + + // outer loop + AS2( mov WORD_REG(si), SSE2_wordsLeft) + AS2( sub WORD_REG(si), 80) + ASJ( jz, 6, f) + AS2( mov SSE2_wordsLeft, WORD_REG(si)) + AS2( mov SSE2_input, WORD_REG(ax)) + AS2( mov SSE2_output, AS_REG_7) + ASJ( jmp, 2, b) + + ASL(4) // final output of less than 16 words + AS2( test WORD_REG(ax), WORD_REG(ax)) + ASJ( jz, 5, f) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+0*4]) + AS2( pxor xmm2, xmm0) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+1*4]) + AS2( pxor xmm3, xmm0) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+2*4]) + AS2( pxor xmm1, xmm0) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+3*4]) + AS2( pxor xmm4, xmm0) + AS2( add WORD_REG(ax), 16) + ASL(5) + AS2( movd dword ptr [AS_REG_7+0*4], xmm2) + AS2( movd dword ptr [AS_REG_7+1*4], xmm3) + AS2( movd dword ptr [AS_REG_7+2*4], xmm1) + AS2( movd dword ptr [AS_REG_7+3*4], xmm4) + AS2( sub WORD_REG(si), 4) + ASJ( jz, 6, f) + AS2( add AS_REG_7, 16) + AS2( psrldq xmm2, 4) + AS2( psrldq xmm3, 4) + AS2( psrldq xmm1, 4) + AS2( psrldq xmm4, 4) + ASJ( jmp, 4, b) + + ASL(6) // save state + AS2( mov AS_REG_6, SSE2_state) + AS2( movdqa xmm0, [SSE2_stateCopy+0*16]) + AS2( movdqa [AS_REG_6+0*16], xmm0) + AS2( movdqa xmm0, [SSE2_stateCopy+1*16]) + AS2( movdqa [AS_REG_6+1*16], xmm0) + AS2( movq xmm0, QWORD PTR [SSE2_stateCopy+2*16]) + AS2( movq QWORD PTR [AS_REG_6+2*16], xmm0) + AS2( mov [AS_REG_6+10*4], ecx) + AS2( mov [AS_REG_6+11*4], edx) + + AS_POP_IF86( sp) + AS_POP_IF86( bp) + +#ifdef __GNUC__ + AS_POP_IF86( bx) + ATT_PREFIX + : + : "a" (m_state.data()), "c" (iterationCount), "S" (s_sosemanukMulTables), "D" (output), "d" (input) + #if CRYPTOPP_BOOL_X64 + , "r" (workspace.data()) + : "memory", "cc", "%r9", "%r10", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" + #else + : "memory", "cc" + #endif + ); +#endif +#ifdef CRYPTOPP_GENERATE_X64_MASM + movdqa xmm6, [rsp + 02f0h] + movdqa xmm7, [rsp + 0300h] + add rsp, 80*4*2+12*4+8*WORD_SZ + 2*16+8 + pop rdi + pop rsi + ret + Sosemanuk_OperateKeystream ENDP +#else + } + else +#endif +#endif +#ifndef CRYPTOPP_GENERATE_X64_MASM + { +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_SOSEMANUK_ASM) +#define MUL_A(x) (x = (rotlConstant<8>(x)), x ^ s_sosemanukMulTables[byte(x)]) +#else +#define MUL_A(x) (((x) << 8) ^ s_sosemanukMulTables[(x) >> 24]) +#endif + +#define DIV_A(x) (((x) >> 8) ^ s_sosemanukMulTables[256 + byte(x)]) + +#define r1(i) ((i%2) ? reg2 : reg1) +#define r2(i) ((i%2) ? reg1 : reg2) + +#define STEP(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, v, u) \ + u = (s##x9 + r2(x0)) ^ r1(x0);\ + t = v = s##x0;\ + s##x0 = MUL_A(t) ^ DIV_A(s##x3) ^ s##x9;\ + r1(x0) += XMUX(r2(x0), s##x2, s##x9);\ + r2(x0) = rotlFixed(r2(x0) * 0x54655307, 7);\ + +#define SOSEMANUK_OUTPUT(x) \ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, u2 ^ v0);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, u3 ^ v1);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, u1 ^ v2);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, u4 ^ v3); + +#define OUTPUT4 \ + S2(0, u0, u1, u2, u3, u4);\ + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SOSEMANUK_OUTPUT, 4*4); + + word32 s0 = m_state[0]; + word32 s1 = m_state[1]; + word32 s2 = m_state[2]; + word32 s3 = m_state[3]; + word32 s4 = m_state[4]; + word32 s5 = m_state[5]; + word32 s6 = m_state[6]; + word32 s7 = m_state[7]; + word32 s8 = m_state[8]; + word32 s9 = m_state[9]; + word32 reg1 = m_state[10]; + word32 reg2 = m_state[11]; + word32 t, u0, u1, u2, u3, u4, v0, v1, v2, v3; + + do + { + STEP(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, v0, u0) + STEP(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, v1, u1) + STEP(2, 3, 4, 5, 6, 7, 8, 9, 0, 1, v2, u2) + STEP(3, 4, 5, 6, 7, 8, 9, 0, 1, 2, v3, u3) + OUTPUT4 + STEP(4, 5, 6, 7, 8, 9, 0, 1, 2, 3, v0, u0) + STEP(5, 6, 7, 8, 9, 0, 1, 2, 3, 4, v1, u1) + STEP(6, 7, 8, 9, 0, 1, 2, 3, 4, 5, v2, u2) + STEP(7, 8, 9, 0, 1, 2, 3, 4, 5, 6, v3, u3) + OUTPUT4 + STEP(8, 9, 0, 1, 2, 3, 4, 5, 6, 7, v0, u0) + STEP(9, 0, 1, 2, 3, 4, 5, 6, 7, 8, v1, u1) + STEP(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, v2, u2) + STEP(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, v3, u3) + OUTPUT4 + STEP(2, 3, 4, 5, 6, 7, 8, 9, 0, 1, v0, u0) + STEP(3, 4, 5, 6, 7, 8, 9, 0, 1, 2, v1, u1) + STEP(4, 5, 6, 7, 8, 9, 0, 1, 2, 3, v2, u2) + STEP(5, 6, 7, 8, 9, 0, 1, 2, 3, 4, v3, u3) + OUTPUT4 + STEP(6, 7, 8, 9, 0, 1, 2, 3, 4, 5, v0, u0) + STEP(7, 8, 9, 0, 1, 2, 3, 4, 5, 6, v1, u1) + STEP(8, 9, 0, 1, 2, 3, 4, 5, 6, 7, v2, u2) + STEP(9, 0, 1, 2, 3, 4, 5, 6, 7, 8, v3, u3) + OUTPUT4 + } + while (--iterationCount); + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; + m_state[4] = s4; + m_state[5] = s5; + m_state[6] = s6; + m_state[7] = s7; + m_state[8] = s8; + m_state[9] = s9; + m_state[10] = reg1; + m_state[11] = reg2; + } +} + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM diff --git a/external/ours/library/crypto/src/shared/original/sosemanuk.h b/external/ours/library/crypto/src/shared/original/sosemanuk.h new file mode 100755 index 000000000..94ebcfead --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sosemanuk.h @@ -0,0 +1,62 @@ +// sosemanuk.h - originally written and placed in the public domain by Wei Dai + +/// \file sosemanuk.h +/// \brief Classes for Sosemanuk stream cipher +/// \since Crypto++ 5.5 + +#ifndef CRYPTOPP_SOSEMANUK_H +#define CRYPTOPP_SOSEMANUK_H + +#include "strciphr.h" +#include "secblock.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_SOSEMANUK_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Sosemanuk stream cipher information +/// \since Crypto++ 5.5 +struct SosemanukInfo : public VariableKeyLength<16, 1, 32, 1, SimpleKeyingInterface::UNIQUE_IV, 16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Sosemanuk";} +}; + +/// \brief Sosemanuk stream cipher implementation +/// \since Crypto++ 5.5 +class SosemanukPolicy : public AdditiveCipherConcretePolicy, public SosemanukInfo +{ +protected: + std::string AlgorithmProvider() const; + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); + bool CipherIsRandomAccess() const {return false;} +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; +#endif + + FixedSizeSecBlock m_key; + FixedSizeAlignedSecBlock m_state; +}; + +/// \brief Sosemanuk stream cipher +/// \details is a stream cipher developed by Come Berbain, Olivier Billet, Anne Canteaut, Nicolas Courtois, +/// Henri Gilbert, Louis Goubin, Aline Gouget, Louis Granboulan, Cédric Lauradoux, Marine Minier, Thomas +/// Pornin and Hervé Sibert. Sosemanuk is one of the final four Profile 1 (software) ciphers selected for +/// the eSTREAM Portfolio. +/// \sa Sosemanuk +/// \since Crypto++ 5.5 +struct Sosemanuk : public SosemanukInfo, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, SosemanukInfo> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/speck.cpp b/external/ours/library/crypto/src/shared/original/speck.cpp new file mode 100755 index 000000000..00b960d78 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/speck.cpp @@ -0,0 +1,487 @@ +// speck.cpp - written and placed in the public domain by Jeffrey Walton + +#include "pch.h" +#include "config.h" + +#include "speck.h" +#include "misc.h" +#include "cpu.h" + +// Uncomment for benchmarking C++ against SSE or NEON. +// Do so in both speck.cpp and speck_simd.cpp. +// #undef CRYPTOPP_SSSE3_AVAILABLE +// #undef CRYPTOPP_SSE41_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlConstant; +using CryptoPP::rotrConstant; + +/// \brief Forward round transformation +/// \tparam W word type +/// \details TF83() is the forward round transformation using a=8 and b=3 rotations. +/// The initial test implementation provided template parameters, but they were +/// removed because SPECK32 using a=7 and b=2 was not on the road map. The +/// additional template parameters also made calling SPECK_Encrypt and SPECK_Decrypt +/// kind of messy. +template +inline void TF83(W& x, W& y, const W k) +{ + x = rotrConstant<8>(x); + x += y; x ^= k; + y = rotlConstant<3>(y); + y ^= x; +} + +/// \brief Reverse round transformation +/// \tparam W word type +/// \details TR83() is the reverse round transformation using a=8 and b=3 rotations. +/// The initial test implementation provided template parameters, but they were +/// removed because SPECK32 using a=7 and b=2 was not on the road map. The +/// additional template parameters also made calling SPECK_Encrypt and SPECK_Decrypt +/// kind of messy. +template +inline void TR83(W& x, W& y, const W k) +{ + y ^= x; + y = rotrConstant<3>(y); + x ^= k; x -= y; + x = rotlConstant<8>(x); +} + +/// \brief Forward transformation +/// \tparam W word type +/// \tparam R number of rounds +/// \param c output array +/// \param p input array +/// \param k subkey array +template +inline void SPECK_Encrypt(W c[2], const W p[2], const W k[R]) +{ + c[0]=p[0]; c[1]=p[1]; + + // Don't unroll this loop. Things slow down. + for (int i = 0; i < static_cast(R); ++i) + TF83(c[0], c[1], k[i]); +} + +/// \brief Reverse transformation +/// \tparam W word type +/// \tparam R number of rounds +/// \param p output array +/// \param c input array +/// \param k subkey array +template +inline void SPECK_Decrypt(W p[2], const W c[2], const W k[R]) +{ + p[0]=c[0]; p[1]=c[1]; + + // Don't unroll this loop. Things slow down. + for (int i = static_cast(R-1); i >= 0; --i) + TR83(p[0], p[1], k[i]); +} + +/// \brief Subkey generation function +/// \details Used when the user key consists of 2 words +/// \tparam W word type +/// \tparam R number of rounds +/// \param key empty subkey array +/// \param k user key array +template +inline void SPECK_ExpandKey_2W(W key[R], const W k[2]) +{ + CRYPTOPP_ASSERT(R==32); + W i=0, B=k[0], A=k[1]; + + while (i +inline void SPECK_ExpandKey_3W(W key[R], const W k[3]) +{ + CRYPTOPP_ASSERT(R==33 || R==26); + W i=0, C=k[0], B=k[1], A=k[2]; + + unsigned int blocks = R/2; + while (blocks--) + { + key[i+0]=A; TF83(B, A, i+0); + key[i+1]=A; TF83(C, A, i+1); + i+=2; + } + + // The constexpr residue should allow the optimizer to remove unneeded statements + if(R%2 == 1) + { + key[R-1]=A; + } +} + +/// \brief Subkey generation function +/// \details Used when the user key consists of 4 words +/// \tparam W word type +/// \tparam R number of rounds +/// \param key empty subkey array +/// \param k user key array +template +inline void SPECK_ExpandKey_4W(W key[R], const W k[4]) +{ + CRYPTOPP_ASSERT(R==34 || R==27); + W i=0, D=k[0], C=k[1], B=k[2], A=k[3]; + + unsigned int blocks = R/3; + while (blocks--) + { + key[i+0]=A; TF83(B, A, i+0); + key[i+1]=A; TF83(C, A, i+1); + key[i+2]=A; TF83(D, A, i+2); + i+=3; + } + + // The constexpr residue should allow the optimizer to remove unneeded statements + if(R%3 == 1) + { + key[R-1]=A; + } + else if(R%3 == 2) + { + key[R-2]=A; TF83(B, A, W(R-2)); + key[R-1]=A; + } +} + +ANONYMOUS_NAMESPACE_END + +/////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) +extern size_t SPECK128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SPECK128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOPP_SSE41_AVAILABLE) +extern size_t SPECK64_Enc_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SPECK64_Dec_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOPP_SSSE3_AVAILABLE) +extern size_t SPECK128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SPECK128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +extern size_t SPECK128_Enc_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); + +extern size_t SPECK128_Dec_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags); +#endif + +std::string SPECK64::Base::AlgorithmProvider() const +{ + return "C++"; +} + +unsigned int SPECK64::Base::OptimalDataAlignment() const +{ + return GetAlignmentOf(); +} + +void SPECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16); + CRYPTOPP_UNUSED(params); + + // Building the key schedule table requires {3,4} words workspace. + // Encrypting and decrypting requires 4 words workspace. + m_kwords = keyLength/sizeof(word32); + m_wspace.New(4U); + + // Do the endian gyrations from the paper and align pointers + typedef GetBlock KeyBlock; + KeyBlock kblk(userKey); + + switch (m_kwords) + { + case 3: + m_rkeys.New((m_rounds = 26)); + kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SPECK_ExpandKey_3W(m_rkeys, m_wspace); + break; + case 4: + m_rkeys.New((m_rounds = 27)); + kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SPECK_ExpandKey_4W(m_rkeys, m_wspace); + break; + default: + CRYPTOPP_ASSERT(0); + } +} + +void SPECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do the endian gyrations from the paper and align pointers + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 26: + SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 27: + SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +void SPECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do the endian gyrations from the paper and align pointers + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 26: + SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 27: + SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +/////////////////////////////////////////////////////////// + +std::string SPECK128::Base::AlgorithmProvider() const +{ +#if (CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS) +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return "SSSE3"; +# endif +# if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; +# endif +# if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return "Altivec"; +# endif +#endif + return "C++"; +} + +unsigned int SPECK128::Base::OptimalDataAlignment() const +{ +#if (CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS) +# if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return 16; // load __m128i +# endif +# if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return 8; // load uint64x2_t +# endif +# if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return 16; // load uint64x2_p +# endif +#endif + return GetAlignmentOf(); +} + +void SPECK128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32); + CRYPTOPP_UNUSED(params); + + // Building the key schedule table requires {2,3,4} words workspace. + // Encrypting and decrypting requires 4 words workspace. + m_kwords = keyLength/sizeof(word64); + m_wspace.New(4U); + + // Do the endian gyrations from the paper and align pointers + typedef GetBlock KeyBlock; + KeyBlock kblk(userKey); + + switch (m_kwords) + { + case 2: + m_rkeys.New((m_rounds = 32)); + kblk(m_wspace[1])(m_wspace[0]); + SPECK_ExpandKey_2W(m_rkeys, m_wspace); + break; + case 3: + m_rkeys.New((m_rounds = 33)); + kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SPECK_ExpandKey_3W(m_rkeys, m_wspace); + break; + case 4: + m_rkeys.New((m_rounds = 34)); + kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); + SPECK_ExpandKey_4W(m_rkeys, m_wspace); + break; + default: + CRYPTOPP_ASSERT(0); + } + +#if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS + + // Pre-splat the round keys for Altivec forward transformation +#if CRYPTOPP_ALTIVEC_AVAILABLE + if (IsForwardTransformation() && HasAltivec()) + { + AlignedSecBlock presplat(m_rkeys.size()*2); + for (size_t i=0, j=0; i InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 32: + SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 33: + SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 34: + SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +void SPECK128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do the endian gyrations from the paper and align pointers + typedef GetBlock InBlock; + InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]); + + switch (m_rounds) + { + case 32: + SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 33: + SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + case 34: + SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); + break; + default: + CRYPTOPP_ASSERT(0); + } + + // Do the endian gyrations from the paper and align pointers + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]); +} + +#if (CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS) +size_t SPECK128::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return SPECK128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return SPECK128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return SPECK128_Enc_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SPECK128::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, + byte *outBlocks, size_t length, word32 flags) const +{ +#if (CRYPTOPP_SSSE3_AVAILABLE) + if (HasSSSE3()) + return SPECK128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return SPECK128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif +#if (CRYPTOPP_ALTIVEC_AVAILABLE) + if (HasAltivec()) + return SPECK128_Dec_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (size_t)m_rounds, + inBlocks, xorBlocks, outBlocks, length, flags); +#endif + return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/speck.h b/external/ours/library/crypto/src/shared/original/speck.h new file mode 100755 index 000000000..dbbdf2f66 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/speck.h @@ -0,0 +1,206 @@ +// speck.h - written and placed in the public domain by Jeffrey Walton + +/// \file speck.h +/// \brief Classes for the Speck block cipher +/// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, +/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. +/// \sa The SIMON and SPECK Families of +/// Lightweight Block Ciphers, +/// The Simon and Speck GitHub and +/// SPECK on the Crypto++ wiki. +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_SPECK_H +#define CRYPTOPP_SPECK_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || \ + CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 || \ + CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 +# ifndef CRYPTOPP_DISABLE_SPECK_SIMD +# define CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS 1 +# endif +#endif + +// Yet another SunStudio/SunCC workaround. Failed self tests +// in SSE code paths on i386 for SunStudio 12.3 and below. +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) +# undef CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SPECK block cipher information +/// \tparam L block size of the cipher, in bytes +/// \tparam D default key length, in bytes +/// \tparam N minimum key length, in bytes +/// \tparam M maximum key length, in bytes +/// \since Crypto++ 6.0 +template +struct SPECK_Info : public FixedBlockSize, VariableKeyLength +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize(Keylength) + return "SPECK-" + IntToString(L*8); + } +}; + +/// \brief SPECK block cipher base class +/// \tparam W the word type +/// \details User code should use SPECK64 or SPECK128 +/// \sa SPECK64, SPECK128, SPECK +/// \since Crypto++ 6.0 +template +struct SPECK_Base +{ + virtual ~SPECK_Base() {} + SPECK_Base() : m_kwords(0), m_rounds(0) {} + + typedef SecBlock > AlignedSecBlock; + mutable AlignedSecBlock m_wspace; // workspace + AlignedSecBlock m_rkeys; // round keys + unsigned int m_kwords; // number of key words + unsigned int m_rounds; // number of rounds +}; + +/// \brief SPECK 64-bit block cipher +/// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, +/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. +/// \details SPECK64 provides 64-bit block size. The valid key sizes are 96-bit and 128-bit. +/// \sa SPECK64, SPECK128, The SIMON and SPECK +/// Families of Lightweight Block Ciphers, +/// The Simon and Speck GitHub, SPECK on the +/// Crypto++ wiki +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE SPECK64 : public SPECK_Info<8, 12, 12, 16>, public BlockCipherDocumentation +{ +public: + /// \brief SPECK64 block cipher base implementation + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base, public BlockCipherImpl > + { + public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details AlgorithmName returns the algorithm's name as a + /// member function. + std::string AlgorithmName() const { + return StaticAlgorithmName() + (m_kwords == 0 ? "" : + "(" + IntToString(m_kwords*sizeof(word32)*8) + ")"); + } + + std::string AlgorithmProvider() const; + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const; + + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief SPECK64 encryption transformation + /// \details Enc provides the encryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief SPECK64 decryption transformation + /// \details Dec provides the decryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief SPECK 128-bit block cipher +/// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith, +/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers. +/// \details SPECK128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit. +/// \sa SPECK64, SPECK128, The SIMON and SPECK +/// Families of Lightweight Block Ciphers, +/// The Simon and Speck GitHub, SPECK on the +/// Crypto++ wiki +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE SPECK128 : public SPECK_Info<16, 16, 16, 32>, public BlockCipherDocumentation +{ +public: + /// \brief SPECK128 block cipher base implementation + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base, public BlockCipherImpl > + { + public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details AlgorithmName returns the algorithm's name as a + /// member function. + std::string AlgorithmName() const { + return StaticAlgorithmName() + (m_kwords == 0 ? "" : + "(" + IntToString(m_kwords*sizeof(word64)*8) + ")"); + } + + std::string AlgorithmProvider() const; + + /// \brief Provides input and output data alignment for optimal performance. + /// \return the input data alignment that provides optimal performance + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const; + + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief SPECK128 encryption transformation + /// \details Enc provides the encryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + /// \brief SPECK128 decryption transformation + /// \details Dec provides the decryption transformation. + /// All key sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; +#if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS + size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; +#endif + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SPECK_H diff --git a/external/ours/library/crypto/src/shared/original/speck128_simd.cpp b/external/ours/library/crypto/src/shared/original/speck128_simd.cpp new file mode 100755 index 000000000..a17ce38d4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/speck128_simd.cpp @@ -0,0 +1,754 @@ +// speck128_simd.cpp - written and placed in the public domain by Jeffrey Walton +// +// This source file uses intrinsics and built-ins to gain access to +// SSSE3, ARM NEON and ARMv8a, and Altivec instructions. A separate +// source file is needed because additional CXXFLAGS are required to enable +// the appropriate instructions sets in some build configurations. + +#include "pch.h" +#include "config.h" + +#include "speck.h" +#include "misc.h" + +// Uncomment for benchmarking C++ against SSE or NEON. +// Do so in both speck.cpp and speck_simd.cpp. +// #undef CRYPTOPP_SSSE3_AVAILABLE +// #undef CRYPTOPP_ARM_NEON_AVAILABLE + +#if (CRYPTOPP_SSSE3_AVAILABLE) +# include "adv_simd.h" +# include +# include +#endif + +#if defined(__XOP__) +# include +# if defined(__GNUC__) +# include +# endif +#endif + +#if (CRYPTOPP_ARM_NEON_HEADER) +# include "adv_simd.h" +# include +#endif + +#if (CRYPTOPP_ARM_ACLE_HEADER) +# include +# include +#endif + +#if defined(_M_ARM64) +# include "adv_simd.h" +#endif + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# include "adv_simd.h" +# include "ppc_simd.h" +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char SPECK128_SIMD_FNAME[] = __FILE__; + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::word64; + +// *************************** ARM NEON ************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + +// Missing from Microsoft's ARM A-32 implementation +#if defined(_MSC_VER) && !defined(_M_ARM64) +inline uint64x2_t vld1q_dup_u64(const uint64_t* ptr) +{ + return vmovq_n_u64(*ptr); +} +#endif + +template +inline T UnpackHigh64(const T& a, const T& b) +{ + const uint64x1_t x(vget_high_u64((uint64x2_t)a)); + const uint64x1_t y(vget_high_u64((uint64x2_t)b)); + return (T)vcombine_u64(x, y); +} + +template +inline T UnpackLow64(const T& a, const T& b) +{ + const uint64x1_t x(vget_low_u64((uint64x2_t)a)); + const uint64x1_t y(vget_low_u64((uint64x2_t)b)); + return (T)vcombine_u64(x, y); +} + +template +inline uint64x2_t RotateLeft64(const uint64x2_t& val) +{ + const uint64x2_t a(vshlq_n_u64(val, R)); + const uint64x2_t b(vshrq_n_u64(val, 64 - R)); + return vorrq_u64(a, b); +} + +template +inline uint64x2_t RotateRight64(const uint64x2_t& val) +{ + const uint64x2_t a(vshlq_n_u64(val, 64 - R)); + const uint64x2_t b(vshrq_n_u64(val, R)); + return vorrq_u64(a, b); +} + +#if defined(__aarch32__) || defined(__aarch64__) +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +inline uint64x2_t RotateLeft64<8>(const uint64x2_t& val) +{ + const uint8_t maskb[16] = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 }; + const uint8x16_t mask = vld1q_u8(maskb); + + return vreinterpretq_u64_u8( + vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +inline uint64x2_t RotateRight64<8>(const uint64x2_t& val) +{ + const uint8_t maskb[16] = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 }; + const uint8x16_t mask = vld1q_u8(maskb); + + return vreinterpretq_u64_u8( + vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); +} +#endif + +inline void SPECK128_Enc_Block(uint64x2_t &block0, uint64x2_t &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + + for (size_t i=0; i < static_cast(rounds); ++i) + { + const uint64x2_t rk = vld1q_dup_u64(subkeys+i); + + x1 = RotateRight64<8>(x1); + x1 = vaddq_u64(x1, y1); + x1 = veorq_u64(x1, rk); + y1 = RotateLeft64<3>(y1); + y1 = veorq_u64(y1, x1); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); +} + +inline void SPECK128_Enc_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, + uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + uint64x2_t x2 = UnpackHigh64(block2, block3); + uint64x2_t y2 = UnpackLow64(block2, block3); + uint64x2_t x3 = UnpackHigh64(block4, block5); + uint64x2_t y3 = UnpackLow64(block4, block5); + + for (size_t i=0; i < static_cast(rounds); ++i) + { + const uint64x2_t rk = vld1q_dup_u64(subkeys+i); + + x1 = RotateRight64<8>(x1); + x2 = RotateRight64<8>(x2); + x3 = RotateRight64<8>(x3); + x1 = vaddq_u64(x1, y1); + x2 = vaddq_u64(x2, y2); + x3 = vaddq_u64(x3, y3); + x1 = veorq_u64(x1, rk); + x2 = veorq_u64(x2, rk); + x3 = veorq_u64(x3, rk); + y1 = RotateLeft64<3>(y1); + y2 = RotateLeft64<3>(y2); + y3 = RotateLeft64<3>(y3); + y1 = veorq_u64(y1, x1); + y2 = veorq_u64(y2, x2); + y3 = veorq_u64(y3, x3); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); + block2 = UnpackLow64(y2, x2); + block3 = UnpackHigh64(y2, x2); + block4 = UnpackLow64(y3, x3); + block5 = UnpackHigh64(y3, x3); +} + +inline void SPECK128_Dec_Block(uint64x2_t &block0, uint64x2_t &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + + for (int i = static_cast(rounds-1); i >= 0; --i) + { + const uint64x2_t rk = vld1q_dup_u64(subkeys+i); + + y1 = veorq_u64(y1, x1); + y1 = RotateRight64<3>(y1); + x1 = veorq_u64(x1, rk); + x1 = vsubq_u64(x1, y1); + x1 = RotateLeft64<8>(x1); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); +} + +inline void SPECK128_Dec_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, + uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + uint64x2_t x1 = UnpackHigh64(block0, block1); + uint64x2_t y1 = UnpackLow64(block0, block1); + uint64x2_t x2 = UnpackHigh64(block2, block3); + uint64x2_t y2 = UnpackLow64(block2, block3); + uint64x2_t x3 = UnpackHigh64(block4, block5); + uint64x2_t y3 = UnpackLow64(block4, block5); + + for (int i = static_cast(rounds-1); i >= 0; --i) + { + const uint64x2_t rk = vld1q_dup_u64(subkeys+i); + + y1 = veorq_u64(y1, x1); + y2 = veorq_u64(y2, x2); + y3 = veorq_u64(y3, x3); + y1 = RotateRight64<3>(y1); + y2 = RotateRight64<3>(y2); + y3 = RotateRight64<3>(y3); + x1 = veorq_u64(x1, rk); + x2 = veorq_u64(x2, rk); + x3 = veorq_u64(x3, rk); + x1 = vsubq_u64(x1, y1); + x2 = vsubq_u64(x2, y2); + x3 = vsubq_u64(x3, y3); + x1 = RotateLeft64<8>(x1); + x2 = RotateLeft64<8>(x2); + x3 = RotateLeft64<8>(x3); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = UnpackLow64(y1, x1); + block1 = UnpackHigh64(y1, x1); + block2 = UnpackLow64(y2, x2); + block3 = UnpackHigh64(y2, x2); + block4 = UnpackLow64(y3, x3); + block5 = UnpackHigh64(y3, x3); +} + +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// ***************************** IA-32 ***************************** // + +#if defined(CRYPTOPP_SSSE3_AVAILABLE) + +// GCC double casts, https://www.spinics.net/lists/gcchelp/msg47735.html +#ifndef DOUBLE_CAST +# define DOUBLE_CAST(x) ((double *)(void *)(x)) +#endif +#ifndef CONST_DOUBLE_CAST +# define CONST_DOUBLE_CAST(x) ((const double *)(const void *)(x)) +#endif + +template +inline __m128i RotateLeft64(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, R); +#else + return _mm_or_si128( + _mm_slli_epi64(val, R), _mm_srli_epi64(val, 64-R)); +#endif +} + +template +inline __m128i RotateRight64(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, 64-R); +#else + return _mm_or_si128( + _mm_slli_epi64(val, 64-R), _mm_srli_epi64(val, R)); +#endif +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +__m128i RotateLeft64<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, 8); +#else + const __m128i mask = _mm_set_epi8(14,13,12,11, 10,9,8,15, 6,5,4,3, 2,1,0,7); + return _mm_shuffle_epi8(val, mask); +#endif +} + +// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. +template <> +__m128i RotateRight64<8>(const __m128i& val) +{ +#if defined(__XOP__) + return _mm_roti_epi64(val, 64-8); +#else + const __m128i mask = _mm_set_epi8(8,15,14,13, 12,11,10,9, 0,7,6,5, 4,3,2,1); + return _mm_shuffle_epi8(val, mask); +#endif +} + +inline void SPECK128_Enc_Block(__m128i &block0, __m128i &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + + for (size_t i=0; i < static_cast(rounds); ++i) + { + // Round keys are pre-splated in forward direction + const __m128i rk = _mm_load_si128(CONST_M128_CAST(subkeys+i*2)); + + x1 = RotateRight64<8>(x1); + x1 = _mm_add_epi64(x1, y1); + x1 = _mm_xor_si128(x1, rk); + y1 = RotateLeft64<3>(y1); + y1 = _mm_xor_si128(y1, x1); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); +} + +inline void SPECK128_Enc_6_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + __m128i x2 = _mm_unpackhi_epi64(block2, block3); + __m128i y2 = _mm_unpacklo_epi64(block2, block3); + __m128i x3 = _mm_unpackhi_epi64(block4, block5); + __m128i y3 = _mm_unpacklo_epi64(block4, block5); + + for (size_t i=0; i < static_cast(rounds); ++i) + { + // Round keys are pre-splated in forward direction + const __m128i rk = _mm_load_si128(CONST_M128_CAST(subkeys+i*2)); + + x1 = RotateRight64<8>(x1); + x2 = RotateRight64<8>(x2); + x3 = RotateRight64<8>(x3); + x1 = _mm_add_epi64(x1, y1); + x2 = _mm_add_epi64(x2, y2); + x3 = _mm_add_epi64(x3, y3); + x1 = _mm_xor_si128(x1, rk); + x2 = _mm_xor_si128(x2, rk); + x3 = _mm_xor_si128(x3, rk); + y1 = RotateLeft64<3>(y1); + y2 = RotateLeft64<3>(y2); + y3 = RotateLeft64<3>(y3); + y1 = _mm_xor_si128(y1, x1); + y2 = _mm_xor_si128(y2, x2); + y3 = _mm_xor_si128(y3, x3); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); + block2 = _mm_unpacklo_epi64(y2, x2); + block3 = _mm_unpackhi_epi64(y2, x2); + block4 = _mm_unpacklo_epi64(y3, x3); + block5 = _mm_unpackhi_epi64(y3, x3); +} + +inline void SPECK128_Dec_Block(__m128i &block0, __m128i &block1, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + + for (int i = static_cast(rounds-1); i >= 0; --i) + { + const __m128i rk = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); + + y1 = _mm_xor_si128(y1, x1); + y1 = RotateRight64<3>(y1); + x1 = _mm_xor_si128(x1, rk); + x1 = _mm_sub_epi64(x1, y1); + x1 = RotateLeft64<8>(x1); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); +} + +inline void SPECK128_Dec_6_Blocks(__m128i &block0, __m128i &block1, + __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, + const word64 *subkeys, unsigned int rounds) +{ + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + __m128i x1 = _mm_unpackhi_epi64(block0, block1); + __m128i y1 = _mm_unpacklo_epi64(block0, block1); + __m128i x2 = _mm_unpackhi_epi64(block2, block3); + __m128i y2 = _mm_unpacklo_epi64(block2, block3); + __m128i x3 = _mm_unpackhi_epi64(block4, block5); + __m128i y3 = _mm_unpacklo_epi64(block4, block5); + + for (int i = static_cast(rounds-1); i >= 0; --i) + { + const __m128i rk = _mm_castpd_si128( + _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); + + y1 = _mm_xor_si128(y1, x1); + y2 = _mm_xor_si128(y2, x2); + y3 = _mm_xor_si128(y3, x3); + y1 = RotateRight64<3>(y1); + y2 = RotateRight64<3>(y2); + y3 = RotateRight64<3>(y3); + x1 = _mm_xor_si128(x1, rk); + x2 = _mm_xor_si128(x2, rk); + x3 = _mm_xor_si128(x3, rk); + x1 = _mm_sub_epi64(x1, y1); + x2 = _mm_sub_epi64(x2, y2); + x3 = _mm_sub_epi64(x3, y3); + x1 = RotateLeft64<8>(x1); + x2 = RotateLeft64<8>(x2); + x3 = RotateLeft64<8>(x3); + } + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = _mm_unpacklo_epi64(y1, x1); + block1 = _mm_unpackhi_epi64(y1, x1); + block2 = _mm_unpacklo_epi64(y2, x2); + block3 = _mm_unpackhi_epi64(y2, x2); + block4 = _mm_unpacklo_epi64(y3, x3); + block5 = _mm_unpackhi_epi64(y3, x3); +} + +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// ***************************** Altivec ***************************** // + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) + +// Altivec uses native 64-bit types on 64-bit environments, or 32-bit types +// in 32-bit environments. Speck128 will use the appropriate type for the +// environment. Functions like VecAdd64 have two overloads, one for each +// environment. The 32-bit overload treats uint32x4_p like a 64-bit type, +// and does things like perform a add with carry or subtract with borrow. + +// Speck128 on Power8 performed as expected because of 64-bit environment. +// Performance sucked on old PowerPC machines because of 32-bit environments. +// At Crypto++ 8.3 we added an implementation that operated on 32-bit words. +// Native 64-bit Speck128 performance dropped from about 4.1 to 6.3 cpb, but +// 32-bit Speck128 improved from 66.5 cpb to 10.4 cpb. Overall it was a +// good win even though we lost some performance in 64-bit environments. + +using CryptoPP::uint8x16_p; +using CryptoPP::uint32x4_p; +#if defined(_ARCH_PWR8) +using CryptoPP::uint64x2_p; +#endif + +using CryptoPP::VecAdd64; +using CryptoPP::VecSub64; +using CryptoPP::VecAnd64; +using CryptoPP::VecOr64; +using CryptoPP::VecXor64; +using CryptoPP::VecSplatWord64; +using CryptoPP::VecRotateLeft64; +using CryptoPP::VecRotateRight64; +using CryptoPP::VecLoad; +using CryptoPP::VecLoadAligned; +using CryptoPP::VecPermute; + +#if defined(_ARCH_PWR8) +#define speck128_t uint64x2_p +#else +#define speck128_t uint32x4_p +#endif + +void SPECK128_Enc_Block(uint32x4_p &block, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + speck128_t x1 = (speck128_t)VecPermute(block, block, m1); + speck128_t y1 = (speck128_t)VecPermute(block, block, m2); + + for (size_t i=0; i < static_cast(rounds); ++i) + { + // Round keys are pre-splated in forward direction + const word32* ptr = reinterpret_cast(subkeys+i*2); + const speck128_t rk = (speck128_t)VecLoadAligned(ptr); + + x1 = (speck128_t)VecRotateRight64<8>(x1); + x1 = (speck128_t)VecAdd64(x1, y1); + x1 = (speck128_t)VecXor64(x1, rk); + + y1 = (speck128_t)VecRotateLeft64<3>(y1); + y1 = (speck128_t)VecXor64(y1, x1); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + //const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + //const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block = (uint32x4_p)VecPermute(x1, y1, m3); +} + +void SPECK128_Dec_Block(uint32x4_p &block, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + speck128_t x1 = (speck128_t)VecPermute(block, block, m1); + speck128_t y1 = (speck128_t)VecPermute(block, block, m2); + + for (int i = static_cast(rounds-1); i >= 0; --i) + { + const speck128_t rk = (speck128_t)VecSplatWord64(subkeys[i]); + + y1 = (speck128_t)VecXor64(y1, x1); + y1 = (speck128_t)VecRotateRight64<3>(y1); + x1 = (speck128_t)VecXor64(x1, rk); + x1 = (speck128_t)VecSub64(x1, y1); + x1 = (speck128_t)VecRotateLeft64<8>(x1); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + //const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + //const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block = (uint32x4_p)VecPermute(x1, y1, m3); +} + +void SPECK128_Enc_6_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, uint32x4_p &block4, + uint32x4_p &block5, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + speck128_t x1 = (speck128_t)VecPermute(block0, block1, m1); + speck128_t y1 = (speck128_t)VecPermute(block0, block1, m2); + speck128_t x2 = (speck128_t)VecPermute(block2, block3, m1); + speck128_t y2 = (speck128_t)VecPermute(block2, block3, m2); + speck128_t x3 = (speck128_t)VecPermute(block4, block5, m1); + speck128_t y3 = (speck128_t)VecPermute(block4, block5, m2); + + for (size_t i=0; i < static_cast(rounds); ++i) + { + // Round keys are pre-splated in forward direction + const word32* ptr = reinterpret_cast(subkeys+i*2); + const speck128_t rk = (speck128_t)VecLoadAligned(ptr); + + x1 = (speck128_t)VecRotateRight64<8>(x1); + x2 = (speck128_t)VecRotateRight64<8>(x2); + x3 = (speck128_t)VecRotateRight64<8>(x3); + x1 = (speck128_t)VecAdd64(x1, y1); + x2 = (speck128_t)VecAdd64(x2, y2); + x3 = (speck128_t)VecAdd64(x3, y3); + x1 = (speck128_t)VecXor64(x1, rk); + x2 = (speck128_t)VecXor64(x2, rk); + x3 = (speck128_t)VecXor64(x3, rk); + + y1 = (speck128_t)VecRotateLeft64<3>(y1); + y2 = (speck128_t)VecRotateLeft64<3>(y2); + y3 = (speck128_t)VecRotateLeft64<3>(y3); + y1 = (speck128_t)VecXor64(y1, x1); + y2 = (speck128_t)VecXor64(y2, x2); + y3 = (speck128_t)VecXor64(y3, x3); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = (uint32x4_p)VecPermute(x1, y1, m3); + block1 = (uint32x4_p)VecPermute(x1, y1, m4); + block2 = (uint32x4_p)VecPermute(x2, y2, m3); + block3 = (uint32x4_p)VecPermute(x2, y2, m4); + block4 = (uint32x4_p)VecPermute(x3, y3, m3); + block5 = (uint32x4_p)VecPermute(x3, y3, m4); +} + +void SPECK128_Dec_6_Blocks(uint32x4_p &block0, uint32x4_p &block1, + uint32x4_p &block2, uint32x4_p &block3, uint32x4_p &block4, + uint32x4_p &block5, const word64 *subkeys, unsigned int rounds) +{ +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m1 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m2 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m1 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m2 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... + speck128_t x1 = (speck128_t)VecPermute(block0, block1, m1); + speck128_t y1 = (speck128_t)VecPermute(block0, block1, m2); + speck128_t x2 = (speck128_t)VecPermute(block2, block3, m1); + speck128_t y2 = (speck128_t)VecPermute(block2, block3, m2); + speck128_t x3 = (speck128_t)VecPermute(block4, block5, m1); + speck128_t y3 = (speck128_t)VecPermute(block4, block5, m2); + + for (int i = static_cast(rounds-1); i >= 0; --i) + { + const speck128_t rk = (speck128_t)VecSplatWord64(subkeys[i]); + + y1 = (speck128_t)VecXor64(y1, x1); + y2 = (speck128_t)VecXor64(y2, x2); + y3 = (speck128_t)VecXor64(y3, x3); + y1 = (speck128_t)VecRotateRight64<3>(y1); + y2 = (speck128_t)VecRotateRight64<3>(y2); + y3 = (speck128_t)VecRotateRight64<3>(y3); + + x1 = (speck128_t)VecXor64(x1, rk); + x2 = (speck128_t)VecXor64(x2, rk); + x3 = (speck128_t)VecXor64(x3, rk); + x1 = (speck128_t)VecSub64(x1, y1); + x2 = (speck128_t)VecSub64(x2, y2); + x3 = (speck128_t)VecSub64(x3, y3); + x1 = (speck128_t)VecRotateLeft64<8>(x1); + x2 = (speck128_t)VecRotateLeft64<8>(x2); + x3 = (speck128_t)VecRotateLeft64<8>(x3); + } + +#if (CRYPTOPP_BIG_ENDIAN) + const uint8x16_p m3 = {31,30,29,28,27,26,25,24, 15,14,13,12,11,10,9,8}; + const uint8x16_p m4 = {23,22,21,20,19,18,17,16, 7,6,5,4,3,2,1,0}; +#else + const uint8x16_p m3 = {7,6,5,4,3,2,1,0, 23,22,21,20,19,18,17,16}; + const uint8x16_p m4 = {15,14,13,12,11,10,9,8, 31,30,29,28,27,26,25,24}; +#endif + + // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... + block0 = (uint32x4_p)VecPermute(x1, y1, m3); + block1 = (uint32x4_p)VecPermute(x1, y1, m4); + block2 = (uint32x4_p)VecPermute(x2, y2, m3); + block3 = (uint32x4_p)VecPermute(x2, y2, m4); + block4 = (uint32x4_p)VecPermute(x3, y3, m3); + block5 = (uint32x4_p)VecPermute(x3, y3, m4); +} + +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +ANONYMOUS_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +// *************************** ARM NEON **************************** // + +#if (CRYPTOPP_ARM_NEON_AVAILABLE) +size_t SPECK128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_NEON(SPECK128_Enc_Block, SPECK128_Enc_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SPECK128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_NEON(SPECK128_Dec_Block, SPECK128_Dec_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_ARM_NEON_AVAILABLE + +// ***************************** IA-32 ***************************** // + +#if (CRYPTOPP_SSSE3_AVAILABLE) +size_t SPECK128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_SSE(SPECK128_Enc_Block, SPECK128_Enc_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SPECK128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x2_SSE(SPECK128_Dec_Block, SPECK128_Dec_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_SSSE3_AVAILABLE + +// ***************************** Altivec ***************************** // + +#if (CRYPTOPP_ALTIVEC_AVAILABLE) +size_t SPECK128_Enc_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x1_ALTIVEC(SPECK128_Enc_Block, SPECK128_Enc_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} + +size_t SPECK128_Dec_AdvancedProcessBlocks_ALTIVEC(const word64* subKeys, size_t rounds, + const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) +{ + return AdvancedProcessBlocks128_6x1_ALTIVEC(SPECK128_Dec_Block, SPECK128_Dec_6_Blocks, + subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); +} +#endif // CRYPTOPP_ALTIVEC_AVAILABLE + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/square.cpp b/external/ours/library/crypto/src/shared/original/square.cpp new file mode 100755 index 000000000..4065a7f33 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/square.cpp @@ -0,0 +1,187 @@ +// square.cpp - originally written and placed in the public domain by Wei Dai +// Based on Paulo S.L.M. Barreto's public domain implementation + +#include "pch.h" +#include "config.h" + +#include "square.h" +#include "misc.h" +#include "gf256.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4244) +#endif + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wmissing-braces" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// apply theta to a roundkey +static void SquareTransform (word32 in[4], word32 out[4]) +{ + static const byte G[4][4] = + { + 0x02U, 0x01U, 0x01U, 0x03U, + 0x03U, 0x02U, 0x01U, 0x01U, + 0x01U, 0x03U, 0x02U, 0x01U, + 0x01U, 0x01U, 0x03U, 0x02U + }; + + GF256 gf256(0xf5); + + for (int i = 0; i < 4; i++) + { + word32 temp = 0; + for (unsigned int j = 0; j < 4; j++) + for (unsigned int k = 0; k < 4; k++) + temp ^= (word32)gf256.Multiply(GETBYTE(in[i], 3-k), G[k][j]) << ((3-j)*8); + out[i] = temp; + } +} + +#define roundkeys(i, j) m_roundkeys[(i)*4+(j)] +#define roundkeys4(i) (m_roundkeys+(i)*4) + +void Square::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + static const word32 offset[ROUNDS] = { + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, + }; + + GetUserKey(BIG_ENDIAN_ORDER, m_roundkeys.data(), KEYLENGTH/4, userKey, KEYLENGTH); + + /* apply the key evolution function */ + for (int i = 1; i < ROUNDS+1; i++) + { + roundkeys(i, 0) = roundkeys(i-1, 0) ^ rotlConstant<8>(roundkeys(i-1, 3)) ^ offset[i-1]; + roundkeys(i, 1) = roundkeys(i-1, 1) ^ roundkeys(i, 0); + roundkeys(i, 2) = roundkeys(i-1, 2) ^ roundkeys(i, 1); + roundkeys(i, 3) = roundkeys(i-1, 3) ^ roundkeys(i, 2); + } + + /* produce the round keys */ + if (IsForwardTransformation()) + { + for (int i = 0; i < ROUNDS; i++) + SquareTransform (roundkeys4(i), roundkeys4(i)); + } + else + { + for (int i = 0; i < ROUNDS/2; i++) + for (int j = 0; j < 4; j++) + std::swap(roundkeys(i, j), roundkeys(ROUNDS-i, j)); + SquareTransform (roundkeys4(ROUNDS), roundkeys4(ROUNDS)); + } +} + +#define MSB(x) (((x) >> 24) & 0xffU) /* most significant byte */ +#define SSB(x) (((x) >> 16) & 0xffU) /* second in significance */ +#define TSB(x) (((x) >> 8) & 0xffU) /* third in significance */ +#define LSB(x) (((x) ) & 0xffU) /* least significant byte */ + +#define squareRound(text, temp, T0, T1, T2, T3, roundkey) \ +{ \ + temp[0] = T0[MSB (text[0])] \ + ^ T1[MSB (text[1])] \ + ^ T2[MSB (text[2])] \ + ^ T3[MSB (text[3])] \ + ^ roundkey[0]; \ + temp[1] = T0[SSB (text[0])] \ + ^ T1[SSB (text[1])] \ + ^ T2[SSB (text[2])] \ + ^ T3[SSB (text[3])] \ + ^ roundkey[1]; \ + temp[2] = T0[TSB (text[0])] \ + ^ T1[TSB (text[1])] \ + ^ T2[TSB (text[2])] \ + ^ T3[TSB (text[3])] \ + ^ roundkey[2]; \ + temp[3] = T0[LSB (text[0])] \ + ^ T1[LSB (text[1])] \ + ^ T2[LSB (text[2])] \ + ^ T3[LSB (text[3])] \ + ^ roundkey[3]; \ +} /* squareRound */ + +#define squareFinal(text, temp, S, roundkey) \ +{ \ + text[0] = ((word32) (S[MSB (temp[0])]) << 24) \ + ^ ((word32) (S[MSB (temp[1])]) << 16) \ + ^ ((word32) (S[MSB (temp[2])]) << 8) \ + ^ (word32) (S[MSB (temp[3])]) \ + ^ roundkey[0]; \ + text[1] = ((word32) (S[SSB (temp[0])]) << 24) \ + ^ ((word32) (S[SSB (temp[1])]) << 16) \ + ^ ((word32) (S[SSB (temp[2])]) << 8) \ + ^ (word32) (S[SSB (temp[3])]) \ + ^ roundkey[1]; \ + text[2] = ((word32) (S[TSB (temp[0])]) << 24) \ + ^ ((word32) (S[TSB (temp[1])]) << 16) \ + ^ ((word32) (S[TSB (temp[2])]) << 8) \ + ^ (word32) (S[TSB (temp[3])]) \ + ^ roundkey[2]; \ + text[3] = ((word32) (S[LSB (temp[0])]) << 24) \ + ^ ((word32) (S[LSB (temp[1])]) << 16) \ + ^ ((word32) (S[LSB (temp[2])]) << 8) \ + ^ (word32) (S[LSB (temp[3])]) \ + ^ roundkey[3]; \ +} /* squareFinal */ + +typedef BlockGetAndPut Block; + +void Square::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 text[4], temp[4]; + Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]); + + /* initial key addition */ + text[0] ^= roundkeys(0, 0); + text[1] ^= roundkeys(0, 1); + text[2] ^= roundkeys(0, 2); + text[3] ^= roundkeys(0, 3); + + /* ROUNDS - 1 full rounds */ + for (int i=1; i+1, public FixedKeyLength<16>, FixedRounds<8> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Square";} +}; + +/// \brief Square block cipher +/// \sa Square +/// \since Crypto++ 2.2 +class Square : public Square_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_roundkeys; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Se[256]; + static const word32 Te[4][256]; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Sd[256]; + static const word32 Td[4][256]; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Square::Encryption SquareEncryption; +typedef Square::Decryption SquareDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/squaretb.cpp b/external/ours/library/crypto/src/shared/original/squaretb.cpp new file mode 100755 index 000000000..e806f610d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/squaretb.cpp @@ -0,0 +1,582 @@ +#include "pch.h" +#include "square.h" + +NAMESPACE_BEGIN(CryptoPP) + +const byte Square::Enc::Se[256] = { +177, 206, 195, 149, 90, 173, 231, 2, 77, 68, 251, 145, 12, 135, 161, 80, +203, 103, 84, 221, 70, 143, 225, 78, 240, 253, 252, 235, 249, 196, 26, 110, + 94, 245, 204, 141, 28, 86, 67, 254, 7, 97, 248, 117, 89, 255, 3, 34, +138, 209, 19, 238, 136, 0, 14, 52, 21, 128, 148, 227, 237, 181, 83, 35, + 75, 71, 23, 167, 144, 53, 171, 216, 184, 223, 79, 87, 154, 146, 219, 27, + 60, 200, 153, 4, 142, 224, 215, 125, 133, 187, 64, 44, 58, 69, 241, 66, +101, 32, 65, 24, 114, 37, 147, 112, 54, 5, 242, 11, 163, 121, 236, 8, + 39, 49, 50, 182, 124, 176, 10, 115, 91, 123, 183, 129, 210, 13, 106, 38, +158, 88, 156, 131, 116, 179, 172, 48, 122, 105, 119, 15, 174, 33, 222, 208, + 46, 151, 16, 164, 152, 168, 212, 104, 45, 98, 41, 109, 22, 73, 118, 199, +232, 193, 150, 55, 229, 202, 244, 233, 99, 18, 194, 166, 20, 188, 211, 40, +175, 47, 230, 36, 82, 198, 160, 9, 189, 140, 207, 93, 17, 95, 1, 197, +159, 61, 162, 155, 201, 59, 190, 81, 25, 31, 63, 92, 178, 239, 74, 205, +191, 186, 111, 100, 217, 243, 62, 180, 170, 220, 213, 6, 192, 126, 246, 102, +108, 132, 113, 56, 185, 29, 127, 157, 72, 139, 42, 218, 165, 51, 130, 57, +214, 120, 134, 250, 228, 43, 169, 30, 137, 96, 107, 234, 85, 76, 247, 226, +}; + +const byte Square::Dec::Sd[256] = { + 53, 190, 7, 46, 83, 105, 219, 40, 111, 183, 118, 107, 12, 125, 54, 139, +146, 188, 169, 50, 172, 56, 156, 66, 99, 200, 30, 79, 36, 229, 247, 201, + 97, 141, 47, 63, 179, 101, 127, 112, 175, 154, 234, 245, 91, 152, 144, 177, +135, 113, 114, 237, 55, 69, 104, 163, 227, 239, 92, 197, 80, 193, 214, 202, + 90, 98, 95, 38, 9, 93, 20, 65, 232, 157, 206, 64, 253, 8, 23, 74, + 15, 199, 180, 62, 18, 252, 37, 75, 129, 44, 4, 120, 203, 187, 32, 189, +249, 41, 153, 168, 211, 96, 223, 17, 151, 137, 126, 250, 224, 155, 31, 210, +103, 226, 100, 119, 132, 43, 158, 138, 241, 109, 136, 121, 116, 87, 221, 230, + 57, 123, 238, 131, 225, 88, 242, 13, 52, 248, 48, 233, 185, 35, 84, 21, + 68, 11, 77, 102, 58, 3, 162, 145, 148, 82, 76, 195, 130, 231, 128, 192, +182, 14, 194, 108, 147, 236, 171, 67, 149, 246, 216, 70, 134, 5, 140, 176, +117, 0, 204, 133, 215, 61, 115, 122, 72, 228, 209, 89, 173, 184, 198, 208, +220, 161, 170, 2, 29, 191, 181, 159, 81, 196, 165, 16, 34, 207, 1, 186, +143, 49, 124, 174, 150, 218, 240, 86, 71, 212, 235, 78, 217, 19, 142, 73, + 85, 22, 255, 59, 244, 164, 178, 6, 160, 167, 251, 27, 110, 60, 51, 205, + 24, 94, 106, 213, 166, 33, 222, 254, 42, 28, 243, 10, 26, 25, 39, 45, +}; + +const word32 Square::Enc::Te[4][256] = { +{ +0x97b1b126UL, 0x69cecea7UL, 0x73c3c3b0UL, 0xdf95954aUL, +0xb45a5aeeUL, 0xafadad02UL, 0x3be7e7dcUL, 0x04020206UL, +0x9a4d4dd7UL, 0x884444ccUL, 0x03fbfbf8UL, 0xd7919146UL, +0x180c0c14UL, 0xfb87877cUL, 0xb7a1a116UL, 0xa05050f0UL, +0x63cbcba8UL, 0xce6767a9UL, 0xa85454fcUL, 0x4fdddd92UL, +0x8c4646caUL, 0xeb8f8f64UL, 0x37e1e1d6UL, 0x9c4e4ed2UL, +0x15f0f0e5UL, 0x0ffdfdf2UL, 0x0dfcfcf1UL, 0x23ebebc8UL, +0x07f9f9feUL, 0x7dc4c4b9UL, 0x341a1a2eUL, 0xdc6e6eb2UL, +0xbc5e5ee2UL, 0x1ff5f5eaUL, 0x6dcccca1UL, 0xef8d8d62UL, +0x381c1c24UL, 0xac5656faUL, 0x864343c5UL, 0x09fefef7UL, +0x0e070709UL, 0xc26161a3UL, 0x05f8f8fdUL, 0xea75759fUL, +0xb25959ebUL, 0x0bfffff4UL, 0x06030305UL, 0x44222266UL, +0xe18a8a6bUL, 0x57d1d186UL, 0x26131335UL, 0x29eeeec7UL, +0xe588886dUL, 0x00000000UL, 0x1c0e0e12UL, 0x6834345cUL, +0x2a15153fUL, 0xf5808075UL, 0xdd949449UL, 0x33e3e3d0UL, +0x2fededc2UL, 0x9fb5b52aUL, 0xa65353f5UL, 0x46232365UL, +0x964b4bddUL, 0x8e4747c9UL, 0x2e171739UL, 0xbba7a71cUL, +0xd5909045UL, 0x6a35355fUL, 0xa3abab08UL, 0x45d8d89dUL, +0x85b8b83dUL, 0x4bdfdf94UL, 0x9e4f4fd1UL, 0xae5757f9UL, +0xc19a9a5bUL, 0xd1929243UL, 0x43dbdb98UL, 0x361b1b2dUL, +0x783c3c44UL, 0x65c8c8adUL, 0xc799995eUL, 0x0804040cUL, +0xe98e8e67UL, 0x35e0e0d5UL, 0x5bd7d78cUL, 0xfa7d7d87UL, +0xff85857aUL, 0x83bbbb38UL, 0x804040c0UL, 0x582c2c74UL, +0x743a3a4eUL, 0x8a4545cfUL, 0x17f1f1e6UL, 0x844242c6UL, +0xca6565afUL, 0x40202060UL, 0x824141c3UL, 0x30181828UL, +0xe4727296UL, 0x4a25256fUL, 0xd3939340UL, 0xe0707090UL, +0x6c36365aUL, 0x0a05050fUL, 0x11f2f2e3UL, 0x160b0b1dUL, +0xb3a3a310UL, 0xf279798bUL, 0x2dececc1UL, 0x10080818UL, +0x4e272769UL, 0x62313153UL, 0x64323256UL, 0x99b6b62fUL, +0xf87c7c84UL, 0x95b0b025UL, 0x140a0a1eUL, 0xe6737395UL, +0xb65b5bedUL, 0xf67b7b8dUL, 0x9bb7b72cUL, 0xf7818176UL, +0x51d2d283UL, 0x1a0d0d17UL, 0xd46a6abeUL, 0x4c26266aUL, +0xc99e9e57UL, 0xb05858e8UL, 0xcd9c9c51UL, 0xf3838370UL, +0xe874749cUL, 0x93b3b320UL, 0xadacac01UL, 0x60303050UL, +0xf47a7a8eUL, 0xd26969bbUL, 0xee777799UL, 0x1e0f0f11UL, +0xa9aeae07UL, 0x42212163UL, 0x49dede97UL, 0x55d0d085UL, +0x5c2e2e72UL, 0xdb97974cUL, 0x20101030UL, 0xbda4a419UL, +0xc598985dUL, 0xa5a8a80dUL, 0x5dd4d489UL, 0xd06868b8UL, +0x5a2d2d77UL, 0xc46262a6UL, 0x5229297bUL, 0xda6d6db7UL, +0x2c16163aUL, 0x924949dbUL, 0xec76769aUL, 0x7bc7c7bcUL, +0x25e8e8cdUL, 0x77c1c1b6UL, 0xd996964fUL, 0x6e373759UL, +0x3fe5e5daUL, 0x61cacaabUL, 0x1df4f4e9UL, 0x27e9e9ceUL, +0xc66363a5UL, 0x24121236UL, 0x71c2c2b3UL, 0xb9a6a61fUL, +0x2814143cUL, 0x8dbcbc31UL, 0x53d3d380UL, 0x50282878UL, +0xabafaf04UL, 0x5e2f2f71UL, 0x39e6e6dfUL, 0x4824246cUL, +0xa45252f6UL, 0x79c6c6bfUL, 0xb5a0a015UL, 0x1209091bUL, +0x8fbdbd32UL, 0xed8c8c61UL, 0x6bcfcfa4UL, 0xba5d5de7UL, +0x22111133UL, 0xbe5f5fe1UL, 0x02010103UL, 0x7fc5c5baUL, +0xcb9f9f54UL, 0x7a3d3d47UL, 0xb1a2a213UL, 0xc39b9b58UL, +0x67c9c9aeUL, 0x763b3b4dUL, 0x89bebe37UL, 0xa25151f3UL, +0x3219192bUL, 0x3e1f1f21UL, 0x7e3f3f41UL, 0xb85c5ce4UL, +0x91b2b223UL, 0x2befefc4UL, 0x944a4adeUL, 0x6fcdcda2UL, +0x8bbfbf34UL, 0x81baba3bUL, 0xde6f6fb1UL, 0xc86464acUL, +0x47d9d99eUL, 0x13f3f3e0UL, 0x7c3e3e42UL, 0x9db4b429UL, +0xa1aaaa0bUL, 0x4ddcdc91UL, 0x5fd5d58aUL, 0x0c06060aUL, +0x75c0c0b5UL, 0xfc7e7e82UL, 0x19f6f6efUL, 0xcc6666aaUL, +0xd86c6cb4UL, 0xfd848479UL, 0xe2717193UL, 0x70383848UL, +0x87b9b93eUL, 0x3a1d1d27UL, 0xfe7f7f81UL, 0xcf9d9d52UL, +0x904848d8UL, 0xe38b8b68UL, 0x542a2a7eUL, 0x41dada9bUL, +0xbfa5a51aUL, 0x66333355UL, 0xf1828273UL, 0x7239394bUL, +0x59d6d68fUL, 0xf0787888UL, 0xf986867fUL, 0x01fafafbUL, +0x3de4e4d9UL, 0x562b2b7dUL, 0xa7a9a90eUL, 0x3c1e1e22UL, +0xe789896eUL, 0xc06060a0UL, 0xd66b6bbdUL, 0x21eaeacbUL, +0xaa5555ffUL, 0x984c4cd4UL, 0x1bf7f7ecUL, 0x31e2e2d3UL, +}, + +{ +0x2697b1b1UL, 0xa769ceceUL, 0xb073c3c3UL, 0x4adf9595UL, +0xeeb45a5aUL, 0x02afadadUL, 0xdc3be7e7UL, 0x06040202UL, +0xd79a4d4dUL, 0xcc884444UL, 0xf803fbfbUL, 0x46d79191UL, +0x14180c0cUL, 0x7cfb8787UL, 0x16b7a1a1UL, 0xf0a05050UL, +0xa863cbcbUL, 0xa9ce6767UL, 0xfca85454UL, 0x924fddddUL, +0xca8c4646UL, 0x64eb8f8fUL, 0xd637e1e1UL, 0xd29c4e4eUL, +0xe515f0f0UL, 0xf20ffdfdUL, 0xf10dfcfcUL, 0xc823ebebUL, +0xfe07f9f9UL, 0xb97dc4c4UL, 0x2e341a1aUL, 0xb2dc6e6eUL, +0xe2bc5e5eUL, 0xea1ff5f5UL, 0xa16dccccUL, 0x62ef8d8dUL, +0x24381c1cUL, 0xfaac5656UL, 0xc5864343UL, 0xf709fefeUL, +0x090e0707UL, 0xa3c26161UL, 0xfd05f8f8UL, 0x9fea7575UL, +0xebb25959UL, 0xf40bffffUL, 0x05060303UL, 0x66442222UL, +0x6be18a8aUL, 0x8657d1d1UL, 0x35261313UL, 0xc729eeeeUL, +0x6de58888UL, 0x00000000UL, 0x121c0e0eUL, 0x5c683434UL, +0x3f2a1515UL, 0x75f58080UL, 0x49dd9494UL, 0xd033e3e3UL, +0xc22fededUL, 0x2a9fb5b5UL, 0xf5a65353UL, 0x65462323UL, +0xdd964b4bUL, 0xc98e4747UL, 0x392e1717UL, 0x1cbba7a7UL, +0x45d59090UL, 0x5f6a3535UL, 0x08a3ababUL, 0x9d45d8d8UL, +0x3d85b8b8UL, 0x944bdfdfUL, 0xd19e4f4fUL, 0xf9ae5757UL, +0x5bc19a9aUL, 0x43d19292UL, 0x9843dbdbUL, 0x2d361b1bUL, +0x44783c3cUL, 0xad65c8c8UL, 0x5ec79999UL, 0x0c080404UL, +0x67e98e8eUL, 0xd535e0e0UL, 0x8c5bd7d7UL, 0x87fa7d7dUL, +0x7aff8585UL, 0x3883bbbbUL, 0xc0804040UL, 0x74582c2cUL, +0x4e743a3aUL, 0xcf8a4545UL, 0xe617f1f1UL, 0xc6844242UL, +0xafca6565UL, 0x60402020UL, 0xc3824141UL, 0x28301818UL, +0x96e47272UL, 0x6f4a2525UL, 0x40d39393UL, 0x90e07070UL, +0x5a6c3636UL, 0x0f0a0505UL, 0xe311f2f2UL, 0x1d160b0bUL, +0x10b3a3a3UL, 0x8bf27979UL, 0xc12dececUL, 0x18100808UL, +0x694e2727UL, 0x53623131UL, 0x56643232UL, 0x2f99b6b6UL, +0x84f87c7cUL, 0x2595b0b0UL, 0x1e140a0aUL, 0x95e67373UL, +0xedb65b5bUL, 0x8df67b7bUL, 0x2c9bb7b7UL, 0x76f78181UL, +0x8351d2d2UL, 0x171a0d0dUL, 0xbed46a6aUL, 0x6a4c2626UL, +0x57c99e9eUL, 0xe8b05858UL, 0x51cd9c9cUL, 0x70f38383UL, +0x9ce87474UL, 0x2093b3b3UL, 0x01adacacUL, 0x50603030UL, +0x8ef47a7aUL, 0xbbd26969UL, 0x99ee7777UL, 0x111e0f0fUL, +0x07a9aeaeUL, 0x63422121UL, 0x9749dedeUL, 0x8555d0d0UL, +0x725c2e2eUL, 0x4cdb9797UL, 0x30201010UL, 0x19bda4a4UL, +0x5dc59898UL, 0x0da5a8a8UL, 0x895dd4d4UL, 0xb8d06868UL, +0x775a2d2dUL, 0xa6c46262UL, 0x7b522929UL, 0xb7da6d6dUL, +0x3a2c1616UL, 0xdb924949UL, 0x9aec7676UL, 0xbc7bc7c7UL, +0xcd25e8e8UL, 0xb677c1c1UL, 0x4fd99696UL, 0x596e3737UL, +0xda3fe5e5UL, 0xab61cacaUL, 0xe91df4f4UL, 0xce27e9e9UL, +0xa5c66363UL, 0x36241212UL, 0xb371c2c2UL, 0x1fb9a6a6UL, +0x3c281414UL, 0x318dbcbcUL, 0x8053d3d3UL, 0x78502828UL, +0x04abafafUL, 0x715e2f2fUL, 0xdf39e6e6UL, 0x6c482424UL, +0xf6a45252UL, 0xbf79c6c6UL, 0x15b5a0a0UL, 0x1b120909UL, +0x328fbdbdUL, 0x61ed8c8cUL, 0xa46bcfcfUL, 0xe7ba5d5dUL, +0x33221111UL, 0xe1be5f5fUL, 0x03020101UL, 0xba7fc5c5UL, +0x54cb9f9fUL, 0x477a3d3dUL, 0x13b1a2a2UL, 0x58c39b9bUL, +0xae67c9c9UL, 0x4d763b3bUL, 0x3789bebeUL, 0xf3a25151UL, +0x2b321919UL, 0x213e1f1fUL, 0x417e3f3fUL, 0xe4b85c5cUL, +0x2391b2b2UL, 0xc42befefUL, 0xde944a4aUL, 0xa26fcdcdUL, +0x348bbfbfUL, 0x3b81babaUL, 0xb1de6f6fUL, 0xacc86464UL, +0x9e47d9d9UL, 0xe013f3f3UL, 0x427c3e3eUL, 0x299db4b4UL, +0x0ba1aaaaUL, 0x914ddcdcUL, 0x8a5fd5d5UL, 0x0a0c0606UL, +0xb575c0c0UL, 0x82fc7e7eUL, 0xef19f6f6UL, 0xaacc6666UL, +0xb4d86c6cUL, 0x79fd8484UL, 0x93e27171UL, 0x48703838UL, +0x3e87b9b9UL, 0x273a1d1dUL, 0x81fe7f7fUL, 0x52cf9d9dUL, +0xd8904848UL, 0x68e38b8bUL, 0x7e542a2aUL, 0x9b41dadaUL, +0x1abfa5a5UL, 0x55663333UL, 0x73f18282UL, 0x4b723939UL, +0x8f59d6d6UL, 0x88f07878UL, 0x7ff98686UL, 0xfb01fafaUL, +0xd93de4e4UL, 0x7d562b2bUL, 0x0ea7a9a9UL, 0x223c1e1eUL, +0x6ee78989UL, 0xa0c06060UL, 0xbdd66b6bUL, 0xcb21eaeaUL, +0xffaa5555UL, 0xd4984c4cUL, 0xec1bf7f7UL, 0xd331e2e2UL, +}, + +{ +0xb12697b1UL, 0xcea769ceUL, 0xc3b073c3UL, 0x954adf95UL, +0x5aeeb45aUL, 0xad02afadUL, 0xe7dc3be7UL, 0x02060402UL, +0x4dd79a4dUL, 0x44cc8844UL, 0xfbf803fbUL, 0x9146d791UL, +0x0c14180cUL, 0x877cfb87UL, 0xa116b7a1UL, 0x50f0a050UL, +0xcba863cbUL, 0x67a9ce67UL, 0x54fca854UL, 0xdd924fddUL, +0x46ca8c46UL, 0x8f64eb8fUL, 0xe1d637e1UL, 0x4ed29c4eUL, +0xf0e515f0UL, 0xfdf20ffdUL, 0xfcf10dfcUL, 0xebc823ebUL, +0xf9fe07f9UL, 0xc4b97dc4UL, 0x1a2e341aUL, 0x6eb2dc6eUL, +0x5ee2bc5eUL, 0xf5ea1ff5UL, 0xcca16dccUL, 0x8d62ef8dUL, +0x1c24381cUL, 0x56faac56UL, 0x43c58643UL, 0xfef709feUL, +0x07090e07UL, 0x61a3c261UL, 0xf8fd05f8UL, 0x759fea75UL, +0x59ebb259UL, 0xfff40bffUL, 0x03050603UL, 0x22664422UL, +0x8a6be18aUL, 0xd18657d1UL, 0x13352613UL, 0xeec729eeUL, +0x886de588UL, 0x00000000UL, 0x0e121c0eUL, 0x345c6834UL, +0x153f2a15UL, 0x8075f580UL, 0x9449dd94UL, 0xe3d033e3UL, +0xedc22fedUL, 0xb52a9fb5UL, 0x53f5a653UL, 0x23654623UL, +0x4bdd964bUL, 0x47c98e47UL, 0x17392e17UL, 0xa71cbba7UL, +0x9045d590UL, 0x355f6a35UL, 0xab08a3abUL, 0xd89d45d8UL, +0xb83d85b8UL, 0xdf944bdfUL, 0x4fd19e4fUL, 0x57f9ae57UL, +0x9a5bc19aUL, 0x9243d192UL, 0xdb9843dbUL, 0x1b2d361bUL, +0x3c44783cUL, 0xc8ad65c8UL, 0x995ec799UL, 0x040c0804UL, +0x8e67e98eUL, 0xe0d535e0UL, 0xd78c5bd7UL, 0x7d87fa7dUL, +0x857aff85UL, 0xbb3883bbUL, 0x40c08040UL, 0x2c74582cUL, +0x3a4e743aUL, 0x45cf8a45UL, 0xf1e617f1UL, 0x42c68442UL, +0x65afca65UL, 0x20604020UL, 0x41c38241UL, 0x18283018UL, +0x7296e472UL, 0x256f4a25UL, 0x9340d393UL, 0x7090e070UL, +0x365a6c36UL, 0x050f0a05UL, 0xf2e311f2UL, 0x0b1d160bUL, +0xa310b3a3UL, 0x798bf279UL, 0xecc12decUL, 0x08181008UL, +0x27694e27UL, 0x31536231UL, 0x32566432UL, 0xb62f99b6UL, +0x7c84f87cUL, 0xb02595b0UL, 0x0a1e140aUL, 0x7395e673UL, +0x5bedb65bUL, 0x7b8df67bUL, 0xb72c9bb7UL, 0x8176f781UL, +0xd28351d2UL, 0x0d171a0dUL, 0x6abed46aUL, 0x266a4c26UL, +0x9e57c99eUL, 0x58e8b058UL, 0x9c51cd9cUL, 0x8370f383UL, +0x749ce874UL, 0xb32093b3UL, 0xac01adacUL, 0x30506030UL, +0x7a8ef47aUL, 0x69bbd269UL, 0x7799ee77UL, 0x0f111e0fUL, +0xae07a9aeUL, 0x21634221UL, 0xde9749deUL, 0xd08555d0UL, +0x2e725c2eUL, 0x974cdb97UL, 0x10302010UL, 0xa419bda4UL, +0x985dc598UL, 0xa80da5a8UL, 0xd4895dd4UL, 0x68b8d068UL, +0x2d775a2dUL, 0x62a6c462UL, 0x297b5229UL, 0x6db7da6dUL, +0x163a2c16UL, 0x49db9249UL, 0x769aec76UL, 0xc7bc7bc7UL, +0xe8cd25e8UL, 0xc1b677c1UL, 0x964fd996UL, 0x37596e37UL, +0xe5da3fe5UL, 0xcaab61caUL, 0xf4e91df4UL, 0xe9ce27e9UL, +0x63a5c663UL, 0x12362412UL, 0xc2b371c2UL, 0xa61fb9a6UL, +0x143c2814UL, 0xbc318dbcUL, 0xd38053d3UL, 0x28785028UL, +0xaf04abafUL, 0x2f715e2fUL, 0xe6df39e6UL, 0x246c4824UL, +0x52f6a452UL, 0xc6bf79c6UL, 0xa015b5a0UL, 0x091b1209UL, +0xbd328fbdUL, 0x8c61ed8cUL, 0xcfa46bcfUL, 0x5de7ba5dUL, +0x11332211UL, 0x5fe1be5fUL, 0x01030201UL, 0xc5ba7fc5UL, +0x9f54cb9fUL, 0x3d477a3dUL, 0xa213b1a2UL, 0x9b58c39bUL, +0xc9ae67c9UL, 0x3b4d763bUL, 0xbe3789beUL, 0x51f3a251UL, +0x192b3219UL, 0x1f213e1fUL, 0x3f417e3fUL, 0x5ce4b85cUL, +0xb22391b2UL, 0xefc42befUL, 0x4ade944aUL, 0xcda26fcdUL, +0xbf348bbfUL, 0xba3b81baUL, 0x6fb1de6fUL, 0x64acc864UL, +0xd99e47d9UL, 0xf3e013f3UL, 0x3e427c3eUL, 0xb4299db4UL, +0xaa0ba1aaUL, 0xdc914ddcUL, 0xd58a5fd5UL, 0x060a0c06UL, +0xc0b575c0UL, 0x7e82fc7eUL, 0xf6ef19f6UL, 0x66aacc66UL, +0x6cb4d86cUL, 0x8479fd84UL, 0x7193e271UL, 0x38487038UL, +0xb93e87b9UL, 0x1d273a1dUL, 0x7f81fe7fUL, 0x9d52cf9dUL, +0x48d89048UL, 0x8b68e38bUL, 0x2a7e542aUL, 0xda9b41daUL, +0xa51abfa5UL, 0x33556633UL, 0x8273f182UL, 0x394b7239UL, +0xd68f59d6UL, 0x7888f078UL, 0x867ff986UL, 0xfafb01faUL, +0xe4d93de4UL, 0x2b7d562bUL, 0xa90ea7a9UL, 0x1e223c1eUL, +0x896ee789UL, 0x60a0c060UL, 0x6bbdd66bUL, 0xeacb21eaUL, +0x55ffaa55UL, 0x4cd4984cUL, 0xf7ec1bf7UL, 0xe2d331e2UL, +}, + +{ +0xb1b12697UL, 0xcecea769UL, 0xc3c3b073UL, 0x95954adfUL, +0x5a5aeeb4UL, 0xadad02afUL, 0xe7e7dc3bUL, 0x02020604UL, +0x4d4dd79aUL, 0x4444cc88UL, 0xfbfbf803UL, 0x919146d7UL, +0x0c0c1418UL, 0x87877cfbUL, 0xa1a116b7UL, 0x5050f0a0UL, +0xcbcba863UL, 0x6767a9ceUL, 0x5454fca8UL, 0xdddd924fUL, +0x4646ca8cUL, 0x8f8f64ebUL, 0xe1e1d637UL, 0x4e4ed29cUL, +0xf0f0e515UL, 0xfdfdf20fUL, 0xfcfcf10dUL, 0xebebc823UL, +0xf9f9fe07UL, 0xc4c4b97dUL, 0x1a1a2e34UL, 0x6e6eb2dcUL, +0x5e5ee2bcUL, 0xf5f5ea1fUL, 0xcccca16dUL, 0x8d8d62efUL, +0x1c1c2438UL, 0x5656faacUL, 0x4343c586UL, 0xfefef709UL, +0x0707090eUL, 0x6161a3c2UL, 0xf8f8fd05UL, 0x75759feaUL, +0x5959ebb2UL, 0xfffff40bUL, 0x03030506UL, 0x22226644UL, +0x8a8a6be1UL, 0xd1d18657UL, 0x13133526UL, 0xeeeec729UL, +0x88886de5UL, 0x00000000UL, 0x0e0e121cUL, 0x34345c68UL, +0x15153f2aUL, 0x808075f5UL, 0x949449ddUL, 0xe3e3d033UL, +0xededc22fUL, 0xb5b52a9fUL, 0x5353f5a6UL, 0x23236546UL, +0x4b4bdd96UL, 0x4747c98eUL, 0x1717392eUL, 0xa7a71cbbUL, +0x909045d5UL, 0x35355f6aUL, 0xabab08a3UL, 0xd8d89d45UL, +0xb8b83d85UL, 0xdfdf944bUL, 0x4f4fd19eUL, 0x5757f9aeUL, +0x9a9a5bc1UL, 0x929243d1UL, 0xdbdb9843UL, 0x1b1b2d36UL, +0x3c3c4478UL, 0xc8c8ad65UL, 0x99995ec7UL, 0x04040c08UL, +0x8e8e67e9UL, 0xe0e0d535UL, 0xd7d78c5bUL, 0x7d7d87faUL, +0x85857affUL, 0xbbbb3883UL, 0x4040c080UL, 0x2c2c7458UL, +0x3a3a4e74UL, 0x4545cf8aUL, 0xf1f1e617UL, 0x4242c684UL, +0x6565afcaUL, 0x20206040UL, 0x4141c382UL, 0x18182830UL, +0x727296e4UL, 0x25256f4aUL, 0x939340d3UL, 0x707090e0UL, +0x36365a6cUL, 0x05050f0aUL, 0xf2f2e311UL, 0x0b0b1d16UL, +0xa3a310b3UL, 0x79798bf2UL, 0xececc12dUL, 0x08081810UL, +0x2727694eUL, 0x31315362UL, 0x32325664UL, 0xb6b62f99UL, +0x7c7c84f8UL, 0xb0b02595UL, 0x0a0a1e14UL, 0x737395e6UL, +0x5b5bedb6UL, 0x7b7b8df6UL, 0xb7b72c9bUL, 0x818176f7UL, +0xd2d28351UL, 0x0d0d171aUL, 0x6a6abed4UL, 0x26266a4cUL, +0x9e9e57c9UL, 0x5858e8b0UL, 0x9c9c51cdUL, 0x838370f3UL, +0x74749ce8UL, 0xb3b32093UL, 0xacac01adUL, 0x30305060UL, +0x7a7a8ef4UL, 0x6969bbd2UL, 0x777799eeUL, 0x0f0f111eUL, +0xaeae07a9UL, 0x21216342UL, 0xdede9749UL, 0xd0d08555UL, +0x2e2e725cUL, 0x97974cdbUL, 0x10103020UL, 0xa4a419bdUL, +0x98985dc5UL, 0xa8a80da5UL, 0xd4d4895dUL, 0x6868b8d0UL, +0x2d2d775aUL, 0x6262a6c4UL, 0x29297b52UL, 0x6d6db7daUL, +0x16163a2cUL, 0x4949db92UL, 0x76769aecUL, 0xc7c7bc7bUL, +0xe8e8cd25UL, 0xc1c1b677UL, 0x96964fd9UL, 0x3737596eUL, +0xe5e5da3fUL, 0xcacaab61UL, 0xf4f4e91dUL, 0xe9e9ce27UL, +0x6363a5c6UL, 0x12123624UL, 0xc2c2b371UL, 0xa6a61fb9UL, +0x14143c28UL, 0xbcbc318dUL, 0xd3d38053UL, 0x28287850UL, +0xafaf04abUL, 0x2f2f715eUL, 0xe6e6df39UL, 0x24246c48UL, +0x5252f6a4UL, 0xc6c6bf79UL, 0xa0a015b5UL, 0x09091b12UL, +0xbdbd328fUL, 0x8c8c61edUL, 0xcfcfa46bUL, 0x5d5de7baUL, +0x11113322UL, 0x5f5fe1beUL, 0x01010302UL, 0xc5c5ba7fUL, +0x9f9f54cbUL, 0x3d3d477aUL, 0xa2a213b1UL, 0x9b9b58c3UL, +0xc9c9ae67UL, 0x3b3b4d76UL, 0xbebe3789UL, 0x5151f3a2UL, +0x19192b32UL, 0x1f1f213eUL, 0x3f3f417eUL, 0x5c5ce4b8UL, +0xb2b22391UL, 0xefefc42bUL, 0x4a4ade94UL, 0xcdcda26fUL, +0xbfbf348bUL, 0xbaba3b81UL, 0x6f6fb1deUL, 0x6464acc8UL, +0xd9d99e47UL, 0xf3f3e013UL, 0x3e3e427cUL, 0xb4b4299dUL, +0xaaaa0ba1UL, 0xdcdc914dUL, 0xd5d58a5fUL, 0x06060a0cUL, +0xc0c0b575UL, 0x7e7e82fcUL, 0xf6f6ef19UL, 0x6666aaccUL, +0x6c6cb4d8UL, 0x848479fdUL, 0x717193e2UL, 0x38384870UL, +0xb9b93e87UL, 0x1d1d273aUL, 0x7f7f81feUL, 0x9d9d52cfUL, +0x4848d890UL, 0x8b8b68e3UL, 0x2a2a7e54UL, 0xdada9b41UL, +0xa5a51abfUL, 0x33335566UL, 0x828273f1UL, 0x39394b72UL, +0xd6d68f59UL, 0x787888f0UL, 0x86867ff9UL, 0xfafafb01UL, +0xe4e4d93dUL, 0x2b2b7d56UL, 0xa9a90ea7UL, 0x1e1e223cUL, +0x89896ee7UL, 0x6060a0c0UL, 0x6b6bbdd6UL, 0xeaeacb21UL, +0x5555ffaaUL, 0x4c4cd498UL, 0xf7f7ec1bUL, 0xe2e2d331UL, +}}; + +const word32 Square::Dec::Td[4][256] = { +{ +0xe368bc02UL, 0x5585620cUL, 0x2a3f2331UL, 0x61ab13f7UL, +0x98d46d72UL, 0x21cb9a19UL, 0x3c22a461UL, 0x459d3dcdUL, +0x05fdb423UL, 0x2bc4075fUL, 0x9b2c01c0UL, 0x3dd9800fUL, +0x486c5c74UL, 0xf97f7e85UL, 0xf173ab1fUL, 0xb6edde0eUL, +0x283c6bedUL, 0x4997781aUL, 0x9f2a918dUL, 0xc9579f33UL, +0xa907a8aaUL, 0xa50ded7dUL, 0x7c422d8fUL, 0x764db0c9UL, +0x4d91e857UL, 0xcea963ccUL, 0xb4ee96d2UL, 0x3028e1b6UL, +0x0df161b9UL, 0xbd196726UL, 0x419bad80UL, 0xc0a06ec7UL, +0x5183f241UL, 0x92dbf034UL, 0x6fa21efcUL, 0x8f32ce4cUL, +0x13e03373UL, 0x69a7c66dUL, 0xe56d6493UL, 0xbf1a2ffaUL, +0xbb1cbfb7UL, 0x587403b5UL, 0xe76e2c4fUL, 0x5d89b796UL, +0xe89c052aUL, 0x446619a3UL, 0x342e71fbUL, 0x0ff22965UL, +0xfe81827aUL, 0xb11322f1UL, 0xa30835ecUL, 0xcd510f7eUL, +0xff7aa614UL, 0x5c7293f8UL, 0x2fc29712UL, 0xf370e3c3UL, +0x992f491cUL, 0xd1431568UL, 0xc2a3261bUL, 0x88cc32b3UL, +0x8acf7a6fUL, 0xb0e8069fUL, 0x7a47f51eUL, 0xd2bb79daUL, +0xe6950821UL, 0x4398e55cUL, 0xd0b83106UL, 0x11e37bafUL, +0x7e416553UL, 0xccaa2b10UL, 0xd8b4e49cUL, 0x6456a7d4UL, +0xfb7c3659UL, 0x724b2084UL, 0xea9f4df6UL, 0x6a5faadfUL, +0x2dc1dfceUL, 0x70486858UL, 0xcaaff381UL, 0x0605d891UL, +0x5a774b69UL, 0x94de28a5UL, 0x39df1042UL, 0x813bc347UL, +0xfc82caa6UL, 0x23c8d2c5UL, 0x03f86cb2UL, 0x080cd59aUL, +0xdab7ac40UL, 0x7db909e1UL, 0x3824342cUL, 0xcf5247a2UL, +0xdcb274d1UL, 0x63a85b2bUL, 0x35d55595UL, 0x479e7511UL, +0x15e5ebe2UL, 0x4b9430c6UL, 0x4a6f14a8UL, 0x91239c86UL, +0x4c6acc39UL, 0x5f8aff4aUL, 0x0406904dUL, 0xee99ddbbUL, +0x1e1152caUL, 0xaaffc418UL, 0xeb646998UL, 0x07fefcffUL, +0x8b345e01UL, 0x567d0ebeUL, 0xbae79bd9UL, 0x4263c132UL, +0x75b5dc7bUL, 0x97264417UL, 0x67aecb66UL, 0x95250ccbUL, +0xec9a9567UL, 0x57862ad0UL, 0x60503799UL, 0xb8e4d305UL, +0x65ad83baUL, 0x19efae35UL, 0xa4f6c913UL, 0xc15b4aa9UL, +0x873e1bd6UL, 0xa0f0595eUL, 0x18148a5bUL, 0xaf02703bUL, +0xab04e076UL, 0xdd4950bfUL, 0xdf4a1863UL, 0xc6a5b656UL, +0x853d530aUL, 0xfa871237UL, 0x77b694a7UL, 0x4665517fUL, +0xed61b109UL, 0x1bece6e9UL, 0xd5458525UL, 0xf5753b52UL, +0x7fba413dUL, 0x27ce4288UL, 0xb2eb4e43UL, 0xd6bde997UL, +0x527b9ef3UL, 0x62537f45UL, 0x2c3afba0UL, 0x7bbcd170UL, +0xb91ff76bUL, 0x121b171dUL, 0xfd79eec8UL, 0x3a277cf0UL, +0x0c0a45d7UL, 0x96dd6079UL, 0x2233f6abUL, 0xacfa1c89UL, +0xc8acbb5dUL, 0xa10b7d30UL, 0xd4bea14bUL, 0xbee10b94UL, +0x25cd0a54UL, 0x547e4662UL, 0xa2f31182UL, 0x17e6a33eUL, +0x263566e6UL, 0xc3580275UL, 0x83388b9bUL, 0x7844bdc2UL, +0x020348dcUL, 0x4f92a08bUL, 0x2e39b37cUL, 0x4e6984e5UL, +0xf0888f71UL, 0x362d3927UL, 0x9cd2fd3fUL, 0x01fb246eUL, +0x893716ddUL, 0x00000000UL, 0xf68d57e0UL, 0xe293986cUL, +0x744ef815UL, 0x9320d45aUL, 0xad0138e7UL, 0xd3405db4UL, +0x1a17c287UL, 0xb3106a2dUL, 0x5078d62fUL, 0xf48e1f3cUL, +0xa70ea5a1UL, 0x71b34c36UL, 0x9ad725aeUL, 0x5e71db24UL, +0x161d8750UL, 0xef62f9d5UL, 0x8d318690UL, 0x1c121a16UL, +0xa6f581cfUL, 0x5b8c6f07UL, 0x37d61d49UL, 0x6e593a92UL, +0x84c67764UL, 0x86c53fb8UL, 0xd746cdf9UL, 0xe090d0b0UL, +0x29c74f83UL, 0xe49640fdUL, 0x0e090d0bUL, 0x6da15620UL, +0x8ec9ea22UL, 0xdb4c882eUL, 0xf776738eUL, 0xb515b2bcUL, +0x10185fc1UL, 0x322ba96aUL, 0x6ba48eb1UL, 0xaef95455UL, +0x406089eeUL, 0x6655ef08UL, 0xe9672144UL, 0x3e21ecbdUL, +0x2030be77UL, 0xf28bc7adUL, 0x80c0e729UL, 0x141ecf8cUL, +0xbce24348UL, 0xc4a6fe8aUL, 0x31d3c5d8UL, 0xb716fa60UL, +0x5380ba9dUL, 0xd94fc0f2UL, 0x1de93e78UL, 0x24362e3aUL, +0xe16bf4deUL, 0xcb54d7efUL, 0x09f7f1f4UL, 0x82c3aff5UL, +0x0bf4b928UL, 0x9d29d951UL, 0xc75e9238UL, 0xf8845aebUL, +0x90d8b8e8UL, 0xdeb13c0dUL, 0x33d08d04UL, 0x685ce203UL, +0xc55ddae4UL, 0x3bdc589eUL, 0x0a0f9d46UL, 0x3fdac8d3UL, +0x598f27dbUL, 0xa8fc8cc4UL, 0x79bf99acUL, 0x6c5a724eUL, +0x8ccaa2feUL, 0x9ed1b5e3UL, 0x1fea76a4UL, 0x73b004eaUL, +}, + +{ +0x02e368bcUL, 0x0c558562UL, 0x312a3f23UL, 0xf761ab13UL, +0x7298d46dUL, 0x1921cb9aUL, 0x613c22a4UL, 0xcd459d3dUL, +0x2305fdb4UL, 0x5f2bc407UL, 0xc09b2c01UL, 0x0f3dd980UL, +0x74486c5cUL, 0x85f97f7eUL, 0x1ff173abUL, 0x0eb6eddeUL, +0xed283c6bUL, 0x1a499778UL, 0x8d9f2a91UL, 0x33c9579fUL, +0xaaa907a8UL, 0x7da50dedUL, 0x8f7c422dUL, 0xc9764db0UL, +0x574d91e8UL, 0xcccea963UL, 0xd2b4ee96UL, 0xb63028e1UL, +0xb90df161UL, 0x26bd1967UL, 0x80419badUL, 0xc7c0a06eUL, +0x415183f2UL, 0x3492dbf0UL, 0xfc6fa21eUL, 0x4c8f32ceUL, +0x7313e033UL, 0x6d69a7c6UL, 0x93e56d64UL, 0xfabf1a2fUL, +0xb7bb1cbfUL, 0xb5587403UL, 0x4fe76e2cUL, 0x965d89b7UL, +0x2ae89c05UL, 0xa3446619UL, 0xfb342e71UL, 0x650ff229UL, +0x7afe8182UL, 0xf1b11322UL, 0xeca30835UL, 0x7ecd510fUL, +0x14ff7aa6UL, 0xf85c7293UL, 0x122fc297UL, 0xc3f370e3UL, +0x1c992f49UL, 0x68d14315UL, 0x1bc2a326UL, 0xb388cc32UL, +0x6f8acf7aUL, 0x9fb0e806UL, 0x1e7a47f5UL, 0xdad2bb79UL, +0x21e69508UL, 0x5c4398e5UL, 0x06d0b831UL, 0xaf11e37bUL, +0x537e4165UL, 0x10ccaa2bUL, 0x9cd8b4e4UL, 0xd46456a7UL, +0x59fb7c36UL, 0x84724b20UL, 0xf6ea9f4dUL, 0xdf6a5faaUL, +0xce2dc1dfUL, 0x58704868UL, 0x81caaff3UL, 0x910605d8UL, +0x695a774bUL, 0xa594de28UL, 0x4239df10UL, 0x47813bc3UL, +0xa6fc82caUL, 0xc523c8d2UL, 0xb203f86cUL, 0x9a080cd5UL, +0x40dab7acUL, 0xe17db909UL, 0x2c382434UL, 0xa2cf5247UL, +0xd1dcb274UL, 0x2b63a85bUL, 0x9535d555UL, 0x11479e75UL, +0xe215e5ebUL, 0xc64b9430UL, 0xa84a6f14UL, 0x8691239cUL, +0x394c6accUL, 0x4a5f8affUL, 0x4d040690UL, 0xbbee99ddUL, +0xca1e1152UL, 0x18aaffc4UL, 0x98eb6469UL, 0xff07fefcUL, +0x018b345eUL, 0xbe567d0eUL, 0xd9bae79bUL, 0x324263c1UL, +0x7b75b5dcUL, 0x17972644UL, 0x6667aecbUL, 0xcb95250cUL, +0x67ec9a95UL, 0xd057862aUL, 0x99605037UL, 0x05b8e4d3UL, +0xba65ad83UL, 0x3519efaeUL, 0x13a4f6c9UL, 0xa9c15b4aUL, +0xd6873e1bUL, 0x5ea0f059UL, 0x5b18148aUL, 0x3baf0270UL, +0x76ab04e0UL, 0xbfdd4950UL, 0x63df4a18UL, 0x56c6a5b6UL, +0x0a853d53UL, 0x37fa8712UL, 0xa777b694UL, 0x7f466551UL, +0x09ed61b1UL, 0xe91bece6UL, 0x25d54585UL, 0x52f5753bUL, +0x3d7fba41UL, 0x8827ce42UL, 0x43b2eb4eUL, 0x97d6bde9UL, +0xf3527b9eUL, 0x4562537fUL, 0xa02c3afbUL, 0x707bbcd1UL, +0x6bb91ff7UL, 0x1d121b17UL, 0xc8fd79eeUL, 0xf03a277cUL, +0xd70c0a45UL, 0x7996dd60UL, 0xab2233f6UL, 0x89acfa1cUL, +0x5dc8acbbUL, 0x30a10b7dUL, 0x4bd4bea1UL, 0x94bee10bUL, +0x5425cd0aUL, 0x62547e46UL, 0x82a2f311UL, 0x3e17e6a3UL, +0xe6263566UL, 0x75c35802UL, 0x9b83388bUL, 0xc27844bdUL, +0xdc020348UL, 0x8b4f92a0UL, 0x7c2e39b3UL, 0xe54e6984UL, +0x71f0888fUL, 0x27362d39UL, 0x3f9cd2fdUL, 0x6e01fb24UL, +0xdd893716UL, 0x00000000UL, 0xe0f68d57UL, 0x6ce29398UL, +0x15744ef8UL, 0x5a9320d4UL, 0xe7ad0138UL, 0xb4d3405dUL, +0x871a17c2UL, 0x2db3106aUL, 0x2f5078d6UL, 0x3cf48e1fUL, +0xa1a70ea5UL, 0x3671b34cUL, 0xae9ad725UL, 0x245e71dbUL, +0x50161d87UL, 0xd5ef62f9UL, 0x908d3186UL, 0x161c121aUL, +0xcfa6f581UL, 0x075b8c6fUL, 0x4937d61dUL, 0x926e593aUL, +0x6484c677UL, 0xb886c53fUL, 0xf9d746cdUL, 0xb0e090d0UL, +0x8329c74fUL, 0xfde49640UL, 0x0b0e090dUL, 0x206da156UL, +0x228ec9eaUL, 0x2edb4c88UL, 0x8ef77673UL, 0xbcb515b2UL, +0xc110185fUL, 0x6a322ba9UL, 0xb16ba48eUL, 0x55aef954UL, +0xee406089UL, 0x086655efUL, 0x44e96721UL, 0xbd3e21ecUL, +0x772030beUL, 0xadf28bc7UL, 0x2980c0e7UL, 0x8c141ecfUL, +0x48bce243UL, 0x8ac4a6feUL, 0xd831d3c5UL, 0x60b716faUL, +0x9d5380baUL, 0xf2d94fc0UL, 0x781de93eUL, 0x3a24362eUL, +0xdee16bf4UL, 0xefcb54d7UL, 0xf409f7f1UL, 0xf582c3afUL, +0x280bf4b9UL, 0x519d29d9UL, 0x38c75e92UL, 0xebf8845aUL, +0xe890d8b8UL, 0x0ddeb13cUL, 0x0433d08dUL, 0x03685ce2UL, +0xe4c55ddaUL, 0x9e3bdc58UL, 0x460a0f9dUL, 0xd33fdac8UL, +0xdb598f27UL, 0xc4a8fc8cUL, 0xac79bf99UL, 0x4e6c5a72UL, +0xfe8ccaa2UL, 0xe39ed1b5UL, 0xa41fea76UL, 0xea73b004UL, +}, + +{ +0xbc02e368UL, 0x620c5585UL, 0x23312a3fUL, 0x13f761abUL, +0x6d7298d4UL, 0x9a1921cbUL, 0xa4613c22UL, 0x3dcd459dUL, +0xb42305fdUL, 0x075f2bc4UL, 0x01c09b2cUL, 0x800f3dd9UL, +0x5c74486cUL, 0x7e85f97fUL, 0xab1ff173UL, 0xde0eb6edUL, +0x6bed283cUL, 0x781a4997UL, 0x918d9f2aUL, 0x9f33c957UL, +0xa8aaa907UL, 0xed7da50dUL, 0x2d8f7c42UL, 0xb0c9764dUL, +0xe8574d91UL, 0x63cccea9UL, 0x96d2b4eeUL, 0xe1b63028UL, +0x61b90df1UL, 0x6726bd19UL, 0xad80419bUL, 0x6ec7c0a0UL, +0xf2415183UL, 0xf03492dbUL, 0x1efc6fa2UL, 0xce4c8f32UL, +0x337313e0UL, 0xc66d69a7UL, 0x6493e56dUL, 0x2ffabf1aUL, +0xbfb7bb1cUL, 0x03b55874UL, 0x2c4fe76eUL, 0xb7965d89UL, +0x052ae89cUL, 0x19a34466UL, 0x71fb342eUL, 0x29650ff2UL, +0x827afe81UL, 0x22f1b113UL, 0x35eca308UL, 0x0f7ecd51UL, +0xa614ff7aUL, 0x93f85c72UL, 0x97122fc2UL, 0xe3c3f370UL, +0x491c992fUL, 0x1568d143UL, 0x261bc2a3UL, 0x32b388ccUL, +0x7a6f8acfUL, 0x069fb0e8UL, 0xf51e7a47UL, 0x79dad2bbUL, +0x0821e695UL, 0xe55c4398UL, 0x3106d0b8UL, 0x7baf11e3UL, +0x65537e41UL, 0x2b10ccaaUL, 0xe49cd8b4UL, 0xa7d46456UL, +0x3659fb7cUL, 0x2084724bUL, 0x4df6ea9fUL, 0xaadf6a5fUL, +0xdfce2dc1UL, 0x68587048UL, 0xf381caafUL, 0xd8910605UL, +0x4b695a77UL, 0x28a594deUL, 0x104239dfUL, 0xc347813bUL, +0xcaa6fc82UL, 0xd2c523c8UL, 0x6cb203f8UL, 0xd59a080cUL, +0xac40dab7UL, 0x09e17db9UL, 0x342c3824UL, 0x47a2cf52UL, +0x74d1dcb2UL, 0x5b2b63a8UL, 0x559535d5UL, 0x7511479eUL, +0xebe215e5UL, 0x30c64b94UL, 0x14a84a6fUL, 0x9c869123UL, +0xcc394c6aUL, 0xff4a5f8aUL, 0x904d0406UL, 0xddbbee99UL, +0x52ca1e11UL, 0xc418aaffUL, 0x6998eb64UL, 0xfcff07feUL, +0x5e018b34UL, 0x0ebe567dUL, 0x9bd9bae7UL, 0xc1324263UL, +0xdc7b75b5UL, 0x44179726UL, 0xcb6667aeUL, 0x0ccb9525UL, +0x9567ec9aUL, 0x2ad05786UL, 0x37996050UL, 0xd305b8e4UL, +0x83ba65adUL, 0xae3519efUL, 0xc913a4f6UL, 0x4aa9c15bUL, +0x1bd6873eUL, 0x595ea0f0UL, 0x8a5b1814UL, 0x703baf02UL, +0xe076ab04UL, 0x50bfdd49UL, 0x1863df4aUL, 0xb656c6a5UL, +0x530a853dUL, 0x1237fa87UL, 0x94a777b6UL, 0x517f4665UL, +0xb109ed61UL, 0xe6e91becUL, 0x8525d545UL, 0x3b52f575UL, +0x413d7fbaUL, 0x428827ceUL, 0x4e43b2ebUL, 0xe997d6bdUL, +0x9ef3527bUL, 0x7f456253UL, 0xfba02c3aUL, 0xd1707bbcUL, +0xf76bb91fUL, 0x171d121bUL, 0xeec8fd79UL, 0x7cf03a27UL, +0x45d70c0aUL, 0x607996ddUL, 0xf6ab2233UL, 0x1c89acfaUL, +0xbb5dc8acUL, 0x7d30a10bUL, 0xa14bd4beUL, 0x0b94bee1UL, +0x0a5425cdUL, 0x4662547eUL, 0x1182a2f3UL, 0xa33e17e6UL, +0x66e62635UL, 0x0275c358UL, 0x8b9b8338UL, 0xbdc27844UL, +0x48dc0203UL, 0xa08b4f92UL, 0xb37c2e39UL, 0x84e54e69UL, +0x8f71f088UL, 0x3927362dUL, 0xfd3f9cd2UL, 0x246e01fbUL, +0x16dd8937UL, 0x00000000UL, 0x57e0f68dUL, 0x986ce293UL, +0xf815744eUL, 0xd45a9320UL, 0x38e7ad01UL, 0x5db4d340UL, +0xc2871a17UL, 0x6a2db310UL, 0xd62f5078UL, 0x1f3cf48eUL, +0xa5a1a70eUL, 0x4c3671b3UL, 0x25ae9ad7UL, 0xdb245e71UL, +0x8750161dUL, 0xf9d5ef62UL, 0x86908d31UL, 0x1a161c12UL, +0x81cfa6f5UL, 0x6f075b8cUL, 0x1d4937d6UL, 0x3a926e59UL, +0x776484c6UL, 0x3fb886c5UL, 0xcdf9d746UL, 0xd0b0e090UL, +0x4f8329c7UL, 0x40fde496UL, 0x0d0b0e09UL, 0x56206da1UL, +0xea228ec9UL, 0x882edb4cUL, 0x738ef776UL, 0xb2bcb515UL, +0x5fc11018UL, 0xa96a322bUL, 0x8eb16ba4UL, 0x5455aef9UL, +0x89ee4060UL, 0xef086655UL, 0x2144e967UL, 0xecbd3e21UL, +0xbe772030UL, 0xc7adf28bUL, 0xe72980c0UL, 0xcf8c141eUL, +0x4348bce2UL, 0xfe8ac4a6UL, 0xc5d831d3UL, 0xfa60b716UL, +0xba9d5380UL, 0xc0f2d94fUL, 0x3e781de9UL, 0x2e3a2436UL, +0xf4dee16bUL, 0xd7efcb54UL, 0xf1f409f7UL, 0xaff582c3UL, +0xb9280bf4UL, 0xd9519d29UL, 0x9238c75eUL, 0x5aebf884UL, +0xb8e890d8UL, 0x3c0ddeb1UL, 0x8d0433d0UL, 0xe203685cUL, +0xdae4c55dUL, 0x589e3bdcUL, 0x9d460a0fUL, 0xc8d33fdaUL, +0x27db598fUL, 0x8cc4a8fcUL, 0x99ac79bfUL, 0x724e6c5aUL, +0xa2fe8ccaUL, 0xb5e39ed1UL, 0x76a41feaUL, 0x04ea73b0UL, +}, + +{ +0x68bc02e3UL, 0x85620c55UL, 0x3f23312aUL, 0xab13f761UL, +0xd46d7298UL, 0xcb9a1921UL, 0x22a4613cUL, 0x9d3dcd45UL, +0xfdb42305UL, 0xc4075f2bUL, 0x2c01c09bUL, 0xd9800f3dUL, +0x6c5c7448UL, 0x7f7e85f9UL, 0x73ab1ff1UL, 0xedde0eb6UL, +0x3c6bed28UL, 0x97781a49UL, 0x2a918d9fUL, 0x579f33c9UL, +0x07a8aaa9UL, 0x0ded7da5UL, 0x422d8f7cUL, 0x4db0c976UL, +0x91e8574dUL, 0xa963ccceUL, 0xee96d2b4UL, 0x28e1b630UL, +0xf161b90dUL, 0x196726bdUL, 0x9bad8041UL, 0xa06ec7c0UL, +0x83f24151UL, 0xdbf03492UL, 0xa21efc6fUL, 0x32ce4c8fUL, +0xe0337313UL, 0xa7c66d69UL, 0x6d6493e5UL, 0x1a2ffabfUL, +0x1cbfb7bbUL, 0x7403b558UL, 0x6e2c4fe7UL, 0x89b7965dUL, +0x9c052ae8UL, 0x6619a344UL, 0x2e71fb34UL, 0xf229650fUL, +0x81827afeUL, 0x1322f1b1UL, 0x0835eca3UL, 0x510f7ecdUL, +0x7aa614ffUL, 0x7293f85cUL, 0xc297122fUL, 0x70e3c3f3UL, +0x2f491c99UL, 0x431568d1UL, 0xa3261bc2UL, 0xcc32b388UL, +0xcf7a6f8aUL, 0xe8069fb0UL, 0x47f51e7aUL, 0xbb79dad2UL, +0x950821e6UL, 0x98e55c43UL, 0xb83106d0UL, 0xe37baf11UL, +0x4165537eUL, 0xaa2b10ccUL, 0xb4e49cd8UL, 0x56a7d464UL, +0x7c3659fbUL, 0x4b208472UL, 0x9f4df6eaUL, 0x5faadf6aUL, +0xc1dfce2dUL, 0x48685870UL, 0xaff381caUL, 0x05d89106UL, +0x774b695aUL, 0xde28a594UL, 0xdf104239UL, 0x3bc34781UL, +0x82caa6fcUL, 0xc8d2c523UL, 0xf86cb203UL, 0x0cd59a08UL, +0xb7ac40daUL, 0xb909e17dUL, 0x24342c38UL, 0x5247a2cfUL, +0xb274d1dcUL, 0xa85b2b63UL, 0xd5559535UL, 0x9e751147UL, +0xe5ebe215UL, 0x9430c64bUL, 0x6f14a84aUL, 0x239c8691UL, +0x6acc394cUL, 0x8aff4a5fUL, 0x06904d04UL, 0x99ddbbeeUL, +0x1152ca1eUL, 0xffc418aaUL, 0x646998ebUL, 0xfefcff07UL, +0x345e018bUL, 0x7d0ebe56UL, 0xe79bd9baUL, 0x63c13242UL, +0xb5dc7b75UL, 0x26441797UL, 0xaecb6667UL, 0x250ccb95UL, +0x9a9567ecUL, 0x862ad057UL, 0x50379960UL, 0xe4d305b8UL, +0xad83ba65UL, 0xefae3519UL, 0xf6c913a4UL, 0x5b4aa9c1UL, +0x3e1bd687UL, 0xf0595ea0UL, 0x148a5b18UL, 0x02703bafUL, +0x04e076abUL, 0x4950bfddUL, 0x4a1863dfUL, 0xa5b656c6UL, +0x3d530a85UL, 0x871237faUL, 0xb694a777UL, 0x65517f46UL, +0x61b109edUL, 0xece6e91bUL, 0x458525d5UL, 0x753b52f5UL, +0xba413d7fUL, 0xce428827UL, 0xeb4e43b2UL, 0xbde997d6UL, +0x7b9ef352UL, 0x537f4562UL, 0x3afba02cUL, 0xbcd1707bUL, +0x1ff76bb9UL, 0x1b171d12UL, 0x79eec8fdUL, 0x277cf03aUL, +0x0a45d70cUL, 0xdd607996UL, 0x33f6ab22UL, 0xfa1c89acUL, +0xacbb5dc8UL, 0x0b7d30a1UL, 0xbea14bd4UL, 0xe10b94beUL, +0xcd0a5425UL, 0x7e466254UL, 0xf31182a2UL, 0xe6a33e17UL, +0x3566e626UL, 0x580275c3UL, 0x388b9b83UL, 0x44bdc278UL, +0x0348dc02UL, 0x92a08b4fUL, 0x39b37c2eUL, 0x6984e54eUL, +0x888f71f0UL, 0x2d392736UL, 0xd2fd3f9cUL, 0xfb246e01UL, +0x3716dd89UL, 0x00000000UL, 0x8d57e0f6UL, 0x93986ce2UL, +0x4ef81574UL, 0x20d45a93UL, 0x0138e7adUL, 0x405db4d3UL, +0x17c2871aUL, 0x106a2db3UL, 0x78d62f50UL, 0x8e1f3cf4UL, +0x0ea5a1a7UL, 0xb34c3671UL, 0xd725ae9aUL, 0x71db245eUL, +0x1d875016UL, 0x62f9d5efUL, 0x3186908dUL, 0x121a161cUL, +0xf581cfa6UL, 0x8c6f075bUL, 0xd61d4937UL, 0x593a926eUL, +0xc6776484UL, 0xc53fb886UL, 0x46cdf9d7UL, 0x90d0b0e0UL, +0xc74f8329UL, 0x9640fde4UL, 0x090d0b0eUL, 0xa156206dUL, +0xc9ea228eUL, 0x4c882edbUL, 0x76738ef7UL, 0x15b2bcb5UL, +0x185fc110UL, 0x2ba96a32UL, 0xa48eb16bUL, 0xf95455aeUL, +0x6089ee40UL, 0x55ef0866UL, 0x672144e9UL, 0x21ecbd3eUL, +0x30be7720UL, 0x8bc7adf2UL, 0xc0e72980UL, 0x1ecf8c14UL, +0xe24348bcUL, 0xa6fe8ac4UL, 0xd3c5d831UL, 0x16fa60b7UL, +0x80ba9d53UL, 0x4fc0f2d9UL, 0xe93e781dUL, 0x362e3a24UL, +0x6bf4dee1UL, 0x54d7efcbUL, 0xf7f1f409UL, 0xc3aff582UL, +0xf4b9280bUL, 0x29d9519dUL, 0x5e9238c7UL, 0x845aebf8UL, +0xd8b8e890UL, 0xb13c0ddeUL, 0xd08d0433UL, 0x5ce20368UL, +0x5ddae4c5UL, 0xdc589e3bUL, 0x0f9d460aUL, 0xdac8d33fUL, +0x8f27db59UL, 0xfc8cc4a8UL, 0xbf99ac79UL, 0x5a724e6cUL, +0xcaa2fe8cUL, 0xd1b5e39eUL, 0xea76a41fUL, 0xb004ea73UL, +}}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/sse_simd.cpp b/external/ours/library/crypto/src/shared/original/sse_simd.cpp new file mode 100755 index 000000000..96c80a270 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/sse_simd.cpp @@ -0,0 +1,115 @@ +// sse_simd.cpp - written and placed in the public domain by +// Jeffrey Walton, Uri Blumenthal and Marcel Raad. +// +// This source file uses intrinsics to gain access to SSE for CPU +// feature testing. A separate source file is needed because additional +// CXXFLAGS are required to enable the appropriate instructions set in +// some build configurations. + +#include "pch.h" +#include "config.h" +#include "cpu.h" + +// Needed by MIPS for definition of NULL +#include "stdcpp.h" + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +# include +# include +#endif + +#ifndef EXCEPTION_EXECUTE_HANDLER +# define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +// Needed by SunCC and MSVC +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +# if !defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) && !CRYPTOPP_SSE2_ASM_AVAILABLE && CRYPTOPP_SSE2_INTRIN_AVAILABLE +# include +# endif +#endif + +// Squash MS LNK4221 and libtool warnings +extern const char SSE_SIMD_FNAME[] = __FILE__; + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY +extern "C" { + typedef void (*SigHandler)(int); +} + +extern "C" +{ + static jmp_buf s_jmpNoSSE2; + static void SigIllHandler(int) + { + longjmp(s_jmpNoSSE2, 1); + } +} +#endif // CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY + +bool CPU_ProbeSSE2() +{ + // Apple switched to Intel desktops in 2005/2006 using + // Core2 Duo's, which provides SSE2 and above. +#if CRYPTOPP_BOOL_X64 || defined(__APPLE__) + return true; +#elif defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) + return false; +#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + __try + { +# if CRYPTOPP_SSE2_ASM_AVAILABLE + AS2(por xmm0, xmm0) // executing SSE2 instruction +# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE + __m128i x = _mm_setzero_si128(); + return _mm_cvtsi128_si32(x) == 0; +# endif + } + // GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return true; +#else + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + +# ifndef __MINGW32__ + volatile sigset_t oldMask; + if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) + { + signal(SIGILL, oldHandler); + return false; + } +# endif + + if (setjmp(s_jmpNoSSE2)) + result = false; + else + { +# if CRYPTOPP_SSE2_ASM_AVAILABLE + __asm __volatile ("por %xmm0, %xmm0"); +# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE + __m128i x = _mm_setzero_si128(); + result = _mm_cvtsi128_si32(x) == 0; +# endif + } + +# ifndef __MINGW32__ + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); +# endif + + signal(SIGILL, oldHandler); + return result; +#endif +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/stdcpp.h b/external/ours/library/crypto/src/shared/original/stdcpp.h new file mode 100755 index 000000000..8bda29049 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/stdcpp.h @@ -0,0 +1,101 @@ +// stdcpp.h - originally written and placed in the public domain by Wei Dai + +/// \file stdcpp.h +/// \brief Common C++ header files + +#ifndef CRYPTOPP_STDCPP_H +#define CRYPTOPP_STDCPP_H + +#if _MSC_VER >= 1500 +#define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// http://connect.microsoft.com/VisualStudio/feedback/details/1600701/type-info-does-not-compile-with-has-exceptions-0 +#if defined(_MSC_VER) && (_MSC_VER < 1900) && defined(_HAS_EXCEPTIONS) && (_HAS_EXCEPTIONS == 0) +namespace std { + using ::type_info; +} +#endif + +// workaround needed for IBM XLC and debug heaps on AIX +#if defined(_AIX) && (defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__)) +# if defined(__DEBUG_ALLOC__) +namespace std { + using ::_debug_memset; + using ::_debug_memcpy; +} +# endif +#endif + +// make_unchecked_array_iterator +#if _MSC_VER >= 1600 +#include +#endif + +#if defined(CRYPTOPP_CXX11_ATOMIC) +#include +#endif + +#if defined(CRYPTOPP_CXX11_SYNCHRONIZATION) +#include +#endif + +#if defined(CRYPTOPP_CXX11_RVALUES) +# include +#endif + +#include +#include +#include +#include + +// It is 2019 and VS2017/Win10 still can't compile a +// program that includes without making users +// do something special. "Epic fail" comes to mind. +// Also see https://github.com/weidai11/cryptopp/issues/781 +#ifndef _MSC_VER +# include +#endif + +// uintptr_t and ptrdiff_t +#if defined(__SUNPRO_CC) +# if (__SUNPRO_CC >= 0x5100) +# include +# endif +#elif defined(_MSC_VER) +# if (_MSC_VER >= 1700) +# include +# else +# include +# endif +#elif (__cplusplus < 201103L) +# include +#endif + +// workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 +#ifdef CRYPTOPP_INCLUDE_VECTOR_CC +# include +#endif + +// C++Builder's standard library (Dinkumware) do not have C's global log() function +// https://github.com/weidai11/cryptopp/issues/520 +#ifdef __BORLANDC__ +using std::log; +#endif + +#endif // CRYPTOPP_STDCPP_H diff --git a/external/ours/library/crypto/src/shared/original/strciphr.cpp b/external/ours/library/crypto/src/shared/original/strciphr.cpp new file mode 100755 index 000000000..f73a05e10 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/strciphr.cpp @@ -0,0 +1,328 @@ +// strciphr.cpp - originally written and placed in the public domain by Wei Dai + +// TODO: Figure out what is happening in ProcessData. The issue surfaced for +// CFB_CipherTemplate::ProcessData when we cut-in Cryptogams +// AES ARMv7 asm. Then again in AdditiveCipherTemplate::ProcessData +// for CTR mode with HIGHT, which is a 64-bit block cipher. In both cases, +// inString == outString leads to incorrect results. We think it relates to +// aliasing violations because inString == outString. +// +// Also see https://github.com/weidai11/cryptopp/issues/683 and +// https://github.com/weidai11/cryptopp/issues/1010. + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "strciphr.h" + +// Squash MS LNK4221 and libtool warnings +#ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +extern const char STRCIPHER_FNAME[] = __FILE__; +#endif + +NAMESPACE_BEGIN(CryptoPP) + +template +void AdditiveCipherTemplate::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + PolicyInterface &policy = this->AccessPolicy(); + policy.CipherSetKey(params, key, length); + m_leftOver = 0; + unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) : RoundUpToMultipleOf(1024U, GetBufferByteSize(policy)); + m_buffer.New(bufferByteSize); + + if (this->IsResynchronizable()) + { + size_t ivLength; + const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength); + policy.CipherResynchronize(m_buffer, iv, ivLength); + } +} + +template +void AdditiveCipherTemplate::GenerateBlock(byte *outString, size_t length) +{ + if (m_leftOver > 0) + { + const size_t len = STDMIN(m_leftOver, length); + std::memcpy(outString, PtrSub(KeystreamBufferEnd(), m_leftOver), len); + + length -= len; m_leftOver -= len; + outString = PtrAdd(outString, len); + if (!length) {return;} + } + + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + if (length >= bytesPerIteration) + { + const size_t iterations = length / bytesPerIteration; + policy.WriteKeystream(outString, iterations); + length -= iterations * bytesPerIteration; + outString = PtrAdd(outString, iterations * bytesPerIteration); + } + + if (length > 0) + { + size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); + size_t bufferIterations = bufferByteSize / bytesPerIteration; + + policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations); + std::memcpy(outString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length); + m_leftOver = bufferByteSize - length; + } +} + +template +void AdditiveCipherTemplate::ProcessData(byte *outString, const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(outString); CRYPTOPP_ASSERT(inString); + CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0); + + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + // GCC and Clang do not like this for CTR mode and 64-bit ciphers like HIGHT. + // The incorrect result is a partial string of 0's instead of plaintext or + // ciphertext. Recovered plaintext is partially garbage. + // + // It almost feels as if the compiler does not see the string is transformed + // in-place so it short-circuits the transform. In this case, if we use a + // stand-alone reproducer with the same data then the issue is present. + + byte* savedOutString = outString; + size_t savedLength = length; + bool copyOut = false; + + if (inString == outString) + { + // No need to copy inString to outString. + // Just allocate the space. + m_tempOutString.New(length); + m_tempOutString.SetMark(0); + outString = m_tempOutString.BytePtr(); + copyOut = true; + } + + if (m_leftOver > 0) + { + const size_t len = STDMIN(m_leftOver, length); + xorbuf(outString, inString, PtrSub(KeystreamBufferEnd(), m_leftOver), len); + + inString = PtrAdd(inString, len); + outString = PtrAdd(outString, len); + length -= len; m_leftOver -= len; + } + + if (!length) { + if (copyOut) + std::memcpy(savedOutString, m_tempOutString.BytePtr(), savedLength); + return; + } + + const unsigned int alignment = policy.GetAlignment(); + const bool inAligned = IsAlignedOn(inString, alignment); + const bool outAligned = IsAlignedOn(outString, alignment); + CRYPTOPP_UNUSED(inAligned); CRYPTOPP_UNUSED(outAligned); + + if (policy.CanOperateKeystream() && length >= bytesPerIteration) + { + const size_t iterations = length / bytesPerIteration; + KeystreamOperationFlags flags = static_cast( + (inAligned ? EnumToInt(INPUT_ALIGNED) : 0) | (outAligned ? EnumToInt(OUTPUT_ALIGNED) : 0)); + KeystreamOperation operation = KeystreamOperation(flags); + policy.OperateKeystream(operation, outString, inString, iterations); + + inString = PtrAdd(inString, iterations * bytesPerIteration); + outString = PtrAdd(outString, iterations * bytesPerIteration); + length -= iterations * bytesPerIteration; + } + + size_t bufferByteSize = m_buffer.size(); + size_t bufferIterations = bufferByteSize / bytesPerIteration; + + while (length >= bufferByteSize) + { + policy.WriteKeystream(m_buffer, bufferIterations); + xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); + + inString = PtrAdd(inString, bufferByteSize); + outString = PtrAdd(outString, bufferByteSize); + length -= bufferByteSize; + } + + if (length > 0) + { + bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); + bufferIterations = bufferByteSize / bytesPerIteration; + + policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations); + xorbuf(outString, inString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length); + + m_leftOver = bufferByteSize - length; + } + + if (copyOut) + std::memcpy(savedOutString, m_tempOutString.BytePtr(), savedLength); +} + +template +void AdditiveCipherTemplate::Resynchronize(const byte *iv, int length) +{ + PolicyInterface &policy = this->AccessPolicy(); + m_leftOver = 0; + m_buffer.New(GetBufferByteSize(policy)); + policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length)); +} + +template +void AdditiveCipherTemplate::Seek(lword position) +{ + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + policy.SeekToIteration(position / bytesPerIteration); + position %= bytesPerIteration; + + if (position > 0) + { + policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bytesPerIteration), 1); + m_leftOver = bytesPerIteration - static_cast(position); + } + else + m_leftOver = 0; +} + +template +void CFB_CipherTemplate::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + PolicyInterface &policy = this->AccessPolicy(); + policy.CipherSetKey(params, key, length); + + if (this->IsResynchronizable()) + { + size_t ivLength; + const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength); + policy.CipherResynchronize(iv, ivLength); + } + + m_leftOver = policy.GetBytesPerIteration(); +} + +template +void CFB_CipherTemplate::Resynchronize(const byte *iv, int length) +{ + PolicyInterface &policy = this->AccessPolicy(); + policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length)); + m_leftOver = policy.GetBytesPerIteration(); +} + +template +void CFB_CipherTemplate::ProcessData(byte *outString, const byte *inString, size_t length) +{ + CRYPTOPP_ASSERT(outString); CRYPTOPP_ASSERT(inString); + CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0); + + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + byte *reg = policy.GetRegisterBegin(); + + // GCC and Clang do not like this on ARM when inString == outString. The incorrect + // result is a string of 0's instead of plaintext or ciphertext. The 0's trace back + // to the allocation for the std::string in datatest.cpp. Elements in the string + // are initialized to their default value, which is 0. + // + // It almost feels as if the compiler does not see the string is transformed + // in-place so it short-circuits the transform. However, if we use a stand-alone + // reproducer with the same data then the issue is _not_ present. + + byte* savedOutString = outString; + size_t savedLength = length; + bool copyOut = false; + + if (inString == outString) + { + // No need to copy inString to outString. + // Just allocate the space. + m_tempOutString.New(length); + m_tempOutString.SetMark(0); + outString = m_tempOutString.BytePtr(); + copyOut = true; + } + + if (m_leftOver) + { + const size_t len = STDMIN(m_leftOver, length); + CombineMessageAndShiftRegister(outString, PtrAdd(reg, bytesPerIteration - m_leftOver), inString, len); + + inString = PtrAdd(inString, len); + outString = PtrAdd(outString, len); + m_leftOver -= len; length -= len; + } + + if (!length) { + if (copyOut) + std::memcpy(savedOutString, m_tempOutString.BytePtr(), savedLength); + return; + } + + const unsigned int alignment = policy.GetAlignment(); + const bool inAligned = IsAlignedOn(inString, alignment); + const bool outAligned = IsAlignedOn(outString, alignment); + CRYPTOPP_UNUSED(inAligned); CRYPTOPP_UNUSED(outAligned); + + if (policy.CanIterate() && length >= bytesPerIteration && outAligned) + { + CipherDir cipherDir = GetCipherDir(*this); + policy.Iterate(outString, inString, cipherDir, length / bytesPerIteration); + + const size_t remainder = length % bytesPerIteration; + inString = PtrAdd(inString, length - remainder); + outString = PtrAdd(outString, length - remainder); + length = remainder; + } + + while (length >= bytesPerIteration) + { + policy.TransformRegister(); + CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration); + + inString = PtrAdd(inString, bytesPerIteration); + outString = PtrAdd(outString, bytesPerIteration); + length -= bytesPerIteration; + } + + if (length > 0) + { + policy.TransformRegister(); + CombineMessageAndShiftRegister(outString, reg, inString, length); + m_leftOver = bytesPerIteration - length; + } + + if (copyOut) + std::memcpy(savedOutString, m_tempOutString.BytePtr(), savedLength); +} + +template +void CFB_EncryptionTemplate::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) +{ + xorbuf(reg, message, length); + std::memcpy(output, reg, length); +} + +template +void CFB_DecryptionTemplate::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) +{ + for (size_t i=0; i +/// typedef SymmetricCipherFinal\, AdditiveCipherTemplate\<\> \> \> Encryption; +/// +/// \details AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't +/// need to take a policy class as a template parameter (although this is allowed), so +/// that their code is not duplicated for each new cipher. Instead they each get a +/// reference to an abstract policy interface by calling AccessPolicy() on itself, so +/// AccessPolicy() must be overridden to return the actual policy reference. This is done +/// by the ConcretePolicyHolder class. Finally, SymmetricCipherFinal implements the +/// constructors and other functions that must be implemented by the most derived class. + +#ifndef CRYPTOPP_STRCIPHR_H +#define CRYPTOPP_STRCIPHR_H + +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(push) +# pragma warning(disable: 4127 4189 4231 4275) +#endif + +#include "cryptlib.h" +#include "seckey.h" +#include "secblock.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Access a stream cipher policy object +/// \tparam POLICY_INTERFACE class implementing AbstractPolicyHolder +/// \tparam BASE class or type to use as a base class +template +class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE +{ +public: + typedef POLICY_INTERFACE PolicyInterface; + virtual ~AbstractPolicyHolder() {} + +protected: + virtual const POLICY_INTERFACE & GetPolicy() const =0; + virtual POLICY_INTERFACE & AccessPolicy() =0; +}; + +/// \brief Stream cipher policy object +/// \tparam POLICY class implementing AbstractPolicyHolder +/// \tparam BASE class or type to use as a base class +template +class ConcretePolicyHolder : public BASE, protected POLICY +{ +public: + virtual ~ConcretePolicyHolder() {} +protected: + const POLICY_INTERFACE & GetPolicy() const {return *this;} + POLICY_INTERFACE & AccessPolicy() {return *this;} +}; + +/// \brief Keystream operation flags +/// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize() +/// and AdditiveCipherAbstractPolicy::GetAlignment() +enum KeystreamOperationFlags { + /// \brief Output buffer is aligned + OUTPUT_ALIGNED=1, + /// \brief Input buffer is aligned + INPUT_ALIGNED=2, + /// \brief Input buffer is NULL + INPUT_NULL = 4 +}; + +/// \brief Keystream operation flags +/// \sa AdditiveCipherAbstractPolicy::GetBytesPerIteration(), AdditiveCipherAbstractPolicy::GetOptimalBlockSize() +/// and AdditiveCipherAbstractPolicy::GetAlignment() +enum KeystreamOperation { + /// \brief Wirte the keystream to the output buffer, input is NULL + WRITE_KEYSTREAM = INPUT_NULL, + /// \brief Wirte the keystream to the aligned output buffer, input is NULL + WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED, + /// \brief XOR the input buffer and keystream, write to the output buffer + XOR_KEYSTREAM = 0, + /// \brief XOR the aligned input buffer and keystream, write to the output buffer + XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED, + /// \brief XOR the input buffer and keystream, write to the aligned output buffer + XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED, + /// \brief XOR the aligned input buffer and keystream, write to the aligned output buffer + XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED +}; + +/// \brief Policy object for additive stream ciphers +struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy +{ + virtual ~AdditiveCipherAbstractPolicy() {} + + /// \brief Provides data alignment requirements + /// \return data alignment requirements, in bytes + /// \details Internally, the default implementation returns 1. If the stream cipher is implemented + /// using an SSE2 ASM or intrinsics, then the value returned is usually 16. + virtual unsigned int GetAlignment() const {return 1;} + + /// \brief Provides number of bytes operated upon during an iteration + /// \return bytes operated upon during an iteration, in bytes + /// \sa GetOptimalBlockSize() + virtual unsigned int GetBytesPerIteration() const =0; + + /// \brief Provides number of ideal bytes to process + /// \return the ideal number of bytes to process + /// \details Internally, the default implementation returns GetBytesPerIteration() + /// \sa GetBytesPerIteration() + virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();} + + /// \brief Provides buffer size based on iterations + /// \return the buffer size based on iterations, in bytes + virtual unsigned int GetIterationsToBuffer() const =0; + + /// \brief Generate the keystream + /// \param keystream the key stream + /// \param iterationCount the number of iterations to generate the key stream + /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream() + virtual void WriteKeystream(byte *keystream, size_t iterationCount) + {OperateKeystream(KeystreamOperation(INPUT_NULL | static_cast(IsAlignedOn(keystream, GetAlignment()))), keystream, NULLPTR, iterationCount);} + + /// \brief Flag indicating + /// \return true if the stream can be generated independent of the transformation input, false otherwise + /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream() + virtual bool CanOperateKeystream() const {return false;} + + /// \brief Operates the keystream + /// \param operation the operation with additional flags + /// \param output the output buffer + /// \param input the input buffer + /// \param iterationCount the number of iterations to perform on the input + /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer, + /// which will be derived from GetBytesPerIteration(). + /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation() + virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) + {CRYPTOPP_UNUSED(operation); CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); + CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false);} + + /// \brief Key the cipher + /// \param params set of NameValuePairs use to initialize this object + /// \param key a byte array used to key the cipher + /// \param length the size of the key array + virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; + + /// \brief Resynchronize the cipher + /// \param keystreamBuffer the keystream buffer + /// \param iv a byte array used to resynchronize the cipher + /// \param length the size of the IV array + virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) + {CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length); + throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} + + /// \brief Flag indicating random access + /// \return true if the cipher is seekable, false otherwise + /// \sa SeekToIteration() + virtual bool CipherIsRandomAccess() const =0; + + /// \brief Seeks to a random position in the stream + /// \sa CipherIsRandomAccess() + virtual void SeekToIteration(lword iterationCount) + {CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(!CipherIsRandomAccess()); + throw NotImplemented("StreamTransformation: this object doesn't support random access");} + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2". + /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics + /// instead of ASM. + /// \details Algorithms which combine different instructions or ISAs provide the + /// dominant one. For example on x86 AES/GCM returns "AESNI" rather than + /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". + /// \note Provider is not universally implemented yet. + virtual std::string AlgorithmProvider() const { return "C++"; } +}; + +/// \brief Base class for additive stream ciphers +/// \tparam WT word type +/// \tparam W count of words +/// \tparam X bytes per iteration count +/// \tparam BASE AdditiveCipherAbstractPolicy derived base class +template +struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE +{ + /// \brief Word type for the cipher + typedef WT WordType; + + /// \brief Number of bytes for an iteration + /// \details BYTES_PER_ITERATION is the product sizeof(WordType) * W. + /// For example, ChaCha uses 16 each word32, and the value of + /// BYTES_PER_ITERATION is 64. Each invocation of the ChaCha block function + /// produces 64 bytes of keystream. + CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W); + + virtual ~AdditiveCipherConcretePolicy() {} + + /// \brief Provides data alignment requirements + /// \return data alignment requirements, in bytes + /// \details Internally, the default implementation returns 1. If the stream + /// cipher is implemented using an SSE2 ASM or intrinsics, then the value + /// returned is usually 16. + unsigned int GetAlignment() const {return GetAlignmentOf();} + + /// \brief Provides number of bytes operated upon during an iteration + /// \return bytes operated upon during an iteration, in bytes + /// \sa GetOptimalBlockSize() + unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;} + + /// \brief Provides buffer size based on iterations + /// \return the buffer size based on iterations, in bytes + unsigned int GetIterationsToBuffer() const {return X;} + + /// \brief Flag indicating + /// \return true if the stream can be generated independent of the + /// transformation input, false otherwise + /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream() + bool CanOperateKeystream() const {return true;} + + /// \brief Operates the keystream + /// \param operation the operation with additional flags + /// \param output the output buffer + /// \param input the input buffer + /// \param iterationCount the number of iterations to perform on the input + /// \details OperateKeystream() will attempt to operate upon GetOptimalBlockSize() buffer, + /// which will be derived from GetBytesPerIteration(). + /// \sa CanOperateKeystream(), OperateKeystream(), WriteKeystream(), KeystreamOperation() + virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0; +}; + +/// \brief Helper macro to implement OperateKeystream +/// \param x KeystreamOperation mask +/// \param b Endian order +/// \param i index in output buffer +/// \param a value to output +#define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \ + PutWord(((x & OUTPUT_ALIGNED) != 0), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? (a) : (a) ^ GetWord(((x & INPUT_ALIGNED) != 0), b, input+i*sizeof(WordType))); + +/// \brief Helper macro to implement OperateKeystream +/// \param x KeystreamOperation mask +/// \param i index in output buffer +/// \param a value to output +#define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\ + __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\ + if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\ + else _mm_storeu_si128((__m128i *)output+i, t);} + +/// \brief Helper macro to implement OperateKeystream +#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \ + switch (operation) \ + { \ + case WRITE_KEYSTREAM: \ + x(EnumToInt(WRITE_KEYSTREAM)) \ + break; \ + case XOR_KEYSTREAM: \ + x(EnumToInt(XOR_KEYSTREAM)) \ + input += y; \ + break; \ + case XOR_KEYSTREAM_INPUT_ALIGNED: \ + x(EnumToInt(XOR_KEYSTREAM_INPUT_ALIGNED)) \ + input += y; \ + break; \ + case XOR_KEYSTREAM_OUTPUT_ALIGNED: \ + x(EnumToInt(XOR_KEYSTREAM_OUTPUT_ALIGNED)) \ + input += y; \ + break; \ + case WRITE_KEYSTREAM_ALIGNED: \ + x(EnumToInt(WRITE_KEYSTREAM_ALIGNED)) \ + break; \ + case XOR_KEYSTREAM_BOTH_ALIGNED: \ + x(EnumToInt(XOR_KEYSTREAM_BOTH_ALIGNED)) \ + input += y; \ + break; \ + } \ + output += y; + +/// \brief Base class for additive stream ciphers with SymmetricCipher interface +/// \tparam BASE AbstractPolicyHolder base class +template > +class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator +{ +public: + virtual ~AdditiveCipherTemplate() {} + AdditiveCipherTemplate() : m_leftOver(0) {} + + /// \brief Generate random array of bytes + /// \param output the byte buffer + /// \param size the length of the buffer, in bytes + /// \details All generated values are uniformly distributed over the range specified + /// within the constraints of a particular generator. + void GenerateBlock(byte *output, size_t size); + + /// \brief Apply keystream to data + /// \param outString a buffer to write the transformed data + /// \param inString a buffer to read the data + /// \param length the size of the buffers, in bytes + /// \details This is the primary method to operate a stream cipher. For example: + ///
+	///     size_t size = 30;
+	///     byte plain[size] = "Do or do not; there is no try";
+	///     byte cipher[size];
+	///     ...
+	///     ChaCha20 chacha(key, keySize);
+	///     chacha.ProcessData(cipher, plain, size);
+	/// 
+ void ProcessData(byte *outString, const byte *inString, size_t length); + + /// \brief Resynchronize the cipher + /// \param iv a byte array used to resynchronize the cipher + /// \param length the size of the IV array + void Resynchronize(const byte *iv, int length=-1); + + /// \brief Provides number of ideal bytes to process + /// \return the ideal number of bytes to process + /// \details Internally, the default implementation returns GetBytesPerIteration() + /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize() + unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();} + + /// \brief Provides number of ideal bytes to process + /// \return the ideal number of bytes to process + /// \details Internally, the default implementation returns remaining unprocessed bytes + /// \sa GetBytesPerIteration() and OptimalBlockSize() + unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;} + + /// \brief Provides number of ideal data alignment + /// \return the ideal data alignment, in bytes + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} + + /// \brief Determines if the cipher is self inverting + /// \return true if the stream cipher is self inverting, false otherwise + bool IsSelfInverting() const {return true;} + + /// \brief Determines if the cipher is a forward transformation + /// \return true if the stream cipher is a forward transformation, false otherwise + bool IsForwardTransformation() const {return true;} + + /// \brief Flag indicating random access + /// \return true if the cipher is seekable, false otherwise + /// \sa Seek() + bool IsRandomAccess() const {return this->GetPolicy().CipherIsRandomAccess();} + + /// \brief Seeks to a random position in the stream + /// \param position the absolute position in the stream + /// \sa IsRandomAccess() + void Seek(lword position); + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2". + /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics + /// instead of ASM. + /// \details Algorithms which combine different instructions or ISAs provide the + /// dominant one. For example on x86 AES/GCM returns "AESNI" rather than + /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". + /// \note Provider is not universally implemented yet. + std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); } + + typedef typename BASE::PolicyInterface PolicyInterface; + +protected: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + + unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();} + + inline byte * KeystreamBufferBegin() {return this->m_buffer.data();} + inline byte * KeystreamBufferEnd() {return (PtrAdd(this->m_buffer.data(), this->m_buffer.size()));} + + // m_tempOutString added due to GH #1010 + AlignedSecByteBlock m_buffer, m_tempOutString; + size_t m_leftOver; +}; + +/// \brief Policy object for feeback based stream ciphers +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy +{ +public: + virtual ~CFB_CipherAbstractPolicy() {} + + /// \brief Provides data alignment requirements + /// \return data alignment requirements, in bytes + /// \details Internally, the default implementation returns 1. If the stream cipher is implemented + /// using an SSE2 ASM or intrinsics, then the value returned is usually 16. + virtual unsigned int GetAlignment() const =0; + + /// \brief Provides number of bytes operated upon during an iteration + /// \return bytes operated upon during an iteration, in bytes + /// \sa GetOptimalBlockSize() + virtual unsigned int GetBytesPerIteration() const =0; + + /// \brief Access the feedback register + /// \return pointer to the first byte of the feedback register + virtual byte * GetRegisterBegin() =0; + + /// \brief TODO + virtual void TransformRegister() =0; + + /// \brief Flag indicating iteration support + /// \return true if the cipher supports iteration, false otherwise + virtual bool CanIterate() const {return false;} + + /// \brief Iterate the cipher + /// \param output the output buffer + /// \param input the input buffer + /// \param dir the direction of the cipher + /// \param iterationCount the number of iterations to perform on the input + /// \sa IsSelfInverting() and IsForwardTransformation() + virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) + {CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(dir); + CRYPTOPP_UNUSED(iterationCount); CRYPTOPP_ASSERT(false); + throw Exception(Exception::OTHER_ERROR, "SimpleKeyingInterface: unexpected error");} + + /// \brief Key the cipher + /// \param params set of NameValuePairs use to initialize this object + /// \param key a byte array used to key the cipher + /// \param length the size of the key array + virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; + + /// \brief Resynchronize the cipher + /// \param iv a byte array used to resynchronize the cipher + /// \param length the size of the IV array + virtual void CipherResynchronize(const byte *iv, size_t length) + {CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length); + throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2". + /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics + /// instead of ASM. + /// \details Algorithms which combine different instructions or ISAs provide the + /// dominant one. For example on x86 AES/GCM returns "AESNI" rather than + /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". + /// \note Provider is not universally implemented yet. + virtual std::string AlgorithmProvider() const { return "C++"; } +}; + +/// \brief Base class for feedback based stream ciphers +/// \tparam WT word type +/// \tparam W count of words +/// \tparam BASE CFB_CipherAbstractPolicy derived base class +template +struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE +{ + typedef WT WordType; + + virtual ~CFB_CipherConcretePolicy() {} + + /// \brief Provides data alignment requirements + /// \return data alignment requirements, in bytes + /// \details Internally, the default implementation returns 1. If the stream cipher is implemented + /// using an SSE2 ASM or intrinsics, then the value returned is usually 16. + unsigned int GetAlignment() const {return sizeof(WordType);} + + /// \brief Provides number of bytes operated upon during an iteration + /// \return bytes operated upon during an iteration, in bytes + /// \sa GetOptimalBlockSize() + unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;} + + /// \brief Flag indicating iteration support + /// \return true if the cipher supports iteration, false otherwise + bool CanIterate() const {return true;} + + /// \brief Perform one iteration in the forward direction + void TransformRegister() {this->Iterate(NULLPTR, NULLPTR, ENCRYPTION, 1);} + + /// \brief Provides alternate access to a feedback register + /// \tparam B enumeration indicating endianness + /// \details RegisterOutput() provides alternate access to the feedback register. The + /// enumeration B is BigEndian or LittleEndian. Repeatedly applying operator() + /// results in advancing in the register. + template + struct RegisterOutput + { + RegisterOutput(byte *output, const byte *input, CipherDir dir) + : m_output(output), m_input(input), m_dir(dir) {} + + /// \brief XOR feedback register with data + /// \param registerWord data represented as a word type + /// \return reference to the next feedback register word + inline RegisterOutput& operator()(WordType ®isterWord) + { + //CRYPTOPP_ASSERT(IsAligned(m_output)); + //CRYPTOPP_ASSERT(IsAligned(m_input)); + + if (!NativeByteOrderIs(B::ToEnum())) + registerWord = ByteReverse(registerWord); + + if (m_dir == ENCRYPTION) + { + if (m_input == NULLPTR) + { + CRYPTOPP_ASSERT(m_output == NULLPTR); + } + else + { + // WordType ct = *(const WordType *)m_input ^ registerWord; + WordType ct = GetWord(false, NativeByteOrder::ToEnum(), m_input) ^ registerWord; + registerWord = ct; + + // *(WordType*)m_output = ct; + PutWord(false, NativeByteOrder::ToEnum(), m_output, ct); + + m_input += sizeof(WordType); + m_output += sizeof(WordType); + } + } + else + { + // WordType ct = *(const WordType *)m_input; + WordType ct = GetWord(false, NativeByteOrder::ToEnum(), m_input); + + // *(WordType*)m_output = registerWord ^ ct; + PutWord(false, NativeByteOrder::ToEnum(), m_output, registerWord ^ ct); + registerWord = ct; + + m_input += sizeof(WordType); + m_output += sizeof(WordType); + } + + // registerWord is left unreversed so it can be xor-ed with further input + + return *this; + } + + byte *m_output; + const byte *m_input; + CipherDir m_dir; + }; +}; + +/// \brief Base class for feedback based stream ciphers with SymmetricCipher interface +/// \tparam BASE AbstractPolicyHolder base class +template +class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE +{ +public: + virtual ~CFB_CipherTemplate() {} + CFB_CipherTemplate() : m_leftOver(0) {} + + /// \brief Apply keystream to data + /// \param outString a buffer to write the transformed data + /// \param inString a buffer to read the data + /// \param length the size of the buffers, in bytes + /// \details This is the primary method to operate a stream cipher. For example: + ///
+	///     size_t size = 30;
+	///     byte plain[size] = "Do or do not; there is no try";
+	///     byte cipher[size];
+	///     ...
+	///     ChaCha20 chacha(key, keySize);
+	///     chacha.ProcessData(cipher, plain, size);
+	/// 
+ void ProcessData(byte *outString, const byte *inString, size_t length); + + /// \brief Resynchronize the cipher + /// \param iv a byte array used to resynchronize the cipher + /// \param length the size of the IV array + void Resynchronize(const byte *iv, int length=-1); + + /// \brief Provides number of ideal bytes to process + /// \return the ideal number of bytes to process + /// \details Internally, the default implementation returns GetBytesPerIteration() + /// \sa GetBytesPerIteration() and GetOptimalNextBlockSize() + unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();} + + /// \brief Provides number of ideal bytes to process + /// \return the ideal number of bytes to process + /// \details Internally, the default implementation returns remaining unprocessed bytes + /// \sa GetBytesPerIteration() and OptimalBlockSize() + unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;} + + /// \brief Provides number of ideal data alignment + /// \return the ideal data alignment, in bytes + /// \sa GetAlignment() and OptimalBlockSize() + unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} + + /// \brief Flag indicating random access + /// \return true if the cipher is seekable, false otherwise + /// \sa Seek() + bool IsRandomAccess() const {return false;} + + /// \brief Determines if the cipher is self inverting + /// \return true if the stream cipher is self inverting, false otherwise + bool IsSelfInverting() const {return false;} + + /// \brief Retrieve the provider of this algorithm + /// \return the algorithm provider + /// \details The algorithm provider can be a name like "C++", "SSE", "NEON", "AESNI", + /// "ARMv8" and "Power8". C++ is standard C++ code. Other labels, like SSE, + /// usually indicate a specialized implementation using instructions from a higher + /// instruction set architecture (ISA). Future labels may include external hardware + /// like a hardware security module (HSM). + /// \details Generally speaking Wei Dai's original IA-32 ASM code falls under "SSE2". + /// Labels like "SSSE3" and "SSE4.1" follow after Wei's code and use intrinsics + /// instead of ASM. + /// \details Algorithms which combine different instructions or ISAs provide the + /// dominant one. For example on x86 AES/GCM returns "AESNI" rather than + /// "CLMUL" or "AES+SSE4.1" or "AES+CLMUL" or "AES+SSE4.1+CLMUL". + /// \note Provider is not universally implemented yet. + std::string AlgorithmProvider() const { return this->GetPolicy().AlgorithmProvider(); } + + typedef typename BASE::PolicyInterface PolicyInterface; + +protected: + virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0; + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + + // m_tempOutString added due to GH #1010 + AlignedSecByteBlock m_tempOutString; + size_t m_leftOver; +}; + +/// \brief Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface +/// \tparam BASE AbstractPolicyHolder base class +template > +class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate +{ + bool IsForwardTransformation() const {return true;} + void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); +}; + +/// \brief Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface +/// \tparam BASE AbstractPolicyHolder base class +template > +class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate +{ + bool IsForwardTransformation() const {return false;} + void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); +}; + +/// \brief Base class for feedback based stream ciphers with a mandatory block size +/// \tparam BASE CFB_EncryptionTemplate or CFB_DecryptionTemplate base class +template +class CFB_RequireFullDataBlocks : public BASE +{ +public: + unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();} +}; + +/// \brief SymmetricCipher implementation +/// \tparam BASE AbstractPolicyHolder derived base class +/// \tparam INFO AbstractPolicyHolder derived information class +/// \sa Weak::ARC4, ChaCha8, ChaCha12, ChaCha20, Salsa20, SEAL, Sosemanuk, WAKE +template +class SymmetricCipherFinal : public AlgorithmImpl, INFO> +{ +public: + virtual ~SymmetricCipherFinal() {} + + /// \brief Construct a stream cipher + SymmetricCipherFinal() {} + + /// \brief Construct a stream cipher + /// \param key a byte array used to key the cipher + /// \details This overload uses DEFAULT_KEYLENGTH + SymmetricCipherFinal(const byte *key) + {this->SetKey(key, this->DEFAULT_KEYLENGTH);} + + /// \brief Construct a stream cipher + /// \param key a byte array used to key the cipher + /// \param length the size of the key array + SymmetricCipherFinal(const byte *key, size_t length) + {this->SetKey(key, length);} + + /// \brief Construct a stream cipher + /// \param key a byte array used to key the cipher + /// \param length the size of the key array + /// \param iv a byte array used as an initialization vector + SymmetricCipherFinal(const byte *key, size_t length, const byte *iv) + {this->SetKeyWithIV(key, length, iv);} + + /// \brief Clone a SymmetricCipher + /// \return a new SymmetricCipher based on this object + Clonable * Clone() const {return static_cast(new SymmetricCipherFinal(*this));} +}; + +NAMESPACE_END + +// Used by dll.cpp to ensure objects are in dll.o, and not strciphr.o. +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +# include "strciphr.cpp" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder; +CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate >; + +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate >; + +NAMESPACE_END + +#if CRYPTOPP_MSC_VERSION +# pragma warning(pop) +#endif + +#endif diff --git a/external/ours/library/crypto/src/shared/original/tea.cpp b/external/ours/library/crypto/src/shared/original/tea.cpp new file mode 100755 index 000000000..32708c935 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/tea.cpp @@ -0,0 +1,165 @@ +// tea.cpp - modified by Wei Dai from code in the original paper + +#include "pch.h" +#include "tea.h" +#include "misc.h" + +// http://github.com/weidai11/cryptopp/issues/503 +#if defined(__xlC__) || defined(__SUNPRO_CC) +# define MAYBE_VOLATILE(x) (*const_cast(&x)) +#else +# define MAYBE_VOLATILE(x) (x) +#endif + +NAMESPACE_BEGIN(CryptoPP) + +static const word32 DELTA = 0x9e3779b9; +typedef BlockGetAndPut Block; + +#define UINT32_CAST(x) ((word32*)(void*)(x)) +#define CONST_UINT32_CAST(x) ((const word32*)(const void*)(x)) + +void TEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); + m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; +} + +void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z, sum = 0; + Block::Get(inBlock)(y)(z); + + // http://github.com/weidai11/cryptopp/issues/503 + while (MAYBE_VOLATILE(sum) != m_limit) + { + sum += DELTA; + y += ((z << 4) + m_k[0]) ^ (z + sum) ^ ((z >> 5) + m_k[1]); + z += ((y << 4) + m_k[2]) ^ (y + sum) ^ ((y >> 5) + m_k[3]); + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z, sum = m_limit; + Block::Get(inBlock)(y)(z); + + // http://github.com/weidai11/cryptopp/issues/503 + while (MAYBE_VOLATILE(sum) != 0) + { + z -= ((y << 4) + m_k[2]) ^ (y + sum) ^ ((y >> 5) + m_k[3]); + y -= ((z << 4) + m_k[0]) ^ (z + sum) ^ ((z >> 5) + m_k[1]); + sum -= DELTA; + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +void XTEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); + m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; +} + +void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z, sum = 0; + Block::Get(inBlock)(y)(z); + + // http://github.com/weidai11/cryptopp/issues/503 + while (MAYBE_VOLATILE(sum) != m_limit) + { + y += ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]); + sum += DELTA; + z += ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]); + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z, sum = m_limit; + Block::Get(inBlock)(y)(z); + + // http://github.com/weidai11/cryptopp/issues/503 + while (MAYBE_VOLATILE(sum) != 0) + { + z -= ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]); + sum -= DELTA; + y -= ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]); + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +#define MX ((z>>5^y<<2)+(y>>3^z<<4))^((sum^y)+(m_k[(p&3)^e]^z)) + +void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + CRYPTOPP_UNUSED(xorBlock); + CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf())); + CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf())); + + unsigned int n = m_blockSize / 4; + word32 *v = UINT32_CAST(outBlock); + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, CONST_UINT32_CAST(inBlock), m_blockSize); + + word32 y, z = v[n-1], e; + word32 p, q = 6+52/n; + word32 sum = 0; + + while (q-- > 0) + { + sum += DELTA; + e = sum>>2 & 3; + for (p = 0; p < n-1; p++) + { + y = v[p+1]; + z = v[p] += MX; + } + y = v[0]; + z = v[n-1] += MX; + } + + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); +} + +void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + CRYPTOPP_UNUSED(xorBlock); + CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf())); + CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf())); + + unsigned int n = m_blockSize / 4; + word32 *v = UINT32_CAST(outBlock); + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, CONST_UINT32_CAST(inBlock), m_blockSize); + + word32 y = v[0], z, e; + word32 p, q = 6+52/n; + word32 sum = q * DELTA; + + while (sum != 0) + { + e = sum>>2 & 3; + for (p = n-1; p > 0; p--) + { + z = v[p-1]; + y = v[p] -= MX; + } + + z = v[n-1]; + y = v[0] -= MX; + sum -= DELTA; + } + + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/tea.h b/external/ours/library/crypto/src/shared/original/tea.h new file mode 100755 index 000000000..ef671dac8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/tea.h @@ -0,0 +1,161 @@ +// tea.h - originally written and placed in the public domain by Wei Dai + +/// \file tea.h +/// \brief Classes for the TEA, BTEA and XTEA block ciphers + +#ifndef CRYPTOPP_TEA_H +#define CRYPTOPP_TEA_H + +#include "seckey.h" +#include "secblock.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief TEA block cipher information +struct TEA_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<32> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "TEA";} +}; + +/// \brief TEA block cipher +/// \sa TEA +class TEA : public TEA_Info, public BlockCipherDocumentation +{ + /// \brief TEA block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_k; + word32 m_limit; + }; + + /// \brief TEA block cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief TEA block cipher decryption operation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef TEA::Encryption TEAEncryption; +typedef TEA::Decryption TEADecryption; + +/// \brief XTEA block cipher information +struct XTEA_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<32> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "XTEA";} +}; + +/// \brief XTEA block cipher +/// \sa XTEA +class XTEA : public XTEA_Info, public BlockCipherDocumentation +{ + /// \brief XTEA block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_k; + word32 m_limit; + }; + + /// \brief XTEA block cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief XTEA block cipher decryption operation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +/// \brief BTEA block cipher information +struct BTEA_Info : public FixedKeyLength<16> +{ + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BTEA";} +}; + +/// \brief BTEA block cipher +/// \details Corrected Block TEA as described in "xxtea". This class hasn't been tested yet. +/// \sa Correction to xtea and +/// Corrected Block TEA. +class BTEA : public BTEA_Info, public BlockCipherDocumentation +{ + /// \brief BTEA block cipher default operation + class CRYPTOPP_NO_VTABLE Base : public AlgorithmImpl, BTEA_Info> + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) + { + CRYPTOPP_UNUSED(length), CRYPTOPP_UNUSED(params); + m_blockSize = params.GetIntValueWithDefault("BlockSize", 60*4); + GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, key, KEYLENGTH); + } + + unsigned int BlockSize() const {return m_blockSize;} + + protected: + FixedSizeSecBlock m_k; + unsigned int m_blockSize; + }; + + /// \brief BTEA block cipher encryption operation + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief BTEA block cipher decryption operation + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/test.cpp b/external/ours/library/crypto/src/shared/original/test.cpp new file mode 100755 index 000000000..3665dc094 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/test.cpp @@ -0,0 +1,1095 @@ +// test.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 +// scoped_main added to CryptoPP::Test namespace by JW in July 2017 +// Also see http://github.com/weidai11/cryptopp/issues/447 + +#define CRYPTOPP_DEFAULT_NO_DLL +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "dll.h" +#include "cryptlib.h" +#include "aes.h" +#include "filters.h" +#include "md5.h" +#include "ripemd.h" +#include "rng.h" +#include "gzip.h" +#include "default.h" +#include "randpool.h" +#include "ida.h" +#include "base64.h" +#include "factory.h" +#include "whrlpool.h" +#include "tiger.h" +#include "smartptr.h" +#include "pkcspad.h" +#include "stdcpp.h" +#include "osrng.h" +#include "ossig.h" +#include "trap.h" + +#include "validate.h" +#include "bench.h" + +#include +#include +#include +#include +#include + +#ifdef CRYPTOPP_WIN32_AVAILABLE +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_BSD_AVAILABLE) +#include +#include +#include +#define UNIX_PATH_FAMILY 1 +#endif + +#if defined(CRYPTOPP_OSX_AVAILABLE) +#include +#include +#include +#include +#define UNIX_PATH_FAMILY 1 +#endif + +#if (_MSC_VER >= 1000) +#include // for the debug heap +#endif + +#if defined(__MWERKS__) && defined(macintosh) +#include +#endif + +#ifdef _OPENMP +# include +#endif + +#ifdef __BORLANDC__ +#pragma comment(lib, "cryptlib_bds.lib") +#endif + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +// If CRYPTOPP_USE_AES_GENERATOR is 1 then AES/OFB based is used. +// Otherwise the OS random number generator is used. +#define CRYPTOPP_USE_AES_GENERATOR 1 + +// Global namespace, provided by other source files +void FIPS140_SampleApplication(); +void RegisterFactories(CryptoPP::Test::TestClass suites); +int (*AdhocTest)(int argc, char *argv[]) = NULLPTR; + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +const int MAX_PHRASE_LENGTH = 250; +const int GLOBAL_SEED_LENGTH = 16; +std::string g_argvPathHint=""; + +void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed); +std::string RSAEncryptString(const char *pubFilename, const char *seed, const char *message); +std::string RSADecryptString(const char *privFilename, const char *ciphertext); +void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename); +bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename); + +void DigestFile(const char *file); +void HmacFile(const char *hexKey, const char *file); + +void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile); + +std::string EncryptString(const char *plaintext, const char *passPhrase); +std::string DecryptString(const char *ciphertext, const char *passPhrase); + +void EncryptFile(const char *in, const char *out, const char *passPhrase); +void DecryptFile(const char *in, const char *out, const char *passPhrase); + +void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed); +void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames); + +void InformationDisperseFile(int threshold, int nShares, const char *filename); +void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames); + +void GzipFile(const char *in, const char *out, int deflate_level); +void GunzipFile(const char *in, const char *out); + +void Base64Encode(const char *infile, const char *outfile); +void Base64Decode(const char *infile, const char *outfile); +void HexEncode(const char *infile, const char *outfile); +void HexDecode(const char *infile, const char *outfile); + +void FIPS140_GenerateRandomFiles(); + +bool Validate(int, bool); +bool SetGlobalSeed(int argc, char* argv[], std::string& seed); +void SetArgvPathHint(const char* argv0, std::string& pathHint); + +ANONYMOUS_NAMESPACE_BEGIN +#if (CRYPTOPP_USE_AES_GENERATOR) +OFB_Mode::Encryption s_globalRNG; +#else +NonblockingRng s_globalRNG; +#endif +NAMESPACE_END + +RandomNumberGenerator & GlobalRNG() +{ + return dynamic_cast(s_globalRNG); +} + +// Global seed used for the self tests +std::string s_globalSeed; +void PrintSeedAndThreads(); + +// See misc.h and trap.h for comments and usage +#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE) +static const SignalHandler s_dummyHandler; +// static const DebugTrapHandler s_dummyHandler; +#endif + +int scoped_main(int argc, char *argv[]) +{ +#ifdef _CRTDBG_LEAK_CHECK_DF + // Turn on leak-checking + int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); + tempflag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag( tempflag ); +#endif + +#ifdef _SUNPRO_CC + // No need for thread safety for the test program + cout.set_safe_flag(stream_MT::unsafe_object); + cin.set_safe_flag(stream_MT::unsafe_object); +#endif + + try + { + RegisterFactories(All); + + // A hint to help locate TestData/ and TestVectors/ after install. + SetArgvPathHint(argv[0], g_argvPathHint); + + // Set a seed for reproducible results. If the seed is too short then + // it is padded with spaces. If the seed is missing then time() is used. + // For example: + // ./cryptest.exe v seed=abcdefg + SetGlobalSeed(argc, argv, s_globalSeed); + +#if (CRYPTOPP_USE_AES_GENERATOR) + // Fetch the SymmetricCipher interface, not the RandomNumberGenerator + // interface, to key the underlying cipher. If CRYPTOPP_USE_AES_GENERATOR is 1 + // then AES/OFB based is used. Otherwise the OS random number generator is used. + SymmetricCipher& cipher = dynamic_cast(GlobalRNG()); + cipher.SetKeyWithIV((byte *)s_globalSeed.data(), s_globalSeed.size(), (byte *)s_globalSeed.data()); +#endif + + std::string command, executableName, macFilename; + + if (argc < 2) + command = 'h'; + else + command = argv[1]; + + if (command == "g") + { + char thisSeed[1024], privFilename[128], pubFilename[128]; + unsigned int keyLength; + + std::cout << "Key length in bits: "; + std::cin >> keyLength; + + std::cout << "\nSave private key to file: "; + std::cin >> privFilename; + + std::cout << "\nSave public key to file: "; + std::cin >> pubFilename; + + std::cout << "\nRandom Seed: "; + std::ws(std::cin); + std::cin.getline(thisSeed, 1024); + + GenerateRSAKey(keyLength, privFilename, pubFilename, thisSeed); + } + else if (command == "rs") + RSASignFile(argv[2], argv[3], argv[4]); + else if (command == "rv") + { + bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]); + std::cout << (verified ? "valid signature" : "invalid signature") << std::endl; + } + else if (command == "r") + { + char privFilename[128], pubFilename[128]; + char thisSeed[1024], message[1024]; + + std::cout << "Private key file: "; + std::cin >> privFilename; + + std::cout << "\nPublic key file: "; + std::cin >> pubFilename; + + std::cout << "\nRandom Seed: "; + std::ws(std::cin); + std::cin.getline(thisSeed, 1024); + + std::cout << "\nMessage: "; + std::cin.getline(message, 1024); + + std::string ciphertext = RSAEncryptString(pubFilename, thisSeed, message); + std::cout << "\nCiphertext: " << ciphertext << std::endl; + + std::string decrypted = RSADecryptString(privFilename, ciphertext.c_str()); + std::cout << "\nDecrypted: " << decrypted << std::endl; + } + else if (command == "mt") + { + MaurerRandomnessTest mt; + FileStore fs(argv[2]); + fs.TransferAllTo(mt); + std::cout << "Maurer Test Value: " << mt.GetTestValue() << std::endl; + } + else if (command == "mac_dll") + { + std::string fname(argv[2] ? argv[2] : ""); + + // sanity check on file size + std::fstream dllFile(fname.c_str(), std::ios::in | std::ios::out | std::ios::binary); + if (!dllFile.good()) + { + std::cerr << "Failed to open file \"" << fname << "\"\n"; + return 1; + } + + std::ifstream::pos_type fileEnd = dllFile.seekg(0, std::ios_base::end).tellg(); + if (fileEnd > 20*1000*1000) + { + std::cerr << "Input file " << fname << " is too large"; + std::cerr << "(size is " << fileEnd << ").\n"; + return 1; + } + + // read file into memory + unsigned int fileSize = (unsigned int)fileEnd; + SecByteBlock buf(fileSize); + dllFile.seekg(0, std::ios_base::beg); + dllFile.read((char *)buf.begin(), fileSize); + + // find positions of relevant sections in the file, based on version 8 of documentation from http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx + word32 coffPos = *(word16 *)(void *)(buf+0x3c); + word32 optionalHeaderPos = coffPos + 24; + word16 optionalHeaderMagic = *(word16 *)(void *)(buf+optionalHeaderPos); + if (optionalHeaderMagic != 0x10b && optionalHeaderMagic != 0x20b) + { + std::cerr << "Target file is not a PE32 or PE32+ image.\n"; + return 3; + } + word32 checksumPos = optionalHeaderPos + 64; + word32 certificateTableDirectoryPos = optionalHeaderPos + (optionalHeaderMagic == 0x10b ? 128 : 144); + word32 certificateTablePos = *(word32 *)(void *)(buf+certificateTableDirectoryPos); + word32 certificateTableSize = *(word32 *)(void *)(buf+certificateTableDirectoryPos+4); + if (certificateTableSize != 0) + std::cerr << "Warning: certificate table (IMAGE_DIRECTORY_ENTRY_SECURITY) of target image is not empty.\n"; + + // find where to place computed MAC + byte mac[] = CRYPTOPP_DUMMY_DLL_MAC; + byte *found = std::search(buf.begin(), buf.end(), mac+0, mac+sizeof(mac)); + if (found == buf.end()) + { + std::cerr << "MAC placeholder not found. The MAC may already be placed.\n"; + return 2; + } + word32 macPos = (unsigned int)(found-buf.begin()); + + // compute MAC + member_ptr pMac(NewIntegrityCheckingMAC()); + CRYPTOPP_ASSERT(pMac->DigestSize() == sizeof(mac)); + MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, sizeof(mac)))); + f.AddRangeToSkip(0, checksumPos, 4); + f.AddRangeToSkip(0, certificateTableDirectoryPos, 8); + f.AddRangeToSkip(0, macPos, sizeof(mac)); + f.AddRangeToSkip(0, certificateTablePos, certificateTableSize); + f.PutMessageEnd(buf.begin(), buf.size()); + + // Encode MAC + std::string hexMac; + HexEncoder encoder; + encoder.Put(mac, sizeof(mac)), encoder.MessageEnd(); + hexMac.resize(static_cast(encoder.MaxRetrievable())); + encoder.Get(reinterpret_cast(&hexMac[0]), hexMac.size()); + + // Report MAC and location + std::cout << "Placing MAC " << hexMac << " in " << fname << " at file offset " << macPos; + std::cout << " (0x" << std::hex << macPos << std::dec << ").\n"; + + // place MAC + dllFile.seekg(macPos, std::ios_base::beg); + dllFile.write((char *)mac, sizeof(mac)); + } + else if (command == "m") + DigestFile(argv[2]); + else if (command == "tv") + { + // TestDataFile() adds CRYPTOPP_DATA_DIR as required + std::string fname = (argv[2] ? argv[2] : "all"); + if (fname.find(".txt") == std::string::npos) + fname += ".txt"; + if (fname.find("TestVectors") == std::string::npos) + fname = "TestVectors/" + fname; + + PrintSeedAndThreads(); + return !RunTestDataFile(fname.c_str()); + } + else if (command == "t") + { + // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug + char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024]; + + std::cout << "Passphrase: "; + std::cin.getline(passPhrase, MAX_PHRASE_LENGTH); + + std::cout << "\nPlaintext: "; + std::cin.getline(plaintext, sizeof(plaintext)); + + std::string ciphertext = EncryptString(plaintext, passPhrase); + std::cout << "\nCiphertext: " << ciphertext << std::endl; + + std::string decrypted = DecryptString(ciphertext.c_str(), passPhrase); + std::cout << "\nDecrypted: " << decrypted << std::endl; + + return 0; + } + else if (command == "e64") + Base64Encode(argv[2], argv[3]); + else if (command == "d64") + Base64Decode(argv[2], argv[3]); + else if (command == "e16") + HexEncode(argv[2], argv[3]); + else if (command == "d16") + HexDecode(argv[2], argv[3]); + else if (command == "e" || command == "d") + { + char passPhrase[MAX_PHRASE_LENGTH]; + std::cout << "Passphrase: "; + std::cin.getline(passPhrase, MAX_PHRASE_LENGTH); + if (command == "e") + EncryptFile(argv[2], argv[3], passPhrase); + else + DecryptFile(argv[2], argv[3], passPhrase); + } + else if (command == "ss") + { + char thisSeed[1024]; + std::cout << "\nRandom Seed: "; + std::ws(std::cin); + std::cin.getline(thisSeed, sizeof(thisSeed)); + SecretShareFile(StringToValue(argv[2]), StringToValue(argv[3]), argv[4], thisSeed); + } + else if (command == "sr") + SecretRecoverFile(argc-3, argv[2], argv+3); + else if (command == "id") + InformationDisperseFile(StringToValue(argv[2]), StringToValue(argv[3]), argv[4]); + else if (command == "ir") + InformationRecoverFile(argc-3, argv[2], argv+3); + else if (command == "v" || command == "vv") + return !Validate(argc>2 ? StringToValue(argv[2]) : 0, argv[1][1] == 'v'); + else if (command.substr(0,1) == "b") // "b", "b1", "b2", ... + BenchmarkWithCommand(argc, argv); + else if (command == "z") + GzipFile(argv[3], argv[4], argv[2][0]-'0'); + else if (command == "u") + GunzipFile(argv[2], argv[3]); + else if (command == "fips") + FIPS140_SampleApplication(); + else if (command == "fips-rand") + FIPS140_GenerateRandomFiles(); + else if (command == "a") + { + if (AdhocTest) + return (*AdhocTest)(argc, argv); + else + { + std::cerr << "AdhocTest not defined.\n"; + return 1; + } + } + else if (command == "hmac") + HmacFile(argv[2], argv[3]); + else if (command == "ae") + AES_CTR_Encrypt(argv[2], argv[3], argv[4], argv[5]); + else if (command == "h") + { + FileSource usage(DataDir("TestData/usage.dat").c_str(), true, new FileSink(std::cout)); + return 1; + } + else if (command == "V") + { + std::cout << CRYPTOPP_VERSION / 100 << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << std::endl; + } + else + { + std::cerr << "Unrecognized command. Run \"cryptest h\" to obtain usage information.\n"; + return 1; + } + return 0; + } + catch(const Exception &e) + { + std::cout << "\nException caught: " << e.what() << std::endl; + return -1; + } + catch(const std::exception &e) + { + std::cout << "\nstd::exception caught: " << e.what() << std::endl; + return -2; + } +} // main() + +bool SetGlobalSeed(int argc, char* argv[], std::string& seed) +{ + bool ret = false; + + for (int i=0; i::Signer priv(privFile); + FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename)))); +} + +bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename) +{ + FileSource pubFile(pubFilename, true, new HexDecoder); + RSASS::Verifier pub(pubFile); + + FileSource signatureFile(signatureFilename, true, new HexDecoder); + if (signatureFile.MaxRetrievable() != pub.SignatureLength()) + return false; + SecByteBlock signature(pub.SignatureLength()); + signatureFile.Get(signature, signature.size()); + + SignatureVerificationFilter *verifierFilter = new SignatureVerificationFilter(pub); + verifierFilter->Put(signature, pub.SignatureLength()); + FileSource f(messageFilename, true, verifierFilter); + + return verifierFilter->GetLastResult(); +} + +void DigestFile(const char *filename) +{ + SHA1 sha; + RIPEMD160 ripemd; + SHA256 sha256; + Tiger tiger; + SHA512 sha512; + Whirlpool whirlpool; + + vector_member_ptrs filters(6); + filters[0].reset(new HashFilter(sha)); + filters[1].reset(new HashFilter(ripemd)); + filters[2].reset(new HashFilter(tiger)); + filters[3].reset(new HashFilter(sha256)); + filters[4].reset(new HashFilter(sha512)); + filters[5].reset(new HashFilter(whirlpool)); + + member_ptr channelSwitch(new ChannelSwitch); + size_t i; + for (i=0; iAddDefaultRoute(*filters[i]); + FileSource(filename, true, channelSwitch.release()); + + HexEncoder encoder(new FileSink(std::cout), false); + for (i=0; iAlgorithmName() << ": "; + filters[i]->TransferTo(encoder); + std::cout << "\n"; + } +} + +void HmacFile(const char *hexKey, const char *file) +{ + member_ptr mac; + if (strcmp(hexKey, "selftest") == 0) + { + std::cerr << "Computing HMAC/SHA1 value for self test.\n"; + mac.reset(NewIntegrityCheckingMAC()); + } + else + { + std::string decodedKey; + StringSource(hexKey, true, new HexDecoder(new StringSink(decodedKey))); + mac.reset(new HMAC((const byte *)decodedKey.data(), decodedKey.size())); + } + FileSource(file, true, new HashFilter(*mac, new HexEncoder(new FileSink(std::cout)))); +} + +void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile) +{ + SecByteBlock key = HexDecodeString(hexKey); + SecByteBlock iv = HexDecodeString(hexIV); + CTR_Mode::Encryption aes(key, key.size(), iv); + FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile))); +} + +std::string EncryptString(const char *instr, const char *passPhrase) +{ + std::string outstr; + + DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder(new StringSink(outstr))); + encryptor.Put((byte *)instr, strlen(instr)); + encryptor.MessageEnd(); + + return outstr; +} + +std::string DecryptString(const char *instr, const char *passPhrase) +{ + std::string outstr; + + HexDecoder decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr))); + decryptor.Put((byte *)instr, strlen(instr)); + decryptor.MessageEnd(); + + return outstr; +} + +void EncryptFile(const char *in, const char *out, const char *passPhrase) +{ + FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out))); +} + +void DecryptFile(const char *in, const char *out, const char *passPhrase) +{ + FileSource f(in, true, new DefaultDecryptorWithMAC(passPhrase, new FileSink(out))); +} + +void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed) +{ + CRYPTOPP_ASSERT(nShares >= 1 && nShares<=1000); + if (nShares < 1 || nShares > 1000) + throw InvalidArgument("SecretShareFile: " + IntToString(nShares) + " is not in range [1, 1000]"); + + RandomPool rng; + rng.IncorporateEntropy((byte *)seed, strlen(seed)); + + ChannelSwitch *channelSwitch = NULLPTR; + FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch)); + + // Be careful of the type of Sink used. An ArraySink will stop writing data once the array + // is full. Also see http://groups.google.com/forum/#!topic/cryptopp-users/XEKKLCEFH3Y. + vector_member_ptrs fileSinks(nShares); + std::string channel; + for (int i=0; i(i); + fileSinks[i]->Put((const byte *)channel.data(), 4); + channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL); + } + + source.PumpAll(); +} + +void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames) +{ + CRYPTOPP_ASSERT(threshold >= 1 && threshold <=1000); + if (threshold < 1 || threshold > 1000) + throw InvalidArgument("SecretRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]"); + + SecretRecovery recovery(threshold, new FileSink(outFilename)); + + vector_member_ptrs fileSources(threshold); + SecByteBlock channel(4); + int i; + for (i=0; iPump(4); + fileSources[i]->Get(channel, 4); + fileSources[i]->Attach(new ChannelSwitch(recovery, std::string((char *)channel.begin(), 4))); + } + + while (fileSources[0]->Pump(256)) + for (i=1; iPump(256); + + for (i=0; iPumpAll(); +} + +void InformationDisperseFile(int threshold, int nShares, const char *filename) +{ + CRYPTOPP_ASSERT(threshold >= 1 && threshold <=1000); + if (threshold < 1 || threshold > 1000) + throw InvalidArgument("InformationDisperseFile: " + IntToString(nShares) + " is not in range [1, 1000]"); + + ChannelSwitch *channelSwitch = NULLPTR; + FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch)); + + // Be careful of the type of Sink used. An ArraySink will stop writing data once the array + // is full. Also see http://groups.google.com/forum/#!topic/cryptopp-users/XEKKLCEFH3Y. + vector_member_ptrs fileSinks(nShares); + std::string channel; + for (int i=0; i(i); + fileSinks[i]->Put((const byte *)channel.data(), 4); + channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL); + } + + source.PumpAll(); +} + +void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames) +{ + CRYPTOPP_ASSERT(threshold<=1000); + if (threshold < 1 || threshold > 1000) + throw InvalidArgument("InformationRecoverFile: " + IntToString(threshold) + " is not in range [1, 1000]"); + + InformationRecovery recovery(threshold, new FileSink(outFilename)); + + vector_member_ptrs fileSources(threshold); + SecByteBlock channel(4); + int i; + for (i=0; iPump(4); + fileSources[i]->Get(channel, 4); + fileSources[i]->Attach(new ChannelSwitch(recovery, std::string((char *)channel.begin(), 4))); + } + + while (fileSources[0]->Pump(256)) + for (i=1; iPump(256); + + for (i=0; iPumpAll(); +} + +void GzipFile(const char *in, const char *out, int deflate_level) +{ +// FileSource(in, true, new Gzip(new FileSink(out), deflate_level)); + + // use a filter graph to compare decompressed data with original + // + // Source ----> Gzip ------> Sink + // \ | + // \ Gunzip + // \ | + // \ v + // > ComparisonFilter + + EqualityComparisonFilter comparison; + + Gunzip gunzip(new ChannelSwitch(comparison, "0")); + gunzip.SetAutoSignalPropagation(0); + + FileSink sink(out); + + ChannelSwitch *cs; + Gzip gzip(cs = new ChannelSwitch(sink), deflate_level); + cs->AddDefaultRoute(gunzip); + + cs = new ChannelSwitch(gzip); + cs->AddDefaultRoute(comparison, "1"); + FileSource source(in, true, cs); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +void GunzipFile(const char *in, const char *out) +{ + FileSource(in, true, new Gunzip(new FileSink(out))); +} + +void Base64Encode(const char *in, const char *out) +{ + FileSource(in, true, new Base64Encoder(new FileSink(out))); +} + +void Base64Decode(const char *in, const char *out) +{ + FileSource(in, true, new Base64Decoder(new FileSink(out))); +} + +void HexEncode(const char *in, const char *out) +{ + FileSource(in, true, new HexEncoder(new FileSink(out))); +} + +void HexDecode(const char *in, const char *out) +{ + FileSource(in, true, new HexDecoder(new FileSink(out))); +} + +bool Validate(int alg, bool thorough) +{ + bool result; + + g_testBegin = ::time(NULLPTR); + PrintSeedAndThreads(); + + // TODO: we need to group these tests like benchmarks... + switch (alg) + { + case 0: result = ValidateAll(thorough); break; + case 1: result = TestSettings(); break; + case 2: result = TestOS_RNG(); break; +// case 3: result = TestSecRandom(); break; + case 4: result = ValidateMD5(); break; + case 5: result = ValidateSHA(); break; + case 6: result = ValidateDES(); break; + case 7: result = ValidateIDEA(); break; + case 8: result = ValidateARC4(); break; + case 9: result = ValidateRC5(); break; + case 10: result = ValidateBlowfish(); break; +// case 11: result = ValidateDiamond2(); break; + case 12: result = ValidateThreeWay(); break; + case 13: result = ValidateBBS(); break; + case 14: result = ValidateDH(); break; + case 15: result = ValidateX25519(); break; + case 16: result = ValidateRSA(); break; + case 17: result = ValidateElGamal(); break; + case 18: result = ValidateDSA(thorough); break; +// case 18: result = ValidateHAVAL(); break; + case 19: result = ValidateSAFER(); break; + case 20: result = ValidateLUC(); break; + case 21: result = ValidateRabin(); break; +// case 22: result = ValidateBlumGoldwasser(); break; + case 23: result = ValidateECP(); break; + case 24: result = ValidateEC2N(); break; +// case 25: result = ValidateMD5MAC(); break; + case 26: result = ValidateGOST(); break; + case 27: result = ValidateTiger(); break; + case 28: result = ValidateRIPEMD(); break; + case 29: result = ValidateHMAC(); break; +// case 30: result = ValidateXMACC(); break; + case 31: result = ValidateSHARK(); break; + case 32: result = ValidateLUC_DH(); break; + case 33: result = ValidateLUC_DL(); break; + case 34: result = ValidateSEAL(); break; + case 35: result = ValidateCAST(); break; + case 36: result = ValidateSquare(); break; + case 37: result = ValidateRC2(); break; + case 38: result = ValidateRC6(); break; + case 39: result = ValidateMARS(); break; + case 40: result = ValidateRW(); break; + case 41: result = ValidateMD2(); break; + case 42: result = ValidateNR(); break; + case 43: result = ValidateMQV(); break; + case 44: result = ValidateRijndael(); break; + case 45: result = ValidateTwofish(); break; + case 46: result = ValidateSerpent(); break; + case 47: result = ValidateCipherModes(); break; + case 48: result = ValidateCRC32(); break; + case 49: result = ValidateCRC32C(); break; + case 50: result = ValidateECDSA(); break; + case 51: result = ValidateECGDSA(thorough); break; + case 52: result = ValidateXTR_DH(); break; + case 53: result = ValidateSKIPJACK(); break; + case 54: result = ValidateSHA2(); break; + case 55: result = ValidatePanama(); break; + case 56: result = ValidateAdler32(); break; + case 57: result = ValidateMD4(); break; + case 58: result = ValidatePBKDF(); break; + case 59: result = ValidateHKDF(); break; + case 60: result = ValidateScrypt(); break; + case 61: result = ValidateESIGN(); break; + case 62: result = ValidateDLIES(); break; + case 63: result = ValidateBaseCode(); break; + case 64: result = ValidateSHACAL2(); break; + case 65: result = ValidateARIA(); break; + case 66: result = ValidateCamellia(); break; + case 67: result = ValidateWhirlpool(); break; + case 68: result = ValidateLSH(); break; + case 69: result = ValidateTTMAC(); break; + case 70: result = ValidateSalsa(); break; + case 71: result = ValidateChaCha(); break; + case 72: result = ValidateChaChaTLS(); break; + case 73: result = ValidateSosemanuk(); break; + case 74: result = ValidateRabbit(); break; + case 75: result = ValidateHC128(); break; + case 76: result = ValidateHC256(); break; + case 80: result = ValidateVMAC(); break; + case 81: result = ValidateCCM(); break; + case 82: result = ValidateGCM(); break; + case 83: result = ValidateXTS(); break; + case 84: result = ValidateCMAC(); break; + case 85: result = ValidateSM3(); break; + case 86: result = ValidateBLAKE2s(); break; + case 87: result = ValidateBLAKE2b(); break; + case 88: result = ValidatePoly1305(); break; + case 89: result = ValidateSipHash(); break; + case 90: result = ValidateHashDRBG(); break; + case 91: result = ValidateHmacDRBG(); break; + case 92: result = ValidateNaCl(); break; + + case 100: result = ValidateCHAM(); break; + case 101: result = ValidateSIMECK(); break; + case 102: result = ValidateSIMON(); break; + case 103: result = ValidateSPECK(); break; + + case 110: result = ValidateSHA3(); break; + case 111: result = ValidateSHAKE(); break; + case 112: result = ValidateSHAKE_XOF(); break; + + case 120: result = ValidateMQV(); break; + case 121: result = ValidateHMQV(); break; + case 122: result = ValidateFHMQV(); break; + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + // http://github.com/weidai11/cryptopp/issues/92 + case 9999: result = TestSecBlock(); break; + // http://github.com/weidai11/cryptopp/issues/64 + case 9998: result = TestPolynomialMod2(); break; + // http://github.com/weidai11/cryptopp/issues/336 + case 9997: result = TestIntegerBitops(); break; + // http://github.com/weidai11/cryptopp/issues/602 + case 9996: result = TestIntegerOps(); break; + // http://github.com/weidai11/cryptopp/issues/360 + case 9995: result = TestRounding(); break; + // http://github.com/weidai11/cryptopp/issues/242 + case 9994: result = TestHuffmanCodes(); break; + // http://github.com/weidai11/cryptopp/issues/346 + case 9993: result = TestASN1Parse(); break; + case 9992: result = TestASN1Functions(); break; + // http://github.com/weidai11/cryptopp/issues/242 + case 9991: result = TestX25519(); break; + // http://github.com/weidai11/cryptopp/issues/346 + case 9990: result = TestEd25519(); break; +# if defined(CRYPTOPP_ALTIVEC_AVAILABLE) + case 9989: result = TestAltivecOps(); break; +# endif +#endif + + default: return false; + } + + g_testEnd = ::time(NULLPTR); + + std::cout << "\nSeed used was " << s_globalSeed; + std::cout << "\nTest started at " << TimeToString(g_testBegin); + std::cout << "\nTest ended at " << TimeToString(g_testEnd) << std::endl; + + return result; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP + +// Microsoft puts a byte in global namespace. Combined with +// a 'using namespace CryptoPP', it causes compile failures. +// Also see http://github.com/weidai11/cryptopp/issues/442 +// and http://github.com/weidai11/cryptopp/issues/447. +int CRYPTOPP_API main(int argc, char *argv[]) +{ + return CryptoPP::Test::scoped_main(argc, argv); +} diff --git a/external/ours/library/crypto/src/shared/original/tftables.cpp b/external/ours/library/crypto/src/shared/original/tftables.cpp index 22fde97c5..00bb6bac8 100755 --- a/external/ours/library/crypto/src/shared/original/tftables.cpp +++ b/external/ours/library/crypto/src/shared/original/tftables.cpp @@ -1,317 +1,323 @@ -// Twofish tables - -#include "FirstCrypto.h" -#include "twofish.h" - -NAMESPACE_BEGIN(CryptoPP) - -const byte Twofish::q[2][256] = { - 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, - 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, - 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, - 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, - 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, - 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, - 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, - 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, - 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, - 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, - 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, - 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, - 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, - 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, - 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, - 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, - 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, - 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, - 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, - 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, - 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, - 0x4A, 0x5E, 0xC1, 0xE0, - - 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, - 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, - 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, - 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, - 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, - 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, - 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, - 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, - 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, - 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, - 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, - 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, - 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, - 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, - 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, - 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, - 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, - 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, - 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, - 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, - 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, - 0x55, 0x09, 0xBE, 0x91 -}; - -const word32 Twofish::mds[4][256] = { - 0xbcbc3275, 0xecec21f3, 0x202043c6, 0xb3b3c9f4, - 0xdada03db, 0x02028b7b, 0xe2e22bfb, 0x9e9efac8, - 0xc9c9ec4a, 0xd4d409d3, 0x18186be6, 0x1e1e9f6b, - 0x98980e45, 0xb2b2387d, 0xa6a6d2e8, 0x2626b74b, - 0x3c3c57d6, 0x93938a32, 0x8282eed8, 0x525298fd, - 0x7b7bd437, 0xbbbb3771, 0x5b5b97f1, 0x474783e1, - 0x24243c30, 0x5151e20f, 0xbabac6f8, 0x4a4af31b, - 0xbfbf4887, 0x0d0d70fa, 0xb0b0b306, 0x7575de3f, - 0xd2d2fd5e, 0x7d7d20ba, 0x666631ae, 0x3a3aa35b, - 0x59591c8a, 0x00000000, 0xcdcd93bc, 0x1a1ae09d, - 0xaeae2c6d, 0x7f7fabc1, 0x2b2bc7b1, 0xbebeb90e, - 0xe0e0a080, 0x8a8a105d, 0x3b3b52d2, 0x6464bad5, - 0xd8d888a0, 0xe7e7a584, 0x5f5fe807, 0x1b1b1114, - 0x2c2cc2b5, 0xfcfcb490, 0x3131272c, 0x808065a3, - 0x73732ab2, 0x0c0c8173, 0x79795f4c, 0x6b6b4154, - 0x4b4b0292, 0x53536974, 0x94948f36, 0x83831f51, - 0x2a2a3638, 0xc4c49cb0, 0x2222c8bd, 0xd5d5f85a, - 0xbdbdc3fc, 0x48487860, 0xffffce62, 0x4c4c0796, - 0x4141776c, 0xc7c7e642, 0xebeb24f7, 0x1c1c1410, - 0x5d5d637c, 0x36362228, 0x6767c027, 0xe9e9af8c, - 0x4444f913, 0x1414ea95, 0xf5f5bb9c, 0xcfcf18c7, - 0x3f3f2d24, 0xc0c0e346, 0x7272db3b, 0x54546c70, - 0x29294cca, 0xf0f035e3, 0x0808fe85, 0xc6c617cb, - 0xf3f34f11, 0x8c8ce4d0, 0xa4a45993, 0xcaca96b8, - 0x68683ba6, 0xb8b84d83, 0x38382820, 0xe5e52eff, - 0xadad569f, 0x0b0b8477, 0xc8c81dc3, 0x9999ffcc, - 0x5858ed03, 0x19199a6f, 0x0e0e0a08, 0x95957ebf, - 0x70705040, 0xf7f730e7, 0x6e6ecf2b, 0x1f1f6ee2, - 0xb5b53d79, 0x09090f0c, 0x616134aa, 0x57571682, - 0x9f9f0b41, 0x9d9d803a, 0x111164ea, 0x2525cdb9, - 0xafafdde4, 0x4545089a, 0xdfdf8da4, 0xa3a35c97, - 0xeaead57e, 0x353558da, 0xededd07a, 0x4343fc17, - 0xf8f8cb66, 0xfbfbb194, 0x3737d3a1, 0xfafa401d, - 0xc2c2683d, 0xb4b4ccf0, 0x32325dde, 0x9c9c71b3, - 0x5656e70b, 0xe3e3da72, 0x878760a7, 0x15151b1c, - 0xf9f93aef, 0x6363bfd1, 0x3434a953, 0x9a9a853e, - 0xb1b1428f, 0x7c7cd133, 0x88889b26, 0x3d3da65f, - 0xa1a1d7ec, 0xe4e4df76, 0x8181942a, 0x91910149, - 0x0f0ffb81, 0xeeeeaa88, 0x161661ee, 0xd7d77321, - 0x9797f5c4, 0xa5a5a81a, 0xfefe3feb, 0x6d6db5d9, - 0x7878aec5, 0xc5c56d39, 0x1d1de599, 0x7676a4cd, - 0x3e3edcad, 0xcbcb6731, 0xb6b6478b, 0xefef5b01, - 0x12121e18, 0x6060c523, 0x6a6ab0dd, 0x4d4df61f, - 0xcecee94e, 0xdede7c2d, 0x55559df9, 0x7e7e5a48, - 0x2121b24f, 0x03037af2, 0xa0a02665, 0x5e5e198e, - 0x5a5a6678, 0x65654b5c, 0x62624e58, 0xfdfd4519, - 0x0606f48d, 0x404086e5, 0xf2f2be98, 0x3333ac57, - 0x17179067, 0x05058e7f, 0xe8e85e05, 0x4f4f7d64, - 0x89896aaf, 0x10109563, 0x74742fb6, 0x0a0a75fe, - 0x5c5c92f5, 0x9b9b74b7, 0x2d2d333c, 0x3030d6a5, - 0x2e2e49ce, 0x494989e9, 0x46467268, 0x77775544, - 0xa8a8d8e0, 0x9696044d, 0x2828bd43, 0xa9a92969, - 0xd9d97929, 0x8686912e, 0xd1d187ac, 0xf4f44a15, - 0x8d8d1559, 0xd6d682a8, 0xb9b9bc0a, 0x42420d9e, - 0xf6f6c16e, 0x2f2fb847, 0xdddd06df, 0x23233934, - 0xcccc6235, 0xf1f1c46a, 0xc1c112cf, 0x8585ebdc, - 0x8f8f9e22, 0x7171a1c9, 0x9090f0c0, 0xaaaa539b, - 0x0101f189, 0x8b8be1d4, 0x4e4e8ced, 0x8e8e6fab, - 0xababa212, 0x6f6f3ea2, 0xe6e6540d, 0xdbdbf252, - 0x92927bbb, 0xb7b7b602, 0x6969ca2f, 0x3939d9a9, - 0xd3d30cd7, 0xa7a72361, 0xa2a2ad1e, 0xc3c399b4, - 0x6c6c4450, 0x07070504, 0x04047ff6, 0x272746c2, - 0xacaca716, 0xd0d07625, 0x50501386, 0xdcdcf756, - 0x84841a55, 0xe1e15109, 0x7a7a25be, 0x1313ef91, - - 0xa9d93939, 0x67901717, 0xb3719c9c, 0xe8d2a6a6, - 0x04050707, 0xfd985252, 0xa3658080, 0x76dfe4e4, - 0x9a084545, 0x92024b4b, 0x80a0e0e0, 0x78665a5a, - 0xe4ddafaf, 0xddb06a6a, 0xd1bf6363, 0x38362a2a, - 0x0d54e6e6, 0xc6432020, 0x3562cccc, 0x98bef2f2, - 0x181e1212, 0xf724ebeb, 0xecd7a1a1, 0x6c774141, - 0x43bd2828, 0x7532bcbc, 0x37d47b7b, 0x269b8888, - 0xfa700d0d, 0x13f94444, 0x94b1fbfb, 0x485a7e7e, - 0xf27a0303, 0xd0e48c8c, 0x8b47b6b6, 0x303c2424, - 0x84a5e7e7, 0x54416b6b, 0xdf06dddd, 0x23c56060, - 0x1945fdfd, 0x5ba33a3a, 0x3d68c2c2, 0x59158d8d, - 0xf321ecec, 0xae316666, 0xa23e6f6f, 0x82165757, - 0x63951010, 0x015befef, 0x834db8b8, 0x2e918686, - 0xd9b56d6d, 0x511f8383, 0x9b53aaaa, 0x7c635d5d, - 0xa63b6868, 0xeb3ffefe, 0xa5d63030, 0xbe257a7a, - 0x16a7acac, 0x0c0f0909, 0xe335f0f0, 0x6123a7a7, - 0xc0f09090, 0x8cafe9e9, 0x3a809d9d, 0xf5925c5c, - 0x73810c0c, 0x2c273131, 0x2576d0d0, 0x0be75656, - 0xbb7b9292, 0x4ee9cece, 0x89f10101, 0x6b9f1e1e, - 0x53a93434, 0x6ac4f1f1, 0xb499c3c3, 0xf1975b5b, - 0xe1834747, 0xe66b1818, 0xbdc82222, 0x450e9898, - 0xe26e1f1f, 0xf4c9b3b3, 0xb62f7474, 0x66cbf8f8, - 0xccff9999, 0x95ea1414, 0x03ed5858, 0x56f7dcdc, - 0xd4e18b8b, 0x1c1b1515, 0x1eada2a2, 0xd70cd3d3, - 0xfb2be2e2, 0xc31dc8c8, 0x8e195e5e, 0xb5c22c2c, - 0xe9894949, 0xcf12c1c1, 0xbf7e9595, 0xba207d7d, - 0xea641111, 0x77840b0b, 0x396dc5c5, 0xaf6a8989, - 0x33d17c7c, 0xc9a17171, 0x62ceffff, 0x7137bbbb, - 0x81fb0f0f, 0x793db5b5, 0x0951e1e1, 0xaddc3e3e, - 0x242d3f3f, 0xcda47676, 0xf99d5555, 0xd8ee8282, - 0xe5864040, 0xc5ae7878, 0xb9cd2525, 0x4d049696, - 0x44557777, 0x080a0e0e, 0x86135050, 0xe730f7f7, - 0xa1d33737, 0x1d40fafa, 0xaa346161, 0xed8c4e4e, - 0x06b3b0b0, 0x706c5454, 0xb22a7373, 0xd2523b3b, - 0x410b9f9f, 0x7b8b0202, 0xa088d8d8, 0x114ff3f3, - 0x3167cbcb, 0xc2462727, 0x27c06767, 0x90b4fcfc, - 0x20283838, 0xf67f0404, 0x60784848, 0xff2ee5e5, - 0x96074c4c, 0x5c4b6565, 0xb1c72b2b, 0xab6f8e8e, - 0x9e0d4242, 0x9cbbf5f5, 0x52f2dbdb, 0x1bf34a4a, - 0x5fa63d3d, 0x9359a4a4, 0x0abcb9b9, 0xef3af9f9, - 0x91ef1313, 0x85fe0808, 0x49019191, 0xee611616, - 0x2d7cdede, 0x4fb22121, 0x8f42b1b1, 0x3bdb7272, - 0x47b82f2f, 0x8748bfbf, 0x6d2caeae, 0x46e3c0c0, - 0xd6573c3c, 0x3e859a9a, 0x6929a9a9, 0x647d4f4f, - 0x2a948181, 0xce492e2e, 0xcb17c6c6, 0x2fca6969, - 0xfcc3bdbd, 0x975ca3a3, 0x055ee8e8, 0x7ad0eded, - 0xac87d1d1, 0x7f8e0505, 0xd5ba6464, 0x1aa8a5a5, - 0x4bb72626, 0x0eb9bebe, 0xa7608787, 0x5af8d5d5, - 0x28223636, 0x14111b1b, 0x3fde7575, 0x2979d9d9, - 0x88aaeeee, 0x3c332d2d, 0x4c5f7979, 0x02b6b7b7, - 0xb896caca, 0xda583535, 0xb09cc4c4, 0x17fc4343, - 0x551a8484, 0x1ff64d4d, 0x8a1c5959, 0x7d38b2b2, - 0x57ac3333, 0xc718cfcf, 0x8df40606, 0x74695353, - 0xb7749b9b, 0xc4f59797, 0x9f56adad, 0x72dae3e3, - 0x7ed5eaea, 0x154af4f4, 0x229e8f8f, 0x12a2abab, - 0x584e6262, 0x07e85f5f, 0x99e51d1d, 0x34392323, - 0x6ec1f6f6, 0x50446c6c, 0xde5d3232, 0x68724646, - 0x6526a0a0, 0xbc93cdcd, 0xdb03dada, 0xf8c6baba, - 0xc8fa9e9e, 0xa882d6d6, 0x2bcf6e6e, 0x40507070, - 0xdceb8585, 0xfe750a0a, 0x328a9393, 0xa48ddfdf, - 0xca4c2929, 0x10141c1c, 0x2173d7d7, 0xf0ccb4b4, - 0xd309d4d4, 0x5d108a8a, 0x0fe25151, 0x00000000, - 0x6f9a1919, 0x9de01a1a, 0x368f9494, 0x42e6c7c7, - 0x4aecc9c9, 0x5efdd2d2, 0xc1ab7f7f, 0xe0d8a8a8, - - 0xbc75bc32, 0xecf3ec21, 0x20c62043, 0xb3f4b3c9, - 0xdadbda03, 0x027b028b, 0xe2fbe22b, 0x9ec89efa, - 0xc94ac9ec, 0xd4d3d409, 0x18e6186b, 0x1e6b1e9f, - 0x9845980e, 0xb27db238, 0xa6e8a6d2, 0x264b26b7, - 0x3cd63c57, 0x9332938a, 0x82d882ee, 0x52fd5298, - 0x7b377bd4, 0xbb71bb37, 0x5bf15b97, 0x47e14783, - 0x2430243c, 0x510f51e2, 0xbaf8bac6, 0x4a1b4af3, - 0xbf87bf48, 0x0dfa0d70, 0xb006b0b3, 0x753f75de, - 0xd25ed2fd, 0x7dba7d20, 0x66ae6631, 0x3a5b3aa3, - 0x598a591c, 0x00000000, 0xcdbccd93, 0x1a9d1ae0, - 0xae6dae2c, 0x7fc17fab, 0x2bb12bc7, 0xbe0ebeb9, - 0xe080e0a0, 0x8a5d8a10, 0x3bd23b52, 0x64d564ba, - 0xd8a0d888, 0xe784e7a5, 0x5f075fe8, 0x1b141b11, - 0x2cb52cc2, 0xfc90fcb4, 0x312c3127, 0x80a38065, - 0x73b2732a, 0x0c730c81, 0x794c795f, 0x6b546b41, - 0x4b924b02, 0x53745369, 0x9436948f, 0x8351831f, - 0x2a382a36, 0xc4b0c49c, 0x22bd22c8, 0xd55ad5f8, - 0xbdfcbdc3, 0x48604878, 0xff62ffce, 0x4c964c07, - 0x416c4177, 0xc742c7e6, 0xebf7eb24, 0x1c101c14, - 0x5d7c5d63, 0x36283622, 0x672767c0, 0xe98ce9af, - 0x441344f9, 0x149514ea, 0xf59cf5bb, 0xcfc7cf18, - 0x3f243f2d, 0xc046c0e3, 0x723b72db, 0x5470546c, - 0x29ca294c, 0xf0e3f035, 0x088508fe, 0xc6cbc617, - 0xf311f34f, 0x8cd08ce4, 0xa493a459, 0xcab8ca96, - 0x68a6683b, 0xb883b84d, 0x38203828, 0xe5ffe52e, - 0xad9fad56, 0x0b770b84, 0xc8c3c81d, 0x99cc99ff, - 0x580358ed, 0x196f199a, 0x0e080e0a, 0x95bf957e, - 0x70407050, 0xf7e7f730, 0x6e2b6ecf, 0x1fe21f6e, - 0xb579b53d, 0x090c090f, 0x61aa6134, 0x57825716, - 0x9f419f0b, 0x9d3a9d80, 0x11ea1164, 0x25b925cd, - 0xafe4afdd, 0x459a4508, 0xdfa4df8d, 0xa397a35c, - 0xea7eead5, 0x35da3558, 0xed7aedd0, 0x431743fc, - 0xf866f8cb, 0xfb94fbb1, 0x37a137d3, 0xfa1dfa40, - 0xc23dc268, 0xb4f0b4cc, 0x32de325d, 0x9cb39c71, - 0x560b56e7, 0xe372e3da, 0x87a78760, 0x151c151b, - 0xf9eff93a, 0x63d163bf, 0x345334a9, 0x9a3e9a85, - 0xb18fb142, 0x7c337cd1, 0x8826889b, 0x3d5f3da6, - 0xa1eca1d7, 0xe476e4df, 0x812a8194, 0x91499101, - 0x0f810ffb, 0xee88eeaa, 0x16ee1661, 0xd721d773, - 0x97c497f5, 0xa51aa5a8, 0xfeebfe3f, 0x6dd96db5, - 0x78c578ae, 0xc539c56d, 0x1d991de5, 0x76cd76a4, - 0x3ead3edc, 0xcb31cb67, 0xb68bb647, 0xef01ef5b, - 0x1218121e, 0x602360c5, 0x6add6ab0, 0x4d1f4df6, - 0xce4ecee9, 0xde2dde7c, 0x55f9559d, 0x7e487e5a, - 0x214f21b2, 0x03f2037a, 0xa065a026, 0x5e8e5e19, - 0x5a785a66, 0x655c654b, 0x6258624e, 0xfd19fd45, - 0x068d06f4, 0x40e54086, 0xf298f2be, 0x335733ac, - 0x17671790, 0x057f058e, 0xe805e85e, 0x4f644f7d, - 0x89af896a, 0x10631095, 0x74b6742f, 0x0afe0a75, - 0x5cf55c92, 0x9bb79b74, 0x2d3c2d33, 0x30a530d6, - 0x2ece2e49, 0x49e94989, 0x46684672, 0x77447755, - 0xa8e0a8d8, 0x964d9604, 0x284328bd, 0xa969a929, - 0xd929d979, 0x862e8691, 0xd1acd187, 0xf415f44a, - 0x8d598d15, 0xd6a8d682, 0xb90ab9bc, 0x429e420d, - 0xf66ef6c1, 0x2f472fb8, 0xdddfdd06, 0x23342339, - 0xcc35cc62, 0xf16af1c4, 0xc1cfc112, 0x85dc85eb, - 0x8f228f9e, 0x71c971a1, 0x90c090f0, 0xaa9baa53, - 0x018901f1, 0x8bd48be1, 0x4eed4e8c, 0x8eab8e6f, - 0xab12aba2, 0x6fa26f3e, 0xe60de654, 0xdb52dbf2, - 0x92bb927b, 0xb702b7b6, 0x692f69ca, 0x39a939d9, - 0xd3d7d30c, 0xa761a723, 0xa21ea2ad, 0xc3b4c399, - 0x6c506c44, 0x07040705, 0x04f6047f, 0x27c22746, - 0xac16aca7, 0xd025d076, 0x50865013, 0xdc56dcf7, - 0x8455841a, 0xe109e151, 0x7abe7a25, 0x139113ef, - - 0xd939a9d9, 0x90176790, 0x719cb371, 0xd2a6e8d2, - 0x05070405, 0x9852fd98, 0x6580a365, 0xdfe476df, - 0x08459a08, 0x024b9202, 0xa0e080a0, 0x665a7866, - 0xddafe4dd, 0xb06addb0, 0xbf63d1bf, 0x362a3836, - 0x54e60d54, 0x4320c643, 0x62cc3562, 0xbef298be, - 0x1e12181e, 0x24ebf724, 0xd7a1ecd7, 0x77416c77, - 0xbd2843bd, 0x32bc7532, 0xd47b37d4, 0x9b88269b, - 0x700dfa70, 0xf94413f9, 0xb1fb94b1, 0x5a7e485a, - 0x7a03f27a, 0xe48cd0e4, 0x47b68b47, 0x3c24303c, - 0xa5e784a5, 0x416b5441, 0x06dddf06, 0xc56023c5, - 0x45fd1945, 0xa33a5ba3, 0x68c23d68, 0x158d5915, - 0x21ecf321, 0x3166ae31, 0x3e6fa23e, 0x16578216, - 0x95106395, 0x5bef015b, 0x4db8834d, 0x91862e91, - 0xb56dd9b5, 0x1f83511f, 0x53aa9b53, 0x635d7c63, - 0x3b68a63b, 0x3ffeeb3f, 0xd630a5d6, 0x257abe25, - 0xa7ac16a7, 0x0f090c0f, 0x35f0e335, 0x23a76123, - 0xf090c0f0, 0xafe98caf, 0x809d3a80, 0x925cf592, - 0x810c7381, 0x27312c27, 0x76d02576, 0xe7560be7, - 0x7b92bb7b, 0xe9ce4ee9, 0xf10189f1, 0x9f1e6b9f, - 0xa93453a9, 0xc4f16ac4, 0x99c3b499, 0x975bf197, - 0x8347e183, 0x6b18e66b, 0xc822bdc8, 0x0e98450e, - 0x6e1fe26e, 0xc9b3f4c9, 0x2f74b62f, 0xcbf866cb, - 0xff99ccff, 0xea1495ea, 0xed5803ed, 0xf7dc56f7, - 0xe18bd4e1, 0x1b151c1b, 0xada21ead, 0x0cd3d70c, - 0x2be2fb2b, 0x1dc8c31d, 0x195e8e19, 0xc22cb5c2, - 0x8949e989, 0x12c1cf12, 0x7e95bf7e, 0x207dba20, - 0x6411ea64, 0x840b7784, 0x6dc5396d, 0x6a89af6a, - 0xd17c33d1, 0xa171c9a1, 0xceff62ce, 0x37bb7137, - 0xfb0f81fb, 0x3db5793d, 0x51e10951, 0xdc3eaddc, - 0x2d3f242d, 0xa476cda4, 0x9d55f99d, 0xee82d8ee, - 0x8640e586, 0xae78c5ae, 0xcd25b9cd, 0x04964d04, - 0x55774455, 0x0a0e080a, 0x13508613, 0x30f7e730, - 0xd337a1d3, 0x40fa1d40, 0x3461aa34, 0x8c4eed8c, - 0xb3b006b3, 0x6c54706c, 0x2a73b22a, 0x523bd252, - 0x0b9f410b, 0x8b027b8b, 0x88d8a088, 0x4ff3114f, - 0x67cb3167, 0x4627c246, 0xc06727c0, 0xb4fc90b4, - 0x28382028, 0x7f04f67f, 0x78486078, 0x2ee5ff2e, - 0x074c9607, 0x4b655c4b, 0xc72bb1c7, 0x6f8eab6f, - 0x0d429e0d, 0xbbf59cbb, 0xf2db52f2, 0xf34a1bf3, - 0xa63d5fa6, 0x59a49359, 0xbcb90abc, 0x3af9ef3a, - 0xef1391ef, 0xfe0885fe, 0x01914901, 0x6116ee61, - 0x7cde2d7c, 0xb2214fb2, 0x42b18f42, 0xdb723bdb, - 0xb82f47b8, 0x48bf8748, 0x2cae6d2c, 0xe3c046e3, - 0x573cd657, 0x859a3e85, 0x29a96929, 0x7d4f647d, - 0x94812a94, 0x492ece49, 0x17c6cb17, 0xca692fca, - 0xc3bdfcc3, 0x5ca3975c, 0x5ee8055e, 0xd0ed7ad0, - 0x87d1ac87, 0x8e057f8e, 0xba64d5ba, 0xa8a51aa8, - 0xb7264bb7, 0xb9be0eb9, 0x6087a760, 0xf8d55af8, - 0x22362822, 0x111b1411, 0xde753fde, 0x79d92979, - 0xaaee88aa, 0x332d3c33, 0x5f794c5f, 0xb6b702b6, - 0x96cab896, 0x5835da58, 0x9cc4b09c, 0xfc4317fc, - 0x1a84551a, 0xf64d1ff6, 0x1c598a1c, 0x38b27d38, - 0xac3357ac, 0x18cfc718, 0xf4068df4, 0x69537469, - 0x749bb774, 0xf597c4f5, 0x56ad9f56, 0xdae372da, - 0xd5ea7ed5, 0x4af4154a, 0x9e8f229e, 0xa2ab12a2, - 0x4e62584e, 0xe85f07e8, 0xe51d99e5, 0x39233439, - 0xc1f66ec1, 0x446c5044, 0x5d32de5d, 0x72466872, - 0x26a06526, 0x93cdbc93, 0x03dadb03, 0xc6baf8c6, - 0xfa9ec8fa, 0x82d6a882, 0xcf6e2bcf, 0x50704050, - 0xeb85dceb, 0x750afe75, 0x8a93328a, 0x8ddfa48d, - 0x4c29ca4c, 0x141c1014, 0x73d72173, 0xccb4f0cc, - 0x09d4d309, 0x108a5d10, 0xe2510fe2, 0x00000000, - 0x9a196f9a, 0xe01a9de0, 0x8f94368f, 0xe6c742e6, - 0xecc94aec, 0xfdd25efd, 0xab7fc1ab, 0xd8a8e0d8}; - -NAMESPACE_END +// Twofish tables + +#include "pch.h" +#include "config.h" + +#include "twofish.h" + +#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic ignored "-Wmissing-braces" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +const byte Twofish::Base::q[2][256] = { + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0, + + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 +}; + +const word32 Twofish::Base::mds[4][256] = { + 0xbcbc3275, 0xecec21f3, 0x202043c6, 0xb3b3c9f4, + 0xdada03db, 0x02028b7b, 0xe2e22bfb, 0x9e9efac8, + 0xc9c9ec4a, 0xd4d409d3, 0x18186be6, 0x1e1e9f6b, + 0x98980e45, 0xb2b2387d, 0xa6a6d2e8, 0x2626b74b, + 0x3c3c57d6, 0x93938a32, 0x8282eed8, 0x525298fd, + 0x7b7bd437, 0xbbbb3771, 0x5b5b97f1, 0x474783e1, + 0x24243c30, 0x5151e20f, 0xbabac6f8, 0x4a4af31b, + 0xbfbf4887, 0x0d0d70fa, 0xb0b0b306, 0x7575de3f, + 0xd2d2fd5e, 0x7d7d20ba, 0x666631ae, 0x3a3aa35b, + 0x59591c8a, 0x00000000, 0xcdcd93bc, 0x1a1ae09d, + 0xaeae2c6d, 0x7f7fabc1, 0x2b2bc7b1, 0xbebeb90e, + 0xe0e0a080, 0x8a8a105d, 0x3b3b52d2, 0x6464bad5, + 0xd8d888a0, 0xe7e7a584, 0x5f5fe807, 0x1b1b1114, + 0x2c2cc2b5, 0xfcfcb490, 0x3131272c, 0x808065a3, + 0x73732ab2, 0x0c0c8173, 0x79795f4c, 0x6b6b4154, + 0x4b4b0292, 0x53536974, 0x94948f36, 0x83831f51, + 0x2a2a3638, 0xc4c49cb0, 0x2222c8bd, 0xd5d5f85a, + 0xbdbdc3fc, 0x48487860, 0xffffce62, 0x4c4c0796, + 0x4141776c, 0xc7c7e642, 0xebeb24f7, 0x1c1c1410, + 0x5d5d637c, 0x36362228, 0x6767c027, 0xe9e9af8c, + 0x4444f913, 0x1414ea95, 0xf5f5bb9c, 0xcfcf18c7, + 0x3f3f2d24, 0xc0c0e346, 0x7272db3b, 0x54546c70, + 0x29294cca, 0xf0f035e3, 0x0808fe85, 0xc6c617cb, + 0xf3f34f11, 0x8c8ce4d0, 0xa4a45993, 0xcaca96b8, + 0x68683ba6, 0xb8b84d83, 0x38382820, 0xe5e52eff, + 0xadad569f, 0x0b0b8477, 0xc8c81dc3, 0x9999ffcc, + 0x5858ed03, 0x19199a6f, 0x0e0e0a08, 0x95957ebf, + 0x70705040, 0xf7f730e7, 0x6e6ecf2b, 0x1f1f6ee2, + 0xb5b53d79, 0x09090f0c, 0x616134aa, 0x57571682, + 0x9f9f0b41, 0x9d9d803a, 0x111164ea, 0x2525cdb9, + 0xafafdde4, 0x4545089a, 0xdfdf8da4, 0xa3a35c97, + 0xeaead57e, 0x353558da, 0xededd07a, 0x4343fc17, + 0xf8f8cb66, 0xfbfbb194, 0x3737d3a1, 0xfafa401d, + 0xc2c2683d, 0xb4b4ccf0, 0x32325dde, 0x9c9c71b3, + 0x5656e70b, 0xe3e3da72, 0x878760a7, 0x15151b1c, + 0xf9f93aef, 0x6363bfd1, 0x3434a953, 0x9a9a853e, + 0xb1b1428f, 0x7c7cd133, 0x88889b26, 0x3d3da65f, + 0xa1a1d7ec, 0xe4e4df76, 0x8181942a, 0x91910149, + 0x0f0ffb81, 0xeeeeaa88, 0x161661ee, 0xd7d77321, + 0x9797f5c4, 0xa5a5a81a, 0xfefe3feb, 0x6d6db5d9, + 0x7878aec5, 0xc5c56d39, 0x1d1de599, 0x7676a4cd, + 0x3e3edcad, 0xcbcb6731, 0xb6b6478b, 0xefef5b01, + 0x12121e18, 0x6060c523, 0x6a6ab0dd, 0x4d4df61f, + 0xcecee94e, 0xdede7c2d, 0x55559df9, 0x7e7e5a48, + 0x2121b24f, 0x03037af2, 0xa0a02665, 0x5e5e198e, + 0x5a5a6678, 0x65654b5c, 0x62624e58, 0xfdfd4519, + 0x0606f48d, 0x404086e5, 0xf2f2be98, 0x3333ac57, + 0x17179067, 0x05058e7f, 0xe8e85e05, 0x4f4f7d64, + 0x89896aaf, 0x10109563, 0x74742fb6, 0x0a0a75fe, + 0x5c5c92f5, 0x9b9b74b7, 0x2d2d333c, 0x3030d6a5, + 0x2e2e49ce, 0x494989e9, 0x46467268, 0x77775544, + 0xa8a8d8e0, 0x9696044d, 0x2828bd43, 0xa9a92969, + 0xd9d97929, 0x8686912e, 0xd1d187ac, 0xf4f44a15, + 0x8d8d1559, 0xd6d682a8, 0xb9b9bc0a, 0x42420d9e, + 0xf6f6c16e, 0x2f2fb847, 0xdddd06df, 0x23233934, + 0xcccc6235, 0xf1f1c46a, 0xc1c112cf, 0x8585ebdc, + 0x8f8f9e22, 0x7171a1c9, 0x9090f0c0, 0xaaaa539b, + 0x0101f189, 0x8b8be1d4, 0x4e4e8ced, 0x8e8e6fab, + 0xababa212, 0x6f6f3ea2, 0xe6e6540d, 0xdbdbf252, + 0x92927bbb, 0xb7b7b602, 0x6969ca2f, 0x3939d9a9, + 0xd3d30cd7, 0xa7a72361, 0xa2a2ad1e, 0xc3c399b4, + 0x6c6c4450, 0x07070504, 0x04047ff6, 0x272746c2, + 0xacaca716, 0xd0d07625, 0x50501386, 0xdcdcf756, + 0x84841a55, 0xe1e15109, 0x7a7a25be, 0x1313ef91, + + 0xa9d93939, 0x67901717, 0xb3719c9c, 0xe8d2a6a6, + 0x04050707, 0xfd985252, 0xa3658080, 0x76dfe4e4, + 0x9a084545, 0x92024b4b, 0x80a0e0e0, 0x78665a5a, + 0xe4ddafaf, 0xddb06a6a, 0xd1bf6363, 0x38362a2a, + 0x0d54e6e6, 0xc6432020, 0x3562cccc, 0x98bef2f2, + 0x181e1212, 0xf724ebeb, 0xecd7a1a1, 0x6c774141, + 0x43bd2828, 0x7532bcbc, 0x37d47b7b, 0x269b8888, + 0xfa700d0d, 0x13f94444, 0x94b1fbfb, 0x485a7e7e, + 0xf27a0303, 0xd0e48c8c, 0x8b47b6b6, 0x303c2424, + 0x84a5e7e7, 0x54416b6b, 0xdf06dddd, 0x23c56060, + 0x1945fdfd, 0x5ba33a3a, 0x3d68c2c2, 0x59158d8d, + 0xf321ecec, 0xae316666, 0xa23e6f6f, 0x82165757, + 0x63951010, 0x015befef, 0x834db8b8, 0x2e918686, + 0xd9b56d6d, 0x511f8383, 0x9b53aaaa, 0x7c635d5d, + 0xa63b6868, 0xeb3ffefe, 0xa5d63030, 0xbe257a7a, + 0x16a7acac, 0x0c0f0909, 0xe335f0f0, 0x6123a7a7, + 0xc0f09090, 0x8cafe9e9, 0x3a809d9d, 0xf5925c5c, + 0x73810c0c, 0x2c273131, 0x2576d0d0, 0x0be75656, + 0xbb7b9292, 0x4ee9cece, 0x89f10101, 0x6b9f1e1e, + 0x53a93434, 0x6ac4f1f1, 0xb499c3c3, 0xf1975b5b, + 0xe1834747, 0xe66b1818, 0xbdc82222, 0x450e9898, + 0xe26e1f1f, 0xf4c9b3b3, 0xb62f7474, 0x66cbf8f8, + 0xccff9999, 0x95ea1414, 0x03ed5858, 0x56f7dcdc, + 0xd4e18b8b, 0x1c1b1515, 0x1eada2a2, 0xd70cd3d3, + 0xfb2be2e2, 0xc31dc8c8, 0x8e195e5e, 0xb5c22c2c, + 0xe9894949, 0xcf12c1c1, 0xbf7e9595, 0xba207d7d, + 0xea641111, 0x77840b0b, 0x396dc5c5, 0xaf6a8989, + 0x33d17c7c, 0xc9a17171, 0x62ceffff, 0x7137bbbb, + 0x81fb0f0f, 0x793db5b5, 0x0951e1e1, 0xaddc3e3e, + 0x242d3f3f, 0xcda47676, 0xf99d5555, 0xd8ee8282, + 0xe5864040, 0xc5ae7878, 0xb9cd2525, 0x4d049696, + 0x44557777, 0x080a0e0e, 0x86135050, 0xe730f7f7, + 0xa1d33737, 0x1d40fafa, 0xaa346161, 0xed8c4e4e, + 0x06b3b0b0, 0x706c5454, 0xb22a7373, 0xd2523b3b, + 0x410b9f9f, 0x7b8b0202, 0xa088d8d8, 0x114ff3f3, + 0x3167cbcb, 0xc2462727, 0x27c06767, 0x90b4fcfc, + 0x20283838, 0xf67f0404, 0x60784848, 0xff2ee5e5, + 0x96074c4c, 0x5c4b6565, 0xb1c72b2b, 0xab6f8e8e, + 0x9e0d4242, 0x9cbbf5f5, 0x52f2dbdb, 0x1bf34a4a, + 0x5fa63d3d, 0x9359a4a4, 0x0abcb9b9, 0xef3af9f9, + 0x91ef1313, 0x85fe0808, 0x49019191, 0xee611616, + 0x2d7cdede, 0x4fb22121, 0x8f42b1b1, 0x3bdb7272, + 0x47b82f2f, 0x8748bfbf, 0x6d2caeae, 0x46e3c0c0, + 0xd6573c3c, 0x3e859a9a, 0x6929a9a9, 0x647d4f4f, + 0x2a948181, 0xce492e2e, 0xcb17c6c6, 0x2fca6969, + 0xfcc3bdbd, 0x975ca3a3, 0x055ee8e8, 0x7ad0eded, + 0xac87d1d1, 0x7f8e0505, 0xd5ba6464, 0x1aa8a5a5, + 0x4bb72626, 0x0eb9bebe, 0xa7608787, 0x5af8d5d5, + 0x28223636, 0x14111b1b, 0x3fde7575, 0x2979d9d9, + 0x88aaeeee, 0x3c332d2d, 0x4c5f7979, 0x02b6b7b7, + 0xb896caca, 0xda583535, 0xb09cc4c4, 0x17fc4343, + 0x551a8484, 0x1ff64d4d, 0x8a1c5959, 0x7d38b2b2, + 0x57ac3333, 0xc718cfcf, 0x8df40606, 0x74695353, + 0xb7749b9b, 0xc4f59797, 0x9f56adad, 0x72dae3e3, + 0x7ed5eaea, 0x154af4f4, 0x229e8f8f, 0x12a2abab, + 0x584e6262, 0x07e85f5f, 0x99e51d1d, 0x34392323, + 0x6ec1f6f6, 0x50446c6c, 0xde5d3232, 0x68724646, + 0x6526a0a0, 0xbc93cdcd, 0xdb03dada, 0xf8c6baba, + 0xc8fa9e9e, 0xa882d6d6, 0x2bcf6e6e, 0x40507070, + 0xdceb8585, 0xfe750a0a, 0x328a9393, 0xa48ddfdf, + 0xca4c2929, 0x10141c1c, 0x2173d7d7, 0xf0ccb4b4, + 0xd309d4d4, 0x5d108a8a, 0x0fe25151, 0x00000000, + 0x6f9a1919, 0x9de01a1a, 0x368f9494, 0x42e6c7c7, + 0x4aecc9c9, 0x5efdd2d2, 0xc1ab7f7f, 0xe0d8a8a8, + + 0xbc75bc32, 0xecf3ec21, 0x20c62043, 0xb3f4b3c9, + 0xdadbda03, 0x027b028b, 0xe2fbe22b, 0x9ec89efa, + 0xc94ac9ec, 0xd4d3d409, 0x18e6186b, 0x1e6b1e9f, + 0x9845980e, 0xb27db238, 0xa6e8a6d2, 0x264b26b7, + 0x3cd63c57, 0x9332938a, 0x82d882ee, 0x52fd5298, + 0x7b377bd4, 0xbb71bb37, 0x5bf15b97, 0x47e14783, + 0x2430243c, 0x510f51e2, 0xbaf8bac6, 0x4a1b4af3, + 0xbf87bf48, 0x0dfa0d70, 0xb006b0b3, 0x753f75de, + 0xd25ed2fd, 0x7dba7d20, 0x66ae6631, 0x3a5b3aa3, + 0x598a591c, 0x00000000, 0xcdbccd93, 0x1a9d1ae0, + 0xae6dae2c, 0x7fc17fab, 0x2bb12bc7, 0xbe0ebeb9, + 0xe080e0a0, 0x8a5d8a10, 0x3bd23b52, 0x64d564ba, + 0xd8a0d888, 0xe784e7a5, 0x5f075fe8, 0x1b141b11, + 0x2cb52cc2, 0xfc90fcb4, 0x312c3127, 0x80a38065, + 0x73b2732a, 0x0c730c81, 0x794c795f, 0x6b546b41, + 0x4b924b02, 0x53745369, 0x9436948f, 0x8351831f, + 0x2a382a36, 0xc4b0c49c, 0x22bd22c8, 0xd55ad5f8, + 0xbdfcbdc3, 0x48604878, 0xff62ffce, 0x4c964c07, + 0x416c4177, 0xc742c7e6, 0xebf7eb24, 0x1c101c14, + 0x5d7c5d63, 0x36283622, 0x672767c0, 0xe98ce9af, + 0x441344f9, 0x149514ea, 0xf59cf5bb, 0xcfc7cf18, + 0x3f243f2d, 0xc046c0e3, 0x723b72db, 0x5470546c, + 0x29ca294c, 0xf0e3f035, 0x088508fe, 0xc6cbc617, + 0xf311f34f, 0x8cd08ce4, 0xa493a459, 0xcab8ca96, + 0x68a6683b, 0xb883b84d, 0x38203828, 0xe5ffe52e, + 0xad9fad56, 0x0b770b84, 0xc8c3c81d, 0x99cc99ff, + 0x580358ed, 0x196f199a, 0x0e080e0a, 0x95bf957e, + 0x70407050, 0xf7e7f730, 0x6e2b6ecf, 0x1fe21f6e, + 0xb579b53d, 0x090c090f, 0x61aa6134, 0x57825716, + 0x9f419f0b, 0x9d3a9d80, 0x11ea1164, 0x25b925cd, + 0xafe4afdd, 0x459a4508, 0xdfa4df8d, 0xa397a35c, + 0xea7eead5, 0x35da3558, 0xed7aedd0, 0x431743fc, + 0xf866f8cb, 0xfb94fbb1, 0x37a137d3, 0xfa1dfa40, + 0xc23dc268, 0xb4f0b4cc, 0x32de325d, 0x9cb39c71, + 0x560b56e7, 0xe372e3da, 0x87a78760, 0x151c151b, + 0xf9eff93a, 0x63d163bf, 0x345334a9, 0x9a3e9a85, + 0xb18fb142, 0x7c337cd1, 0x8826889b, 0x3d5f3da6, + 0xa1eca1d7, 0xe476e4df, 0x812a8194, 0x91499101, + 0x0f810ffb, 0xee88eeaa, 0x16ee1661, 0xd721d773, + 0x97c497f5, 0xa51aa5a8, 0xfeebfe3f, 0x6dd96db5, + 0x78c578ae, 0xc539c56d, 0x1d991de5, 0x76cd76a4, + 0x3ead3edc, 0xcb31cb67, 0xb68bb647, 0xef01ef5b, + 0x1218121e, 0x602360c5, 0x6add6ab0, 0x4d1f4df6, + 0xce4ecee9, 0xde2dde7c, 0x55f9559d, 0x7e487e5a, + 0x214f21b2, 0x03f2037a, 0xa065a026, 0x5e8e5e19, + 0x5a785a66, 0x655c654b, 0x6258624e, 0xfd19fd45, + 0x068d06f4, 0x40e54086, 0xf298f2be, 0x335733ac, + 0x17671790, 0x057f058e, 0xe805e85e, 0x4f644f7d, + 0x89af896a, 0x10631095, 0x74b6742f, 0x0afe0a75, + 0x5cf55c92, 0x9bb79b74, 0x2d3c2d33, 0x30a530d6, + 0x2ece2e49, 0x49e94989, 0x46684672, 0x77447755, + 0xa8e0a8d8, 0x964d9604, 0x284328bd, 0xa969a929, + 0xd929d979, 0x862e8691, 0xd1acd187, 0xf415f44a, + 0x8d598d15, 0xd6a8d682, 0xb90ab9bc, 0x429e420d, + 0xf66ef6c1, 0x2f472fb8, 0xdddfdd06, 0x23342339, + 0xcc35cc62, 0xf16af1c4, 0xc1cfc112, 0x85dc85eb, + 0x8f228f9e, 0x71c971a1, 0x90c090f0, 0xaa9baa53, + 0x018901f1, 0x8bd48be1, 0x4eed4e8c, 0x8eab8e6f, + 0xab12aba2, 0x6fa26f3e, 0xe60de654, 0xdb52dbf2, + 0x92bb927b, 0xb702b7b6, 0x692f69ca, 0x39a939d9, + 0xd3d7d30c, 0xa761a723, 0xa21ea2ad, 0xc3b4c399, + 0x6c506c44, 0x07040705, 0x04f6047f, 0x27c22746, + 0xac16aca7, 0xd025d076, 0x50865013, 0xdc56dcf7, + 0x8455841a, 0xe109e151, 0x7abe7a25, 0x139113ef, + + 0xd939a9d9, 0x90176790, 0x719cb371, 0xd2a6e8d2, + 0x05070405, 0x9852fd98, 0x6580a365, 0xdfe476df, + 0x08459a08, 0x024b9202, 0xa0e080a0, 0x665a7866, + 0xddafe4dd, 0xb06addb0, 0xbf63d1bf, 0x362a3836, + 0x54e60d54, 0x4320c643, 0x62cc3562, 0xbef298be, + 0x1e12181e, 0x24ebf724, 0xd7a1ecd7, 0x77416c77, + 0xbd2843bd, 0x32bc7532, 0xd47b37d4, 0x9b88269b, + 0x700dfa70, 0xf94413f9, 0xb1fb94b1, 0x5a7e485a, + 0x7a03f27a, 0xe48cd0e4, 0x47b68b47, 0x3c24303c, + 0xa5e784a5, 0x416b5441, 0x06dddf06, 0xc56023c5, + 0x45fd1945, 0xa33a5ba3, 0x68c23d68, 0x158d5915, + 0x21ecf321, 0x3166ae31, 0x3e6fa23e, 0x16578216, + 0x95106395, 0x5bef015b, 0x4db8834d, 0x91862e91, + 0xb56dd9b5, 0x1f83511f, 0x53aa9b53, 0x635d7c63, + 0x3b68a63b, 0x3ffeeb3f, 0xd630a5d6, 0x257abe25, + 0xa7ac16a7, 0x0f090c0f, 0x35f0e335, 0x23a76123, + 0xf090c0f0, 0xafe98caf, 0x809d3a80, 0x925cf592, + 0x810c7381, 0x27312c27, 0x76d02576, 0xe7560be7, + 0x7b92bb7b, 0xe9ce4ee9, 0xf10189f1, 0x9f1e6b9f, + 0xa93453a9, 0xc4f16ac4, 0x99c3b499, 0x975bf197, + 0x8347e183, 0x6b18e66b, 0xc822bdc8, 0x0e98450e, + 0x6e1fe26e, 0xc9b3f4c9, 0x2f74b62f, 0xcbf866cb, + 0xff99ccff, 0xea1495ea, 0xed5803ed, 0xf7dc56f7, + 0xe18bd4e1, 0x1b151c1b, 0xada21ead, 0x0cd3d70c, + 0x2be2fb2b, 0x1dc8c31d, 0x195e8e19, 0xc22cb5c2, + 0x8949e989, 0x12c1cf12, 0x7e95bf7e, 0x207dba20, + 0x6411ea64, 0x840b7784, 0x6dc5396d, 0x6a89af6a, + 0xd17c33d1, 0xa171c9a1, 0xceff62ce, 0x37bb7137, + 0xfb0f81fb, 0x3db5793d, 0x51e10951, 0xdc3eaddc, + 0x2d3f242d, 0xa476cda4, 0x9d55f99d, 0xee82d8ee, + 0x8640e586, 0xae78c5ae, 0xcd25b9cd, 0x04964d04, + 0x55774455, 0x0a0e080a, 0x13508613, 0x30f7e730, + 0xd337a1d3, 0x40fa1d40, 0x3461aa34, 0x8c4eed8c, + 0xb3b006b3, 0x6c54706c, 0x2a73b22a, 0x523bd252, + 0x0b9f410b, 0x8b027b8b, 0x88d8a088, 0x4ff3114f, + 0x67cb3167, 0x4627c246, 0xc06727c0, 0xb4fc90b4, + 0x28382028, 0x7f04f67f, 0x78486078, 0x2ee5ff2e, + 0x074c9607, 0x4b655c4b, 0xc72bb1c7, 0x6f8eab6f, + 0x0d429e0d, 0xbbf59cbb, 0xf2db52f2, 0xf34a1bf3, + 0xa63d5fa6, 0x59a49359, 0xbcb90abc, 0x3af9ef3a, + 0xef1391ef, 0xfe0885fe, 0x01914901, 0x6116ee61, + 0x7cde2d7c, 0xb2214fb2, 0x42b18f42, 0xdb723bdb, + 0xb82f47b8, 0x48bf8748, 0x2cae6d2c, 0xe3c046e3, + 0x573cd657, 0x859a3e85, 0x29a96929, 0x7d4f647d, + 0x94812a94, 0x492ece49, 0x17c6cb17, 0xca692fca, + 0xc3bdfcc3, 0x5ca3975c, 0x5ee8055e, 0xd0ed7ad0, + 0x87d1ac87, 0x8e057f8e, 0xba64d5ba, 0xa8a51aa8, + 0xb7264bb7, 0xb9be0eb9, 0x6087a760, 0xf8d55af8, + 0x22362822, 0x111b1411, 0xde753fde, 0x79d92979, + 0xaaee88aa, 0x332d3c33, 0x5f794c5f, 0xb6b702b6, + 0x96cab896, 0x5835da58, 0x9cc4b09c, 0xfc4317fc, + 0x1a84551a, 0xf64d1ff6, 0x1c598a1c, 0x38b27d38, + 0xac3357ac, 0x18cfc718, 0xf4068df4, 0x69537469, + 0x749bb774, 0xf597c4f5, 0x56ad9f56, 0xdae372da, + 0xd5ea7ed5, 0x4af4154a, 0x9e8f229e, 0xa2ab12a2, + 0x4e62584e, 0xe85f07e8, 0xe51d99e5, 0x39233439, + 0xc1f66ec1, 0x446c5044, 0x5d32de5d, 0x72466872, + 0x26a06526, 0x93cdbc93, 0x03dadb03, 0xc6baf8c6, + 0xfa9ec8fa, 0x82d6a882, 0xcf6e2bcf, 0x50704050, + 0xeb85dceb, 0x750afe75, 0x8a93328a, 0x8ddfa48d, + 0x4c29ca4c, 0x141c1014, 0x73d72173, 0xccb4f0cc, + 0x09d4d309, 0x108a5d10, 0xe2510fe2, 0x00000000, + 0x9a196f9a, 0xe01a9de0, 0x8f94368f, 0xe6c742e6, + 0xecc94aec, 0xfdd25efd, 0xab7fc1ab, 0xd8a8e0d8}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/threefish.cpp b/external/ours/library/crypto/src/shared/original/threefish.cpp new file mode 100755 index 000000000..bf038ab89 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/threefish.cpp @@ -0,0 +1,503 @@ +// threefish.cpp - written and placed in the public domain by Jeffrey Walton +// Based on public domain code by Keru Kuro. Kuro's code is +// available at http://cppcrypto.sourceforge.net/. + +#include "pch.h" +#include "config.h" + +#include "threefish.h" +#include "misc.h" +#include "algparam.h" +#include "argnames.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::word64; +using CryptoPP::rotlConstant; +using CryptoPP::rotrConstant; +using CryptoPP::rotlVariable; +using CryptoPP::rotrVariable; + +template +inline void G256(word64& G0, word64& G1, word64& G2, word64& G3) +{ + G0 += G1; + G1 = rotlConstant(G1) ^ G0; + G2 += G3; + G3 = rotlConstant(G3) ^ G2; +} + +template +inline void IG256(word64& G0, word64& G1, word64& G2, word64& G3) +{ + G3 = rotrConstant(G3 ^ G2); + G2 -= G3; + G1 = rotrConstant(G1 ^ G0); + G0 -= G1; +} + +#define KS256(r) \ + G0 += m_rkey[(r + 1) % 5]; \ + G1 += m_rkey[(r + 2) % 5] + m_tweak[(r + 1) % 3]; \ + G2 += m_rkey[(r + 3) % 5] + m_tweak[(r + 2) % 3]; \ + G3 += m_rkey[(r + 4) % 5] + r + 1; + +#define IKS256(r) \ + G0 -= m_rkey[(r + 1) % 5]; \ + G1 -= (m_rkey[(r + 2) % 5] + m_tweak[(r + 1) % 3]); \ + G2 -= (m_rkey[(r + 3) % 5] + m_tweak[(r + 2) % 3]); \ + G3 -= (m_rkey[(r + 4) % 5] + r + 1); + +#define G256x8(r) \ + G256<14, 16>(G0, G1, G2, G3); \ + G256<52, 57>(G0, G3, G2, G1); \ + G256<23, 40>(G0, G1, G2, G3); \ + G256< 5, 37>(G0, G3, G2, G1); \ + KS256(r); \ + G256<25, 33>(G0, G1, G2, G3); \ + G256<46, 12>(G0, G3, G2, G1); \ + G256<58, 22>(G0, G1, G2, G3); \ + G256<32, 32>(G0, G3, G2, G1); \ + KS256(r + 1); + +#define IG256x8(r) \ + IG256<32, 32>(G0, G3, G2, G1); \ + IG256<58, 22>(G0, G1, G2, G3); \ + IG256<46, 12>(G0, G3, G2, G1); \ + IG256<25, 33>(G0, G1, G2, G3); \ + IKS256(r); \ + IG256< 5, 37>(G0, G3, G2, G1); \ + IG256<23, 40>(G0, G1, G2, G3); \ + IG256<52, 57>(G0, G3, G2, G1); \ + IG256<14, 16>(G0, G1, G2, G3); \ + IKS256(r - 1); + +/////////////////// + +template +inline void G512(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5, word64& G6, word64& G7) +{ + G0 += G1; + G1 = rotlConstant(G1) ^ G0; + G2 += G3; + G3 = rotlConstant(G3) ^ G2; + G4 += G5; + G5 = rotlConstant(G5) ^ G4; + G6 += G7; + G7 = rotlConstant(G7) ^ G6; +} + +template +inline void IG512(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5, word64& G6, word64& G7) +{ + G7 = rotrConstant(G7 ^ G6); + G6 -= G7; + G5 = rotrConstant(G5 ^ G4); + G4 -= G5; + G3 = rotrConstant(G3 ^ G2); + G2 -= G3; + G1 = rotrConstant(G1 ^ G0); + G0 -= G1; +} + +#define KS512(r) \ + G0 += m_rkey[(r + 1) % 9]; \ + G1 += m_rkey[(r + 2) % 9]; \ + G2 += m_rkey[(r + 3) % 9]; \ + G3 += m_rkey[(r + 4) % 9]; \ + G4 += m_rkey[(r + 5) % 9]; \ + G5 += m_rkey[(r + 6) % 9] + m_tweak[(r + 1) % 3]; \ + G6 += m_rkey[(r + 7) % 9] + m_tweak[(r + 2) % 3]; \ + G7 += m_rkey[(r + 8) % 9] + r + 1; + +#define IKS512(r) \ + G0 -= m_rkey[(r + 1) % 9]; \ + G1 -= m_rkey[(r + 2) % 9]; \ + G2 -= m_rkey[(r + 3) % 9]; \ + G3 -= m_rkey[(r + 4) % 9]; \ + G4 -= m_rkey[(r + 5) % 9]; \ + G5 -= (m_rkey[(r + 6) % 9] + m_tweak[(r + 1) % 3]); \ + G6 -= (m_rkey[(r + 7) % 9] + m_tweak[(r + 2) % 3]); \ + G7 -= (m_rkey[(r + 8) % 9] + r + 1); + +#define IG512x8(r) \ + IG512< 8, 35, 56, 22>(G6, G1, G0, G7, G2, G5, G4, G3); \ + IG512<25, 29, 39, 43>(G4, G1, G6, G3, G0, G5, G2, G7); \ + IG512<13, 50, 10, 17>(G2, G1, G4, G7, G6, G5, G0, G3); \ + IG512<39, 30, 34, 24>(G0, G1, G2, G3, G4, G5, G6, G7); \ + IKS512(r) \ + IG512<44, 9, 54, 56>(G6, G1, G0, G7, G2, G5, G4, G3); \ + IG512<17, 49, 36, 39>(G4, G1, G6, G3, G0, G5, G2, G7); \ + IG512<33, 27, 14, 42>(G2, G1, G4, G7, G6, G5, G0, G3); \ + IG512<46, 36, 19, 37>(G0, G1, G2, G3, G4, G5, G6, G7); \ + IKS512(r - 1) + +#define G512x8(r) \ + G512<46, 36, 19, 37>(G0, G1, G2, G3, G4, G5, G6, G7); \ + G512<33, 27, 14, 42>(G2, G1, G4, G7, G6, G5, G0, G3); \ + G512<17, 49, 36, 39>(G4, G1, G6, G3, G0, G5, G2, G7); \ + G512<44, 9, 54, 56>(G6, G1, G0, G7, G2, G5, G4, G3); \ + KS512(r) \ + G512<39, 30, 34, 24>(G0, G1, G2, G3, G4, G5, G6, G7); \ + G512<13, 50, 10, 17>(G2, G1, G4, G7, G6, G5, G0, G3); \ + G512<25, 29, 39, 43>(G4, G1, G6, G3, G0, G5, G2, G7); \ + G512< 8, 35, 56, 22>(G6, G1, G0, G7, G2, G5, G4, G3); \ + KS512(r + 1) + +/////////////////// + +template +inline void G1024A(word64& G0, word64& G1, word64& G2, word64& G3, + word64& G4, word64& G5, word64& G6, word64& G7) +{ + G0 += G1; + G1 = rotlConstant(G1) ^ G0; + G2 += G3; + G3 = rotlConstant(G3) ^ G2; + G4 += G5; + G5 = rotlConstant(G5) ^ G4; + G6 += G7; + G7 = rotlConstant(G7) ^ G6; +} + +template +inline void G1024B(word64& G8, word64& G9, word64& G10, word64& G11, + word64& G12, word64& G13, word64& G14, word64& G15) +{ + G8 += G9; + G9 = rotlConstant(G9) ^ G8; + G10 += G11; + G11 = rotlConstant(G11) ^ G10; + G12 += G13; + G13 = rotlConstant(G13) ^ G12; + G14 += G15; + G15 = rotlConstant(G15) ^ G14; +} + +template +inline void G1024(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5, + word64& G6, word64& G7, word64& G8, word64& G9, word64& G10, word64& G11, word64& G12, + word64& G13, word64& G14, word64& G15) +{ + // The extra gyrations promote inlining. Without it Threefish1024 looses 10 cpb. + G1024A(G0, G1, G2, G3, G4, G5, G6, G7); + G1024B(G8, G9, G10, G11, G12, G13, G14, G15); +} + +template +inline void IG1024A(word64& G8, word64& G9, word64& G10, word64& G11, + word64& G12, word64& G13, word64& G14, word64& G15) +{ + G15 = rotrConstant(G15 ^ G14); + G14 -= G15; + G13 = rotrConstant(G13 ^ G12); + G12 -= G13; + G11 = rotrConstant(G11 ^ G10); + G10 -= G11; + G9 = rotrConstant(G9 ^ G8); + G8 -= G9; +} + +template +inline void IG1024B(word64& G0, word64& G1, word64& G2, word64& G3, + word64& G4, word64& G5, word64& G6, word64& G7) +{ + G7 = rotrConstant(G7 ^ G6); + G6 -= G7; + G5 = rotrConstant(G5 ^ G4); + G4 -= G5; + G3 = rotrConstant(G3 ^ G2); + G2 -= G3; + G1 = rotrConstant(G1 ^ G0); + G0 -= G1; +} + +template +inline void IG1024(word64& G0, word64& G1, word64& G2, word64& G3, word64& G4, word64& G5, + word64& G6, word64& G7, word64& G8, word64& G9, word64& G10, word64& G11, word64& G12, + word64& G13, word64& G14, word64& G15) +{ + // The extra gyrations promote inlining. Without it Threefish1024 looses 10 cpb. + IG1024A(G8, G9, G10, G11, G12, G13, G14, G15); + IG1024B(G0, G1, G2, G3, G4, G5, G6, G7); +} + +#define KS1024(r) \ + G0 += m_rkey[(r + 1) % 17]; \ + G1 += m_rkey[(r + 2) % 17]; \ + G2 += m_rkey[(r + 3) % 17]; \ + G3 += m_rkey[(r + 4) % 17]; \ + G4 += m_rkey[(r + 5) % 17]; \ + G5 += m_rkey[(r + 6) % 17]; \ + G6 += m_rkey[(r + 7) % 17]; \ + G7 += m_rkey[(r + 8) % 17]; \ + G8 += m_rkey[(r + 9) % 17]; \ + G9 += m_rkey[(r + 10) % 17]; \ + G10 += m_rkey[(r + 11) % 17]; \ + G11 += m_rkey[(r + 12) % 17]; \ + G12 += m_rkey[(r + 13) % 17]; \ + G13 += m_rkey[(r + 14) % 17] + m_tweak[(r + 1) % 3]; \ + G14 += m_rkey[(r + 15) % 17] + m_tweak[(r + 2) % 3]; \ + G15 += m_rkey[(r + 16) % 17] + r + 1; + +#define IKS1024(r) \ + G0 -= m_rkey[(r + 1) % 17]; \ + G1 -= m_rkey[(r + 2) % 17]; \ + G2 -= m_rkey[(r + 3) % 17]; \ + G3 -= m_rkey[(r + 4) % 17]; \ + G4 -= m_rkey[(r + 5) % 17]; \ + G5 -= m_rkey[(r + 6) % 17]; \ + G6 -= m_rkey[(r + 7) % 17]; \ + G7 -= m_rkey[(r + 8) % 17]; \ + G8 -= m_rkey[(r + 9) % 17]; \ + G9 -= m_rkey[(r + 10) % 17]; \ + G10 -= m_rkey[(r + 11) % 17]; \ + G11 -= m_rkey[(r + 12) % 17]; \ + G12 -= m_rkey[(r + 13) % 17]; \ + G13 -= (m_rkey[(r + 14) % 17] + m_tweak[(r + 1) % 3]); \ + G14 -= (m_rkey[(r + 15) % 17] + m_tweak[(r + 2) % 3]); \ + G15 -= (m_rkey[(r + 16) % 17] + r + 1); + +#define G1024x8(r) \ + G1024A<24, 13, 8, 47>(G0, G1, G2, G3, G4, G5, G6, G7); \ + G1024B< 8, 17, 22, 37>(G8, G9, G10, G11, G12, G13, G14, G15); \ + G1024A<38, 19, 10, 55>(G0, G9, G2, G13, G6, G11, G4, G15); \ + G1024B<49, 18, 23, 52>(G10, G7, G12, G3, G14, G5, G8, G1); \ + G1024A<33, 4, 51, 13>(G0, G7, G2, G5, G4, G3, G6, G1); \ + G1024B<34, 41, 59, 17>(G12, G15, G14, G13, G8, G11, G10, G9); \ + G1024A< 5, 20, 48, 41>(G0, G15, G2, G11, G6, G13, G4, G9); \ + G1024B<47, 28, 16, 25>(G14, G1, G8, G5, G10, G3, G12, G7); \ + KS1024(r); \ + G1024A<41, 9, 37, 31>(G0, G1, G2, G3, G4, G5, G6, G7); \ + G1024B<12, 47, 44, 30>(G8, G9, G10, G11, G12, G13, G14, G15); \ + G1024A<16, 34, 56, 51>(G0, G9, G2, G13, G6, G11, G4, G15); \ + G1024B< 4, 53, 42, 41>(G10, G7, G12, G3, G14, G5, G8, G1); \ + G1024A<31, 44, 47, 46>(G0, G7, G2, G5, G4, G3, G6, G1); \ + G1024B<19, 42, 44, 25>(G12, G15, G14, G13, G8, G11, G10, G9); \ + G1024A< 9, 48, 35, 52>(G0, G15, G2, G11, G6, G13, G4, G9); \ + G1024B<23, 31, 37, 20>(G14, G1, G8, G5, G10, G3, G12, G7); \ + KS1024(r + 1); + +#define IG1024x8(r) \ + IG1024A< 9, 48, 35, 52>(G0, G15, G2, G11, G6, G13, G4, G9); \ + IG1024B<23, 31, 37, 20>(G14, G1, G8, G5, G10, G3, G12, G7); \ + IG1024A<31, 44, 47, 46>(G0, G7, G2, G5, G4, G3, G6, G1); \ + IG1024B<19, 42, 44, 25>(G12, G15, G14, G13, G8, G11, G10, G9); \ + IG1024A<16, 34, 56, 51>(G0, G9, G2, G13, G6, G11, G4, G15); \ + IG1024B< 4, 53, 42, 41>(G10, G7, G12, G3, G14, G5, G8, G1); \ + IG1024A<41, 9, 37, 31>(G0, G1, G2, G3, G4, G5, G6, G7); \ + IG1024B<12, 47, 44, 30>(G8, G9, G10, G11, G12, G13, G14, G15); \ + IKS1024(r); \ + IG1024A< 5, 20, 48, 41>(G0, G15, G2, G11, G6, G13, G4, G9); \ + IG1024B<47, 28, 16, 25>(G14, G1, G8, G5, G10, G3, G12, G7); \ + IG1024A<33, 4, 51, 13>(G0, G7, G2, G5, G4, G3, G6, G1); \ + IG1024B<34, 41, 59, 17>(G12, G15, G14, G13, G8, G11, G10, G9); \ + IG1024A<38, 19, 10, 55>(G0, G9, G2, G13, G6, G11, G4, G15); \ + IG1024B<49, 18, 23, 52>(G10, G7, G12, G3, G14, G5, G8, G1); \ + IG1024A<24, 13, 8, 47>(G0, G1, G2, G3, G4, G5, G6, G7); \ + IG1024B< 8, 17, 22, 37>(G8, G9, G10, G11, G12, G13, G14, G15); \ + IKS1024(r - 1); + +ANONYMOUS_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +NAMESPACE_BEGIN(CryptoPP) + +void Threefish256::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + // Blocksize is Keylength for Threefish + CRYPTOPP_ASSERT(keyLength == KEYLENGTH); + + m_rkey.New(5); + m_wspace.New(4); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 4, userKey, keyLength); + m_rkey[4] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3]; + + SetTweak(params); +} + +void Threefish256::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3); + + G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; + G3 += m_rkey[3]; G1 += m_tweak[0]; G2 += m_tweak[1]; + + G256x8(0); G256x8(2); G256x8(4); G256x8(6); G256x8(8); + G256x8(10); G256x8(12); G256x8(14); G256x8(16); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3); +} + +void Threefish256::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3); + + G0 -= m_rkey[3]; G1 -= m_rkey[4]; G2 -= m_rkey[0]; G3 -= m_rkey[1]; + G1 -= m_tweak[0]; G2 -= m_tweak[1]; G3 -= 18; + + IG256x8(16); IG256x8(14); IG256x8(12); IG256x8(10); + IG256x8(8); IG256x8(6); IG256x8(4); IG256x8(2); IG256x8(0); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3); +} + +///////////////////////////////////////////////////////////////// + +void Threefish512::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + // Blocksize is Keylength for Threefish + CRYPTOPP_ASSERT(keyLength == KEYLENGTH); + + m_rkey.New(9); + m_wspace.New(8); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 8, userKey, keyLength); + m_rkey[8] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ + m_rkey[4] ^ m_rkey[5] ^ m_rkey[6] ^ m_rkey[7]; + + SetTweak(params); +} + +void Threefish512::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); + + // 34 integer instructions total + G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; G3 += m_rkey[3]; + G4 += m_rkey[4]; G5 += m_rkey[5]; G6 += m_rkey[6]; G7 += m_rkey[7]; + G5 += m_tweak[0]; G6 += m_tweak[1]; + + G512x8(0); G512x8(2); G512x8(4); G512x8(6); G512x8(8); + G512x8(10); G512x8(12); G512x8(14); G512x8(16); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); +} + +void Threefish512::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); + + G0 -= m_rkey[0]; G1 -= m_rkey[1]; G2 -= m_rkey[2]; G3 -= m_rkey[3]; + G4 -= m_rkey[4]; G5 -= m_rkey[5]; G6 -= m_rkey[6]; G7 -= m_rkey[7]; + G5 -= m_tweak[0]; G6 -= m_tweak[1]; G7 -= 18; + + IG512x8(16); IG512x8(14); IG512x8(12); IG512x8(10); + IG512x8(8); IG512x8(6); IG512x8(4); IG512x8(2); IG512x8(0); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); +} + +///////////////////////////////////////////////////////////////// + +void Threefish1024::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + // Blocksize is Keylength for Threefish + CRYPTOPP_ASSERT(keyLength == KEYLENGTH); + + m_rkey.New(17); + m_wspace.New(16); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 16, userKey, keyLength); + m_rkey[16] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ m_rkey[4] ^ + m_rkey[5] ^ m_rkey[6] ^ m_rkey[7] ^ m_rkey[8] ^ m_rkey[9] ^ m_rkey[10] ^ m_rkey[11] ^ m_rkey[12] ^ + m_rkey[13] ^ m_rkey[14] ^ m_rkey[15]; + + SetTweak(params); +} + +void Threefish1024::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; + word64 &G8=m_wspace[8], &G9=m_wspace[9], &G10=m_wspace[10], &G11=m_wspace[11]; + word64 &G12=m_wspace[12], &G13=m_wspace[13], &G14=m_wspace[14], &G15=m_wspace[15]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); + + G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; G3 += m_rkey[3]; + G4 += m_rkey[4]; G5 += m_rkey[5]; G6 += m_rkey[6]; G7 += m_rkey[7]; + G8 += m_rkey[8]; G9 += m_rkey[9]; G10 += m_rkey[10]; G11 += m_rkey[11]; + G12 += m_rkey[12]; G13 += m_rkey[13]; G14 += m_rkey[14]; G15 += m_rkey[15]; + G13 += m_tweak[0]; G14 += m_tweak[1]; + + G1024x8(0); G1024x8(2); G1024x8(4); G1024x8(6); G1024x8(8); + G1024x8(10); G1024x8(12); G1024x8(14); G1024x8(16); G1024x8(18); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); +} + +void Threefish1024::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; + word64 &G8=m_wspace[8], &G9=m_wspace[9], &G10=m_wspace[10], &G11=m_wspace[11]; + word64 &G12=m_wspace[12], &G13=m_wspace[13], &G14=m_wspace[14], &G15=m_wspace[15]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); + + G0 -= m_rkey[3]; G1 -= m_rkey[4]; G2 -= m_rkey[5]; G3 -= m_rkey[6]; + G4 -= m_rkey[7]; G5 -= m_rkey[8]; G6 -= m_rkey[9]; G7 -= m_rkey[10]; + G8 -= m_rkey[11]; G9 -= m_rkey[12]; G10 -= m_rkey[13]; G11 -= m_rkey[14]; + G12 -= m_rkey[15]; G13 -= m_rkey[16]; G14 -= m_rkey[0]; G15 -= m_rkey[1]; + G13 -= m_tweak[2]; G14 -= m_tweak[0]; G15 -= 20; + + IG1024x8(18); IG1024x8(16); IG1024x8(14); IG1024x8(12); IG1024x8(10); + IG1024x8(8); IG1024x8(6); IG1024x8(4); IG1024x8(2); IG1024x8(0); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/threefish.h b/external/ours/library/crypto/src/shared/original/threefish.h new file mode 100755 index 000000000..cb53d78a9 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/threefish.h @@ -0,0 +1,201 @@ +// threefish.h - written and placed in the public domain by Jeffrey Walton +// Based on public domain code by Keru Kuro. Kuro's code is +// available at http://cppcrypto.sourceforge.net/. + +/// \file Threefish.h +/// \brief Classes for the Threefish block cipher +/// \since Crypto++ 6.0 + +#ifndef CRYPTOPP_THREEFISH_H +#define CRYPTOPP_THREEFISH_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" +#include "argnames.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Threefish block cipher information +/// \tparam BS block size of the cipher, in bytes +/// \since Crypto++ 6.0 +template +struct Threefish_Info : public FixedBlockSize, FixedKeyLength +{ + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize(Keylength) + return "Threefish-" + IntToString(BS*8) + "(" + IntToString(BS*8) + ")"; + } +}; + +/// \brief Threefish block cipher base class +/// \tparam BS block size of the cipher, in bytes +/// \details User code should use Threefish256, Threefish512, Threefish1024 +/// \sa Threefish256, Threefish512, Threefish1024, Threefish +/// \since Crypto++ 6.0 +template +struct CRYPTOPP_NO_VTABLE Threefish_Base +{ + virtual ~Threefish_Base() {} + + void SetTweak(const NameValuePairs ¶ms) + { + m_tweak.New(3); + ConstByteArrayParameter t; + if (params.GetValue(Name::Tweak(), t)) + { + // Tweak size is fixed at 16 for Threefish + CRYPTOPP_ASSERT(t.size() == 16); + GetUserKey(LITTLE_ENDIAN_ORDER, m_tweak.begin(), 2, t.begin(), 16); + m_tweak[2] = m_tweak[0] ^ m_tweak[1]; + } + else + { + std::memset(m_tweak.begin(), 0x00, 24); + } + } + + typedef SecBlock > AlignedSecBlock64; + mutable AlignedSecBlock64 m_wspace; // workspace + AlignedSecBlock64 m_rkey; // keys + AlignedSecBlock64 m_tweak; +}; + +/// \brief Threefish 256-bit block cipher +/// \details Threefish256 provides 256-bit block size. The valid key size is 256-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa Threefish512, Threefish1024, Threefish +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Threefish256 : public Threefish_Info<32>, public BlockCipherDocumentation +{ +public: + /// \brief Threefish block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : public Threefish_Base<32>, public BlockCipherImpl > + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Threefish256::Encryption Threefish256Encryption; +typedef Threefish256::Decryption Threefish256Decryption; + +/// \brief Threefish 512-bit block cipher +/// \details Threefish512 provides 512-bit block size. The valid key size is 512-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa Threefish256, Threefish1024, Threefish +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Threefish512 : public Threefish_Info<64>, public BlockCipherDocumentation +{ +public: + /// \brief Threefish block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : public Threefish_Base<64>, public BlockCipherImpl > + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Decryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Threefish512::Encryption Threefish512Encryption; +typedef Threefish512::Decryption Threefish512Decryption; + +/// \brief Threefish 1024-bit block cipher +/// \details Threefish1024 provides 1024-bit block size. The valid key size is 1024-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa Threefish256, Threefish512, Threefish +/// \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Threefish1024 : public Threefish_Info<128>, public BlockCipherDocumentation +{ +public: + /// \brief Threefish block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : public Threefish_Base<128>, public BlockCipherImpl > + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + /// \brief Encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + /// \brief Encryption transformation + /// \details Dec provides implementation for decryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Threefish1024::Encryption Threefish1024Encryption; +typedef Threefish1024::Decryption Threefish1024Decryption; + +NAMESPACE_END + +#endif // CRYPTOPP_THREEFISH_H diff --git a/external/ours/library/crypto/src/shared/original/tiger.cpp b/external/ours/library/crypto/src/shared/original/tiger.cpp new file mode 100755 index 000000000..c71cdc2f5 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/tiger.cpp @@ -0,0 +1,282 @@ +// tiger.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "config.h" + +#include "tiger.h" +#include "misc.h" +#include "cpu.h" + +#if defined(CRYPTOPP_DISABLE_TIGER_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +NAMESPACE_BEGIN(CryptoPP) + +std::string Tiger::AlgorithmProvider() const +{ +#ifndef CRYPTOPP_DISABLE_TIGER_ASM +# if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return "SSE2"; +# endif +#endif + return "C++"; +} + +void Tiger::InitState(HashWordType *state) +{ + state[0] = W64LIT(0x0123456789ABCDEF); + state[1] = W64LIT(0xFEDCBA9876543210); + state[2] = W64LIT(0xF096A5B4C3B2E187); +} + +void Tiger::TruncatedFinal(byte *digest, size_t digestSize) +{ + CRYPTOPP_ASSERT(digest != NULLPTR); + ThrowIfInvalidTruncatedSize(digestSize); + + PadLastBlock(56, 0x01); + CorrectEndianess(m_data, m_data, 56); + + m_data[7] = GetBitCountLo(); + + Transform(m_state, m_data); + CorrectEndianess(m_state, m_state, DigestSize()); + memcpy(digest, m_state, digestSize); + + Restart(); // reinit for next use +} + +void Tiger::Transform (word64 *state, const word64 *data) +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 + if (HasSSE2()) + { +#ifdef __GNUC__ + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS_PUSH_IF86(bx) +#else + AS2( lea edx, [table]) + AS2( mov eax, state) + AS2( mov esi, data) +#endif + AS2( movq mm0, [eax]) + AS2( movq mm1, [eax+1*8]) + AS2( movq mm5, mm1) + AS2( movq mm2, [eax+2*8]) + AS2( movq mm7, [edx+4*2048+0*8]) + AS2( movq mm6, [edx+4*2048+1*8]) + AS2( mov ecx, esp) + AS2( and esp, 0xfffffff0) + AS2( sub esp, 8*8) + AS_PUSH_IF86(cx) + +#define SSE2_round(a,b,c,x,mul) \ + AS2( pxor c, [x])\ + AS2( movd ecx, c)\ + AS2( movzx edi, cl)\ + AS2( movq mm3, [edx+0*2048+edi*8])\ + AS2( movzx edi, ch)\ + AS2( movq mm4, [edx+3*2048+edi*8])\ + AS2( shr ecx, 16)\ + AS2( movzx edi, cl)\ + AS2( pxor mm3, [edx+1*2048+edi*8])\ + AS2( movzx edi, ch)\ + AS2( pxor mm4, [edx+2*2048+edi*8])\ + AS3( pextrw ecx, c, 2)\ + AS2( movzx edi, cl)\ + AS2( pxor mm3, [edx+2*2048+edi*8])\ + AS2( movzx edi, ch)\ + AS2( pxor mm4, [edx+1*2048+edi*8])\ + AS3( pextrw ecx, c, 3)\ + AS2( movzx edi, cl)\ + AS2( pxor mm3, [edx+3*2048+edi*8])\ + AS2( psubq a, mm3)\ + AS2( movzx edi, ch)\ + AS2( pxor mm4, [edx+0*2048+edi*8])\ + AS2( paddq b, mm4)\ + SSE2_mul_##mul(b) + +#define SSE2_mul_5(b) \ + AS2( movq mm3, b)\ + AS2( psllq b, 2)\ + AS2( paddq b, mm3) + +#define SSE2_mul_7(b) \ + AS2( movq mm3, b)\ + AS2( psllq b, 3)\ + AS2( psubq b, mm3) + +#define SSE2_mul_9(b) \ + AS2( movq mm3, b)\ + AS2( psllq b, 3)\ + AS2( paddq b, mm3) + +#define label2_5 1 +#define label2_7 2 +#define label2_9 3 + +#define SSE2_pass(A,B,C,mul,X) \ + AS2( xor ebx, ebx)\ + ASL(mul)\ + SSE2_round(A,B,C,X+0*8+ebx,mul)\ + SSE2_round(B,C,A,X+1*8+ebx,mul)\ + AS2( cmp ebx, 6*8)\ + ASJ( je, label2_##mul, f)\ + SSE2_round(C,A,B,X+2*8+ebx,mul)\ + AS2( add ebx, 3*8)\ + ASJ( jmp, mul, b)\ + ASL(label2_##mul) + +#define SSE2_key_schedule(Y,X) \ + AS2( movq mm3, [X+7*8])\ + AS2( pxor mm3, mm6)\ + AS2( movq mm4, [X+0*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+0*8], mm4)\ + AS2( pxor mm4, [X+1*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+1*8], mm4)\ + AS2( paddq mm4, [X+2*8])\ + AS2( pxor mm3, mm7)\ + AS2( psllq mm3, 19)\ + AS2( movq [Y+2*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [X+3*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+3*8], mm4)\ + AS2( pxor mm4, [X+4*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+4*8], mm4)\ + AS2( paddq mm4, [X+5*8])\ + AS2( pxor mm3, mm7)\ + AS2( psrlq mm3, 23)\ + AS2( movq [Y+5*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [X+6*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+6*8], mm4)\ + AS2( pxor mm4, [X+7*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+7*8], mm4)\ + AS2( paddq mm4, [Y+0*8])\ + AS2( pxor mm3, mm7)\ + AS2( psllq mm3, 19)\ + AS2( movq [Y+0*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [Y+1*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+1*8], mm4)\ + AS2( pxor mm4, [Y+2*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+2*8], mm4)\ + AS2( paddq mm4, [Y+3*8])\ + AS2( pxor mm3, mm7)\ + AS2( psrlq mm3, 23)\ + AS2( movq [Y+3*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [Y+4*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+4*8], mm4)\ + AS2( pxor mm4, [Y+5*8])\ + AS2( movq [Y+5*8], mm4)\ + AS2( paddq mm4, [Y+6*8])\ + AS2( movq [Y+6*8], mm4)\ + AS2( pxor mm4, [edx+4*2048+2*8])\ + AS2( movq mm3, [Y+7*8])\ + AS2( psubq mm3, mm4)\ + AS2( movq [Y+7*8], mm3) + + SSE2_pass(mm0, mm1, mm2, 5, esi) + SSE2_key_schedule(esp+4, esi) + SSE2_pass(mm2, mm0, mm1, 7, esp+4) + SSE2_key_schedule(esp+4, esp+4) + SSE2_pass(mm1, mm2, mm0, 9, esp+4) + + AS2( pxor mm0, [eax+0*8]) + AS2( movq [eax+0*8], mm0) + AS2( psubq mm1, mm5) + AS2( movq [eax+1*8], mm1) + AS2( paddq mm2, [eax+2*8]) + AS2( movq [eax+2*8], mm2) + + AS_POP_IF86(sp) + AS1( emms) + +#ifdef __GNUC__ + AS_POP_IF86(bx) + ATT_PREFIX + : + : "a" (state), "S" (data), "d" (table) + : "%ecx", "%edi", "memory", "cc" + ); +#endif + } + else +#endif + { + word64 a = state[0]; + word64 b = state[1]; + word64 c = state[2]; + word64 Y[8]; + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +#define round(a,b,c,x,mul) \ + c ^= x; \ + a -= t1[GETBYTE(c,0)] ^ t2[GETBYTE(c,2)] ^ t3[GETBYTE(c,4)] ^ t4[GETBYTE(c,6)]; \ + b += t4[GETBYTE(c,1)] ^ t3[GETBYTE(c,3)] ^ t2[GETBYTE(c,5)] ^ t1[GETBYTE(c,7)]; \ + b *= mul + +#define pass(a,b,c,mul,X) {\ + int i=0;\ + while (true)\ + {\ + round(a,b,c,X[i+0],mul); \ + round(b,c,a,X[i+1],mul); \ + if (i==6)\ + break;\ + round(c,a,b,X[i+2],mul); \ + i+=3;\ + }} + +#define key_schedule(Y,X) \ + Y[0] = X[0] - (X[7]^W64LIT(0xA5A5A5A5A5A5A5A5)); \ + Y[1] = X[1] ^ Y[0]; \ + Y[2] = X[2] + Y[1]; \ + Y[3] = X[3] - (Y[2] ^ ((~Y[1])<<19)); \ + Y[4] = X[4] ^ Y[3]; \ + Y[5] = X[5] + Y[4]; \ + Y[6] = X[6] - (Y[5] ^ ((~Y[4])>>23)); \ + Y[7] = X[7] ^ Y[6]; \ + Y[0] += Y[7]; \ + Y[1] -= Y[0] ^ ((~Y[7])<<19); \ + Y[2] ^= Y[1]; \ + Y[3] += Y[2]; \ + Y[4] -= Y[3] ^ ((~Y[2])>>23); \ + Y[5] ^= Y[4]; \ + Y[6] += Y[5]; \ + Y[7] -= Y[6] ^ W64LIT(0x0123456789ABCDEF) + + pass(a,b,c,5,data); + key_schedule(Y,data); + pass(c,a,b,7,Y); + key_schedule(Y,Y); + pass(b,c,a,9,Y); + + state[0] = a ^ state[0]; + state[1] = b - state[1]; + state[2] = c + state[2]; + } +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/tiger.h b/external/ours/library/crypto/src/shared/original/tiger.h new file mode 100755 index 000000000..4737dd923 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/tiger.h @@ -0,0 +1,61 @@ +// tiger.h - originally written and placed in the public domain by Wei Dai + +/// \file tiger.h +/// \brief Classes for the Tiger message digest +/// \details Crypto++ provides the original Tiger hash that was +/// submitted to the NESSIE project. The implementation is different +/// from the revised Tiger2 hash. +/// \sa Tiger and +/// Tiger: +/// A Fast New Cryptographic Hash Function +/// \since Crypto++ 2.1 + +#ifndef CRYPTOPP_TIGER_H +#define CRYPTOPP_TIGER_H + +#include "config.h" +#include "iterhash.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_TIGER_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Tiger message digest +/// \details Crypto++ provides the original Tiger hash that was +/// submitted to the NESSIE project. The implementation is different +/// from the revised Tiger2 hash. +/// \sa Tiger and +/// Tiger: +/// A Fast New Cryptographic Hash Function +/// \since Crypto++ 2.1 +class Tiger : public IteratedHashWithStaticTransform +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Tiger";} + std::string AlgorithmProvider() const; + + /// \brief Initialize state array + /// \param state the state of the hash + static void InitState(HashWordType *state); + /// \brief Operate the hash + /// \param digest the state of the hash + /// \param data the data to be digested + static void Transform(word64 *digest, const word64 *data); + /// \brief Computes the hash of the current message + /// \param digest a pointer to the buffer to receive the hash + /// \param digestSize the size of the truncated digest, in bytes + /// \details TruncatedFinal() calls Final() and then copies digestSize bytes to digest. + /// The hash is restarted the hash for the next message. + void TruncatedFinal(byte *digest, size_t digestSize); + +protected: + static const word64 table[4*256+3]; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/tigertab.cpp b/external/ours/library/crypto/src/shared/original/tigertab.cpp new file mode 100755 index 000000000..5e219dcf6 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/tigertab.cpp @@ -0,0 +1,525 @@ +#include "pch.h" +#include "tiger.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word64 Tiger::table[4*256+3] = +{ + W64LIT(0x02AAB17CF7E90C5E) /* 0 */, W64LIT(0xAC424B03E243A8EC) /* 1 */, + W64LIT(0x72CD5BE30DD5FCD3) /* 2 */, W64LIT(0x6D019B93F6F97F3A) /* 3 */, + W64LIT(0xCD9978FFD21F9193) /* 4 */, W64LIT(0x7573A1C9708029E2) /* 5 */, + W64LIT(0xB164326B922A83C3) /* 6 */, W64LIT(0x46883EEE04915870) /* 7 */, + W64LIT(0xEAACE3057103ECE6) /* 8 */, W64LIT(0xC54169B808A3535C) /* 9 */, + W64LIT(0x4CE754918DDEC47C) /* 10 */, W64LIT(0x0AA2F4DFDC0DF40C) /* 11 */, + W64LIT(0x10B76F18A74DBEFA) /* 12 */, W64LIT(0xC6CCB6235AD1AB6A) /* 13 */, + W64LIT(0x13726121572FE2FF) /* 14 */, W64LIT(0x1A488C6F199D921E) /* 15 */, + W64LIT(0x4BC9F9F4DA0007CA) /* 16 */, W64LIT(0x26F5E6F6E85241C7) /* 17 */, + W64LIT(0x859079DBEA5947B6) /* 18 */, W64LIT(0x4F1885C5C99E8C92) /* 19 */, + W64LIT(0xD78E761EA96F864B) /* 20 */, W64LIT(0x8E36428C52B5C17D) /* 21 */, + W64LIT(0x69CF6827373063C1) /* 22 */, W64LIT(0xB607C93D9BB4C56E) /* 23 */, + W64LIT(0x7D820E760E76B5EA) /* 24 */, W64LIT(0x645C9CC6F07FDC42) /* 25 */, + W64LIT(0xBF38A078243342E0) /* 26 */, W64LIT(0x5F6B343C9D2E7D04) /* 27 */, + W64LIT(0xF2C28AEB600B0EC6) /* 28 */, W64LIT(0x6C0ED85F7254BCAC) /* 29 */, + W64LIT(0x71592281A4DB4FE5) /* 30 */, W64LIT(0x1967FA69CE0FED9F) /* 31 */, + W64LIT(0xFD5293F8B96545DB) /* 32 */, W64LIT(0xC879E9D7F2A7600B) /* 33 */, + W64LIT(0x860248920193194E) /* 34 */, W64LIT(0xA4F9533B2D9CC0B3) /* 35 */, + W64LIT(0x9053836C15957613) /* 36 */, W64LIT(0xDB6DCF8AFC357BF1) /* 37 */, + W64LIT(0x18BEEA7A7A370F57) /* 38 */, W64LIT(0x037117CA50B99066) /* 39 */, + W64LIT(0x6AB30A9774424A35) /* 40 */, W64LIT(0xF4E92F02E325249B) /* 41 */, + W64LIT(0x7739DB07061CCAE1) /* 42 */, W64LIT(0xD8F3B49CECA42A05) /* 43 */, + W64LIT(0xBD56BE3F51382F73) /* 44 */, W64LIT(0x45FAED5843B0BB28) /* 45 */, + W64LIT(0x1C813D5C11BF1F83) /* 46 */, W64LIT(0x8AF0E4B6D75FA169) /* 47 */, + W64LIT(0x33EE18A487AD9999) /* 48 */, W64LIT(0x3C26E8EAB1C94410) /* 49 */, + W64LIT(0xB510102BC0A822F9) /* 50 */, W64LIT(0x141EEF310CE6123B) /* 51 */, + W64LIT(0xFC65B90059DDB154) /* 52 */, W64LIT(0xE0158640C5E0E607) /* 53 */, + W64LIT(0x884E079826C3A3CF) /* 54 */, W64LIT(0x930D0D9523C535FD) /* 55 */, + W64LIT(0x35638D754E9A2B00) /* 56 */, W64LIT(0x4085FCCF40469DD5) /* 57 */, + W64LIT(0xC4B17AD28BE23A4C) /* 58 */, W64LIT(0xCAB2F0FC6A3E6A2E) /* 59 */, + W64LIT(0x2860971A6B943FCD) /* 60 */, W64LIT(0x3DDE6EE212E30446) /* 61 */, + W64LIT(0x6222F32AE01765AE) /* 62 */, W64LIT(0x5D550BB5478308FE) /* 63 */, + W64LIT(0xA9EFA98DA0EDA22A) /* 64 */, W64LIT(0xC351A71686C40DA7) /* 65 */, + W64LIT(0x1105586D9C867C84) /* 66 */, W64LIT(0xDCFFEE85FDA22853) /* 67 */, + W64LIT(0xCCFBD0262C5EEF76) /* 68 */, W64LIT(0xBAF294CB8990D201) /* 69 */, + W64LIT(0xE69464F52AFAD975) /* 70 */, W64LIT(0x94B013AFDF133E14) /* 71 */, + W64LIT(0x06A7D1A32823C958) /* 72 */, W64LIT(0x6F95FE5130F61119) /* 73 */, + W64LIT(0xD92AB34E462C06C0) /* 74 */, W64LIT(0xED7BDE33887C71D2) /* 75 */, + W64LIT(0x79746D6E6518393E) /* 76 */, W64LIT(0x5BA419385D713329) /* 77 */, + W64LIT(0x7C1BA6B948A97564) /* 78 */, W64LIT(0x31987C197BFDAC67) /* 79 */, + W64LIT(0xDE6C23C44B053D02) /* 80 */, W64LIT(0x581C49FED002D64D) /* 81 */, + W64LIT(0xDD474D6338261571) /* 82 */, W64LIT(0xAA4546C3E473D062) /* 83 */, + W64LIT(0x928FCE349455F860) /* 84 */, W64LIT(0x48161BBACAAB94D9) /* 85 */, + W64LIT(0x63912430770E6F68) /* 86 */, W64LIT(0x6EC8A5E602C6641C) /* 87 */, + W64LIT(0x87282515337DDD2B) /* 88 */, W64LIT(0x2CDA6B42034B701B) /* 89 */, + W64LIT(0xB03D37C181CB096D) /* 90 */, W64LIT(0xE108438266C71C6F) /* 91 */, + W64LIT(0x2B3180C7EB51B255) /* 92 */, W64LIT(0xDF92B82F96C08BBC) /* 93 */, + W64LIT(0x5C68C8C0A632F3BA) /* 94 */, W64LIT(0x5504CC861C3D0556) /* 95 */, + W64LIT(0xABBFA4E55FB26B8F) /* 96 */, W64LIT(0x41848B0AB3BACEB4) /* 97 */, + W64LIT(0xB334A273AA445D32) /* 98 */, W64LIT(0xBCA696F0A85AD881) /* 99 */, + W64LIT(0x24F6EC65B528D56C) /* 100 */, W64LIT(0x0CE1512E90F4524A) /* 101 */, + W64LIT(0x4E9DD79D5506D35A) /* 102 */, W64LIT(0x258905FAC6CE9779) /* 103 */, + W64LIT(0x2019295B3E109B33) /* 104 */, W64LIT(0xF8A9478B73A054CC) /* 105 */, + W64LIT(0x2924F2F934417EB0) /* 106 */, W64LIT(0x3993357D536D1BC4) /* 107 */, + W64LIT(0x38A81AC21DB6FF8B) /* 108 */, W64LIT(0x47C4FBF17D6016BF) /* 109 */, + W64LIT(0x1E0FAADD7667E3F5) /* 110 */, W64LIT(0x7ABCFF62938BEB96) /* 111 */, + W64LIT(0xA78DAD948FC179C9) /* 112 */, W64LIT(0x8F1F98B72911E50D) /* 113 */, + W64LIT(0x61E48EAE27121A91) /* 114 */, W64LIT(0x4D62F7AD31859808) /* 115 */, + W64LIT(0xECEBA345EF5CEAEB) /* 116 */, W64LIT(0xF5CEB25EBC9684CE) /* 117 */, + W64LIT(0xF633E20CB7F76221) /* 118 */, W64LIT(0xA32CDF06AB8293E4) /* 119 */, + W64LIT(0x985A202CA5EE2CA4) /* 120 */, W64LIT(0xCF0B8447CC8A8FB1) /* 121 */, + W64LIT(0x9F765244979859A3) /* 122 */, W64LIT(0xA8D516B1A1240017) /* 123 */, + W64LIT(0x0BD7BA3EBB5DC726) /* 124 */, W64LIT(0xE54BCA55B86ADB39) /* 125 */, + W64LIT(0x1D7A3AFD6C478063) /* 126 */, W64LIT(0x519EC608E7669EDD) /* 127 */, + W64LIT(0x0E5715A2D149AA23) /* 128 */, W64LIT(0x177D4571848FF194) /* 129 */, + W64LIT(0xEEB55F3241014C22) /* 130 */, W64LIT(0x0F5E5CA13A6E2EC2) /* 131 */, + W64LIT(0x8029927B75F5C361) /* 132 */, W64LIT(0xAD139FABC3D6E436) /* 133 */, + W64LIT(0x0D5DF1A94CCF402F) /* 134 */, W64LIT(0x3E8BD948BEA5DFC8) /* 135 */, + W64LIT(0xA5A0D357BD3FF77E) /* 136 */, W64LIT(0xA2D12E251F74F645) /* 137 */, + W64LIT(0x66FD9E525E81A082) /* 138 */, W64LIT(0x2E0C90CE7F687A49) /* 139 */, + W64LIT(0xC2E8BCBEBA973BC5) /* 140 */, W64LIT(0x000001BCE509745F) /* 141 */, + W64LIT(0x423777BBE6DAB3D6) /* 142 */, W64LIT(0xD1661C7EAEF06EB5) /* 143 */, + W64LIT(0xA1781F354DAACFD8) /* 144 */, W64LIT(0x2D11284A2B16AFFC) /* 145 */, + W64LIT(0xF1FC4F67FA891D1F) /* 146 */, W64LIT(0x73ECC25DCB920ADA) /* 147 */, + W64LIT(0xAE610C22C2A12651) /* 148 */, W64LIT(0x96E0A810D356B78A) /* 149 */, + W64LIT(0x5A9A381F2FE7870F) /* 150 */, W64LIT(0xD5AD62EDE94E5530) /* 151 */, + W64LIT(0xD225E5E8368D1427) /* 152 */, W64LIT(0x65977B70C7AF4631) /* 153 */, + W64LIT(0x99F889B2DE39D74F) /* 154 */, W64LIT(0x233F30BF54E1D143) /* 155 */, + W64LIT(0x9A9675D3D9A63C97) /* 156 */, W64LIT(0x5470554FF334F9A8) /* 157 */, + W64LIT(0x166ACB744A4F5688) /* 158 */, W64LIT(0x70C74CAAB2E4AEAD) /* 159 */, + W64LIT(0xF0D091646F294D12) /* 160 */, W64LIT(0x57B82A89684031D1) /* 161 */, + W64LIT(0xEFD95A5A61BE0B6B) /* 162 */, W64LIT(0x2FBD12E969F2F29A) /* 163 */, + W64LIT(0x9BD37013FEFF9FE8) /* 164 */, W64LIT(0x3F9B0404D6085A06) /* 165 */, + W64LIT(0x4940C1F3166CFE15) /* 166 */, W64LIT(0x09542C4DCDF3DEFB) /* 167 */, + W64LIT(0xB4C5218385CD5CE3) /* 168 */, W64LIT(0xC935B7DC4462A641) /* 169 */, + W64LIT(0x3417F8A68ED3B63F) /* 170 */, W64LIT(0xB80959295B215B40) /* 171 */, + W64LIT(0xF99CDAEF3B8C8572) /* 172 */, W64LIT(0x018C0614F8FCB95D) /* 173 */, + W64LIT(0x1B14ACCD1A3ACDF3) /* 174 */, W64LIT(0x84D471F200BB732D) /* 175 */, + W64LIT(0xC1A3110E95E8DA16) /* 176 */, W64LIT(0x430A7220BF1A82B8) /* 177 */, + W64LIT(0xB77E090D39DF210E) /* 178 */, W64LIT(0x5EF4BD9F3CD05E9D) /* 179 */, + W64LIT(0x9D4FF6DA7E57A444) /* 180 */, W64LIT(0xDA1D60E183D4A5F8) /* 181 */, + W64LIT(0xB287C38417998E47) /* 182 */, W64LIT(0xFE3EDC121BB31886) /* 183 */, + W64LIT(0xC7FE3CCC980CCBEF) /* 184 */, W64LIT(0xE46FB590189BFD03) /* 185 */, + W64LIT(0x3732FD469A4C57DC) /* 186 */, W64LIT(0x7EF700A07CF1AD65) /* 187 */, + W64LIT(0x59C64468A31D8859) /* 188 */, W64LIT(0x762FB0B4D45B61F6) /* 189 */, + W64LIT(0x155BAED099047718) /* 190 */, W64LIT(0x68755E4C3D50BAA6) /* 191 */, + W64LIT(0xE9214E7F22D8B4DF) /* 192 */, W64LIT(0x2ADDBF532EAC95F4) /* 193 */, + W64LIT(0x32AE3909B4BD0109) /* 194 */, W64LIT(0x834DF537B08E3450) /* 195 */, + W64LIT(0xFA209DA84220728D) /* 196 */, W64LIT(0x9E691D9B9EFE23F7) /* 197 */, + W64LIT(0x0446D288C4AE8D7F) /* 198 */, W64LIT(0x7B4CC524E169785B) /* 199 */, + W64LIT(0x21D87F0135CA1385) /* 200 */, W64LIT(0xCEBB400F137B8AA5) /* 201 */, + W64LIT(0x272E2B66580796BE) /* 202 */, W64LIT(0x3612264125C2B0DE) /* 203 */, + W64LIT(0x057702BDAD1EFBB2) /* 204 */, W64LIT(0xD4BABB8EACF84BE9) /* 205 */, + W64LIT(0x91583139641BC67B) /* 206 */, W64LIT(0x8BDC2DE08036E024) /* 207 */, + W64LIT(0x603C8156F49F68ED) /* 208 */, W64LIT(0xF7D236F7DBEF5111) /* 209 */, + W64LIT(0x9727C4598AD21E80) /* 210 */, W64LIT(0xA08A0896670A5FD7) /* 211 */, + W64LIT(0xCB4A8F4309EBA9CB) /* 212 */, W64LIT(0x81AF564B0F7036A1) /* 213 */, + W64LIT(0xC0B99AA778199ABD) /* 214 */, W64LIT(0x959F1EC83FC8E952) /* 215 */, + W64LIT(0x8C505077794A81B9) /* 216 */, W64LIT(0x3ACAAF8F056338F0) /* 217 */, + W64LIT(0x07B43F50627A6778) /* 218 */, W64LIT(0x4A44AB49F5ECCC77) /* 219 */, + W64LIT(0x3BC3D6E4B679EE98) /* 220 */, W64LIT(0x9CC0D4D1CF14108C) /* 221 */, + W64LIT(0x4406C00B206BC8A0) /* 222 */, W64LIT(0x82A18854C8D72D89) /* 223 */, + W64LIT(0x67E366B35C3C432C) /* 224 */, W64LIT(0xB923DD61102B37F2) /* 225 */, + W64LIT(0x56AB2779D884271D) /* 226 */, W64LIT(0xBE83E1B0FF1525AF) /* 227 */, + W64LIT(0xFB7C65D4217E49A9) /* 228 */, W64LIT(0x6BDBE0E76D48E7D4) /* 229 */, + W64LIT(0x08DF828745D9179E) /* 230 */, W64LIT(0x22EA6A9ADD53BD34) /* 231 */, + W64LIT(0xE36E141C5622200A) /* 232 */, W64LIT(0x7F805D1B8CB750EE) /* 233 */, + W64LIT(0xAFE5C7A59F58E837) /* 234 */, W64LIT(0xE27F996A4FB1C23C) /* 235 */, + W64LIT(0xD3867DFB0775F0D0) /* 236 */, W64LIT(0xD0E673DE6E88891A) /* 237 */, + W64LIT(0x123AEB9EAFB86C25) /* 238 */, W64LIT(0x30F1D5D5C145B895) /* 239 */, + W64LIT(0xBB434A2DEE7269E7) /* 240 */, W64LIT(0x78CB67ECF931FA38) /* 241 */, + W64LIT(0xF33B0372323BBF9C) /* 242 */, W64LIT(0x52D66336FB279C74) /* 243 */, + W64LIT(0x505F33AC0AFB4EAA) /* 244 */, W64LIT(0xE8A5CD99A2CCE187) /* 245 */, + W64LIT(0x534974801E2D30BB) /* 246 */, W64LIT(0x8D2D5711D5876D90) /* 247 */, + W64LIT(0x1F1A412891BC038E) /* 248 */, W64LIT(0xD6E2E71D82E56648) /* 249 */, + W64LIT(0x74036C3A497732B7) /* 250 */, W64LIT(0x89B67ED96361F5AB) /* 251 */, + W64LIT(0xFFED95D8F1EA02A2) /* 252 */, W64LIT(0xE72B3BD61464D43D) /* 253 */, + W64LIT(0xA6300F170BDC4820) /* 254 */, W64LIT(0xEBC18760ED78A77A) /* 255 */, + W64LIT(0xE6A6BE5A05A12138) /* 256 */, W64LIT(0xB5A122A5B4F87C98) /* 257 */, + W64LIT(0x563C6089140B6990) /* 258 */, W64LIT(0x4C46CB2E391F5DD5) /* 259 */, + W64LIT(0xD932ADDBC9B79434) /* 260 */, W64LIT(0x08EA70E42015AFF5) /* 261 */, + W64LIT(0xD765A6673E478CF1) /* 262 */, W64LIT(0xC4FB757EAB278D99) /* 263 */, + W64LIT(0xDF11C6862D6E0692) /* 264 */, W64LIT(0xDDEB84F10D7F3B16) /* 265 */, + W64LIT(0x6F2EF604A665EA04) /* 266 */, W64LIT(0x4A8E0F0FF0E0DFB3) /* 267 */, + W64LIT(0xA5EDEEF83DBCBA51) /* 268 */, W64LIT(0xFC4F0A2A0EA4371E) /* 269 */, + W64LIT(0xE83E1DA85CB38429) /* 270 */, W64LIT(0xDC8FF882BA1B1CE2) /* 271 */, + W64LIT(0xCD45505E8353E80D) /* 272 */, W64LIT(0x18D19A00D4DB0717) /* 273 */, + W64LIT(0x34A0CFEDA5F38101) /* 274 */, W64LIT(0x0BE77E518887CAF2) /* 275 */, + W64LIT(0x1E341438B3C45136) /* 276 */, W64LIT(0xE05797F49089CCF9) /* 277 */, + W64LIT(0xFFD23F9DF2591D14) /* 278 */, W64LIT(0x543DDA228595C5CD) /* 279 */, + W64LIT(0x661F81FD99052A33) /* 280 */, W64LIT(0x8736E641DB0F7B76) /* 281 */, + W64LIT(0x15227725418E5307) /* 282 */, W64LIT(0xE25F7F46162EB2FA) /* 283 */, + W64LIT(0x48A8B2126C13D9FE) /* 284 */, W64LIT(0xAFDC541792E76EEA) /* 285 */, + W64LIT(0x03D912BFC6D1898F) /* 286 */, W64LIT(0x31B1AAFA1B83F51B) /* 287 */, + W64LIT(0xF1AC2796E42AB7D9) /* 288 */, W64LIT(0x40A3A7D7FCD2EBAC) /* 289 */, + W64LIT(0x1056136D0AFBBCC5) /* 290 */, W64LIT(0x7889E1DD9A6D0C85) /* 291 */, + W64LIT(0xD33525782A7974AA) /* 292 */, W64LIT(0xA7E25D09078AC09B) /* 293 */, + W64LIT(0xBD4138B3EAC6EDD0) /* 294 */, W64LIT(0x920ABFBE71EB9E70) /* 295 */, + W64LIT(0xA2A5D0F54FC2625C) /* 296 */, W64LIT(0xC054E36B0B1290A3) /* 297 */, + W64LIT(0xF6DD59FF62FE932B) /* 298 */, W64LIT(0x3537354511A8AC7D) /* 299 */, + W64LIT(0xCA845E9172FADCD4) /* 300 */, W64LIT(0x84F82B60329D20DC) /* 301 */, + W64LIT(0x79C62CE1CD672F18) /* 302 */, W64LIT(0x8B09A2ADD124642C) /* 303 */, + W64LIT(0xD0C1E96A19D9E726) /* 304 */, W64LIT(0x5A786A9B4BA9500C) /* 305 */, + W64LIT(0x0E020336634C43F3) /* 306 */, W64LIT(0xC17B474AEB66D822) /* 307 */, + W64LIT(0x6A731AE3EC9BAAC2) /* 308 */, W64LIT(0x8226667AE0840258) /* 309 */, + W64LIT(0x67D4567691CAECA5) /* 310 */, W64LIT(0x1D94155C4875ADB5) /* 311 */, + W64LIT(0x6D00FD985B813FDF) /* 312 */, W64LIT(0x51286EFCB774CD06) /* 313 */, + W64LIT(0x5E8834471FA744AF) /* 314 */, W64LIT(0xF72CA0AEE761AE2E) /* 315 */, + W64LIT(0xBE40E4CDAEE8E09A) /* 316 */, W64LIT(0xE9970BBB5118F665) /* 317 */, + W64LIT(0x726E4BEB33DF1964) /* 318 */, W64LIT(0x703B000729199762) /* 319 */, + W64LIT(0x4631D816F5EF30A7) /* 320 */, W64LIT(0xB880B5B51504A6BE) /* 321 */, + W64LIT(0x641793C37ED84B6C) /* 322 */, W64LIT(0x7B21ED77F6E97D96) /* 323 */, + W64LIT(0x776306312EF96B73) /* 324 */, W64LIT(0xAE528948E86FF3F4) /* 325 */, + W64LIT(0x53DBD7F286A3F8F8) /* 326 */, W64LIT(0x16CADCE74CFC1063) /* 327 */, + W64LIT(0x005C19BDFA52C6DD) /* 328 */, W64LIT(0x68868F5D64D46AD3) /* 329 */, + W64LIT(0x3A9D512CCF1E186A) /* 330 */, W64LIT(0x367E62C2385660AE) /* 331 */, + W64LIT(0xE359E7EA77DCB1D7) /* 332 */, W64LIT(0x526C0773749ABE6E) /* 333 */, + W64LIT(0x735AE5F9D09F734B) /* 334 */, W64LIT(0x493FC7CC8A558BA8) /* 335 */, + W64LIT(0xB0B9C1533041AB45) /* 336 */, W64LIT(0x321958BA470A59BD) /* 337 */, + W64LIT(0x852DB00B5F46C393) /* 338 */, W64LIT(0x91209B2BD336B0E5) /* 339 */, + W64LIT(0x6E604F7D659EF19F) /* 340 */, W64LIT(0xB99A8AE2782CCB24) /* 341 */, + W64LIT(0xCCF52AB6C814C4C7) /* 342 */, W64LIT(0x4727D9AFBE11727B) /* 343 */, + W64LIT(0x7E950D0C0121B34D) /* 344 */, W64LIT(0x756F435670AD471F) /* 345 */, + W64LIT(0xF5ADD442615A6849) /* 346 */, W64LIT(0x4E87E09980B9957A) /* 347 */, + W64LIT(0x2ACFA1DF50AEE355) /* 348 */, W64LIT(0xD898263AFD2FD556) /* 349 */, + W64LIT(0xC8F4924DD80C8FD6) /* 350 */, W64LIT(0xCF99CA3D754A173A) /* 351 */, + W64LIT(0xFE477BACAF91BF3C) /* 352 */, W64LIT(0xED5371F6D690C12D) /* 353 */, + W64LIT(0x831A5C285E687094) /* 354 */, W64LIT(0xC5D3C90A3708A0A4) /* 355 */, + W64LIT(0x0F7F903717D06580) /* 356 */, W64LIT(0x19F9BB13B8FDF27F) /* 357 */, + W64LIT(0xB1BD6F1B4D502843) /* 358 */, W64LIT(0x1C761BA38FFF4012) /* 359 */, + W64LIT(0x0D1530C4E2E21F3B) /* 360 */, W64LIT(0x8943CE69A7372C8A) /* 361 */, + W64LIT(0xE5184E11FEB5CE66) /* 362 */, W64LIT(0x618BDB80BD736621) /* 363 */, + W64LIT(0x7D29BAD68B574D0B) /* 364 */, W64LIT(0x81BB613E25E6FE5B) /* 365 */, + W64LIT(0x071C9C10BC07913F) /* 366 */, W64LIT(0xC7BEEB7909AC2D97) /* 367 */, + W64LIT(0xC3E58D353BC5D757) /* 368 */, W64LIT(0xEB017892F38F61E8) /* 369 */, + W64LIT(0xD4EFFB9C9B1CC21A) /* 370 */, W64LIT(0x99727D26F494F7AB) /* 371 */, + W64LIT(0xA3E063A2956B3E03) /* 372 */, W64LIT(0x9D4A8B9A4AA09C30) /* 373 */, + W64LIT(0x3F6AB7D500090FB4) /* 374 */, W64LIT(0x9CC0F2A057268AC0) /* 375 */, + W64LIT(0x3DEE9D2DEDBF42D1) /* 376 */, W64LIT(0x330F49C87960A972) /* 377 */, + W64LIT(0xC6B2720287421B41) /* 378 */, W64LIT(0x0AC59EC07C00369C) /* 379 */, + W64LIT(0xEF4EAC49CB353425) /* 380 */, W64LIT(0xF450244EEF0129D8) /* 381 */, + W64LIT(0x8ACC46E5CAF4DEB6) /* 382 */, W64LIT(0x2FFEAB63989263F7) /* 383 */, + W64LIT(0x8F7CB9FE5D7A4578) /* 384 */, W64LIT(0x5BD8F7644E634635) /* 385 */, + W64LIT(0x427A7315BF2DC900) /* 386 */, W64LIT(0x17D0C4AA2125261C) /* 387 */, + W64LIT(0x3992486C93518E50) /* 388 */, W64LIT(0xB4CBFEE0A2D7D4C3) /* 389 */, + W64LIT(0x7C75D6202C5DDD8D) /* 390 */, W64LIT(0xDBC295D8E35B6C61) /* 391 */, + W64LIT(0x60B369D302032B19) /* 392 */, W64LIT(0xCE42685FDCE44132) /* 393 */, + W64LIT(0x06F3DDB9DDF65610) /* 394 */, W64LIT(0x8EA4D21DB5E148F0) /* 395 */, + W64LIT(0x20B0FCE62FCD496F) /* 396 */, W64LIT(0x2C1B912358B0EE31) /* 397 */, + W64LIT(0xB28317B818F5A308) /* 398 */, W64LIT(0xA89C1E189CA6D2CF) /* 399 */, + W64LIT(0x0C6B18576AAADBC8) /* 400 */, W64LIT(0xB65DEAA91299FAE3) /* 401 */, + W64LIT(0xFB2B794B7F1027E7) /* 402 */, W64LIT(0x04E4317F443B5BEB) /* 403 */, + W64LIT(0x4B852D325939D0A6) /* 404 */, W64LIT(0xD5AE6BEEFB207FFC) /* 405 */, + W64LIT(0x309682B281C7D374) /* 406 */, W64LIT(0xBAE309A194C3B475) /* 407 */, + W64LIT(0x8CC3F97B13B49F05) /* 408 */, W64LIT(0x98A9422FF8293967) /* 409 */, + W64LIT(0x244B16B01076FF7C) /* 410 */, W64LIT(0xF8BF571C663D67EE) /* 411 */, + W64LIT(0x1F0D6758EEE30DA1) /* 412 */, W64LIT(0xC9B611D97ADEB9B7) /* 413 */, + W64LIT(0xB7AFD5887B6C57A2) /* 414 */, W64LIT(0x6290AE846B984FE1) /* 415 */, + W64LIT(0x94DF4CDEACC1A5FD) /* 416 */, W64LIT(0x058A5BD1C5483AFF) /* 417 */, + W64LIT(0x63166CC142BA3C37) /* 418 */, W64LIT(0x8DB8526EB2F76F40) /* 419 */, + W64LIT(0xE10880036F0D6D4E) /* 420 */, W64LIT(0x9E0523C9971D311D) /* 421 */, + W64LIT(0x45EC2824CC7CD691) /* 422 */, W64LIT(0x575B8359E62382C9) /* 423 */, + W64LIT(0xFA9E400DC4889995) /* 424 */, W64LIT(0xD1823ECB45721568) /* 425 */, + W64LIT(0xDAFD983B8206082F) /* 426 */, W64LIT(0xAA7D29082386A8CB) /* 427 */, + W64LIT(0x269FCD4403B87588) /* 428 */, W64LIT(0x1B91F5F728BDD1E0) /* 429 */, + W64LIT(0xE4669F39040201F6) /* 430 */, W64LIT(0x7A1D7C218CF04ADE) /* 431 */, + W64LIT(0x65623C29D79CE5CE) /* 432 */, W64LIT(0x2368449096C00BB1) /* 433 */, + W64LIT(0xAB9BF1879DA503BA) /* 434 */, W64LIT(0xBC23ECB1A458058E) /* 435 */, + W64LIT(0x9A58DF01BB401ECC) /* 436 */, W64LIT(0xA070E868A85F143D) /* 437 */, + W64LIT(0x4FF188307DF2239E) /* 438 */, W64LIT(0x14D565B41A641183) /* 439 */, + W64LIT(0xEE13337452701602) /* 440 */, W64LIT(0x950E3DCF3F285E09) /* 441 */, + W64LIT(0x59930254B9C80953) /* 442 */, W64LIT(0x3BF299408930DA6D) /* 443 */, + W64LIT(0xA955943F53691387) /* 444 */, W64LIT(0xA15EDECAA9CB8784) /* 445 */, + W64LIT(0x29142127352BE9A0) /* 446 */, W64LIT(0x76F0371FFF4E7AFB) /* 447 */, + W64LIT(0x0239F450274F2228) /* 448 */, W64LIT(0xBB073AF01D5E868B) /* 449 */, + W64LIT(0xBFC80571C10E96C1) /* 450 */, W64LIT(0xD267088568222E23) /* 451 */, + W64LIT(0x9671A3D48E80B5B0) /* 452 */, W64LIT(0x55B5D38AE193BB81) /* 453 */, + W64LIT(0x693AE2D0A18B04B8) /* 454 */, W64LIT(0x5C48B4ECADD5335F) /* 455 */, + W64LIT(0xFD743B194916A1CA) /* 456 */, W64LIT(0x2577018134BE98C4) /* 457 */, + W64LIT(0xE77987E83C54A4AD) /* 458 */, W64LIT(0x28E11014DA33E1B9) /* 459 */, + W64LIT(0x270CC59E226AA213) /* 460 */, W64LIT(0x71495F756D1A5F60) /* 461 */, + W64LIT(0x9BE853FB60AFEF77) /* 462 */, W64LIT(0xADC786A7F7443DBF) /* 463 */, + W64LIT(0x0904456173B29A82) /* 464 */, W64LIT(0x58BC7A66C232BD5E) /* 465 */, + W64LIT(0xF306558C673AC8B2) /* 466 */, W64LIT(0x41F639C6B6C9772A) /* 467 */, + W64LIT(0x216DEFE99FDA35DA) /* 468 */, W64LIT(0x11640CC71C7BE615) /* 469 */, + W64LIT(0x93C43694565C5527) /* 470 */, W64LIT(0xEA038E6246777839) /* 471 */, + W64LIT(0xF9ABF3CE5A3E2469) /* 472 */, W64LIT(0x741E768D0FD312D2) /* 473 */, + W64LIT(0x0144B883CED652C6) /* 474 */, W64LIT(0xC20B5A5BA33F8552) /* 475 */, + W64LIT(0x1AE69633C3435A9D) /* 476 */, W64LIT(0x97A28CA4088CFDEC) /* 477 */, + W64LIT(0x8824A43C1E96F420) /* 478 */, W64LIT(0x37612FA66EEEA746) /* 479 */, + W64LIT(0x6B4CB165F9CF0E5A) /* 480 */, W64LIT(0x43AA1C06A0ABFB4A) /* 481 */, + W64LIT(0x7F4DC26FF162796B) /* 482 */, W64LIT(0x6CBACC8E54ED9B0F) /* 483 */, + W64LIT(0xA6B7FFEFD2BB253E) /* 484 */, W64LIT(0x2E25BC95B0A29D4F) /* 485 */, + W64LIT(0x86D6A58BDEF1388C) /* 486 */, W64LIT(0xDED74AC576B6F054) /* 487 */, + W64LIT(0x8030BDBC2B45805D) /* 488 */, W64LIT(0x3C81AF70E94D9289) /* 489 */, + W64LIT(0x3EFF6DDA9E3100DB) /* 490 */, W64LIT(0xB38DC39FDFCC8847) /* 491 */, + W64LIT(0x123885528D17B87E) /* 492 */, W64LIT(0xF2DA0ED240B1B642) /* 493 */, + W64LIT(0x44CEFADCD54BF9A9) /* 494 */, W64LIT(0x1312200E433C7EE6) /* 495 */, + W64LIT(0x9FFCC84F3A78C748) /* 496 */, W64LIT(0xF0CD1F72248576BB) /* 497 */, + W64LIT(0xEC6974053638CFE4) /* 498 */, W64LIT(0x2BA7B67C0CEC4E4C) /* 499 */, + W64LIT(0xAC2F4DF3E5CE32ED) /* 500 */, W64LIT(0xCB33D14326EA4C11) /* 501 */, + W64LIT(0xA4E9044CC77E58BC) /* 502 */, W64LIT(0x5F513293D934FCEF) /* 503 */, + W64LIT(0x5DC9645506E55444) /* 504 */, W64LIT(0x50DE418F317DE40A) /* 505 */, + W64LIT(0x388CB31A69DDE259) /* 506 */, W64LIT(0x2DB4A83455820A86) /* 507 */, + W64LIT(0x9010A91E84711AE9) /* 508 */, W64LIT(0x4DF7F0B7B1498371) /* 509 */, + W64LIT(0xD62A2EABC0977179) /* 510 */, W64LIT(0x22FAC097AA8D5C0E) /* 511 */, + W64LIT(0xF49FCC2FF1DAF39B) /* 512 */, W64LIT(0x487FD5C66FF29281) /* 513 */, + W64LIT(0xE8A30667FCDCA83F) /* 514 */, W64LIT(0x2C9B4BE3D2FCCE63) /* 515 */, + W64LIT(0xDA3FF74B93FBBBC2) /* 516 */, W64LIT(0x2FA165D2FE70BA66) /* 517 */, + W64LIT(0xA103E279970E93D4) /* 518 */, W64LIT(0xBECDEC77B0E45E71) /* 519 */, + W64LIT(0xCFB41E723985E497) /* 520 */, W64LIT(0xB70AAA025EF75017) /* 521 */, + W64LIT(0xD42309F03840B8E0) /* 522 */, W64LIT(0x8EFC1AD035898579) /* 523 */, + W64LIT(0x96C6920BE2B2ABC5) /* 524 */, W64LIT(0x66AF4163375A9172) /* 525 */, + W64LIT(0x2174ABDCCA7127FB) /* 526 */, W64LIT(0xB33CCEA64A72FF41) /* 527 */, + W64LIT(0xF04A4933083066A5) /* 528 */, W64LIT(0x8D970ACDD7289AF5) /* 529 */, + W64LIT(0x8F96E8E031C8C25E) /* 530 */, W64LIT(0xF3FEC02276875D47) /* 531 */, + W64LIT(0xEC7BF310056190DD) /* 532 */, W64LIT(0xF5ADB0AEBB0F1491) /* 533 */, + W64LIT(0x9B50F8850FD58892) /* 534 */, W64LIT(0x4975488358B74DE8) /* 535 */, + W64LIT(0xA3354FF691531C61) /* 536 */, W64LIT(0x0702BBE481D2C6EE) /* 537 */, + W64LIT(0x89FB24057DEDED98) /* 538 */, W64LIT(0xAC3075138596E902) /* 539 */, + W64LIT(0x1D2D3580172772ED) /* 540 */, W64LIT(0xEB738FC28E6BC30D) /* 541 */, + W64LIT(0x5854EF8F63044326) /* 542 */, W64LIT(0x9E5C52325ADD3BBE) /* 543 */, + W64LIT(0x90AA53CF325C4623) /* 544 */, W64LIT(0xC1D24D51349DD067) /* 545 */, + W64LIT(0x2051CFEEA69EA624) /* 546 */, W64LIT(0x13220F0A862E7E4F) /* 547 */, + W64LIT(0xCE39399404E04864) /* 548 */, W64LIT(0xD9C42CA47086FCB7) /* 549 */, + W64LIT(0x685AD2238A03E7CC) /* 550 */, W64LIT(0x066484B2AB2FF1DB) /* 551 */, + W64LIT(0xFE9D5D70EFBF79EC) /* 552 */, W64LIT(0x5B13B9DD9C481854) /* 553 */, + W64LIT(0x15F0D475ED1509AD) /* 554 */, W64LIT(0x0BEBCD060EC79851) /* 555 */, + W64LIT(0xD58C6791183AB7F8) /* 556 */, W64LIT(0xD1187C5052F3EEE4) /* 557 */, + W64LIT(0xC95D1192E54E82FF) /* 558 */, W64LIT(0x86EEA14CB9AC6CA2) /* 559 */, + W64LIT(0x3485BEB153677D5D) /* 560 */, W64LIT(0xDD191D781F8C492A) /* 561 */, + W64LIT(0xF60866BAA784EBF9) /* 562 */, W64LIT(0x518F643BA2D08C74) /* 563 */, + W64LIT(0x8852E956E1087C22) /* 564 */, W64LIT(0xA768CB8DC410AE8D) /* 565 */, + W64LIT(0x38047726BFEC8E1A) /* 566 */, W64LIT(0xA67738B4CD3B45AA) /* 567 */, + W64LIT(0xAD16691CEC0DDE19) /* 568 */, W64LIT(0xC6D4319380462E07) /* 569 */, + W64LIT(0xC5A5876D0BA61938) /* 570 */, W64LIT(0x16B9FA1FA58FD840) /* 571 */, + W64LIT(0x188AB1173CA74F18) /* 572 */, W64LIT(0xABDA2F98C99C021F) /* 573 */, + W64LIT(0x3E0580AB134AE816) /* 574 */, W64LIT(0x5F3B05B773645ABB) /* 575 */, + W64LIT(0x2501A2BE5575F2F6) /* 576 */, W64LIT(0x1B2F74004E7E8BA9) /* 577 */, + W64LIT(0x1CD7580371E8D953) /* 578 */, W64LIT(0x7F6ED89562764E30) /* 579 */, + W64LIT(0xB15926FF596F003D) /* 580 */, W64LIT(0x9F65293DA8C5D6B9) /* 581 */, + W64LIT(0x6ECEF04DD690F84C) /* 582 */, W64LIT(0x4782275FFF33AF88) /* 583 */, + W64LIT(0xE41433083F820801) /* 584 */, W64LIT(0xFD0DFE409A1AF9B5) /* 585 */, + W64LIT(0x4325A3342CDB396B) /* 586 */, W64LIT(0x8AE77E62B301B252) /* 587 */, + W64LIT(0xC36F9E9F6655615A) /* 588 */, W64LIT(0x85455A2D92D32C09) /* 589 */, + W64LIT(0xF2C7DEA949477485) /* 590 */, W64LIT(0x63CFB4C133A39EBA) /* 591 */, + W64LIT(0x83B040CC6EBC5462) /* 592 */, W64LIT(0x3B9454C8FDB326B0) /* 593 */, + W64LIT(0x56F56A9E87FFD78C) /* 594 */, W64LIT(0x2DC2940D99F42BC6) /* 595 */, + W64LIT(0x98F7DF096B096E2D) /* 596 */, W64LIT(0x19A6E01E3AD852BF) /* 597 */, + W64LIT(0x42A99CCBDBD4B40B) /* 598 */, W64LIT(0xA59998AF45E9C559) /* 599 */, + W64LIT(0x366295E807D93186) /* 600 */, W64LIT(0x6B48181BFAA1F773) /* 601 */, + W64LIT(0x1FEC57E2157A0A1D) /* 602 */, W64LIT(0x4667446AF6201AD5) /* 603 */, + W64LIT(0xE615EBCACFB0F075) /* 604 */, W64LIT(0xB8F31F4F68290778) /* 605 */, + W64LIT(0x22713ED6CE22D11E) /* 606 */, W64LIT(0x3057C1A72EC3C93B) /* 607 */, + W64LIT(0xCB46ACC37C3F1F2F) /* 608 */, W64LIT(0xDBB893FD02AAF50E) /* 609 */, + W64LIT(0x331FD92E600B9FCF) /* 610 */, W64LIT(0xA498F96148EA3AD6) /* 611 */, + W64LIT(0xA8D8426E8B6A83EA) /* 612 */, W64LIT(0xA089B274B7735CDC) /* 613 */, + W64LIT(0x87F6B3731E524A11) /* 614 */, W64LIT(0x118808E5CBC96749) /* 615 */, + W64LIT(0x9906E4C7B19BD394) /* 616 */, W64LIT(0xAFED7F7E9B24A20C) /* 617 */, + W64LIT(0x6509EADEEB3644A7) /* 618 */, W64LIT(0x6C1EF1D3E8EF0EDE) /* 619 */, + W64LIT(0xB9C97D43E9798FB4) /* 620 */, W64LIT(0xA2F2D784740C28A3) /* 621 */, + W64LIT(0x7B8496476197566F) /* 622 */, W64LIT(0x7A5BE3E6B65F069D) /* 623 */, + W64LIT(0xF96330ED78BE6F10) /* 624 */, W64LIT(0xEEE60DE77A076A15) /* 625 */, + W64LIT(0x2B4BEE4AA08B9BD0) /* 626 */, W64LIT(0x6A56A63EC7B8894E) /* 627 */, + W64LIT(0x02121359BA34FEF4) /* 628 */, W64LIT(0x4CBF99F8283703FC) /* 629 */, + W64LIT(0x398071350CAF30C8) /* 630 */, W64LIT(0xD0A77A89F017687A) /* 631 */, + W64LIT(0xF1C1A9EB9E423569) /* 632 */, W64LIT(0x8C7976282DEE8199) /* 633 */, + W64LIT(0x5D1737A5DD1F7ABD) /* 634 */, W64LIT(0x4F53433C09A9FA80) /* 635 */, + W64LIT(0xFA8B0C53DF7CA1D9) /* 636 */, W64LIT(0x3FD9DCBC886CCB77) /* 637 */, + W64LIT(0xC040917CA91B4720) /* 638 */, W64LIT(0x7DD00142F9D1DCDF) /* 639 */, + W64LIT(0x8476FC1D4F387B58) /* 640 */, W64LIT(0x23F8E7C5F3316503) /* 641 */, + W64LIT(0x032A2244E7E37339) /* 642 */, W64LIT(0x5C87A5D750F5A74B) /* 643 */, + W64LIT(0x082B4CC43698992E) /* 644 */, W64LIT(0xDF917BECB858F63C) /* 645 */, + W64LIT(0x3270B8FC5BF86DDA) /* 646 */, W64LIT(0x10AE72BB29B5DD76) /* 647 */, + W64LIT(0x576AC94E7700362B) /* 648 */, W64LIT(0x1AD112DAC61EFB8F) /* 649 */, + W64LIT(0x691BC30EC5FAA427) /* 650 */, W64LIT(0xFF246311CC327143) /* 651 */, + W64LIT(0x3142368E30E53206) /* 652 */, W64LIT(0x71380E31E02CA396) /* 653 */, + W64LIT(0x958D5C960AAD76F1) /* 654 */, W64LIT(0xF8D6F430C16DA536) /* 655 */, + W64LIT(0xC8FFD13F1BE7E1D2) /* 656 */, W64LIT(0x7578AE66004DDBE1) /* 657 */, + W64LIT(0x05833F01067BE646) /* 658 */, W64LIT(0xBB34B5AD3BFE586D) /* 659 */, + W64LIT(0x095F34C9A12B97F0) /* 660 */, W64LIT(0x247AB64525D60CA8) /* 661 */, + W64LIT(0xDCDBC6F3017477D1) /* 662 */, W64LIT(0x4A2E14D4DECAD24D) /* 663 */, + W64LIT(0xBDB5E6D9BE0A1EEB) /* 664 */, W64LIT(0x2A7E70F7794301AB) /* 665 */, + W64LIT(0xDEF42D8A270540FD) /* 666 */, W64LIT(0x01078EC0A34C22C1) /* 667 */, + W64LIT(0xE5DE511AF4C16387) /* 668 */, W64LIT(0x7EBB3A52BD9A330A) /* 669 */, + W64LIT(0x77697857AA7D6435) /* 670 */, W64LIT(0x004E831603AE4C32) /* 671 */, + W64LIT(0xE7A21020AD78E312) /* 672 */, W64LIT(0x9D41A70C6AB420F2) /* 673 */, + W64LIT(0x28E06C18EA1141E6) /* 674 */, W64LIT(0xD2B28CBD984F6B28) /* 675 */, + W64LIT(0x26B75F6C446E9D83) /* 676 */, W64LIT(0xBA47568C4D418D7F) /* 677 */, + W64LIT(0xD80BADBFE6183D8E) /* 678 */, W64LIT(0x0E206D7F5F166044) /* 679 */, + W64LIT(0xE258A43911CBCA3E) /* 680 */, W64LIT(0x723A1746B21DC0BC) /* 681 */, + W64LIT(0xC7CAA854F5D7CDD3) /* 682 */, W64LIT(0x7CAC32883D261D9C) /* 683 */, + W64LIT(0x7690C26423BA942C) /* 684 */, W64LIT(0x17E55524478042B8) /* 685 */, + W64LIT(0xE0BE477656A2389F) /* 686 */, W64LIT(0x4D289B5E67AB2DA0) /* 687 */, + W64LIT(0x44862B9C8FBBFD31) /* 688 */, W64LIT(0xB47CC8049D141365) /* 689 */, + W64LIT(0x822C1B362B91C793) /* 690 */, W64LIT(0x4EB14655FB13DFD8) /* 691 */, + W64LIT(0x1ECBBA0714E2A97B) /* 692 */, W64LIT(0x6143459D5CDE5F14) /* 693 */, + W64LIT(0x53A8FBF1D5F0AC89) /* 694 */, W64LIT(0x97EA04D81C5E5B00) /* 695 */, + W64LIT(0x622181A8D4FDB3F3) /* 696 */, W64LIT(0xE9BCD341572A1208) /* 697 */, + W64LIT(0x1411258643CCE58A) /* 698 */, W64LIT(0x9144C5FEA4C6E0A4) /* 699 */, + W64LIT(0x0D33D06565CF620F) /* 700 */, W64LIT(0x54A48D489F219CA1) /* 701 */, + W64LIT(0xC43E5EAC6D63C821) /* 702 */, W64LIT(0xA9728B3A72770DAF) /* 703 */, + W64LIT(0xD7934E7B20DF87EF) /* 704 */, W64LIT(0xE35503B61A3E86E5) /* 705 */, + W64LIT(0xCAE321FBC819D504) /* 706 */, W64LIT(0x129A50B3AC60BFA6) /* 707 */, + W64LIT(0xCD5E68EA7E9FB6C3) /* 708 */, W64LIT(0xB01C90199483B1C7) /* 709 */, + W64LIT(0x3DE93CD5C295376C) /* 710 */, W64LIT(0xAED52EDF2AB9AD13) /* 711 */, + W64LIT(0x2E60F512C0A07884) /* 712 */, W64LIT(0xBC3D86A3E36210C9) /* 713 */, + W64LIT(0x35269D9B163951CE) /* 714 */, W64LIT(0x0C7D6E2AD0CDB5FA) /* 715 */, + W64LIT(0x59E86297D87F5733) /* 716 */, W64LIT(0x298EF221898DB0E7) /* 717 */, + W64LIT(0x55000029D1A5AA7E) /* 718 */, W64LIT(0x8BC08AE1B5061B45) /* 719 */, + W64LIT(0xC2C31C2B6C92703A) /* 720 */, W64LIT(0x94CC596BAF25EF42) /* 721 */, + W64LIT(0x0A1D73DB22540456) /* 722 */, W64LIT(0x04B6A0F9D9C4179A) /* 723 */, + W64LIT(0xEFFDAFA2AE3D3C60) /* 724 */, W64LIT(0xF7C8075BB49496C4) /* 725 */, + W64LIT(0x9CC5C7141D1CD4E3) /* 726 */, W64LIT(0x78BD1638218E5534) /* 727 */, + W64LIT(0xB2F11568F850246A) /* 728 */, W64LIT(0xEDFABCFA9502BC29) /* 729 */, + W64LIT(0x796CE5F2DA23051B) /* 730 */, W64LIT(0xAAE128B0DC93537C) /* 731 */, + W64LIT(0x3A493DA0EE4B29AE) /* 732 */, W64LIT(0xB5DF6B2C416895D7) /* 733 */, + W64LIT(0xFCABBD25122D7F37) /* 734 */, W64LIT(0x70810B58105DC4B1) /* 735 */, + W64LIT(0xE10FDD37F7882A90) /* 736 */, W64LIT(0x524DCAB5518A3F5C) /* 737 */, + W64LIT(0x3C9E85878451255B) /* 738 */, W64LIT(0x4029828119BD34E2) /* 739 */, + W64LIT(0x74A05B6F5D3CECCB) /* 740 */, W64LIT(0xB610021542E13ECA) /* 741 */, + W64LIT(0x0FF979D12F59E2AC) /* 742 */, W64LIT(0x6037DA27E4F9CC50) /* 743 */, + W64LIT(0x5E92975A0DF1847D) /* 744 */, W64LIT(0xD66DE190D3E623FE) /* 745 */, + W64LIT(0x5032D6B87B568048) /* 746 */, W64LIT(0x9A36B7CE8235216E) /* 747 */, + W64LIT(0x80272A7A24F64B4A) /* 748 */, W64LIT(0x93EFED8B8C6916F7) /* 749 */, + W64LIT(0x37DDBFF44CCE1555) /* 750 */, W64LIT(0x4B95DB5D4B99BD25) /* 751 */, + W64LIT(0x92D3FDA169812FC0) /* 752 */, W64LIT(0xFB1A4A9A90660BB6) /* 753 */, + W64LIT(0x730C196946A4B9B2) /* 754 */, W64LIT(0x81E289AA7F49DA68) /* 755 */, + W64LIT(0x64669A0F83B1A05F) /* 756 */, W64LIT(0x27B3FF7D9644F48B) /* 757 */, + W64LIT(0xCC6B615C8DB675B3) /* 758 */, W64LIT(0x674F20B9BCEBBE95) /* 759 */, + W64LIT(0x6F31238275655982) /* 760 */, W64LIT(0x5AE488713E45CF05) /* 761 */, + W64LIT(0xBF619F9954C21157) /* 762 */, W64LIT(0xEABAC46040A8EAE9) /* 763 */, + W64LIT(0x454C6FE9F2C0C1CD) /* 764 */, W64LIT(0x419CF6496412691C) /* 765 */, + W64LIT(0xD3DC3BEF265B0F70) /* 766 */, W64LIT(0x6D0E60F5C3578A9E) /* 767 */, + W64LIT(0x5B0E608526323C55) /* 768 */, W64LIT(0x1A46C1A9FA1B59F5) /* 769 */, + W64LIT(0xA9E245A17C4C8FFA) /* 770 */, W64LIT(0x65CA5159DB2955D7) /* 771 */, + W64LIT(0x05DB0A76CE35AFC2) /* 772 */, W64LIT(0x81EAC77EA9113D45) /* 773 */, + W64LIT(0x528EF88AB6AC0A0D) /* 774 */, W64LIT(0xA09EA253597BE3FF) /* 775 */, + W64LIT(0x430DDFB3AC48CD56) /* 776 */, W64LIT(0xC4B3A67AF45CE46F) /* 777 */, + W64LIT(0x4ECECFD8FBE2D05E) /* 778 */, W64LIT(0x3EF56F10B39935F0) /* 779 */, + W64LIT(0x0B22D6829CD619C6) /* 780 */, W64LIT(0x17FD460A74DF2069) /* 781 */, + W64LIT(0x6CF8CC8E8510ED40) /* 782 */, W64LIT(0xD6C824BF3A6ECAA7) /* 783 */, + W64LIT(0x61243D581A817049) /* 784 */, W64LIT(0x048BACB6BBC163A2) /* 785 */, + W64LIT(0xD9A38AC27D44CC32) /* 786 */, W64LIT(0x7FDDFF5BAAF410AB) /* 787 */, + W64LIT(0xAD6D495AA804824B) /* 788 */, W64LIT(0xE1A6A74F2D8C9F94) /* 789 */, + W64LIT(0xD4F7851235DEE8E3) /* 790 */, W64LIT(0xFD4B7F886540D893) /* 791 */, + W64LIT(0x247C20042AA4BFDA) /* 792 */, W64LIT(0x096EA1C517D1327C) /* 793 */, + W64LIT(0xD56966B4361A6685) /* 794 */, W64LIT(0x277DA5C31221057D) /* 795 */, + W64LIT(0x94D59893A43ACFF7) /* 796 */, W64LIT(0x64F0C51CCDC02281) /* 797 */, + W64LIT(0x3D33BCC4FF6189DB) /* 798 */, W64LIT(0xE005CB184CE66AF1) /* 799 */, + W64LIT(0xFF5CCD1D1DB99BEA) /* 800 */, W64LIT(0xB0B854A7FE42980F) /* 801 */, + W64LIT(0x7BD46A6A718D4B9F) /* 802 */, W64LIT(0xD10FA8CC22A5FD8C) /* 803 */, + W64LIT(0xD31484952BE4BD31) /* 804 */, W64LIT(0xC7FA975FCB243847) /* 805 */, + W64LIT(0x4886ED1E5846C407) /* 806 */, W64LIT(0x28CDDB791EB70B04) /* 807 */, + W64LIT(0xC2B00BE2F573417F) /* 808 */, W64LIT(0x5C9590452180F877) /* 809 */, + W64LIT(0x7A6BDDFFF370EB00) /* 810 */, W64LIT(0xCE509E38D6D9D6A4) /* 811 */, + W64LIT(0xEBEB0F00647FA702) /* 812 */, W64LIT(0x1DCC06CF76606F06) /* 813 */, + W64LIT(0xE4D9F28BA286FF0A) /* 814 */, W64LIT(0xD85A305DC918C262) /* 815 */, + W64LIT(0x475B1D8732225F54) /* 816 */, W64LIT(0x2D4FB51668CCB5FE) /* 817 */, + W64LIT(0xA679B9D9D72BBA20) /* 818 */, W64LIT(0x53841C0D912D43A5) /* 819 */, + W64LIT(0x3B7EAA48BF12A4E8) /* 820 */, W64LIT(0x781E0E47F22F1DDF) /* 821 */, + W64LIT(0xEFF20CE60AB50973) /* 822 */, W64LIT(0x20D261D19DFFB742) /* 823 */, + W64LIT(0x16A12B03062A2E39) /* 824 */, W64LIT(0x1960EB2239650495) /* 825 */, + W64LIT(0x251C16FED50EB8B8) /* 826 */, W64LIT(0x9AC0C330F826016E) /* 827 */, + W64LIT(0xED152665953E7671) /* 828 */, W64LIT(0x02D63194A6369570) /* 829 */, + W64LIT(0x5074F08394B1C987) /* 830 */, W64LIT(0x70BA598C90B25CE1) /* 831 */, + W64LIT(0x794A15810B9742F6) /* 832 */, W64LIT(0x0D5925E9FCAF8C6C) /* 833 */, + W64LIT(0x3067716CD868744E) /* 834 */, W64LIT(0x910AB077E8D7731B) /* 835 */, + W64LIT(0x6A61BBDB5AC42F61) /* 836 */, W64LIT(0x93513EFBF0851567) /* 837 */, + W64LIT(0xF494724B9E83E9D5) /* 838 */, W64LIT(0xE887E1985C09648D) /* 839 */, + W64LIT(0x34B1D3C675370CFD) /* 840 */, W64LIT(0xDC35E433BC0D255D) /* 841 */, + W64LIT(0xD0AAB84234131BE0) /* 842 */, W64LIT(0x08042A50B48B7EAF) /* 843 */, + W64LIT(0x9997C4EE44A3AB35) /* 844 */, W64LIT(0x829A7B49201799D0) /* 845 */, + W64LIT(0x263B8307B7C54441) /* 846 */, W64LIT(0x752F95F4FD6A6CA6) /* 847 */, + W64LIT(0x927217402C08C6E5) /* 848 */, W64LIT(0x2A8AB754A795D9EE) /* 849 */, + W64LIT(0xA442F7552F72943D) /* 850 */, W64LIT(0x2C31334E19781208) /* 851 */, + W64LIT(0x4FA98D7CEAEE6291) /* 852 */, W64LIT(0x55C3862F665DB309) /* 853 */, + W64LIT(0xBD0610175D53B1F3) /* 854 */, W64LIT(0x46FE6CB840413F27) /* 855 */, + W64LIT(0x3FE03792DF0CFA59) /* 856 */, W64LIT(0xCFE700372EB85E8F) /* 857 */, + W64LIT(0xA7BE29E7ADBCE118) /* 858 */, W64LIT(0xE544EE5CDE8431DD) /* 859 */, + W64LIT(0x8A781B1B41F1873E) /* 860 */, W64LIT(0xA5C94C78A0D2F0E7) /* 861 */, + W64LIT(0x39412E2877B60728) /* 862 */, W64LIT(0xA1265EF3AFC9A62C) /* 863 */, + W64LIT(0xBCC2770C6A2506C5) /* 864 */, W64LIT(0x3AB66DD5DCE1CE12) /* 865 */, + W64LIT(0xE65499D04A675B37) /* 866 */, W64LIT(0x7D8F523481BFD216) /* 867 */, + W64LIT(0x0F6F64FCEC15F389) /* 868 */, W64LIT(0x74EFBE618B5B13C8) /* 869 */, + W64LIT(0xACDC82B714273E1D) /* 870 */, W64LIT(0xDD40BFE003199D17) /* 871 */, + W64LIT(0x37E99257E7E061F8) /* 872 */, W64LIT(0xFA52626904775AAA) /* 873 */, + W64LIT(0x8BBBF63A463D56F9) /* 874 */, W64LIT(0xF0013F1543A26E64) /* 875 */, + W64LIT(0xA8307E9F879EC898) /* 876 */, W64LIT(0xCC4C27A4150177CC) /* 877 */, + W64LIT(0x1B432F2CCA1D3348) /* 878 */, W64LIT(0xDE1D1F8F9F6FA013) /* 879 */, + W64LIT(0x606602A047A7DDD6) /* 880 */, W64LIT(0xD237AB64CC1CB2C7) /* 881 */, + W64LIT(0x9B938E7225FCD1D3) /* 882 */, W64LIT(0xEC4E03708E0FF476) /* 883 */, + W64LIT(0xFEB2FBDA3D03C12D) /* 884 */, W64LIT(0xAE0BCED2EE43889A) /* 885 */, + W64LIT(0x22CB8923EBFB4F43) /* 886 */, W64LIT(0x69360D013CF7396D) /* 887 */, + W64LIT(0x855E3602D2D4E022) /* 888 */, W64LIT(0x073805BAD01F784C) /* 889 */, + W64LIT(0x33E17A133852F546) /* 890 */, W64LIT(0xDF4874058AC7B638) /* 891 */, + W64LIT(0xBA92B29C678AA14A) /* 892 */, W64LIT(0x0CE89FC76CFAADCD) /* 893 */, + W64LIT(0x5F9D4E0908339E34) /* 894 */, W64LIT(0xF1AFE9291F5923B9) /* 895 */, + W64LIT(0x6E3480F60F4A265F) /* 896 */, W64LIT(0xEEBF3A2AB29B841C) /* 897 */, + W64LIT(0xE21938A88F91B4AD) /* 898 */, W64LIT(0x57DFEFF845C6D3C3) /* 899 */, + W64LIT(0x2F006B0BF62CAAF2) /* 900 */, W64LIT(0x62F479EF6F75EE78) /* 901 */, + W64LIT(0x11A55AD41C8916A9) /* 902 */, W64LIT(0xF229D29084FED453) /* 903 */, + W64LIT(0x42F1C27B16B000E6) /* 904 */, W64LIT(0x2B1F76749823C074) /* 905 */, + W64LIT(0x4B76ECA3C2745360) /* 906 */, W64LIT(0x8C98F463B91691BD) /* 907 */, + W64LIT(0x14BCC93CF1ADE66A) /* 908 */, W64LIT(0x8885213E6D458397) /* 909 */, + W64LIT(0x8E177DF0274D4711) /* 910 */, W64LIT(0xB49B73B5503F2951) /* 911 */, + W64LIT(0x10168168C3F96B6B) /* 912 */, W64LIT(0x0E3D963B63CAB0AE) /* 913 */, + W64LIT(0x8DFC4B5655A1DB14) /* 914 */, W64LIT(0xF789F1356E14DE5C) /* 915 */, + W64LIT(0x683E68AF4E51DAC1) /* 916 */, W64LIT(0xC9A84F9D8D4B0FD9) /* 917 */, + W64LIT(0x3691E03F52A0F9D1) /* 918 */, W64LIT(0x5ED86E46E1878E80) /* 919 */, + W64LIT(0x3C711A0E99D07150) /* 920 */, W64LIT(0x5A0865B20C4E9310) /* 921 */, + W64LIT(0x56FBFC1FE4F0682E) /* 922 */, W64LIT(0xEA8D5DE3105EDF9B) /* 923 */, + W64LIT(0x71ABFDB12379187A) /* 924 */, W64LIT(0x2EB99DE1BEE77B9C) /* 925 */, + W64LIT(0x21ECC0EA33CF4523) /* 926 */, W64LIT(0x59A4D7521805C7A1) /* 927 */, + W64LIT(0x3896F5EB56AE7C72) /* 928 */, W64LIT(0xAA638F3DB18F75DC) /* 929 */, + W64LIT(0x9F39358DABE9808E) /* 930 */, W64LIT(0xB7DEFA91C00B72AC) /* 931 */, + W64LIT(0x6B5541FD62492D92) /* 932 */, W64LIT(0x6DC6DEE8F92E4D5B) /* 933 */, + W64LIT(0x353F57ABC4BEEA7E) /* 934 */, W64LIT(0x735769D6DA5690CE) /* 935 */, + W64LIT(0x0A234AA642391484) /* 936 */, W64LIT(0xF6F9508028F80D9D) /* 937 */, + W64LIT(0xB8E319A27AB3F215) /* 938 */, W64LIT(0x31AD9C1151341A4D) /* 939 */, + W64LIT(0x773C22A57BEF5805) /* 940 */, W64LIT(0x45C7561A07968633) /* 941 */, + W64LIT(0xF913DA9E249DBE36) /* 942 */, W64LIT(0xDA652D9B78A64C68) /* 943 */, + W64LIT(0x4C27A97F3BC334EF) /* 944 */, W64LIT(0x76621220E66B17F4) /* 945 */, + W64LIT(0x967743899ACD7D0B) /* 946 */, W64LIT(0xF3EE5BCAE0ED6782) /* 947 */, + W64LIT(0x409F753600C879FC) /* 948 */, W64LIT(0x06D09A39B5926DB6) /* 949 */, + W64LIT(0x6F83AEB0317AC588) /* 950 */, W64LIT(0x01E6CA4A86381F21) /* 951 */, + W64LIT(0x66FF3462D19F3025) /* 952 */, W64LIT(0x72207C24DDFD3BFB) /* 953 */, + W64LIT(0x4AF6B6D3E2ECE2EB) /* 954 */, W64LIT(0x9C994DBEC7EA08DE) /* 955 */, + W64LIT(0x49ACE597B09A8BC4) /* 956 */, W64LIT(0xB38C4766CF0797BA) /* 957 */, + W64LIT(0x131B9373C57C2A75) /* 958 */, W64LIT(0xB1822CCE61931E58) /* 959 */, + W64LIT(0x9D7555B909BA1C0C) /* 960 */, W64LIT(0x127FAFDD937D11D2) /* 961 */, + W64LIT(0x29DA3BADC66D92E4) /* 962 */, W64LIT(0xA2C1D57154C2ECBC) /* 963 */, + W64LIT(0x58C5134D82F6FE24) /* 964 */, W64LIT(0x1C3AE3515B62274F) /* 965 */, + W64LIT(0xE907C82E01CB8126) /* 966 */, W64LIT(0xF8ED091913E37FCB) /* 967 */, + W64LIT(0x3249D8F9C80046C9) /* 968 */, W64LIT(0x80CF9BEDE388FB63) /* 969 */, + W64LIT(0x1881539A116CF19E) /* 970 */, W64LIT(0x5103F3F76BD52457) /* 971 */, + W64LIT(0x15B7E6F5AE47F7A8) /* 972 */, W64LIT(0xDBD7C6DED47E9CCF) /* 973 */, + W64LIT(0x44E55C410228BB1A) /* 974 */, W64LIT(0xB647D4255EDB4E99) /* 975 */, + W64LIT(0x5D11882BB8AAFC30) /* 976 */, W64LIT(0xF5098BBB29D3212A) /* 977 */, + W64LIT(0x8FB5EA14E90296B3) /* 978 */, W64LIT(0x677B942157DD025A) /* 979 */, + W64LIT(0xFB58E7C0A390ACB5) /* 980 */, W64LIT(0x89D3674C83BD4A01) /* 981 */, + W64LIT(0x9E2DA4DF4BF3B93B) /* 982 */, W64LIT(0xFCC41E328CAB4829) /* 983 */, + W64LIT(0x03F38C96BA582C52) /* 984 */, W64LIT(0xCAD1BDBD7FD85DB2) /* 985 */, + W64LIT(0xBBB442C16082AE83) /* 986 */, W64LIT(0xB95FE86BA5DA9AB0) /* 987 */, + W64LIT(0xB22E04673771A93F) /* 988 */, W64LIT(0x845358C9493152D8) /* 989 */, + W64LIT(0xBE2A488697B4541E) /* 990 */, W64LIT(0x95A2DC2DD38E6966) /* 991 */, + W64LIT(0xC02C11AC923C852B) /* 992 */, W64LIT(0x2388B1990DF2A87B) /* 993 */, + W64LIT(0x7C8008FA1B4F37BE) /* 994 */, W64LIT(0x1F70D0C84D54E503) /* 995 */, + W64LIT(0x5490ADEC7ECE57D4) /* 996 */, W64LIT(0x002B3C27D9063A3A) /* 997 */, + W64LIT(0x7EAEA3848030A2BF) /* 998 */, W64LIT(0xC602326DED2003C0) /* 999 */, + W64LIT(0x83A7287D69A94086) /* 1000 */, W64LIT(0xC57A5FCB30F57A8A) /* 1001 */, + W64LIT(0xB56844E479EBE779) /* 1002 */, W64LIT(0xA373B40F05DCBCE9) /* 1003 */, + W64LIT(0xD71A786E88570EE2) /* 1004 */, W64LIT(0x879CBACDBDE8F6A0) /* 1005 */, + W64LIT(0x976AD1BCC164A32F) /* 1006 */, W64LIT(0xAB21E25E9666D78B) /* 1007 */, + W64LIT(0x901063AAE5E5C33C) /* 1008 */, W64LIT(0x9818B34448698D90) /* 1009 */, + W64LIT(0xE36487AE3E1E8ABB) /* 1010 */, W64LIT(0xAFBDF931893BDCB4) /* 1011 */, + W64LIT(0x6345A0DC5FBBD519) /* 1012 */, W64LIT(0x8628FE269B9465CA) /* 1013 */, + W64LIT(0x1E5D01603F9C51EC) /* 1014 */, W64LIT(0x4DE44006A15049B7) /* 1015 */, + W64LIT(0xBF6C70E5F776CBB1) /* 1016 */, W64LIT(0x411218F2EF552BED) /* 1017 */, + W64LIT(0xCB0C0708705A36A3) /* 1018 */, W64LIT(0xE74D14754F986044) /* 1019 */, + W64LIT(0xCD56D9430EA8280E) /* 1020 */, W64LIT(0xC12591D7535F5065) /* 1021 */, + W64LIT(0xC83223F1720AEF96) /* 1022 */, W64LIT(0xC3A0396F7363A51F) /* 1023 */, + W64LIT(0xffffffffffffffff), + W64LIT(0xA5A5A5A5A5A5A5A5), + W64LIT(0x0123456789ABCDEF), +}; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/trap.h b/external/ours/library/crypto/src/shared/original/trap.h new file mode 100755 index 000000000..15360b562 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/trap.h @@ -0,0 +1,163 @@ +// trap.h - written and placed in public domain by Jeffrey Walton. + +/// \file trap.h +/// \brief Debugging and diagnostic assertions +/// \details CRYPTOPP_ASSERT is the library's debugging and diagnostic +/// assertion. CRYPTOPP_ASSERT is enabled by CRYPTOPP_DEBUG, +/// DEBUG or _DEBUG. +/// \details CRYPTOPP_ASSERT raises a SIGTRAP (Unix) or calls +/// DebugBreak() (Windows). +/// \details CRYPTOPP_ASSERT is only in effect when the user requests a +/// debug configuration. NDEBUG (or failure to define it) does not +/// affect CRYPTOPP_ASSERT. +/// \since Crypto++ 5.6.5 +/// \sa DebugTrapHandler, Issue 277, +/// CVE-2016-7420 + +#ifndef CRYPTOPP_TRAP_H +#define CRYPTOPP_TRAP_H + +#include "config.h" + +#if defined(CRYPTOPP_DEBUG) +# include +# include +# if defined(UNIX_SIGNALS_AVAILABLE) +# include "ossig.h" +# elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(__CYGWIN__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); +# endif +#endif // CRYPTOPP_DEBUG + +// ************** run-time assertion *************** + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Debugging and diagnostic assertion +/// \details CRYPTOPP_ASSERT is the library's debugging and diagnostic +/// assertion. CRYPTOPP_ASSERT is enabled by the preprocessor macros +/// CRYPTOPP_DEBUG, DEBUG or _DEBUG. +/// \details CRYPTOPP_ASSERT raises a SIGTRAP (Unix) or calls +/// DebugBreak() (Windows). CRYPTOPP_ASSERT is only in effect +/// when the user explicitly requests a debug configuration. +/// \details If you want to ensure CRYPTOPP_ASSERT is inert, then do +/// not define CRYPTOPP_DEBUG, DEBUG or _DEBUG. +/// Avoiding the defines means CRYPTOPP_ASSERT is preprocessed into an +/// empty string. +/// \details The traditional Posix define NDEBUG has no effect on +/// CRYPTOPP_DEBUG, CRYPTOPP_ASSERT or DebugTrapHandler. +/// \details An example of using CRYPTOPP_ASSERT and DebugTrapHandler is shown +/// below. The library's test program, cryptest.exe (from test.cpp), +/// exercises the structure: +///
+///   \#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
+///   static const DebugTrapHandler g_dummyHandler;
+///   \#endif
+///
+///   int main(int argc, char* argv[])
+///   {
+///      CRYPTOPP_ASSERT(argv != nullptr);
+///      ...
+///   }
+///  
+/// \since Crypto++ 5.6.5 +/// \sa DebugTrapHandler, SignalHandler, Issue 277, +/// CVE-2016-7420 +# define CRYPTOPP_ASSERT(exp) { ... } +#endif + +#if defined(CRYPTOPP_DEBUG) +# if defined(UNIX_SIGNALS_AVAILABLE) || defined(__CYGWIN__) +# define CRYPTOPP_ASSERT(exp) { \ + if (!(exp)) { \ + std::ostringstream oss; \ + oss << "Assertion failed: " << __FILE__ << "(" \ + << __LINE__ << "): " << __func__ \ + << std::endl; \ + std::cout << std::flush; \ + std::cerr << oss.str(); \ + raise(SIGTRAP); \ + } \ + } +# elif CRYPTOPP_DEBUG && defined(CRYPTOPP_WIN32_AVAILABLE) +# define CRYPTOPP_ASSERT(exp) { \ + if (!(exp)) { \ + std::ostringstream oss; \ + oss << "Assertion failed: " << __FILE__ << "(" \ + << __LINE__ << "): " << __FUNCTION__ \ + << std::endl; \ + std::cout << std::flush; \ + std::cerr << oss.str(); \ + if (IsDebuggerPresent()) {DebugBreak();} \ + } \ + } +# endif // Unix or Windows +#endif // CRYPTOPP_DEBUG + +// Remove CRYPTOPP_ASSERT in non-debug builds. +#ifndef CRYPTOPP_ASSERT +# define CRYPTOPP_ASSERT(exp) (void)0 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// ************** SIGTRAP handler *************** + +#if (CRYPTOPP_DEBUG && defined(UNIX_SIGNALS_AVAILABLE)) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +/// \brief Default SIGTRAP handler +/// \details DebugTrapHandler() can be used by a program to install an empty +/// SIGTRAP handler. If present, the handler ensures there is a signal +/// handler in place for SIGTRAP raised by +/// CRYPTOPP_ASSERT. If CRYPTOPP_ASSERT raises +/// SIGTRAP without a handler, then one of two things can +/// occur. First, the OS might allow the program to continue. Second, the OS +/// might terminate the program. OS X allows the program to continue, while +/// some Linuxes terminate the program. +/// \details If DebugTrapHandler detects another handler in place, then it will +/// not install a handler. This ensures a debugger can gain control of the +/// SIGTRAP signal without contention. It also allows multiple +/// DebugTrapHandler to be created without contentious or unusual behavior. +/// Though multiple DebugTrapHandler can be created, a program should only +/// create one, if needed. +/// \details A DebugTrapHandler is subject to C++ static initialization +/// [dis]order. If you need to install a handler and it must be installed +/// early, then reference the code associated with +/// CRYPTOPP_INIT_PRIORITY in cryptlib.cpp and cpu.cpp. +/// \details If you want to ensure CRYPTOPP_ASSERT is inert, then +/// do not define CRYPTOPP_DEBUG, DEBUG or +/// _DEBUG. Avoiding the defines means CRYPTOPP_ASSERT +/// is processed into ((void)0). +/// \details The traditional Posix define NDEBUG has no effect on +/// CRYPTOPP_DEBUG, CRYPTOPP_ASSERT or DebugTrapHandler. +/// \details An example of using \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT" and +/// DebugTrapHandler is shown below. The library's test program, +/// cryptest.exe (from test.cpp), exercises the structure: +///
+///   \#if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
+///   const DebugTrapHandler g_dummyHandler;
+///   \#endif
+///
+///   int main(int argc, char* argv[])
+///   {
+///      CRYPTOPP_ASSERT(argv != nullptr);
+///      ...
+///   }
+///  
+/// \since Crypto++ 5.6.5 +/// \sa \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", SignalHandler, Issue 277, +/// CVE-2016-7420 + +#if defined(CRYPTOPP_DOXYGEN_PROCESSING) +class DebugTrapHandler : public SignalHandler { }; +#else +typedef SignalHandler DebugTrapHandler; +#endif + +#endif // Linux, Unix and Documentation + +NAMESPACE_END + +#endif // CRYPTOPP_TRAP_H diff --git a/external/ours/library/crypto/src/shared/original/trunhash.h b/external/ours/library/crypto/src/shared/original/trunhash.h new file mode 100755 index 000000000..36df5bebe --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/trunhash.h @@ -0,0 +1,63 @@ +// trunhash.h - originally written and placed in the public domain by Wei Dai + +/// \file trunhash.h +/// \brief Classes for truncated hashes + +#ifndef CRYPTOPP_TRUNHASH_H +#define CRYPTOPP_TRUNHASH_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Null hash +/// \details A null hash that conforms to HashTransformation interface +class NullHash : public HashTransformation +{ +public: + void Update(const byte *input, size_t length) + {CRYPTOPP_UNUSED(input);CRYPTOPP_UNUSED(length);} + unsigned int DigestSize() const + {return 0;} + void TruncatedFinal(byte *digest, size_t digestSize) + {CRYPTOPP_UNUSED(digest);CRYPTOPP_UNUSED(digestSize);} + bool TruncatedVerify(const byte *digest, size_t digestLength) + {CRYPTOPP_UNUSED(digest);CRYPTOPP_UNUSED(digestLength);return true;} +}; + +/// \brief Construct new HashModule with smaller digest size from an existing one +/// \tparam T HashTransformation derived class +template +class TruncatedHashTemplate : public HashTransformation +{ +public: + /// \brief Construct a TruncatedHashTemplate + TruncatedHashTemplate(T hm, unsigned int digestSize) + : m_hm(hm), m_digestSize(digestSize) {} + /// \brief Construct a TruncatedHashTemplate + TruncatedHashTemplate(const byte *key, size_t keyLength, unsigned int digestSize) + : m_hm(key, keyLength), m_digestSize(digestSize) {} + /// \brief Construct a TruncatedHashTemplate + TruncatedHashTemplate(size_t digestSize) + : m_digestSize(digestSize) {} + + void Restart() + {m_hm.Restart();} + void Update(const byte *input, size_t length) + {m_hm.Update(input, length);} + unsigned int DigestSize() const {return m_digestSize;} + void TruncatedFinal(byte *digest, size_t digestSize) + {m_hm.TruncatedFinal(digest, digestSize);} + bool TruncatedVerify(const byte *digest, size_t digestLength) + {return m_hm.TruncatedVerify(digest, digestLength);} + +private: + T m_hm; + unsigned int m_digestSize; +}; + +typedef TruncatedHashTemplate TruncatedHashModule; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/ttmac.cpp b/external/ours/library/crypto/src/shared/original/ttmac.cpp new file mode 100755 index 000000000..db7e3485f --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ttmac.cpp @@ -0,0 +1,348 @@ +// ttmac.cpp - written and placed in the public domain by Kevin Springle + +#include "pch.h" +#include "ttmac.h" +#include "misc.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::word32; +using CryptoPP::rotlVariable; +using CryptoPP::rotlConstant; + +// RIPEMD-160 definitions used by Two-Track-MAC +word32 F(word32 x, word32 y, word32 z) { return x ^ y ^ z; } +word32 G(word32 x, word32 y, word32 z) { return z ^ (x & (y^z)); } +word32 H(word32 x, word32 y, word32 z) { return z ^ (x | ~y); } +word32 I(word32 x, word32 y, word32 z) { return y ^ (z & (x^y)); } +word32 J(word32 x, word32 y, word32 z) { return x ^ (y | ~z); } + +template +void Subround(Fn fn, word32& a, word32 b, word32& c, word32 d, word32 e, word32 x, word32 k) +{ + a += fn(b, c, d) + x + k; + a = rotlVariable(a, S) + e; + c = rotlConstant<10>(c); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +const unsigned int k0 = 0; +const unsigned int k1 = 0x5a827999; +const unsigned int k2 = 0x6ed9eba1; +const unsigned int k3 = 0x8f1bbcdc; +const unsigned int k4 = 0xa953fd4e; +const unsigned int k5 = 0x50a28be6; +const unsigned int k6 = 0x5c4dd124; +const unsigned int k7 = 0x6d703ef3; +const unsigned int k8 = 0x7a6d76e9; +const unsigned int k9 = 0; + +void TTMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + memcpy(m_key, userKey, KEYLENGTH); + CorrectEndianess(m_key, m_key, KEYLENGTH); + + Init(); +} + +void TTMAC_Base::Init() +{ + m_digest[0] = m_digest[5] = m_key[0]; + m_digest[1] = m_digest[6] = m_key[1]; + m_digest[2] = m_digest[7] = m_key[2]; + m_digest[3] = m_digest[8] = m_key[3]; + m_digest[4] = m_digest[9] = m_key[4]; +} + +void TTMAC_Base::TruncatedFinal(byte *hash, size_t size) +{ + PadLastBlock(BlockSize() - 2*sizeof(HashWordType)); + CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType)); + + m_data[m_data.size()-2] = GetBitCountLo(); + m_data[m_data.size()-1] = GetBitCountHi(); + + Transform(m_digest, m_data, true); + + word32 t2 = m_digest[2]; + word32 t3 = m_digest[3]; + if (size != DIGESTSIZE) + { + switch (size) + { + case 16: + m_digest[3] += m_digest[1] + m_digest[4]; + // fall through + case 12: + m_digest[2] += m_digest[0] + t3; + // fall through + case 8: + m_digest[0] += m_digest[1] + t3; + m_digest[1] += m_digest[4] + t2; + break; + + case 4: + m_digest[0] += + m_digest[1] + + m_digest[2] + + m_digest[3] + + m_digest[4]; + break; + + case 0: + // Used by HashTransformation::Restart() + break; + + default: + throw InvalidArgument("TTMAC_Base: can't truncate a Two-Track-MAC 20 byte digest to " + IntToString(size) + " bytes"); + break; + } + } + + CorrectEndianess(m_digest, m_digest, size); + memcpy(hash, m_digest, size); + + Restart(); // reinit for next use +} + +void TTMAC_Base::Transform(word32 *digest, const word32 *X, bool last) +{ + word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; + word32 *trackA, *trackB; + + if (!last) + { + trackA = digest; + trackB = digest+5; + } + else + { + trackB = digest; + trackA = digest+5; + } + a1 = trackA[0]; + b1 = trackA[1]; + c1 = trackA[2]; + d1 = trackA[3]; + e1 = trackA[4]; + a2 = trackB[0]; + b2 = trackB[1]; + c2 = trackB[2]; + d2 = trackB[3]; + e2 = trackB[4]; + + Subround<11>(F, a1, b1, c1, d1, e1, X[ 0], k0); + Subround<14>(F, e1, a1, b1, c1, d1, X[ 1], k0); + Subround<15>(F, d1, e1, a1, b1, c1, X[ 2], k0); + Subround<12>(F, c1, d1, e1, a1, b1, X[ 3], k0); + Subround< 5>(F, b1, c1, d1, e1, a1, X[ 4], k0); + Subround< 8>(F, a1, b1, c1, d1, e1, X[ 5], k0); + Subround< 7>(F, e1, a1, b1, c1, d1, X[ 6], k0); + Subround< 9>(F, d1, e1, a1, b1, c1, X[ 7], k0); + Subround<11>(F, c1, d1, e1, a1, b1, X[ 8], k0); + Subround<13>(F, b1, c1, d1, e1, a1, X[ 9], k0); + Subround<14>(F, a1, b1, c1, d1, e1, X[10], k0); + Subround<15>(F, e1, a1, b1, c1, d1, X[11], k0); + Subround< 6>(F, d1, e1, a1, b1, c1, X[12], k0); + Subround< 7>(F, c1, d1, e1, a1, b1, X[13], k0); + Subround< 9>(F, b1, c1, d1, e1, a1, X[14], k0); + Subround< 8>(F, a1, b1, c1, d1, e1, X[15], k0); + + Subround< 7>(G, e1, a1, b1, c1, d1, X[ 7], k1); + Subround< 6>(G, d1, e1, a1, b1, c1, X[ 4], k1); + Subround< 8>(G, c1, d1, e1, a1, b1, X[13], k1); + Subround<13>(G, b1, c1, d1, e1, a1, X[ 1], k1); + Subround<11>(G, a1, b1, c1, d1, e1, X[10], k1); + Subround< 9>(G, e1, a1, b1, c1, d1, X[ 6], k1); + Subround< 7>(G, d1, e1, a1, b1, c1, X[15], k1); + Subround<15>(G, c1, d1, e1, a1, b1, X[ 3], k1); + Subround< 7>(G, b1, c1, d1, e1, a1, X[12], k1); + Subround<12>(G, a1, b1, c1, d1, e1, X[ 0], k1); + Subround<15>(G, e1, a1, b1, c1, d1, X[ 9], k1); + Subround< 9>(G, d1, e1, a1, b1, c1, X[ 5], k1); + Subround<11>(G, c1, d1, e1, a1, b1, X[ 2], k1); + Subround< 7>(G, b1, c1, d1, e1, a1, X[14], k1); + Subround<13>(G, a1, b1, c1, d1, e1, X[11], k1); + Subround<12>(G, e1, a1, b1, c1, d1, X[ 8], k1); + + Subround<11>(H, d1, e1, a1, b1, c1, X[ 3], k2); + Subround<13>(H, c1, d1, e1, a1, b1, X[10], k2); + Subround< 6>(H, b1, c1, d1, e1, a1, X[14], k2); + Subround< 7>(H, a1, b1, c1, d1, e1, X[ 4], k2); + Subround<14>(H, e1, a1, b1, c1, d1, X[ 9], k2); + Subround< 9>(H, d1, e1, a1, b1, c1, X[15], k2); + Subround<13>(H, c1, d1, e1, a1, b1, X[ 8], k2); + Subround<15>(H, b1, c1, d1, e1, a1, X[ 1], k2); + Subround<14>(H, a1, b1, c1, d1, e1, X[ 2], k2); + Subround< 8>(H, e1, a1, b1, c1, d1, X[ 7], k2); + Subround<13>(H, d1, e1, a1, b1, c1, X[ 0], k2); + Subround< 6>(H, c1, d1, e1, a1, b1, X[ 6], k2); + Subround< 5>(H, b1, c1, d1, e1, a1, X[13], k2); + Subround<12>(H, a1, b1, c1, d1, e1, X[11], k2); + Subround< 7>(H, e1, a1, b1, c1, d1, X[ 5], k2); + Subround< 5>(H, d1, e1, a1, b1, c1, X[12], k2); + + Subround<11>(I, c1, d1, e1, a1, b1, X[ 1], k3); + Subround<12>(I, b1, c1, d1, e1, a1, X[ 9], k3); + Subround<14>(I, a1, b1, c1, d1, e1, X[11], k3); + Subround<15>(I, e1, a1, b1, c1, d1, X[10], k3); + Subround<14>(I, d1, e1, a1, b1, c1, X[ 0], k3); + Subround<15>(I, c1, d1, e1, a1, b1, X[ 8], k3); + Subround< 9>(I, b1, c1, d1, e1, a1, X[12], k3); + Subround< 8>(I, a1, b1, c1, d1, e1, X[ 4], k3); + Subround< 9>(I, e1, a1, b1, c1, d1, X[13], k3); + Subround<14>(I, d1, e1, a1, b1, c1, X[ 3], k3); + Subround< 5>(I, c1, d1, e1, a1, b1, X[ 7], k3); + Subround< 6>(I, b1, c1, d1, e1, a1, X[15], k3); + Subround< 8>(I, a1, b1, c1, d1, e1, X[14], k3); + Subround< 6>(I, e1, a1, b1, c1, d1, X[ 5], k3); + Subround< 5>(I, d1, e1, a1, b1, c1, X[ 6], k3); + Subround<12>(I, c1, d1, e1, a1, b1, X[ 2], k3); + + Subround< 9>(J, b1, c1, d1, e1, a1, X[ 4], k4); + Subround<15>(J, a1, b1, c1, d1, e1, X[ 0], k4); + Subround< 5>(J, e1, a1, b1, c1, d1, X[ 5], k4); + Subround<11>(J, d1, e1, a1, b1, c1, X[ 9], k4); + Subround< 6>(J, c1, d1, e1, a1, b1, X[ 7], k4); + Subround< 8>(J, b1, c1, d1, e1, a1, X[12], k4); + Subround<13>(J, a1, b1, c1, d1, e1, X[ 2], k4); + Subround<12>(J, e1, a1, b1, c1, d1, X[10], k4); + Subround< 5>(J, d1, e1, a1, b1, c1, X[14], k4); + Subround<12>(J, c1, d1, e1, a1, b1, X[ 1], k4); + Subround<13>(J, b1, c1, d1, e1, a1, X[ 3], k4); + Subround<14>(J, a1, b1, c1, d1, e1, X[ 8], k4); + Subround<11>(J, e1, a1, b1, c1, d1, X[11], k4); + Subround< 8>(J, d1, e1, a1, b1, c1, X[ 6], k4); + Subround< 5>(J, c1, d1, e1, a1, b1, X[15], k4); + Subround< 6>(J, b1, c1, d1, e1, a1, X[13], k4); + + Subround< 8>(J, a2, b2, c2, d2, e2, X[ 5], k5); + Subround< 9>(J, e2, a2, b2, c2, d2, X[14], k5); + Subround< 9>(J, d2, e2, a2, b2, c2, X[ 7], k5); + Subround<11>(J, c2, d2, e2, a2, b2, X[ 0], k5); + Subround<13>(J, b2, c2, d2, e2, a2, X[ 9], k5); + Subround<15>(J, a2, b2, c2, d2, e2, X[ 2], k5); + Subround<15>(J, e2, a2, b2, c2, d2, X[11], k5); + Subround< 5>(J, d2, e2, a2, b2, c2, X[ 4], k5); + Subround< 7>(J, c2, d2, e2, a2, b2, X[13], k5); + Subround< 7>(J, b2, c2, d2, e2, a2, X[ 6], k5); + Subround< 8>(J, a2, b2, c2, d2, e2, X[15], k5); + Subround<11>(J, e2, a2, b2, c2, d2, X[ 8], k5); + Subround<14>(J, d2, e2, a2, b2, c2, X[ 1], k5); + Subround<14>(J, c2, d2, e2, a2, b2, X[10], k5); + Subround<12>(J, b2, c2, d2, e2, a2, X[ 3], k5); + Subround< 6>(J, a2, b2, c2, d2, e2, X[12], k5); + + Subround< 9>(I, e2, a2, b2, c2, d2, X[ 6], k6); + Subround<13>(I, d2, e2, a2, b2, c2, X[11], k6); + Subround<15>(I, c2, d2, e2, a2, b2, X[ 3], k6); + Subround< 7>(I, b2, c2, d2, e2, a2, X[ 7], k6); + Subround<12>(I, a2, b2, c2, d2, e2, X[ 0], k6); + Subround< 8>(I, e2, a2, b2, c2, d2, X[13], k6); + Subround< 9>(I, d2, e2, a2, b2, c2, X[ 5], k6); + Subround<11>(I, c2, d2, e2, a2, b2, X[10], k6); + Subround< 7>(I, b2, c2, d2, e2, a2, X[14], k6); + Subround< 7>(I, a2, b2, c2, d2, e2, X[15], k6); + Subround<12>(I, e2, a2, b2, c2, d2, X[ 8], k6); + Subround< 7>(I, d2, e2, a2, b2, c2, X[12], k6); + Subround< 6>(I, c2, d2, e2, a2, b2, X[ 4], k6); + Subround<15>(I, b2, c2, d2, e2, a2, X[ 9], k6); + Subround<13>(I, a2, b2, c2, d2, e2, X[ 1], k6); + Subround<11>(I, e2, a2, b2, c2, d2, X[ 2], k6); + + Subround< 9>(H, d2, e2, a2, b2, c2, X[15], k7); + Subround< 7>(H, c2, d2, e2, a2, b2, X[ 5], k7); + Subround<15>(H, b2, c2, d2, e2, a2, X[ 1], k7); + Subround<11>(H, a2, b2, c2, d2, e2, X[ 3], k7); + Subround< 8>(H, e2, a2, b2, c2, d2, X[ 7], k7); + Subround< 6>(H, d2, e2, a2, b2, c2, X[14], k7); + Subround< 6>(H, c2, d2, e2, a2, b2, X[ 6], k7); + Subround<14>(H, b2, c2, d2, e2, a2, X[ 9], k7); + Subround<12>(H, a2, b2, c2, d2, e2, X[11], k7); + Subround<13>(H, e2, a2, b2, c2, d2, X[ 8], k7); + Subround< 5>(H, d2, e2, a2, b2, c2, X[12], k7); + Subround<14>(H, c2, d2, e2, a2, b2, X[ 2], k7); + Subround<13>(H, b2, c2, d2, e2, a2, X[10], k7); + Subround<13>(H, a2, b2, c2, d2, e2, X[ 0], k7); + Subround< 7>(H, e2, a2, b2, c2, d2, X[ 4], k7); + Subround< 5>(H, d2, e2, a2, b2, c2, X[13], k7); + + Subround<15>(G, c2, d2, e2, a2, b2, X[ 8], k8); + Subround< 5>(G, b2, c2, d2, e2, a2, X[ 6], k8); + Subround< 8>(G, a2, b2, c2, d2, e2, X[ 4], k8); + Subround<11>(G, e2, a2, b2, c2, d2, X[ 1], k8); + Subround<14>(G, d2, e2, a2, b2, c2, X[ 3], k8); + Subround<14>(G, c2, d2, e2, a2, b2, X[11], k8); + Subround< 6>(G, b2, c2, d2, e2, a2, X[15], k8); + Subround<14>(G, a2, b2, c2, d2, e2, X[ 0], k8); + Subround< 6>(G, e2, a2, b2, c2, d2, X[ 5], k8); + Subround< 9>(G, d2, e2, a2, b2, c2, X[12], k8); + Subround<12>(G, c2, d2, e2, a2, b2, X[ 2], k8); + Subround< 9>(G, b2, c2, d2, e2, a2, X[13], k8); + Subround<12>(G, a2, b2, c2, d2, e2, X[ 9], k8); + Subround< 5>(G, e2, a2, b2, c2, d2, X[ 7], k8); + Subround<15>(G, d2, e2, a2, b2, c2, X[10], k8); + Subround< 8>(G, c2, d2, e2, a2, b2, X[14], k8); + + Subround< 8>(F, b2, c2, d2, e2, a2, X[12], k9); + Subround< 5>(F, a2, b2, c2, d2, e2, X[15], k9); + Subround<12>(F, e2, a2, b2, c2, d2, X[10], k9); + Subround< 9>(F, d2, e2, a2, b2, c2, X[ 4], k9); + Subround<12>(F, c2, d2, e2, a2, b2, X[ 1], k9); + Subround< 5>(F, b2, c2, d2, e2, a2, X[ 5], k9); + Subround<14>(F, a2, b2, c2, d2, e2, X[ 8], k9); + Subround< 6>(F, e2, a2, b2, c2, d2, X[ 7], k9); + Subround< 8>(F, d2, e2, a2, b2, c2, X[ 6], k9); + Subround<13>(F, c2, d2, e2, a2, b2, X[ 2], k9); + Subround< 6>(F, b2, c2, d2, e2, a2, X[13], k9); + Subround< 5>(F, a2, b2, c2, d2, e2, X[14], k9); + Subround<15>(F, e2, a2, b2, c2, d2, X[ 0], k9); + Subround<13>(F, d2, e2, a2, b2, c2, X[ 3], k9); + Subround<11>(F, c2, d2, e2, a2, b2, X[ 9], k9); + Subround<11>(F, b2, c2, d2, e2, a2, X[11], k9); + + a1 -= trackA[0]; + b1 -= trackA[1]; + c1 -= trackA[2]; + d1 -= trackA[3]; + e1 -= trackA[4]; + a2 -= trackB[0]; + b2 -= trackB[1]; + c2 -= trackB[2]; + d2 -= trackB[3]; + e2 -= trackB[4]; + + if (!last) + { + trackA[0] = (b1 + e1) - d2; + trackA[1] = c1 - e2; + trackA[2] = d1 - a2; + trackA[3] = e1 - b2; + trackA[4] = a1 - c2; + trackB[0] = d1 - e2; + trackB[1] = (e1 + c1) - a2; + trackB[2] = a1 - b2; + trackB[3] = b1 - c2; + trackB[4] = c1 - d2; + } + else + { + trackB[0] = a2 - a1; + trackB[1] = b2 - b1; + trackB[2] = c2 - c1; + trackB[3] = d2 - d1; + trackB[4] = e2 - e1; + trackA[0] = 0; + trackA[1] = 0; + trackA[2] = 0; + trackA[3] = 0; + trackA[4] = 0; + } +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/ttmac.h b/external/ours/library/crypto/src/shared/original/ttmac.h new file mode 100755 index 000000000..d50b0038c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/ttmac.h @@ -0,0 +1,44 @@ +// ttmac.h - written and placed in the public domain by Kevin Springle + +/// \file ttmac.h +/// \brief Classes for the TTMAC message authentication code + +#ifndef CRYPTOPP_TTMAC_H +#define CRYPTOPP_TTMAC_H + +#include "seckey.h" +#include "iterhash.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief TTMAC message authentication code information +class CRYPTOPP_NO_VTABLE TTMAC_Base : public FixedKeyLength<20>, public IteratedHash +{ +public: + static std::string StaticAlgorithmName() {return std::string("Two-Track-MAC");} + CRYPTOPP_CONSTANT(DIGESTSIZE=20); + + unsigned int DigestSize() const {return DIGESTSIZE;}; + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + void TruncatedFinal(byte *mac, size_t size); + +protected: + static void Transform (word32 *digest, const word32 *X, bool last); + void HashEndianCorrectedBlock(const word32 *data) {Transform(m_digest, data, false);} + void Init(); + word32* StateBuf() {return m_digest;} + + FixedSizeSecBlock m_digest; + FixedSizeSecBlock m_key; +}; + +/// \brief Two-Track-MAC message authentication code +/// \tparam T HashTransformation class +/// \details 160-bit MAC with 160-bit key +/// \sa MessageAuthenticationCode(), Two-Track-MAC +DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal, TTMAC); + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/tweetnacl.cpp b/external/ours/library/crypto/src/shared/original/tweetnacl.cpp new file mode 100755 index 000000000..71d80e707 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/tweetnacl.cpp @@ -0,0 +1,924 @@ +// tweetnacl.cpp - modified tweetnacl.c placed in public domain by Jeffrey Walton. +// The NaCl library and tweetnacl.c is public domain source code +// written by Daniel J. Bernstein, Bernard van Gastel, Wesley +// Janssen, Tanja Lange, Peter Schwabe and Sjaak Smetsers. + +#include "pch.h" +#include "config.h" +#include "naclite.h" +#include "misc.h" +#include "osrng.h" +#include "stdcpp.h" + +// Don't destroy const time properties when squashing warnings. +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4146 4242 4244 4245) +#endif + +// Can't use GetAlignmentOf() because of C++11 and constexpr +// Can use 'const unsigned int' because of MSVC 2013 +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +# define ALIGN_SPEC 16 +#else +# define ALIGN_SPEC 4 +#endif + +#ifndef CRYPTOPP_DISABLE_NACL + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(NaCl) + +typedef sword64 gf[16]; + +static const byte + _0[32] = {0}, + _9[32] = {9}; + +static const gf + gf0 = {0}, + gf1 = {1}, + _121665 = {0xDB41,1}, + D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203}, + D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406}, + X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169}, + Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666}, + I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; + +// Added by Crypto++ for TweetNaCl +static void randombytes(byte * block, word64 size) +{ + DefaultAutoSeededRNG prng; + prng.GenerateBlock(block, (size_t)size); +} + +static word32 L32(word32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); } + +static word32 ld32(const byte *x) +{ + word32 u = x[3]; + u = (u<<8)|x[2]; + u = (u<<8)|x[1]; + return (u<<8)|x[0]; +} + +static word64 dl64(const byte *x) +{ + word64 i,u=0; + for(i=0; i<8; ++i) u=(u<<8)|x[i]; + return u; +} + +static void st32(byte *x,word32 u) +{ + int i; + for(i=0; i<4; ++i) { x[i] = u; u >>= 8; } +} + +static void ts64(byte *x,word64 u) +{ + int i; + for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; } +} + +// Extra cast due to Coverity CID 186949 +static int verify_n(const byte *x,const byte *y,word32 n) +{ + word32 i,d = 0; + for(i=0; i> 8)) - 1; +} + +int crypto_verify_16(const byte *x,const byte *y) +{ + return verify_n(x,y,16); +} + +int crypto_verify_32(const byte *x,const byte *y) +{ + return verify_n(x,y,32); +} + +static void core(byte *out,const byte *in,const byte *k,const byte *c,int h) +{ + word32 w[16],x[16],y[16],t[4]; + int i,j,m; + + for(i=0; i<4; ++i) { + x[5*i] = ld32(c+4*i); + x[1+i] = ld32(k+4*i); + x[6+i] = ld32(in+4*i); + x[11+i] = ld32(k+16+4*i); + } + + for(i=0; i<16; ++i) y[i] = x[i]; + + for(i=0; i<20; ++i) { + for(j=0; j<4; ++j) { + for(m=0; m<4; ++m) t[m] = x[(5*j+4*m)%16]; + t[1] ^= L32(t[0]+t[3], 7); + t[2] ^= L32(t[1]+t[0], 9); + t[3] ^= L32(t[2]+t[1],13); + t[0] ^= L32(t[3]+t[2],18); + for(m=0; m<4; ++m) w[4*j+(j+m)%4] = t[m]; + } + for(m=0; m<16; ++m) x[m] = w[m]; + } + + if (h) { + for(i=0; i<16; ++i) x[i] += y[i]; + for(i=0; i<4; ++i) { + x[5*i] -= ld32(c+4*i); + x[6+i] -= ld32(in+4*i); + } + for(i=0; i<4; ++i) { + st32(out+4*i,x[5*i]); + st32(out+16+4*i,x[6+i]); + } + } else + for(i=0; i<16; ++i) st32(out + 4 * i,x[i] + y[i]); +} + +int crypto_core_salsa20(byte *out,const byte *in,const byte *k,const byte *c) +{ + core(out,in,k,c,0); + return 0; +} + +int crypto_core_hsalsa20(byte *out,const byte *in,const byte *k,const byte *c) +{ + core(out,in,k,c,1); + return 0; +} + +static const byte sigma[16] = {0x65,0x78,0x70,0x61,0x6E,0x64,0x20,0x33,0x32,0x2D,0x62,0x79,0x74,0x65,0x20,0x6B}; + +int crypto_stream_salsa20_xor(byte *c,const byte *m,word64 b,const byte *n,const byte *k) +{ + byte z[16],x[64]; + word32 u,i; + if (!b) return 0; + for(i=0; i<16; ++i) z[i] = 0; + for(i=0; i<8; ++i) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x,z,k,sigma); + for(i=0; i<64; ++i) c[i] = (m?m[i]:0) ^ x[i]; + u = 1; + for (i = 8;i < 16;++i) { + u += (word32) z[i]; + z[i] = u; + u >>= 8; + } + b -= 64; + c += 64; + if (m) m += 64; + } + if (b) { + crypto_core_salsa20(x,z,k,sigma); + for(i=0; i>= 8; + } +} + +static const word32 minusp[17] = { + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 +} ; + +int crypto_onetimeauth(byte *out,const byte *m,word64 n,const byte *k) +{ + word32 s,i,j,u,x[17],r[17],h[17],c[17],g[17]; + + for(j=0; j<17; ++j) r[j]=h[j]=0; + for(j=0; j<16; ++j) r[j]=k[j]; + r[3]&=15; + r[4]&=252; + r[7]&=15; + r[8]&=252; + r[11]&=15; + r[12]&=252; + r[15]&=15; + + while (n > 0) { + for(j=0; j<17; ++j) c[j] = 0; + for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j]; + c[j] = 1; + m += j; n -= j; + add1305(h,c); + for(i=0; i<17; ++i) { + x[i] = 0; + for(j=0; j<17; ++j) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); + } + for(i=0; i<17; ++i) h[i] = x[i]; + u = 0; + for(j=0; j<16; ++j) { + u += h[j]; + h[j] = u & 255; + u >>= 8; + } + u += h[16]; h[16] = u & 3; + u = 5 * (u >> 2); + for(j=0; j<16; ++j) { + u += h[j]; + h[j] = u & 255; + u >>= 8; + } + u += h[16]; h[16] = u; + } + + for(j=0; j<17; ++j) g[j] = h[j]; + add1305(h,minusp); + s = -(h[16] >> 7); + for(j=0; j<17; ++j) h[j] ^= s & (g[j] ^ h[j]); + + for(j=0; j<16; ++j) c[j] = k[j + 16]; + c[16] = 0; + add1305(h,c); + for(j=0; j<16; ++j) out[j] = h[j]; + return 0; +} + +int crypto_onetimeauth_verify(const byte *h,const byte *m,word64 n,const byte *k) +{ + byte x[16]; + crypto_onetimeauth(x,m,n,k); + return crypto_verify_16(h,x); +} + +int crypto_secretbox(byte *c,const byte *m,word64 d,const byte *n,const byte *k) +{ + int i; + if (d < 32) return -1; + crypto_stream_xor(c,m,d,n,k); + crypto_onetimeauth(c + 16,c + 32,d - 32,c); + for(i=0; i<16; ++i) c[i] = 0; + return 0; +} + +int crypto_secretbox_open(byte *m,const byte *c,word64 d,const byte *n,const byte *k) +{ + int i; + byte x[32]; + if (d < 32) return -1; + crypto_stream(x,32,n,k); + if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1; + crypto_stream_xor(m,c,d,n,k); + for(i=0; i<32; ++i) m[i] = 0; + return 0; +} + +static void set25519(gf r, const gf a) +{ + int i; + for(i=0; i<16; ++i) r[i]=a[i]; +} + +static void car25519(gf o) +{ + int i; + sword64 c; + for(i=0; i<16; ++i) { + o[i]+=(1LL<<16); + c=o[i]>>16; + o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15); + o[i]-=((word64)c)<<16; + } +} + +static void sel25519(gf p,gf q,int b) +{ + sword64 t,i,c=~(b-1); + for(i=0; i<16; ++i) { + t= c&(p[i]^q[i]); + p[i]^=t; + q[i]^=t; + } +} + +static void pack25519(byte *o,const gf n) +{ + int i,j,b; + gf m,t; + for(i=0; i<16; ++i) t[i]=n[i]; + car25519(t); + car25519(t); + car25519(t); + for(j=0; j<2; ++j) { + m[0]=t[0]-0xffed; + for(i=1;i<15;i++) { + m[i]=t[i]-0xffff-((m[i-1]>>16)&1); + m[i-1]&=0xffff; + } + m[15]=t[15]-0x7fff-((m[14]>>16)&1); + b=(m[15]>>16)&1; + m[14]&=0xffff; + sel25519(t,m,1-b); + } + for(i=0; i<16; ++i) { + o[2*i]=t[i]&0xff; + o[2*i+1]=t[i]>>8; + } +} + +static int neq25519(const gf a, const gf b) +{ + byte c[32],d[32]; + pack25519(c,a); + pack25519(d,b); + return crypto_verify_32(c,d); +} + +static byte par25519(const gf a) +{ + byte d[32]; + pack25519(d,a); + return d[0]&1; +} + +static void unpack25519(gf o, const byte *n) +{ + int i; + for(i=0; i<16; ++i) o[i]=n[2*i]+((sword64)n[2*i+1]<<8); + o[15]&=0x7fff; +} + +static void A(gf o,const gf a,const gf b) +{ + int i; + for(i=0; i<16; ++i) o[i]=a[i]+b[i]; +} + +static void Z(gf o,const gf a,const gf b) +{ + int i; + for(i=0; i<16; ++i) o[i]=a[i]-b[i]; +} + +static void M(gf o,const gf a,const gf b) +{ + sword64 i,j,t[31]; + for(i=0; i<31; ++i) t[i]=0; + for(i=0; i<16; ++i) for(j=0; j<16; ++j) t[i+j]+=a[i]*b[j]; + for(i=0; i<15; ++i) t[i]+=38*t[i+16]; + for(i=0; i<16; ++i) o[i]=t[i]; + car25519(o); + car25519(o); +} + +static void S(gf o,const gf a) +{ + M(o,a,a); +} + +static void inv25519(gf o,const gf i) +{ + gf c; + int a; + for(a=0; a<16; ++a) c[a]=i[a]; + for(a=253;a>=0;a--) { + S(c,c); + if(a!=2&&a!=4) M(c,c,i); + } + for(a=0; a<16; ++a) o[a]=c[a]; +} + +static void pow2523(gf o,const gf i) +{ + gf c; + int a; + for(a=0; a<16; ++a) c[a]=i[a]; + for(a=250;a>=0;a--) { + S(c,c); + if(a!=1) M(c,c,i); + } + for(a=0; a<16; ++a) o[a]=c[a]; +} + +// https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c +static int has_small_order(const byte s[32]) +{ + CRYPTOPP_ALIGN_DATA(ALIGN_SPEC) + const byte blacklist[][32] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 }, + { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 }, + { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 }, + { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 }, + { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } + }; + CRYPTOPP_COMPILE_ASSERT(12 == COUNTOF(blacklist)); + + byte c[12] = { 0 }; + for (size_t j = 0; j < 32; j++) { + for (size_t i = 0; i < COUNTOF(blacklist); i++) { + c[i] |= s[j] ^ blacklist[i][j]; + } + } + + unsigned int k = 0; + for (size_t i = 0; i < COUNTOF(blacklist); i++) { + k |= (c[i] - 1); + } + + return (int) ((k >> 8) & 1); +} + +int crypto_scalarmult(byte *q,const byte *n,const byte *p) +{ + byte z[32]; + sword64 x[80],r,i; + gf a,b,c,d,e,f; + for(i=0; i<31; ++i) z[i]=n[i]; + z[31]=(n[31]&127)|64; + z[0]&=248; + unpack25519(x,p); + for(i=0; i<16; ++i) { + b[i]=x[i]; + d[i]=a[i]=c[i]=0; + } + a[0]=d[0]=1; + for(i=254;i>=0;--i) { + r=(z[i>>3]>>(i&7))&1; + sel25519(a,b,r); + sel25519(c,d,r); + A(e,a,c); + Z(a,a,c); + A(c,b,d); + Z(b,b,d); + S(d,e); + S(f,a); + M(a,c,a); + M(c,b,e); + A(e,a,c); + Z(a,a,c); + S(b,a); + Z(c,d,f); + M(a,c,_121665); + A(a,a,d); + M(c,c,a); + M(a,d,f); + M(d,b,x); + S(b,e); + sel25519(a,b,r); + sel25519(c,d,r); + } + for(i=0; i<16; ++i) { + x[i+16]=a[i]; + x[i+32]=c[i]; + x[i+48]=b[i]; + x[i+64]=d[i]; + } + inv25519(x+32,x+32); + M(x+16,x+16,x+32); + pack25519(q,x+16); + return 0; +} + +int crypto_scalarmult_base(byte *q,const byte *n) +{ + return crypto_scalarmult(q,n,_9); +} + +int crypto_box_keypair(byte *y,byte *x) +{ + randombytes(x,32); + return crypto_scalarmult_base(y,x); +} + +// Avoid small order elements. Also see https://eprint.iacr.org/2017/806.pdf +// and https://github.com/jedisct1/libsodium/commit/675149b9b8b66ff4. +int crypto_box_beforenm(byte *k,const byte *y,const byte *x) +{ + byte s[32]; + if(crypto_scalarmult(s,x,y) != 0) return -1; + if(has_small_order(s) != 0) return -1; + return crypto_core_hsalsa20(k,_0,s,sigma); +} + +// Allow small order elements. Also see https://eprint.iacr.org/2017/806.pdf +int crypto_box_beforenm_unchecked(byte *k,const byte *y,const byte *x) +{ + byte s[32]; + if(crypto_scalarmult(s,x,y) != 0) return -1; + return crypto_core_hsalsa20(k,_0,s,sigma); +} + +int crypto_box_afternm(byte *c,const byte *m,word64 d,const byte *n,const byte *k) +{ + return crypto_secretbox(c,m,d,n,k); +} + +int crypto_box_open_afternm(byte *m,const byte *c,word64 d,const byte *n,const byte *k) +{ + return crypto_secretbox_open(m,c,d,n,k); +} + +int crypto_box(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x) +{ + byte k[32]; + if (crypto_box_beforenm(k, y, x) != 0) return -1; + return crypto_box_afternm(c, m, d, n, k); +} + +int crypto_box_unchecked(byte *c, const byte *m, word64 d, const byte *n, const byte *y, const byte *x) +{ + byte k[32]; + crypto_box_beforenm_unchecked(k, y, x); + return crypto_box_afternm(c, m, d, n, k); +} + +int crypto_box_open(byte *m,const byte *c,word64 d,const byte *n,const byte *y,const byte *x) +{ + byte k[32]; + if(crypto_box_beforenm(k,y,x) != 0) return -1; + return crypto_box_open_afternm(m,c,d,n,k); +} + +int crypto_box_open_unchecked(byte *m,const byte *c,word64 d,const byte *n,const byte *y,const byte *x) +{ + byte k[32]; + crypto_box_beforenm_unchecked(k,y,x); + return crypto_box_open_afternm(m,c,d,n,k); +} + +static word64 R(word64 x,int c) { return (x >> c) | (x << (64 - c)); } +static word64 Ch(word64 x,word64 y,word64 z) { return (x & y) ^ (~x & z); } +static word64 Maj(word64 x,word64 y,word64 z) { return (x & y) ^ (x & z) ^ (y & z); } +static word64 Sigma0(word64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); } +static word64 Sigma1(word64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); } +static word64 sigma0(word64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } +static word64 sigma1(word64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } + +static const word64 K[80] = +{ + W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), + W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), + W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), + W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), + W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), + W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), + W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), + W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), + W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), + W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), + W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), + W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), + W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), + W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), + W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), + W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), + W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), + W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), + W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), + W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) +}; + +int crypto_hashblocks(byte *x,const byte *m,word64 n) +{ + word64 z[8],b[8],a[8],w[16],t; + int i,j; + + for(i=0; i<8; ++i) z[i] = a[i] = dl64(x + 8 * i); + + while (n >= 128) { + for(i=0; i<16; ++i) w[i] = dl64(m + 8 * i); + + for(i=0; i<80; ++i) { + for(j=0; j<8; ++j) b[j] = a[j]; + t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16]; + b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]); + b[3] += t; + for(j=0; j<8; ++j) a[(j+1)%8] = b[j]; + if (i%16 == 15) + for(j=0; j<16; ++j) + w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]); + } + + for(i=0; i<8; ++i) { a[i] += z[i]; z[i] = a[i]; } + + m += 128; + n -= 128; + } + + for(i=0; i<8; ++i) ts64(x+8*i,z[i]); + + return n; +} + +static const byte iv[64] = { + 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, + 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, + 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, + 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, + 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, + 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, + 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, + 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 +} ; + +int crypto_hash(byte *out,const byte *m,word64 n) +{ + byte h[64],x[256]; + word64 i,b = n; + + for(i=0; i<64; ++i) h[i] = iv[i]; + + crypto_hashblocks(h,m,n); + m += n; + n &= 127; + m -= n; + + for(i=0; i<256; ++i) x[i] = 0; + for(i=0; i> 61; + ts64(x+n-8,b<<3); + crypto_hashblocks(h,x,n); + + for(i=0; i<64; ++i) out[i] = h[i]; + + return 0; +} + +static void add(gf p[4],gf q[4]) +{ + gf a,b,c,d,t,e,f,g,h; + + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); + + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); +} + +static void cswap(gf p[4],gf q[4],byte b) +{ + int i; + for(i=0; i<4; ++i) + sel25519(p[i],q[i],b); +} + +static void pack(byte *r,gf p[4]) +{ + gf tx, ty, zi; + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; +} + +static void scalarmult(gf p[4],gf q[4],const byte *s) +{ + int i; + set25519(p[0],gf0); + set25519(p[1],gf1); + set25519(p[2],gf1); + set25519(p[3],gf0); + for (i = 255;i >= 0;--i) { + byte b = (s[i/8]>>(i&7))&1; + cswap(p,q,b); + add(q,p); + add(p,p); + cswap(p,q,b); + } +} + +static void scalarbase(gf p[4],const byte *s) +{ + gf q[4]; + set25519(q[0],X); + set25519(q[1],Y); + set25519(q[2],gf1); + M(q[3],X,Y); + scalarmult(p,q,s); +} + +int crypto_sign_keypair(byte *pk, byte *sk) +{ + byte d[64]; + gf p[4]; + int i; + + randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + scalarbase(p,d); + pack(pk,p); + + for(i=0; i<32; ++i) sk[32 + i] = pk[i]; + return 0; +} + +int crypto_sign_sk2pk(byte *pk, const byte *sk) +{ + byte d[64]; + gf p[4]; + // int i; + + // randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + scalarbase(p,d); + pack(pk,p); + + // for(i=0; i<32; ++i) sk[32 + i] = pk[i]; + return 0; +} + +static const word64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; + +static void modL(byte *r,sword64 x[64]) +{ + sword64 carry,i,j; + for (i = 63;i >= 32;--i) { + carry = 0; + for (j = i - 32;j < i - 12;++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= ((word64)carry) << 8; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for(j=0; j<32; ++j) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for(j=0; j<32; ++j) x[j] -= carry * L[j]; + for(i=0; i<32; ++i) { + x[i+1] += x[i] >> 8; + r[i] = x[i] & 255; + } +} + +static void reduce(byte *r) +{ + sword64 x[64],i; + for(i=0; i<64; ++i) x[i] = (word64) r[i]; + for(i=0; i<64; ++i) r[i] = 0; + modL(r,x); +} + +int crypto_sign(byte *sm,word64 *smlen,const byte *m,word64 n,const byte *sk) +{ + byte d[64],h[64],r[64]; + word64 i; sword64 j,x[64]; + gf p[4]; + + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + + *smlen = n+64; + for(i=0; i>7)) Z(r[0],gf0,r[0]); + + M(r[3],r[0],r[1]); + return 0; +} + +int crypto_sign_open(byte *m,word64 *mlen,const byte *sm,word64 n,const byte *pk) +{ + word32 i; + byte t[32],h[64]; + gf p[4],q[4]; + + *mlen = ~W64LIT(0); + if (n < 64) return -1; + + if (unpackneg(q,pk)) return -1; + + for(i=0; i>1) ^ ((c & 1) ? (modulus>>1) : 0); - return c | (c1 << 8) | (c2 << 16) | (c1 << 24); -} - -// compute RS(12,8) code with the above polynomial as generator -// this is equivalent to multiplying by the RS matrix -static word32 ReedSolomon(word32 high, word32 low) -{ - for (unsigned int i=0; i<8; i++) - { - high = Mod(high>>24) ^ (high<<8) ^ (low>>24); - low <<= 8; - } - return high; -} - -inline word32 Twofish::h0(word32 x, const word32 *key, unsigned int kLen) -{ - x = x | (x<<8) | (x<<16) | (x<<24); - switch(kLen) - { -#define Q(a, b, c, d, t) q[a][GETBYTE(t,0)] ^ (q[b][GETBYTE(t,1)] << 8) ^ (q[c][GETBYTE(t,2)] << 16) ^ (q[d][GETBYTE(t,3)] << 24) - case 4: x = Q(1, 0, 0, 1, x) ^ key[6]; - case 3: x = Q(1, 1, 0, 0, x) ^ key[4]; - case 2: x = Q(0, 1, 0, 1, x) ^ key[2]; - x = Q(0, 0, 1, 1, x) ^ key[0]; - } - return x; -} - -inline word32 Twofish::h(word32 x, const word32 *key, unsigned int kLen) -{ - x = h0(x, key, kLen); - return mds[0][GETBYTE(x,0)] ^ mds[1][GETBYTE(x,1)] ^ mds[2][GETBYTE(x,2)] ^ mds[3][GETBYTE(x,3)]; -} - -Twofish::Twofish(const byte *userKey, unsigned int keylength) - : m_k(40), m_s(4) -{ - assert(keylength == KeyLength(keylength)); - - unsigned int len = (keylength <= 16 ? 2 : (keylength <= 24 ? 3 : 4)); - SecBlock key(len*2); - GetUserKeyLittleEndian(key.ptr, len*2, userKey, keylength); - - unsigned int i; - for (i=0; i<40; i+=2) - { - word32 a = h(i, key, len); - word32 b = rotlFixed(h(i+1, key+1u, len), 8); - m_k[i] = a+b; - m_k[i+1] = rotlFixed(a+2*b, 9); - } - - SecBlock svec(2*len); - for (i=0; i>1) ^ ((c & 1) ? (modulus>>1) : 0); + return c | (c1 << 8) | (c2 << 16) | (c1 << 24); +} + +// compute RS(12,8) code with the above polynomial as generator +// this is equivalent to multiplying by the RS matrix +static word32 ReedSolomon(word32 high, word32 low) +{ + for (unsigned int i=0; i<8; i++) + { + high = Mod(high>>24) ^ (high<<8) ^ (low>>24); + low <<= 8; + } + return high; +} + +inline word32 Twofish::Base::h0(word32 x, const word32 *key, unsigned int kLen) +{ + x = x | (x<<8) | (x<<16) | (x<<24); + switch(kLen) + { +#define Q(a, b, c, d, t) q[a][GETBYTE(t,0)] ^ (q[b][GETBYTE(t,1)] << 8) ^ (q[c][GETBYTE(t,2)] << 16) ^ (q[d][GETBYTE(t,3)] << 24) + case 4: x = Q(1, 0, 0, 1, x) ^ key[6]; + // fall through + case 3: x = Q(1, 1, 0, 0, x) ^ key[4]; + // fall through + case 2: x = Q(0, 1, 0, 1, x) ^ key[2]; + x = Q(0, 0, 1, 1, x) ^ key[0]; + } + return x; +} + +inline word32 Twofish::Base::h(word32 x, const word32 *key, unsigned int kLen) +{ + x = h0(x, key, kLen); + return mds[0][GETBYTE(x,0)] ^ mds[1][GETBYTE(x,1)] ^ mds[2][GETBYTE(x,2)] ^ mds[3][GETBYTE(x,3)]; +} + +void Twofish::Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + unsigned int len = (keylength <= 16 ? 2 : (keylength <= 24 ? 3 : 4)); + SecBlock key(len*2); + GetUserKey(LITTLE_ENDIAN_ORDER, key.begin(), len*2, userKey, keylength); + + unsigned int i; + for (i=0; i<40; i+=2) + { + word32 a = h(i, key, len); + word32 b = rotlConstant<8>(h(i + 1, key + 1, len)); + m_k[i] = a+b; + m_k[i + 1] = rotlConstant<9>(a + 2 * b); + } + + SecBlock svec(2*len); + for (i=0; i(c); \ + (d) = rotlConstant<1>(d) ^ y + +#define ENCCYCLE(n) \ + ENCROUND (2 * (n), a, b, c, d); \ + ENCROUND (2 * (n) + 1, c, d, a, b) + +#define DECROUND(n, a, b, c, d) \ + x = G1 (a); y = G2 (b); \ + x += y; y += x; \ + (d) ^= y + k[2 * (n) + 1]; \ + (d) = rotrConstant<1>(d); \ + (c) = rotlConstant<1>(c); \ + (c) ^= (x + k[2 * (n)]) + +#define DECCYCLE(n) \ + DECROUND (2 * (n) + 1, c, d, a, b); \ + DECROUND (2 * (n), a, b, c, d) + +typedef BlockGetAndPut Block; + +void Twofish::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 x, y, a, b, c, d; + + Block::Get(inBlock)(a)(b)(c)(d); + + a ^= m_k[0]; + b ^= m_k[1]; + c ^= m_k[2]; + d ^= m_k[3]; + + const word32 *k = m_k+8; + ENCCYCLE (0); + ENCCYCLE (1); + ENCCYCLE (2); + ENCCYCLE (3); + ENCCYCLE (4); + ENCCYCLE (5); + ENCCYCLE (6); + ENCCYCLE (7); + + c ^= m_k[4]; + d ^= m_k[5]; + a ^= m_k[6]; + b ^= m_k[7]; + + Block::Put(xorBlock, outBlock)(c)(d)(a)(b); +} + +void Twofish::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 x, y, a, b, c, d; + + Block::Get(inBlock)(c)(d)(a)(b); + + c ^= m_k[4]; + d ^= m_k[5]; + a ^= m_k[6]; + b ^= m_k[7]; + + const word32 *k = m_k+8; + DECCYCLE (7); + DECCYCLE (6); + DECCYCLE (5); + DECCYCLE (4); + DECCYCLE (3); + DECCYCLE (2); + DECCYCLE (1); + DECCYCLE (0); + + a ^= m_k[0]; + b ^= m_k[1]; + c ^= m_k[2]; + d ^= m_k[3]; + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/twofish.h b/external/ours/library/crypto/src/shared/original/twofish.h index bc7a84f43..16284b486 100755 --- a/external/ours/library/crypto/src/shared/original/twofish.h +++ b/external/ours/library/crypto/src/shared/original/twofish.h @@ -1,53 +1,64 @@ -#ifndef CRYPTOPP_TWOFISH_H -#define CRYPTOPP_TWOFISH_H - -/** \file -*/ - -#include "cryptlib.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// base class, do not use directly -class Twofish : public FixedBlockSize<16>, public VariableKeyLength<16, 0, 32> -{ -protected: - Twofish(const byte *userKey, unsigned int keylength); - static word32 h0(word32 x, const word32 *key, unsigned int kLen); - static word32 h(word32 x, const word32 *key, unsigned int kLen); - - static const byte q[2][256]; - static const word32 mds[4][256]; - - SecBlock m_k; - SecBlock m_s; -}; - -/// Twofish -class TwofishEncryption : public Twofish -{ -public: - TwofishEncryption(const byte *userKey, unsigned int keylength=DEFAULT_KEYLENGTH) - : Twofish(userKey, keylength) {} - - void ProcessBlock(const byte *inBlock, byte * outBlock) const; - void ProcessBlock(byte * inoutBlock) const - {TwofishEncryption::ProcessBlock(inoutBlock, inoutBlock);} -}; - -/// Twofish -class TwofishDecryption : public Twofish -{ -public: - TwofishDecryption(const byte *userKey, unsigned int keylength=DEFAULT_KEYLENGTH) - : Twofish(userKey, keylength) {} - - void ProcessBlock(const byte *inBlock, byte * outBlock) const; - void ProcessBlock(byte * inoutBlock) const - {TwofishDecryption::ProcessBlock(inoutBlock, inoutBlock);} -}; - -NAMESPACE_END - -#endif +// twofish.h - originally written and placed in the public domain by Wei Dai + +/// \file twofish.h +/// \brief Classes for the Twofish block cipher + +#ifndef CRYPTOPP_TWOFISH_H +#define CRYPTOPP_TWOFISH_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Twofish block cipher information +/// \since Crypto++ 3.1 +struct Twofish_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8>, FixedRounds<16> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Twofish";} +}; + +/// \brief Twofish block cipher +/// \sa Twofish +/// \since Crypto++ 3.1 +class Twofish : public Twofish_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static word32 h0(word32 x, const word32 *key, unsigned int kLen); + static word32 h(word32 x, const word32 *key, unsigned int kLen); + + static const byte q[2][256]; + static const word32 mds[4][256]; + + FixedSizeSecBlock m_k; + FixedSizeSecBlock m_s; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Twofish::Encryption TwofishEncryption; +typedef Twofish::Decryption TwofishDecryption; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/validat0.cpp b/external/ours/library/crypto/src/shared/original/validat0.cpp new file mode 100755 index 000000000..a32bcf019 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat0.cpp @@ -0,0 +1,1669 @@ +// validat0.cpp - originally written and placed in the public domain by Wei Dai and Jeffrey Walton +// Routines in this source file are only tested in Debug builds. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "asn.h" +#include "gf2n.h" +#include "default.h" +#include "integer.h" +#include "polynomi.h" +#include "channels.h" + +#include "ida.h" +#include "gzip.h" +#include "zlib.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +// Issue 64: "PolynomialMod2::operator<<=", http://github.com/weidai11/cryptopp/issues/64 +bool TestPolynomialMod2() +{ + std::cout << "\nTesting PolynomialMod2 bit operations...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + const unsigned int start = 0; + const unsigned int stop = 4 * WORD_BITS + 1; + + for (unsigned int i = start; i < stop; i++) + { + PolynomialMod2 p(1); + p <<= i; + + Integer n(Integer::One()); + n <<= i; + + std::ostringstream oss1; + oss1 << p; + + std::string str1, str2; + + // str1 needs the commas removed used for grouping + str1 = oss1.str(); + str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end()); + + // str1 needs the trailing 'b' removed + str1.erase(str1.end() - 1); + + // str2 is fine as-is + str2 = IntToString(n, 2); + + pass1 &= (str1 == str2); + } + + for (unsigned int i = start; i < stop; i++) + { + const word w((word)SIZE_MAX); + + PolynomialMod2 p(w); + p <<= i; + + Integer n(Integer::POSITIVE, static_cast(w)); + n <<= i; + + std::ostringstream oss1; + oss1 << p; + + std::string str1, str2; + + // str1 needs the commas removed used for grouping + str1 = oss1.str(); + str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end()); + + // str1 needs the trailing 'b' removed + str1.erase(str1.end() - 1); + + // str2 is fine as-is + str2 = IntToString(n, 2); + + pass2 &= (str1 == str2); + } + + RandomNumberGenerator& prng = GlobalRNG(); + for (unsigned int i = start; i < stop; i++) + { + word w; // Cast to lword due to Visual Studio + prng.GenerateBlock((byte*)&w, sizeof(w)); + + PolynomialMod2 p(w); + p <<= i; + + Integer n(Integer::POSITIVE, static_cast(w)); + n <<= i; + + std::ostringstream oss1; + oss1 << p; + + std::string str1, str2; + + // str1 needs the commas removed used for grouping + str1 = oss1.str(); + str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end()); + + // str1 needs the trailing 'b' removed + str1.erase(str1.end() - 1); + + // str2 is fine as-is + str2 = IntToString(n, 2); + + if (str1 != str2) + { + std::cout << " Oops..." << "\n"; + std::cout << " random: " << std::hex << n << std::dec << "\n"; + std::cout << " str1: " << str1 << "\n"; + std::cout << " str2: " << str2 << "\n"; + } + + pass3 &= (str1 == str2); + } + + std::cout << (!pass1 ? "FAILED" : "passed") << ": " << "1 shifted over range [" << std::dec << start << "," << stop << "]" << "\n"; + std::cout << (!pass2 ? "FAILED" : "passed") << ": " << "0x" << std::hex << word(SIZE_MAX) << std::dec << " shifted over range [" << start << "," << stop << "]" << "\n"; + std::cout << (!pass3 ? "FAILED" : "passed") << ": " << "random values shifted over range [" << std::dec << start << "," << stop << "]" << "\n"; + + return pass1 && pass2 && pass3; +} +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +bool TestCompressors() +{ + std::cout << "\nTesting Compressors and Decompressors...\n\n"; + bool fail1 = false, fail2 = false, fail3 = false; + const unsigned int COMP_COUNT = 64; + + try + { + // Gzip uses Adler32 checksums. We expect a failure to happen on occasion. + // If we see more than 2 failures in a run of 128, then we need to investigate. + unsigned int truncatedCount=0; + for (unsigned int i = 0; i= 2) + { + std::cout << "FAILED: Gzip failed to detect a truncated stream\n"; + fail1 = true; + } + } + catch (const Exception&) {} + } + } + catch (const Exception& ex) + { + std::cout << "FAILED: " << ex.what() << "\n"; + fail1 = true; + } + + // ************************************************************** + + // Gzip Filename, Filetime and Comment + try + { + std::string filename = "test.txt"; + std::string comment = "This is a test"; + word32 filetime = GlobalRNG().GenerateWord32(4, 0xffffff); + + AlgorithmParameters params = MakeParameters(Name::FileTime(), (int)filetime) + (Name::FileName(), ConstByteArrayParameter(filename.c_str(), false)) + (Name::Comment(), ConstByteArrayParameter(comment.c_str(), false)); + + std::string src, dest; + unsigned int len = GlobalRNG().GenerateWord32(4, 0xfff); + + RandomNumberSource(GlobalRNG(), len, true, new StringSink(src)); + Gunzip unzip(new StringSink(dest)); + StringSource(src, true, new Gzip(params, new Redirector(unzip))); + + if (filename != unzip.GetFilename()) + throw Exception(Exception::OTHER_ERROR, "Failed to retrieve filename"); + + if (filetime != unzip.GetFiletime()) + throw Exception(Exception::OTHER_ERROR, "Failed to retrieve filetime"); + + if (comment != unzip.GetComment()) + throw Exception(Exception::OTHER_ERROR, "Failed to retrieve comment"); + + std::cout << "passed: filenames, filetimes and comments\n"; + } + catch (const Exception& ex) + { + std::cout << "FAILED: " << ex.what() << "\n"; + } + + // Unzip random data. See if we can induce a crash + for (unsigned int i = 0; i strShares(shares); + vector_member_ptrs strSinks(shares); + std::string channel; + + // ********** Create Shares + for (unsigned int i=0; i(i); + strSinks[i]->Put((const byte *)channel.data(), CHID_LENGTH); + channelSwitch->AddRoute(channel, *strSinks[i], DEFAULT_CHANNEL); + } + source.PumpAll(); + + // ********** Randomize shares + + GlobalRNG().Shuffle(strShares.begin(), strShares.end()); + + // ********** Recover secret + try + { + std::string recovered; + InformationRecovery recovery(threshold, new StringSink(recovered)); + + vector_member_ptrs strSources(threshold); + channel.resize(CHID_LENGTH); + + for (unsigned int i=0; iPump(CHID_LENGTH); + strSources[i]->Get((byte*)&channel[0], CHID_LENGTH); + strSources[i]->Attach(new ChannelSwitch(recovery, channel)); + } + + while (strSources[0]->Pump(256)) + { + for (unsigned int i=1; iPump(256); + } + + for (unsigned int i=0; iPumpAll(); + + fail = (message != recovered); + } + catch (const Exception&) + { + fail = true; + } + + pass &= !fail; + } + + std::cout << (fail ? "FAILED:" : "passed:") << " " << INFORMATION_SHARES << " information dispersals\n"; + + // ********** Secret Sharing **********// + + for (unsigned int shares=3; shares strShares(shares); + vector_member_ptrs strSinks(shares); + std::string channel; + + // ********** Create Shares + for (unsigned int i=0; i(i); + strSinks[i]->Put((const byte *)channel.data(), CHID_LENGTH); + channelSwitch->AddRoute(channel, *strSinks[i], DEFAULT_CHANNEL); + } + source.PumpAll(); + + // ********** Randomize shares + + GlobalRNG().Shuffle(strShares.begin(), strShares.end()); + + // ********** Recover secret + try + { + std::string recovered; + SecretRecovery recovery(threshold, new StringSink(recovered)); + + vector_member_ptrs strSources(threshold); + channel.resize(CHID_LENGTH); + for (unsigned int i=0; iPump(CHID_LENGTH); + strSources[i]->Get((byte*)&channel[0], CHID_LENGTH); + strSources[i]->Attach(new ChannelSwitch(recovery, channel)); + } + + while (strSources[0]->Pump(256)) + { + for (unsigned int i=1; iPump(256); + } + + for (unsigned int i=0; iPumpAll(); + + fail = (message != recovered); + } + catch (const Exception&) + { + fail = true; + } + + pass &= !fail; + } + + std::cout << (fail ? "FAILED:" : "passed:") << " " << SECRET_SHARES << " secret sharings\n"; + + return pass; +} + +bool TestRounding() +{ + std::cout << "\nTesting RoundUpToMultipleOf/RoundDownToMultipleOf...\n\n"; + bool pass=true, fail; + + // ********** byte **********// + try + { + const byte v=0, b=0x08; + byte r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, byte, no overflow\n"; + + try + { + const byte v=1, b=0x08; + byte r=RoundUpToMultipleOf(v, b); + fail = (r != b); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, byte, no overflow\n"; + + try + { + const byte v=0x08, b=0x08; + byte r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, byte, no overflow\n"; + + try + { + const byte v=0xf7, b=0x08; + byte r=RoundUpToMultipleOf(v, b); + fail = (r != 0xf8); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, byte, no overflow\n"; + + try + { + const byte v=0xf8, b=0x08; + byte r=RoundUpToMultipleOf(v, b); + fail = (r != 0xf8); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, byte, no overflow\n"; + + try + { + const byte v=0xf9, b=0x08; + byte r=RoundUpToMultipleOf(v, b); + CRYPTOPP_UNUSED(r); + fail = true; + } + catch(const Exception&) + { + fail = false; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, byte, overflow\n"; + + // ********** word16 **********// + try + { + const word16 v=0, b=0x08; + word16 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word16, no overflow\n"; + + try + { + const word16 v=1, b=0x08; + word16 r=RoundUpToMultipleOf(v, b); + fail = (r != b); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word16, no overflow\n"; + + try + { + const word16 v=0x08, b=0x08; + word16 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word16, no overflow\n"; + + try + { + const word16 v=0xfff7, b=0x08; + word16 r=RoundUpToMultipleOf(v, b); + fail = (r != 0xfff8); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word16, no overflow\n"; + + try + { + const word16 v=0xfff8, b=0x08; + word16 r=RoundUpToMultipleOf(v, b); + fail = (r != 0xfff8); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word16, no overflow\n"; + + try + { + const word16 v=0xfff9, b=0x08; + word16 r=RoundUpToMultipleOf(v, b); + CRYPTOPP_UNUSED(r); + fail = true; + } + catch(const Exception&) + { + fail = false; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word16, overflow\n"; + + // ********** word32 **********// + try + { + const word32 v=0, b=0x08; + word32 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word32, no overflow\n"; + + try + { + const word32 v=1, b=0x08; + word32 r=RoundUpToMultipleOf(v, b); + fail = (r != b); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word32, no overflow\n"; + + try + { + const word32 v=0x08, b=0x08; + word32 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word32, no overflow\n"; + + try + { + const word32 v=0xfffffff7, b=0x08; + word32 r=RoundUpToMultipleOf(v, b); + fail = (r != 0xfffffff8); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word32, no overflow\n"; + + try + { + const word32 v=0xfffffff8, b=0x08; + word32 r=RoundUpToMultipleOf(v, b); + fail = (r != 0xfffffff8); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word32, no overflow\n"; + + try + { + const word32 v=0xfffffff9, b=0x08; + word32 r=RoundUpToMultipleOf(v, b); + CRYPTOPP_UNUSED(r); + fail = true; + } + catch(const Exception&) + { + fail = false; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word32, overflow\n"; + + // ********** word64 **********// + try + { + const word64 v=0, b=0x08; + word64 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word64, no overflow\n"; + + try + { + const word64 v=1, b=0x08; + word64 r=RoundUpToMultipleOf(v, b); + fail = (r != b); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word64, no overflow\n"; + + try + { + const word64 v=0x08, b=0x08; + word64 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word64, no overflow\n"; + + try + { + const word64 v=W64LIT(0xffffffffffffff7), b=0x08; + word64 r=RoundUpToMultipleOf(v, b); + fail = (r != W64LIT(0xffffffffffffff8)); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word64, no overflow\n"; + + try + { + const word64 v=W64LIT(0xffffffffffffff8), b=0x08; + word64 r=RoundUpToMultipleOf(v, b); + fail = (r != W64LIT(0xffffffffffffff8)); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word64, no overflow\n"; + + try + { + const word64 v=W64LIT(0xfffffffffffffff9), b=0x08; + word64 r=RoundUpToMultipleOf(v, b); + CRYPTOPP_UNUSED(r); + fail = true; + } + catch(const Exception&) + { + fail = false; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word64, overflow\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + // ********** word128 **********// + try + { + const word128 v=0, b=0x08; + word128 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word128, no overflow\n"; + + try + { + const word128 v=1, b=0x08; + word128 r=RoundUpToMultipleOf(v, b); + fail = (r != b); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word128, no overflow\n"; + + try + { + const word128 v=0x08, b=0x08; + word128 r=RoundUpToMultipleOf(v, b); + fail = (r != v); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word128, no overflow\n"; + + try + { + // http://stackoverflow.com/q/31461318/608639 + const word128 h = ((word128)W64LIT(0xffffffffffffffff)) << 64U; + const word128 v = h | (word128)W64LIT(0xfffffffffffffff7), b=0x08; + word128 r=RoundUpToMultipleOf(v, b); + fail = (r != (h | (word128)W64LIT(0xfffffffffffffff8))); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word128, no overflow\n"; + + try + { + const word128 h = ((word128)W64LIT(0xffffffffffffffff)) << 64U; + const word128 v = h | (word128)W64LIT(0xfffffffffffffff8), b=0x08; + word128 r=RoundUpToMultipleOf(v, b); + fail = (r != (h | (word128)W64LIT(0xfffffffffffffff8))); + } + catch(const Exception&) + { + fail = true; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word128, no overflow\n"; + + try + { + const word128 h = ((word128)W64LIT(0xffffffffffffffff)) << 64U; + const word128 v = h | (word128)W64LIT(0xfffffffffffffff9), b=0x08; + word128 r=RoundUpToMultipleOf(v, b); + CRYPTOPP_UNUSED(r); + fail = true; + } + catch(const Exception&) + { + fail = false; + } + + pass = !fail && pass; + std::cout << (fail ? "FAILED:" : "passed:") << " RoundUpToMultipleOf, word128, overflow\n"; +#endif + + return pass; +} +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +struct ASN1_TestTuple +{ + ASN1_TestTuple(int tag, int result, const char* data, size_t len) { + m_result = result; + m_tag = tag; + m_data = std::string(data, len); + } + + std::string Name() const { + return Id2String(); + } + + const byte* Data() const { + return ConstBytePtr(m_data); + } + + size_t Size() const { + return BytePtrSize(m_data); + } + + int Tag() const { + return m_tag; + } + + int Result() const { + return m_result; + } + + std::string Id2String() const + { + switch(m_tag) + { + case BIT_STRING: + return "BIT_STRING"; + case OCTET_STRING: + return "OCTET_STRING"; + case INTEGER: + return "INTEGER"; + case UTF8_STRING: + return "UTF8_STRING"; + case PRINTABLE_STRING: + return "PRINTABLE_STRING"; + case IA5_STRING: + return "IA5_STRING"; + default: + return "Unknown"; + } + } + +protected: + std::string m_data; + int m_tag, m_result; +}; + +bool RunASN1TestSet(const ASN1_TestTuple asnTuples[], size_t count) +{ + bool pass=true, fail; + + // Disposition + enum {REJECT=3, ACCEPT=4}; + + for(size_t i=0; i(as2, unused5, byte(INTEGER), 0, W64LIT(0xffffffffffffffff)); + break; + + case UTF8_STRING: case PRINTABLE_STRING: case IA5_STRING: + BERDecodeTextString(as1, unused2, tag); + break; + + default: + BERGeneralDecoder(as1, tag); + break; + } + + fail = thisTest.Result() != ACCEPT; + } + catch(const Exception&) + { + fail = thisTest.Result() != REJECT; + } + + std::cout << (fail ? "FAILED:" : "passed:") << (thisTest.Result() == ACCEPT ? " accept " : " reject "); + std::cout << asnTuples[i].Name() << " " << val << "\n"; + pass = !fail && pass; + } + + return pass; +} + +bool TestASN1Parse() +{ + std::cout << "\nTesting ASN.1 parser...\n\n"; + + bool pass = true; + + // Disposition + enum {REJECT=3, ACCEPT=4}; + + // All the types Crypto++ recognizes. + // "C" is one content octet with value 0x43. + const ASN1_TestTuple bitStrings[] = + { + // The first "\x00" content octet is the "initial octet" representing unused bits. In the + // primitive encoding form, there may be zero, one or more contents after the initial octet. + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x01" "\x00", 3), // definite length, short form, initial octet, zero subsequent octets + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x01" "\x08", 3), // definite length, short form, initial octet, zero subsequent octets + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x02" "\x00" "C", 4), // definite length, short form, expected subsequent octets + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x02" "\x08" "C", 4), // too many unused bits + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x7F" "\x00" "C", 4), // runt or underrun + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x81\x01" "\x00", 4), // definite length, long form, initial octet, zero subsequent octets + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x81\x01" "\x08", 4), // definite length, long form, initial octet, zero subsequent octets + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x81\x02" "\x00" "C", 5), // definite length, long form + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x81\x02" "\x08" "C", 5), // too many unused bits + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x81\xff" "\x00" "C", 5), // runt or underrun + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x82\x00\x02" "\x00" "C", 6), // definite length, long form + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x82\x00\x02" "\x08" "C", 6), // too many unused bits + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x82\xff\xff" "\x00" "C", 6), // runt or underrun + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x83\x00\x00\x02" "\x00" "C", 7), // definite length, long form + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x83\x00\x00\x02" "\x08" "C", 7), // too many unused bits + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x83\xff\xff\xff" "\x00" "C", 7), // runt or underrun + ASN1_TestTuple(BIT_STRING, ACCEPT, "\x03\x84\x00\x00\x00\x02" "\x00" "C", 8), // definite length, long form + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x84\x00\x00\x00\x02" "\x08" "C", 8), // too many unused bits + ASN1_TestTuple(BIT_STRING, REJECT, "\x03\x84\xff\xff\xff\xff" "\x00" "C", 8), // <== Issue 346; requires large allocation + }; + + pass = RunASN1TestSet(bitStrings, COUNTOF(bitStrings)) && pass; + + const ASN1_TestTuple octetStrings[] = + { + // In the primitive encoding form, there may be zero, one or more contents. + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x00", 2), // definite length, short form, zero content octets + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x01" "C", 3), // definite length, short form, expected content octets + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x02" "C", 3), // runt or underrun + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x7F" "C", 3), // runt or underrun + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x81\x00", 3), // definite length, long form, zero content octets + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x81\x01" "C", 4), // definite length, long form, expected content octets + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x81\x02" "C", 4), // runt or underrun + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x81\xff" "C", 4), // runt or underrun + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x82\x00\x00", 4), // definite length, long form, zero content octets + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x82\x00\x01" "C", 5), // definite length, long form, expected content octets + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x82\x00\x02" "C", 5), // runt or underrun + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x82\xff\xff" "C", 5), // runt or underrun + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x83\x00\x00\x00", 5), // definite length, long form, zero content octets + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x83\x00\x00\x01" "C", 6), // definite length, long form, expected content octets + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x83\x00\x00\x02" "C", 6), // runt or underrun + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x83\xff\xff\xff" "C", 6), // runt or underrun + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x84\x00\x00\x00\x00", 6), // definite length, long form, zero content octets + ASN1_TestTuple(OCTET_STRING, ACCEPT, "\x04\x84\x00\x00\x00\x01" "C", 7), // definite length, long form, expected content octets + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x84\x00\x00\x00\x02" "C", 7), // runt or underrun + ASN1_TestTuple(OCTET_STRING, REJECT, "\x04\x84\xff\xff\xff\xff" "C", 7), // <== Issue 346; requires large allocation + }; + + pass = RunASN1TestSet(octetStrings, COUNTOF(octetStrings)) && pass; + + const ASN1_TestTuple utf8Strings[] = + { + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x00", 2), // definite length, short form, zero content octets + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x01" "C", 3), // definite length, short form, expected content octets + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x02" "C", 3), // runt or underrun + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x7F" "C", 3), // runt or underrun + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x81\x00", 3), // definite length, long form, zero content octets + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x81\x01" "C", 4), // definite length, long form, expected content octets + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x81\x02" "C", 4), // runt or underrun + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x81\xff" "C", 4), // runt or underrun + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x82\x00\x00", 4), // definite length, long form, zero content octets + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x82\x00\x01" "C", 5), // definite length, long form, expected content octets + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x82\x00\x02" "C", 5), // runt or underrun + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x82\xff\xff" "C", 5), // runt or underrun + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x83\x00\x00\x00", 5), // definite length, long form, zero content octets + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x83\x00\x00\x01" "C", 6), // definite length, long form, expected content octets + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x83\x00\x00\x02" "C", 6), // runt or underrun + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x83\xff\xff\xff" "C", 6), // runt or underrun + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x84\x00\x00\x00\x00", 6), // definite length, long form, zero content octets + ASN1_TestTuple(UTF8_STRING, ACCEPT, "\x0c\x84\x00\x00\x00\x01" "C", 7), // definite length, long form, expected content octets + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x84\x00\x00\x00\x02" "C", 7), // runt or underrun + ASN1_TestTuple(UTF8_STRING, REJECT, "\x0c\x84\xff\xff\xff\xff" "C", 7), // <== Issue 346; requires large allocation + }; + + pass = RunASN1TestSet(utf8Strings, COUNTOF(utf8Strings)) && pass; + + const ASN1_TestTuple printableStrings[] = + { + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x00", 2), // definite length, short form, zero content octets + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x01" "C", 3), // definite length, short form, expected content octets + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x02" "C", 3), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x7F" "C", 3), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x81\x00", 3), // definite length, long form, zero content octets + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x81\x01" "C", 4), // definite length, long form, expected content octets + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x81\x02" "C", 4), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x81\xff" "C", 4), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x82\x00\x00", 4), // definite length, long form, zero content octets + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x82\x00\x01" "C", 5), // definite length, long form, expected content octets + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x82\x00\x02" "C", 5), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x82\xff\xff" "C", 5), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x83\x00\x00\x00", 5), // definite length, long form, zero content octets + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x83\x00\x00\x01" "C", 6), // definite length, long form, expected content octets + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x83\x00\x00\x02" "C", 6), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x83\xff\xff\xff" "C", 6), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x84\x00\x00\x00\x00", 6), // definite length, long form, zero content octets + ASN1_TestTuple(PRINTABLE_STRING, ACCEPT, "\x13\x84\x00\x00\x00\x01" "C", 7), // definite length, long form, expected content octets + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x84\x00\x00\x00\x02" "C", 7), // runt or underrun + ASN1_TestTuple(PRINTABLE_STRING, REJECT, "\x13\x84\xff\xff\xff\xff" "C", 7), // <== Issue 346; requires large allocation + }; + + pass = RunASN1TestSet(printableStrings, COUNTOF(printableStrings)) && pass; + + const ASN1_TestTuple ia5Strings[] = + { + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x00", 2), // definite length, short form, zero content octets + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x01" "C", 3), // definite length, short form, expected content octets + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x02" "C", 3), // runt or underrun + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x7F" "C", 3), // runt or underrun + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x81\x00", 3), // definite length, long form, zero content octets + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x81\x01" "C", 4), // definite length, long form, expected content octets + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x81\x02" "C", 4), // runt or underrun + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x81\xff" "C", 4), // runt or underrun + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x82\x00\x00", 4), // definite length, long form, zero content octets + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x82\x00\x01" "C", 5), // definite length, long form, expected content octets + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x82\x00\x02" "C", 5), // runt or underrun + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x82\xff\xff" "C", 5), // runt or underrun + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x83\x00\x00\x00", 5), // definite length, long form, zero content octets + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x83\x00\x00\x01" "C", 6), // definite length, long form, expected content octets + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x83\x00\x00\x02" "C", 6), // runt or underrun + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x83\xff\xff\xff" "C", 6), // runt or underrun + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x84\x00\x00\x00\x00", 6), // definite length, long form, zero content octets + ASN1_TestTuple(IA5_STRING, ACCEPT, "\x16\x84\x00\x00\x00\x01" "C", 7), // definite length, long form, expected content octets + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x84\x00\x00\x00\x02" "C", 7), // runt or underrun + ASN1_TestTuple(IA5_STRING, REJECT, "\x16\x84\xff\xff\xff\xff" "C", 7), // <== Issue 346; requires large allocation + }; + + pass = RunASN1TestSet(ia5Strings, COUNTOF(ia5Strings)) && pass; + + const ASN1_TestTuple integerValues[] = + { + // 8.3.1 The encoding of an integer value shall be primitive. The contents octets shall consist of one or more octets. + ASN1_TestTuple(INTEGER, REJECT, "\x02\x00", 2), // definite length, short form, zero content octets + ASN1_TestTuple(INTEGER, ACCEPT, "\x02\x01" "C", 3), // definite length, short form, expected content octets + ASN1_TestTuple(INTEGER, REJECT, "\x02\x02" "C", 3), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x7F" "C", 3), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x81\x00", 3), // definite length, long form, zero content octets + ASN1_TestTuple(INTEGER, ACCEPT, "\x02\x81\x01" "C", 4), // definite length, long form, expected content octets + ASN1_TestTuple(INTEGER, REJECT, "\x02\x81\x02" "C", 4), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x81\xff" "C", 4), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x82\x00\x00", 4), // definite length, long form, zero content octets + ASN1_TestTuple(INTEGER, ACCEPT, "\x02\x82\x00\x01" "C", 5), // definite length, long form, expected content octets + ASN1_TestTuple(INTEGER, REJECT, "\x02\x82\x00\x02" "C", 5), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x82\xff\xff" "C", 5), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x83\x00\x00\x00", 5), // definite length, long form, zero content octets + ASN1_TestTuple(INTEGER, ACCEPT, "\x02\x83\x00\x00\x01" "C", 6), // definite length, long form, expected content octets + ASN1_TestTuple(INTEGER, REJECT, "\x02\x83\x00\x00\x02" "C", 6), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x83\xff\xff\xff" "C", 6), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x84\x00\x00\x00\x00", 6), // definite length, long form, zero content octets + ASN1_TestTuple(INTEGER, ACCEPT, "\x02\x84\x00\x00\x00\x01" "C", 7), // definite length, long form, expected content octets + ASN1_TestTuple(INTEGER, REJECT, "\x02\x84\x00\x00\x00\x02" "C", 7), // runt or underrun + ASN1_TestTuple(INTEGER, REJECT, "\x02\x84\xff\xff\xff\xff" "C", 7), // <== Issue 346; requires large allocation + }; + + pass = RunASN1TestSet(integerValues, COUNTOF(integerValues)) && pass; + + return pass; +} + +bool TestASN1Functions() +{ + std::cout << "\nTesting ASN.1 functions...\n\n"; + + bool pass = true, fail; + + { + const std::string message = "Now is the time for all good men to come to the aide of their country"; + ByteQueue encoded, reencoded, decoded; + size_t len = 0, rlen = 0; + + len = DEREncodeOctetString(encoded, ConstBytePtr(message), BytePtrSize(message)); + DERReencode(encoded, reencoded); + rlen = reencoded.MaxRetrievable(); + (void)BERDecodeOctetString(reencoded, decoded); + + std::string recovered; + StringSink sink(recovered); + decoded.TransferTo(sink); + + fail = (len != rlen || message != recovered); + pass = pass && !fail; + CRYPTOPP_ASSERT(!fail); + + std::cout << (fail ? "FAILED" : "passed") << " "; + std::cout << "DEREncodeOctetString" << "\n"; + std::cout << (fail ? "FAILED" : "passed") << " "; + std::cout << "BERDecodeOctetString" << "\n"; + } + + { + const std::string message = "Now is the time for all good men to come to the aide of their country"; + const int asnStringTypes[] = {UTF8_STRING, PRINTABLE_STRING, T61_STRING, VIDEOTEXT_STRING, IA5_STRING, VISIBLE_STRING}; + unsigned int failed = 0; + size_t len = 0, rlen = 0, i = 0; + + for (i = 0; i < COUNTOF(asnStringTypes); ++i) + { + ByteQueue encoded, reencoded, decoded; + std::string recovered; + + len = DEREncodeTextString(encoded, ConstBytePtr(message), BytePtrSize(message), asnStringTypes[i]); + DERReencode(encoded, reencoded); + rlen = reencoded.MaxRetrievable(); + (void)BERDecodeTextString(reencoded, recovered, asnStringTypes[i]); + + fail = (len != rlen || message != recovered); + if (fail) failed++; + CRYPTOPP_ASSERT(!fail); + } + + failed ? fail = true : fail = false; + pass = pass && !fail; + + std::cout << (fail ? "FAILED" : "passed") << " "; + std::cout << "DEREncodeTextString" << "\n"; + std::cout << (fail ? "FAILED" : "passed") << " "; + std::cout << "DEREncodeTextString" << "\n"; + } + + { + const byte date[] = "Sun, 21 Mar 2021 01:00:00 +0000"; + SecByteBlock message; message.Assign(date, sizeof(date)-1); + const int asnDateTypes[] = {UTC_TIME, GENERALIZED_TIME}; + unsigned int failed = 0; + size_t i = 0; + + for (i = 0; i < COUNTOF(asnDateTypes); ++i) + { + ByteQueue encoded, decoded; + SecByteBlock recovered; + + (void)DEREncodeDate(encoded, message, asnDateTypes[i]); + (void)BERDecodeDate(encoded, recovered, asnDateTypes[i]); + + fail = (message != recovered); + if (fail) failed++; + CRYPTOPP_ASSERT(!fail); + } + + failed ? fail = true : fail = false; + pass = pass && !fail; + + std::cout << (fail ? "FAILED" : "passed") << " "; + std::cout << "DEREncodeDate" << "\n"; + std::cout << (fail ? "FAILED" : "passed") << " "; + std::cout << "BERDecodeDate" << "\n"; + } + + return pass; +} + +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +bool TestStringSink() +{ + try + { + std::string in = "The quick brown fox jumps over the lazy dog"; + + std::string str; + StringSource s1(in, true, new StringSink(str)); + + std::vector vec; + StringSource s2(in, true, new VectorSink(vec)); + + std::vector vec2; + VectorSource s3(vec, true, new VectorSink(vec2)); + + return str.size() == vec.size() && + std::equal(str.begin(), str.end(), vec.begin()) && + vec.size() == vec2.size() && + std::equal(vec.begin(), vec.end(), vec2.begin()); + } + catch(const std::exception&) + { + } + return false; +} +#endif + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat1.cpp b/external/ours/library/crypto/src/shared/original/validat1.cpp new file mode 100755 index 000000000..db5238802 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat1.cpp @@ -0,0 +1,1225 @@ +// validat1.cpp - originally written and placed in the public domain by Wei Dai and Jeffrey Walton +// Routines in this source file are only tested in Debug builds. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "secblock.h" +#include "gzip.h" +#include "zlib.h" + +#if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +# include "ppc_simd.h" +#endif + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +bool TestSecBlock() +{ + std::cout << "\nTesting SecBlock...\n\n"; + + bool pass1=true, pass2=true, pass3=true, pass4=true, pass5=true, pass6=true, pass7=true, temp=false; + + //************ Allocators ************// + + { + std::basic_string, AllocatorWithCleanup > s1; + std::basic_string, AllocatorWithCleanup > s2; + s1.resize(1024); s2.resize(1024); + + std::vector > v1; + std::vector > v2; + v1.resize(1024); v2.resize(1024); + } + + //********** Zeroized block **********// + + { + // NULL ptr with a size means to create a new SecBlock with all elements zero'd + SecByteBlock z1(NULLPTR, 256); + temp = true; + + for (size_t i = 0; i < z1.size(); i++) + temp &= (z1[i] == 0); + + pass1 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Zeroized byte array\n"; + + SecBlock z2(NULLPTR, 256); + temp = true; + + for (size_t i = 0; i < z2.size(); i++) + temp &= (z2[i] == 0); + + pass1 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Zeroized word32 array\n"; + + SecBlock z3(NULLPTR, 256); + temp = true; + + for (size_t i = 0; i < z3.size(); i++) + temp &= (z3[i] == 0); + + pass1 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Zeroized word64 array\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + SecBlock z4(NULLPTR, 256); + temp = true; + + for (size_t i = 0; i < z4.size(); i++) + temp &= (z4[i] == 0); + + pass1 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Zeroized word128 array\n"; +#endif + } + + //********** Non-zero'd block **********// + + { + SecByteBlock z1(NULLPTR, 256); + z1.SetMark(0); + + SecBlock z2(NULLPTR, 256); + z2.SetMark(0); + + SecBlock z3(NULLPTR, 256); + z3.SetMark(0); + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + SecBlock z4(NULLPTR, 256); + z4.SetMark(0); +#endif + } + + //********** Assign **********// + + try + { + SecByteBlock a, b; + temp = true; + + a.Assign((const byte*)"a", 1); + b.Assign((const byte*)"b", 1); + + temp &= (a.SizeInBytes() == 1); + temp &= (b.SizeInBytes() == 1); + temp &= (a[0] == 'a'); + temp &= (b[0] == 'b'); + + a.Assign((const byte*)"ab", 2); + b.Assign((const byte*)"cd", 2); + + temp &= (a.SizeInBytes() == 2); + temp &= (b.SizeInBytes() == 2); + temp &= (a[0] == 'a' && a[1] == 'b'); + temp &= (b[0] == 'c' && b[1] == 'd'); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass2 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Assign byte\n"; + + try + { + SecBlock a, b; + temp = true; + + word32 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + temp &= (a.SizeInBytes() == 4); + temp &= (b.SizeInBytes() == 4); + temp &= (a[0] == 1); + temp &= (b[0] == 2); + + word32 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + temp &= (a.SizeInBytes() == 8); + temp &= (b.SizeInBytes() == 8); + temp &= (a[0] == 1 && a[1] == 2); + temp &= (b[0] == 3 && b[1] == 4); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass2 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Assign word32\n"; + + try + { + SecBlock a, b; + temp = true; + + word64 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + temp &= (a.SizeInBytes() == 8); + temp &= (b.SizeInBytes() == 8); + temp &= (a[0] == 1); + temp &= (b[0] == 2); + + word64 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + temp &= (a.SizeInBytes() == 16); + temp &= (b.SizeInBytes() == 16); + temp &= (a[0] == 1 && a[1] == 2); + temp &= (b[0] == 3 && b[1] == 4); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass2 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Assign word64\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + try + { + SecBlock a, b; + temp = true; + + word128 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + temp &= (a.SizeInBytes() == 16); + temp &= (b.SizeInBytes() == 16); + temp &= (a[0] == 1); + temp &= (b[0] == 2); + + word128 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + temp &= (a.SizeInBytes() == 32); + temp &= (b.SizeInBytes() == 32); + temp &= (a[0] == 1 && a[1] == 2); + temp &= (b[0] == 3 && b[1] == 4); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass2 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Assign word128\n"; +#endif + + //********** Append **********// + + try + { + SecByteBlock a, b; + temp = true; + + a.Assign((const byte*)"a", 1); + b.Assign((const byte*)"b", 1); + + a += b; + temp &= (a.SizeInBytes() == 2); + temp &= (a[0] == 'a' && a[1] == 'b'); + + a.Assign((const byte*)"ab", 2); + b.Assign((const byte*)"cd", 2); + + a += b; + temp &= (a.SizeInBytes() == 4); + temp &= (a[0] == 'a' && a[1] == 'b' && a[2] == 'c' && a[3] == 'd'); + + a.Assign((const byte*)"a", 1); + + a += a; + temp &= (a.SizeInBytes() == 2); + temp &= (a[0] == 'a' && a[1] == 'a'); + + a.Assign((const byte*)"ab", 2); + + a += a; + temp &= (a.SizeInBytes() == 4); + temp &= (a[0] == 'a' && a[1] == 'b' && a[2] == 'a' && a[3] == 'b'); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass3 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Append byte\n"; + + try + { + SecBlock a, b; + temp = true; + + const word32 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + a += b; + temp &= (a.SizeInBytes() == 8); + temp &= (a[0] == 1 && a[1] == 2); + + const word32 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + a += b; + temp &= (a.SizeInBytes() == 16); + temp &= (a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4); + + a.Assign(one, 1); + + a += a; + temp &= (a.SizeInBytes() == 8); + temp &= (a[0] == 1 && a[1] == 1); + + a.Assign(three, 2); + + a += a; + temp &= (a.SizeInBytes() == 16); + temp &= (a[0] == 1 && a[1] == 2 && a[2] == 1 && a[3] == 2); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass3 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Append word32\n"; + + try + { + SecBlock a, b; + temp = true; + + const word64 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + a += b; + temp &= (a.SizeInBytes() == 16); + temp &= (a[0] == 1 && a[1] == 2); + + const word64 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + a += b; + temp &= (a.SizeInBytes() == 32); + temp &= (a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4); + + a.Assign(one, 1); + + a += a; + temp &= (a.SizeInBytes() == 16); + temp &= (a[0] == 1 && a[1] == 1); + + a.Assign(three, 2); + + a += a; + temp &= (a.SizeInBytes() == 32); + temp &= (a[0] == 1 && a[1] == 2 && a[2] == 1 && a[3] == 2); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass3 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Append word64\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + try + { + SecBlock a, b; + temp = true; + + const word128 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + a += b; + temp &= (a.SizeInBytes() == 32); + temp &= (a[0] == 1 && a[1] == 2); + + const word128 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + a += b; + temp &= (a.SizeInBytes() == 64); + temp &= (a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4); + + a.Assign(one, 1); + + a += a; + temp &= (a.SizeInBytes() == 32); + temp &= (a[0] == 1 && a[1] == 1); + + a.Assign(three, 2); + + a += a; + temp &= (a.SizeInBytes() == 64); + temp &= (a[0] == 1 && a[1] == 2 && a[2] == 1 && a[3] == 2); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass3 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Append word128\n"; +#endif + + //********** Concatenate **********// + + // byte + try + { + SecByteBlock a, b, c; + temp = true; + + a.Assign((const byte*)"a", 1); + b.Assign((const byte*)"b", 1); + + c = a + b; + temp &= (a[0] == 'a'); + temp &= (b[0] == 'b'); + temp &= (c.SizeInBytes() == 2); + temp &= (c[0] == 'a' && c[1] == 'b'); + + a.Assign((const byte*)"ab", 2); + b.Assign((const byte*)"cd", 2); + + c = a + b; + temp &= (a[0] == 'a' && a[1] == 'b'); + temp &= (b[0] == 'c' && b[1] == 'd'); + temp &= (c.SizeInBytes() == 4); + temp &= (c[0] == 'a' && c[1] == 'b' && c[2] == 'c' && c[3] == 'd'); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass4 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Concatenate byte\n"; + + // word32 + try + { + SecBlock a, b, c; + temp = true; + + const word32 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + c = a + b; + temp &= (a[0] == 1); + temp &= (b[0] == 2); + temp &= (c.SizeInBytes() == 8); + temp &= (c[0] == 1 && c[1] == 2); + + const word32 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + c = a + b; + temp &= (a[0] == 1 && a[1] == 2); + temp &= (b[0] == 3 && b[1] == 4); + temp &= (c.SizeInBytes() == 16); + temp &= (c[0] == 1 && c[1] == 2 && c[2] == 3 && c[3] == 4); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass4 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Concatenate word32\n"; + + // word64 + try + { + SecBlock a, b, c; + temp = true; + + const word64 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + c = a + b; + temp &= (a[0] == 1); + temp &= (b[0] == 2); + temp &= (c.SizeInBytes() == 16); + temp &= (c[0] == 1 && c[1] == 2); + + const word64 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + c = a + b; + temp &= (a[0] == 1 && a[1] == 2); + temp &= (b[0] == 3 && b[1] == 4); + temp &= (c.SizeInBytes() == 32); + temp &= (c[0] == 1 && c[1] == 2 && c[2] == 3 && c[3] == 4); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass4 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Concatenate word64\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + try + { + SecBlock a, b, c; + temp = true; + + const word128 one[1] = {1}, two[1] = {2}; + a.Assign(one, 1); + b.Assign(two, 1); + + c = a + b; + temp &= (a[0] == 1); + temp &= (b[0] == 2); + temp &= (c.SizeInBytes() == 32); + temp &= (c[0] == 1 && c[1] == 2); + + const word128 three[2] = {1,2}, four[2] = {3,4}; + a.Assign(three, 2); + b.Assign(four, 2); + + c = a + b; + temp &= (a[0] == 1 && a[1] == 2); + temp &= (b[0] == 3 && b[1] == 4); + temp &= (c.SizeInBytes() == 64); + temp &= (c[0] == 1 && c[1] == 2 && c[2] == 3 && c[3] == 4); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass4 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Concatenate word128\n"; +#endif + + //********** Equality **********// + + // byte + try + { + static const byte str1[] = "abcdefghijklmnopqrstuvwxyz"; + static const byte str2[] = "zyxwvutsrqponmlkjihgfedcba"; + static const byte str3[] = "0123456789"; + + temp = true; + SecByteBlock a,b; + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str1, COUNTOF(str1)); + temp &= (a.operator==(b)); + + a.Assign(str3, COUNTOF(str3)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a == b); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str2, COUNTOF(str2)); + temp &= (a.operator!=(b)); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a != b); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass5 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Equality byte\n"; + + // word32 + try + { + static const word32 str1[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; + static const word32 str2[] = {97,89,83,79,73,71,67,61,59,53,47,43,41,37,31,29,23,19,17,13,11,7,5,3,2}; + static const word32 str3[] = {0,1,2,3,4,5,6,7,8,9}; + + temp = true; + SecBlock a,b; + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str1, COUNTOF(str1)); + temp &= (a.operator==(b)); + + a.Assign(str3, COUNTOF(str3)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a == b); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str2, COUNTOF(str2)); + temp &= (a.operator!=(b)); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a != b); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass5 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Equality word32\n"; + + // word64 + try + { + static const word64 str1[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; + static const word64 str2[] = {97,89,83,79,73,71,67,61,59,53,47,43,41,37,31,29,23,19,17,13,11,7,5,3,2}; + static const word64 str3[] = {0,1,2,3,4,5,6,7,8,9}; + + temp = true; + SecBlock a,b; + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str1, COUNTOF(str1)); + temp &= (a.operator==(b)); + + a.Assign(str3, COUNTOF(str3)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a == b); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str2, COUNTOF(str2)); + temp &= (a.operator!=(b)); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a != b); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass5 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Equality word64\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + // word128 + try + { + static const word128 str1[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; + static const word128 str2[] = {97,89,83,79,73,71,67,61,59,53,47,43,41,37,31,29,23,19,17,13,11,7,5,3,2}; + static const word128 str3[] = {0,1,2,3,4,5,6,7,8,9}; + + temp = true; + SecBlock a,b; + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str1, COUNTOF(str1)); + temp &= (a.operator==(b)); + + a.Assign(str3, COUNTOF(str3)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a == b); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str2, COUNTOF(str2)); + temp &= (a.operator!=(b)); + + a.Assign(str1, COUNTOF(str1)); + b.Assign(str3, COUNTOF(str3)); + temp &= (a != b); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + + pass5 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Equality word128\n"; +#endif + + //********** Allocator Size/Overflow **********// + + try + { + temp = false; + + AllocatorBase A; + const size_t max = A.max_size(); + SecBlock t(max+1); + } + catch(const Exception& /*ex*/) + { + temp = true; + } + catch(const std::exception& /*ex*/) + { + temp = true; + } + + pass6 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Overflow word32\n"; + + try + { + temp = false; + + AllocatorBase A; + const size_t max = A.max_size(); + SecBlock t(max+1); + } + catch(const Exception& /*ex*/) + { + temp = true; + } + catch(const std::exception& /*ex*/) + { + temp = true; + } + + pass6 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Overflow word64\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + try + { + temp = false; + + AllocatorBase A; + const size_t max = A.max_size(); + SecBlock t(max+1); + } + catch(const Exception& /*ex*/) + { + temp = true; + } + catch(const std::exception& /*ex*/) + { + temp = true; + } + + pass6 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Overflow word128\n"; +#endif + + //********** FixedSizeAllocatorWithCleanup and Grow **********// + + // byte + try + { + static const unsigned int SIZE = 8; + SecBlockWithHint block(SIZE); + memset(block, 0xaa, block.SizeInBytes()); + + temp = true; + block.CleanGrow(SIZE*2); + temp &= (block.size() == SIZE*2); + + for (size_t i = 0; i < block.size()/2; i++) + temp &= (block[i] == 0xaa); + for (size_t i = block.size()/2; i < block.size(); i++) + temp &= (block[i] == 0); + + block.CleanNew(SIZE*4); + temp &= (block.size() == SIZE*4); + for (size_t i = 0; i < block.size(); i++) + temp &= (block[i] == 0); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + catch(const std::exception& /*ex*/) + { + temp = false; + } + + pass7 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " FixedSizeAllocator Grow with byte\n"; + + // word32 + try + { + static const unsigned int SIZE = 8; + SecBlockWithHint block(SIZE); + memset(block, 0xaa, block.SizeInBytes()); + + temp = true; + block.CleanGrow(SIZE*2); + temp &= (block.size() == SIZE*2); + + for (size_t i = 0; i < block.size()/2; i++) + temp &= (block[i] == 0xaaaaaaaa); + + for (size_t i = block.size()/2; i < block.size(); i++) + temp &= (block[i] == 0); + + block.CleanNew(SIZE*4); + temp &= (block.size() == SIZE*4); + for (size_t i = 0; i < block.size(); i++) + temp &= (block[i] == 0); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + catch(const std::exception& /*ex*/) + { + temp = false; + } + + pass7 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " FixedSizeAllocator Grow with word32\n"; + + // word64 + try + { + static const unsigned int SIZE = 8; + SecBlockWithHint block(SIZE); + memset(block, 0xaa, block.SizeInBytes()); + + temp = true; + block.CleanGrow(SIZE*2); + temp &= (block.size() == SIZE*2); + + for (size_t i = 0; i < block.size()/2; i++) + temp &= (block[i] == W64LIT(0xaaaaaaaaaaaaaaaa)); + + for (size_t i = block.size()/2; i < block.size(); i++) + temp &= (block[i] == 0); + + block.CleanNew(SIZE*4); + temp &= (block.size() == SIZE*4); + for (size_t i = 0; i < block.size(); i++) + temp &= (block[i] == 0); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + catch(const std::exception& /*ex*/) + { + temp = false; + } + + pass7 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " FixedSizeAllocator Grow with word64\n"; + +#if defined(CRYPTOPP_WORD128_AVAILABLE) + // word128 + try + { + static const unsigned int SIZE = 8; + SecBlock > block(SIZE); + memset(block, 0xaa, block.SizeInBytes()); + + temp = true; + block.CleanGrow(SIZE*2); + temp &= (block.size() == SIZE*2); + + for (size_t i = 0; i < block.size()/2; i++) + temp &= (block[i] == (((word128)W64LIT(0xaaaaaaaaaaaaaaaa) << 64U) | W64LIT(0xaaaaaaaaaaaaaaaa))); + + for (size_t i = block.size()/2; i < block.size(); i++) + temp &= (block[i] == 0); + + block.CleanNew(SIZE*4); + temp &= (block.size() == SIZE*4); + for (size_t i = 0; i < block.size(); i++) + temp &= (block[i] == 0); + } + catch(const Exception& /*ex*/) + { + temp = false; + } + catch(const std::exception& /*ex*/) + { + temp = false; + } + + pass7 &= temp; + if (!temp) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " FixedSizeAllocator Grow with word128\n"; +#endif + + return pass1 && pass2 && pass3 && pass4 && pass5 && pass6 && pass7; +} +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +bool TestHuffmanCodes() +{ + std::cout << "\nTesting Huffman codes...\n\n"; + bool pass=true; + + static const size_t nCodes = 30; + const unsigned int codeCounts[nCodes] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + static const unsigned int maxCodeBits = nCodes >> 1; + unsigned int codeBits[nCodes] = { + ~0u, ~0u, ~0u, ~0u, ~0u, + ~0u, ~0u, ~0u, ~0u, ~0u, + ~0u, ~0u, ~0u, ~0u, ~0u, + }; + + try + { + HuffmanEncoder::GenerateCodeLengths(codeBits, maxCodeBits, codeCounts, nCodes); + } + catch(const Exception& /*ex*/) + { + pass=false; + } + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " GenerateCodeLengths" << std::endl; + + // Try to crash the HuffmanDecoder + for (unsigned int i=0; i<128; ++i) + { + try + { + byte data1[0xfff]; // Place on stack, avoid new + unsigned int data2[0xff]; + + unsigned int len1 = GlobalRNG().GenerateWord32(4, 0xfff); + GlobalRNG().GenerateBlock(data1, len1); + unsigned int len2 = GlobalRNG().GenerateWord32(4, 0xff); + GlobalRNG().GenerateBlock((byte*)data2, len2*sizeof(unsigned int)); + + ArraySource source(data1, len1, false); + HuffmanDecoder decoder(data2, len2); + + LowFirstBitReader reader(source); + unsigned int val; + for (unsigned int j=0; !source.AnyRetrievable(); ++j) + decoder.Decode(reader, val); + } + catch (const Exception&) {} + } + + std::cout << "passed: HuffmanDecoder decode" << std::endl; + + return pass; +} +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +# if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +bool TestAltivecOps() +{ + std::cout << "\nTesting Altivec operations...\n\n"; + + if (HasAltivec() == false) + { + std::cout << "\nAltivec not available, skipping test." << std::endl; + return true; + } + + // These tests may seem superflous, but we really want to test the + // Altivec/POWER4 implementation. That does not happen when POWER7 + // or POWER8 is available because we use POWER7's unaligned loads + // and stores with POWER8's AES, SHA, etc. These tests enage + // Altivec/POWER4 without POWER7, like on an old PowerMac. + + //********** Unaligned loads and stores **********// + bool pass1=true; + + CRYPTOPP_ALIGN_DATA(16) + byte dest[20], src[20] = {23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4}; + const byte st1[16] = {22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7}; + const byte st2[16] = {21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6}; + const byte st3[16] = {20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5}; + + VecStore(VecLoad(src), dest); + pass1 = (0 == std::memcmp(src, dest, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStore(VecLoad(src+1), dest+1); + pass1 = (0 == std::memcmp(st1, dest+1, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStore(VecLoad(src+2), dest+2); + pass1 = (0 == std::memcmp(st2, dest+2, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStore(VecLoad(src+3), dest+3); + pass1 = (0 == std::memcmp(st3, dest+3, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStoreBE(VecLoadBE(src), dest); + pass1 = (0 == std::memcmp(src, dest, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStoreBE(VecLoadBE(src+1), dest+1); + pass1 = (0 == std::memcmp(st1, dest+1, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStoreBE(VecLoadBE(src+2), dest+2); + pass1 = (0 == std::memcmp(st2, dest+2, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStoreBE(VecLoadBE(src+3), dest+3); + pass1 = (0 == std::memcmp(st3, dest+3, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + +#if (CRYPTOPP_LITTLE_ENDIAN) + VecStore(VecLoadBE(src), dest); + pass1 = (0 != std::memcmp(src, dest, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); + + VecStoreBE(VecLoad(src), dest); + pass1 = (0 != std::memcmp(src, dest, 16)) && pass1; + CRYPTOPP_ASSERT(pass1); +#endif + + if (!pass1) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Altivec loads and stores" << std::endl; + + //********** Shifts **********// + bool pass2=true; + + uint8x16_p val = {0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff}; + + pass2 = (VecEqual(val, VecShiftLeftOctet<0>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + pass2 = (VecEqual(val, VecShiftRightOctet<0>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + + uint8x16_p lsh1 = {0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x00}; + uint8x16_p rsh1 = {0x00,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff}; + + pass2 = (VecEqual(lsh1, VecShiftLeftOctet<1>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + pass2 = (VecEqual(rsh1, VecShiftRightOctet<1>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + + uint8x16_p lsh15 = {0xff,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; + uint8x16_p rsh15 = {0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xff}; + + pass2 = (VecEqual(lsh15, VecShiftLeftOctet<15>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + pass2 = (VecEqual(rsh15, VecShiftRightOctet<15>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + + uint8x16_p lsh16 = {0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; + uint8x16_p rsh16 = {0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; + + pass2 = (VecEqual(lsh16, VecShiftLeftOctet<16>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + pass2 = (VecEqual(rsh16, VecShiftRightOctet<16>(val))) && pass2; + CRYPTOPP_ASSERT(pass2); + + if (!pass2) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Altivec left and right shifts" << std::endl; + + //********** Extraction **********// + bool pass3=true; + + const byte bex1[] = {0x1f,0x1e,0x1d,0x1c, 0x1b,0x1a,0x19,0x18, + 0x17,0x16,0x15,0x14, 0x13,0x12,0x11,0x10}; + const byte bex2[] = {0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x17,0x16,0x15,0x14, 0x13,0x12,0x11,0x10}; + const byte bex3[] = {0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x1f,0x1e,0x1d,0x1c, 0x1b,0x1a,0x19,0x18}; + + const uint8x16_p ex1 = (uint8x16_p)VecLoad(bex1); + const uint8x16_p ex2 = (uint8x16_p)VecLoad(bex2); + const uint8x16_p ex3 = (uint8x16_p)VecLoad(bex3); + + pass3 = VecEqual(ex2, VecGetLow(ex1)) && pass3; + CRYPTOPP_ASSERT(pass3); + pass3 = VecEqual(ex3, VecGetHigh(ex1)) && pass3; + CRYPTOPP_ASSERT(pass3); + + uint8x16_p ex4 = VecShiftRightOctet<8>(VecShiftLeftOctet<8>(ex1)); + pass3 = VecEqual(ex4, VecGetLow(ex1)) && pass3; + CRYPTOPP_ASSERT(pass3); + uint8x16_p ex5 = VecShiftRightOctet<8>(ex1); + pass3 = VecEqual(ex5, VecGetHigh(ex1)) && pass3; + CRYPTOPP_ASSERT(pass3); + + if (!pass3) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Altivec vector extraction" << std::endl; + + return pass1 && pass2 && pass3; +} +#endif +#endif + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat10.cpp b/external/ours/library/crypto/src/shared/original/validat10.cpp new file mode 100755 index 000000000..4e7bf9f8e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat10.cpp @@ -0,0 +1,535 @@ +// validat10.cpp - written and placed in the public domain by Jeffrey Walton +// Routines in this source file test NaCl library routines. +// Source files split in July 2018 to expedite compiles. +// +// There are two types or sets of self tests. First is a known answer test, +// and second are pairwise consitency checks. The known answer tests are test +// vectors lifted from libsodium. The pairwise consitency checks are randomized +// and confirm the library can arrive at the same result or round trip data +// using it's own transformations. +// +// A link like https://github.com/jedisct1/libsodium/blob/master/test/default/box.c +// references the libsodium test data for a test. For example, box.c is one of the +// test runners for crypto_box, and there is a box.exp with the known answer. The +// glue code for box.c and box.exp is in "cmptest.h". box.c runs the test and +// generates output, while cmptest.h gathers the output and compares them. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "secblock.h" +#include "integer.h" +#include "naclite.h" +#include "validate.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4610 4510 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +#ifndef CRYPTOPP_DISABLE_NACL + +USING_NAMESPACE(NaCl) + +bool TestCryptoBox() +{ + // https://github.com/jedisct1/libsodium/blob/master/test/default/box.c + const byte alicesk[32] = { + 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, + 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, + 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a + }; + + const byte bobpk[32] = { + 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f + }; + + const byte small_order_p[crypto_box_PUBLICKEYBYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 + }; + + const byte nonce[24] = { + 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 + }; + + /* API requires first 32 bytes to be 0 */ + const byte m[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0xbe, 0x07, 0x5f, 0xc5, + 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, + 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, 0x4b, 0x66, 0x84, 0x9b, + 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, + 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, 0x6c, 0xdc, 0x3c, 0x01, + 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, + 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, 0xce, 0xea, 0x3a, 0x7f, + 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, + 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, 0x04, 0x89, 0x77, 0xeb, + 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, + 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, 0xe0, 0x82, 0xf9, 0x37, + 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 + }; + + const byte exp1[] = { + 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9, + 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce, + 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a, + 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72, + 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38, + 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae, + 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda, + 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3, + 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74, + 0xe3,0x55,0xa5 + }; + + const byte exp2[] = { + 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9, + 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce, + 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a, + 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72, + 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38, + 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae, + 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda, + 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3, + 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74, + 0xe3,0x55,0xa5 + }; + + byte c[163]; + byte k[crypto_box_BEFORENMBYTES]; + + bool pass = true; int rc; + + // Reject small order elements + + rc = crypto_box(c, m, 163, nonce, bobpk, alicesk); + pass = (rc == 0) && pass; + pass = (std::memcmp(c+16, exp1, 163-16) == 0) && pass; + + rc = crypto_box(c, m, 163, nonce, small_order_p, alicesk); + pass = (rc != 0) && pass; + std::memset(c, 0, sizeof(c)); + + rc = crypto_box_beforenm(k, bobpk, alicesk); + pass = (rc == 0) && pass; + rc = crypto_box_afternm(c, m, 163, nonce, k); + pass = (rc == 0) && pass; + pass = (std::memcmp(c+16, exp2, 163-16) == 0) && pass; + + rc = crypto_box_beforenm(k, small_order_p, alicesk); + pass = (rc != 0) && pass; + + // Allow small order elements + + rc = crypto_box_unchecked(c, m, 163, nonce, bobpk, alicesk); + pass = (rc == 0) && pass; + pass = (std::memcmp(c+16, exp1, 163-16) == 0) && pass; + + rc = crypto_box_unchecked(c, m, 163, nonce, small_order_p, alicesk); + pass = (rc == 0) && pass; + std::memset(c, 0, sizeof(c)); + + rc = crypto_box_beforenm_unchecked(k, bobpk, alicesk); + pass = (rc == 0) && pass; + rc = crypto_box_afternm(c, m, 163, nonce, k); + pass = (rc == 0) && pass; + pass = (std::memcmp(c+16, exp2, 163-16) == 0) && pass; + + rc = crypto_box_beforenm_unchecked(k, small_order_p, alicesk); + pass = (rc == 0) && pass; + + return pass; +} + +bool TestCryptoBoxOpen() +{ + // https://github.com/jedisct1/libsodium/blob/master/test/default/box2.c + const byte bobsk[32] = { + 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, + 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, + 0xff, 0x88, 0xe0, 0xeb + }; + + const byte alicepk[32] = { + 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, + 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, + 0xaa, 0x9b, 0x4e, 0x6a + }; + + static const byte small_order_p[crypto_box_PUBLICKEYBYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, + 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, + 0x5f, 0x49, 0xb8, 0x00 + }; + + const byte nonce[24] = { + 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 + }; + + /* API requires first 16 bytes to be 0 */ + const byte c[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f, + 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5, + 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f, + 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, 0x45, + 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61, + 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, 0x59, 0x9b, 0x1f, 0x65, + 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5 + }; + + const byte exp1[] = { + 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5, 0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b, + 0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4, 0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc, + 0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a, 0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29, + 0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4, 0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31, + 0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d, 0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57, + 0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a, 0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde, + 0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd, 0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52, + 0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40, 0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64, + 0x5e,0x07,0x05 + }; + + const byte exp2[] = { + 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5, 0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b, + 0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4, 0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc, + 0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a, 0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29, + 0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4, 0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31, + 0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d, 0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57, + 0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a, 0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde, + 0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd, 0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52, + 0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40, 0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64, + 0x5e,0x07,0x05 + }; + + byte m[163]; + byte k[crypto_box_BEFORENMBYTES]; + + bool pass = true; int rc; + + // Reject small order elements + + rc = crypto_box_open(m, c, 163, nonce, alicepk, bobsk); + pass = (rc == 0) && pass; + pass = (std::memcmp(m+32, exp1, 163-32) == 0) && pass; + + rc = crypto_box_open(m, c, 163, nonce, small_order_p, bobsk); + pass = (rc != 0) && pass; + + rc = crypto_box_beforenm(k, small_order_p, bobsk); + pass = (rc != 0) && pass; + rc = crypto_box_beforenm(k, alicepk, bobsk); + pass = (rc == 0) && pass; + + rc = crypto_box_open_afternm(m, c, 163, nonce, k); + pass = (rc == 0) && pass; + pass = (std::memcmp(m+32, exp2, 163-32) == 0) && pass; + + // Allow small order elements + + rc = crypto_box_open_unchecked(m, c, 163, nonce, alicepk, bobsk); + pass = (rc == 0) && pass; + pass = (std::memcmp(m+32, exp1, 163-32) == 0) && pass; + + rc = crypto_box_beforenm_unchecked(k, small_order_p, bobsk); + pass = (rc == 0) && pass; + rc = crypto_box_beforenm_unchecked(k, alicepk, bobsk); + pass = (rc == 0) && pass; + + rc = crypto_box_open_afternm(m, c, 163, nonce, k); + pass = (rc == 0) && pass; + pass = (std::memcmp(m+32, exp2, 163-32) == 0) && pass; + + return pass; +} + +bool TestCryptoBoxKeys() +{ + // https://github.com/jedisct1/libsodium/blob/master/test/default/box7.c + const unsigned int MAX_TEST = 64; + const unsigned int MAX_MESSAGE = 4096; + + byte alicesk[crypto_box_SECRETKEYBYTES]; + byte alicepk[crypto_box_PUBLICKEYBYTES]; + byte bobsk[crypto_box_SECRETKEYBYTES]; + byte bobpk[crypto_box_PUBLICKEYBYTES]; + + // byte m[MAX_MESSAGE+32]; + // byte c[MAX_MESSAGE+32]; + // byte r[MAX_MESSAGE+32]; + + bool pass = true, fail; int rc; + for (unsigned int i=0; i < MAX_TEST; ++i) + { + fail = (crypto_box_keypair(alicepk, alicesk) != 0); + pass = !fail && pass; + fail = (crypto_box_keypair(bobpk, bobsk) != 0); + pass = !fail && pass; + + SecByteBlock m, c, r, n; + const word32 len = (i == 0 ? 0 : GlobalRNG().GenerateWord32(1, MAX_MESSAGE)); + + m.New(len+crypto_box_ZEROBYTES); + c.New(len+crypto_box_BOXZEROBYTES+crypto_box_MACBYTES); + r.New(len+crypto_box_ZEROBYTES); + n.New(crypto_box_NONCEBYTES); + + GlobalRNG().GenerateBlock(m+crypto_box_ZEROBYTES, len); + GlobalRNG().GenerateBlock(n, crypto_box_NONCEBYTES); + + std::memset(m, 0x00, crypto_box_ZEROBYTES); + rc = crypto_box(c, m, len + crypto_box_ZEROBYTES, n, bobpk, alicesk); + fail = (rc != 0); pass = !fail && pass; + + std::memset(c, 0x00, crypto_box_BOXZEROBYTES); + rc = crypto_box_open(r, c, len + crypto_box_BOXZEROBYTES + crypto_box_MACBYTES, n, alicepk, bobsk); + fail = (rc != 0); pass = !fail && pass; + + fail = std::memcmp(m+crypto_box_ZEROBYTES, r+crypto_box_ZEROBYTES, len) != 0; + pass = !fail && pass; + + m.SetMark(16); c.SetMark(16); r.SetMark(16); + } + + return pass; +} + +struct TestData { + const byte sk[crypto_sign_SEEDBYTES]; + const byte pk[crypto_sign_PUBLICKEYBYTES]; + const byte sig[crypto_sign_BYTES]; + const word32 len; + const char* msg; +}; + +// https://github.com/jedisct1/libsodium/blob/master/test/default/sign.c +const TestData test_data[] = { + {{0x9d,0x61,0xb1,0x9d,0xef,0xfd,0x5a,0x60,0xba,0x84,0x4a,0xf4,0x92,0xec,0x2c,0xc4,0x44,0x49,0xc5,0x69,0x7b,0x32,0x69,0x19,0x70,0x3b,0xac,0x03,0x1c,0xae,0x7f,0x60,},{0xd7,0x5a,0x98,0x01,0x82,0xb1,0x0a,0xb7,0xd5,0x4b,0xfe,0xd3,0xc9,0x64,0x07,0x3a,0x0e,0xe1,0x72,0xf3,0xda,0xa6,0x23,0x25,0xaf,0x02,0x1a,0x68,0xf7,0x07,0x51,0x1a,},{0xe5,0x56,0x43,0x00,0xc3,0x60,0xac,0x72,0x90,0x86,0xe2,0xcc,0x80,0x6e,0x82,0x8a,0x84,0x87,0x7f,0x1e,0xb8,0xe5,0xd9,0x74,0xd8,0x73,0xe0,0x65,0x22,0x49,0x01,0x55,0x5f,0xb8,0x82,0x15,0x90,0xa3,0x3b,0xac,0xc6,0x1e,0x39,0x70,0x1c,0xf9,0xb4,0x6b,0xd2,0x5b,0xf5,0xf0,0x59,0x5b,0xbe,0x24,0x65,0x51,0x41,0x43,0x8e,0x7a,0x10,0x0b,},0,""}, + {{0x4c,0xcd,0x08,0x9b,0x28,0xff,0x96,0xda,0x9d,0xb6,0xc3,0x46,0xec,0x11,0x4e,0x0f,0x5b,0x8a,0x31,0x9f,0x35,0xab,0xa6,0x24,0xda,0x8c,0xf6,0xed,0x4f,0xb8,0xa6,0xfb,},{0x3d,0x40,0x17,0xc3,0xe8,0x43,0x89,0x5a,0x92,0xb7,0x0a,0xa7,0x4d,0x1b,0x7e,0xbc,0x9c,0x98,0x2c,0xcf,0x2e,0xc4,0x96,0x8c,0xc0,0xcd,0x55,0xf1,0x2a,0xf4,0x66,0x0c,},{0x92,0xa0,0x09,0xa9,0xf0,0xd4,0xca,0xb8,0x72,0x0e,0x82,0x0b,0x5f,0x64,0x25,0x40,0xa2,0xb2,0x7b,0x54,0x16,0x50,0x3f,0x8f,0xb3,0x76,0x22,0x23,0xeb,0xdb,0x69,0xda,0x08,0x5a,0xc1,0xe4,0x3e,0x15,0x99,0x6e,0x45,0x8f,0x36,0x13,0xd0,0xf1,0x1d,0x8c,0x38,0x7b,0x2e,0xae,0xb4,0x30,0x2a,0xee,0xb0,0x0d,0x29,0x16,0x12,0xbb,0x0c,0x00,},1,"\x72"}, + {{0xc5,0xaa,0x8d,0xf4,0x3f,0x9f,0x83,0x7b,0xed,0xb7,0x44,0x2f,0x31,0xdc,0xb7,0xb1,0x66,0xd3,0x85,0x35,0x07,0x6f,0x09,0x4b,0x85,0xce,0x3a,0x2e,0x0b,0x44,0x58,0xf7,},{0xfc,0x51,0xcd,0x8e,0x62,0x18,0xa1,0xa3,0x8d,0xa4,0x7e,0xd0,0x02,0x30,0xf0,0x58,0x08,0x16,0xed,0x13,0xba,0x33,0x03,0xac,0x5d,0xeb,0x91,0x15,0x48,0x90,0x80,0x25,},{0x62,0x91,0xd6,0x57,0xde,0xec,0x24,0x02,0x48,0x27,0xe6,0x9c,0x3a,0xbe,0x01,0xa3,0x0c,0xe5,0x48,0xa2,0x84,0x74,0x3a,0x44,0x5e,0x36,0x80,0xd7,0xdb,0x5a,0xc3,0xac,0x18,0xff,0x9b,0x53,0x8d,0x16,0xf2,0x90,0xae,0x67,0xf7,0x60,0x98,0x4d,0xc6,0x59,0x4a,0x7c,0x15,0xe9,0x71,0x6e,0xd2,0x8d,0xc0,0x27,0xbe,0xce,0xea,0x1e,0xc4,0x0a,},2,"\xaf\x82"}, + {{0x0d,0x4a,0x05,0xb0,0x73,0x52,0xa5,0x43,0x6e,0x18,0x03,0x56,0xda,0x0a,0xe6,0xef,0xa0,0x34,0x5f,0xf7,0xfb,0x15,0x72,0x57,0x57,0x72,0xe8,0x00,0x5e,0xd9,0x78,0xe9,},{0xe6,0x1a,0x18,0x5b,0xce,0xf2,0x61,0x3a,0x6c,0x7c,0xb7,0x97,0x63,0xce,0x94,0x5d,0x3b,0x24,0x5d,0x76,0x11,0x4d,0xd4,0x40,0xbc,0xf5,0xf2,0xdc,0x1a,0xa5,0x70,0x57,},{0xd9,0x86,0x8d,0x52,0xc2,0xbe,0xbc,0xe5,0xf3,0xfa,0x5a,0x79,0x89,0x19,0x70,0xf3,0x09,0xcb,0x65,0x91,0xe3,0xe1,0x70,0x2a,0x70,0x27,0x6f,0xa9,0x7c,0x24,0xb3,0xa8,0xe5,0x86,0x06,0xc3,0x8c,0x97,0x58,0x52,0x9d,0xa5,0x0e,0xe3,0x1b,0x82,0x19,0xcb,0xa4,0x52,0x71,0xc6,0x89,0xaf,0xa6,0x0b,0x0e,0xa2,0x6c,0x99,0xdb,0x19,0xb0,0x0c,},3,"\xcb\xc7\x7b"}, + {{0x6d,0xf9,0x34,0x0c,0x13,0x8c,0xc1,0x88,0xb5,0xfe,0x44,0x64,0xeb,0xaa,0x3f,0x7f,0xc2,0x06,0xa2,0xd5,0x5c,0x34,0x34,0x70,0x7e,0x74,0xc9,0xfc,0x04,0xe2,0x0e,0xbb,},{0xc0,0xda,0xc1,0x02,0xc4,0x53,0x31,0x86,0xe2,0x5d,0xc4,0x31,0x28,0x47,0x23,0x53,0xea,0xab,0xdb,0x87,0x8b,0x15,0x2a,0xeb,0x8e,0x00,0x1f,0x92,0xd9,0x02,0x33,0xa7,},{0x12,0x4f,0x6f,0xc6,0xb0,0xd1,0x00,0x84,0x27,0x69,0xe7,0x1b,0xd5,0x30,0x66,0x4d,0x88,0x8d,0xf8,0x50,0x7d,0xf6,0xc5,0x6d,0xed,0xfd,0xb5,0x09,0xae,0xb9,0x34,0x16,0xe2,0x6b,0x91,0x8d,0x38,0xaa,0x06,0x30,0x5d,0xf3,0x09,0x56,0x97,0xc1,0x8b,0x2a,0xa8,0x32,0xea,0xa5,0x2e,0xdc,0x0a,0xe4,0x9f,0xba,0xe5,0xa8,0x5e,0x15,0x0c,0x07,},4,"\x5f\x4c\x89\x89"}, + {{0xb7,0x80,0x38,0x1a,0x65,0xed,0xf8,0xb7,0x8f,0x69,0x45,0xe8,0xdb,0xec,0x79,0x41,0xac,0x04,0x9f,0xd4,0xc6,0x10,0x40,0xcf,0x0c,0x32,0x43,0x57,0x97,0x5a,0x29,0x3c,},{0xe2,0x53,0xaf,0x07,0x66,0x80,0x4b,0x86,0x9b,0xb1,0x59,0x5b,0xe9,0x76,0x5b,0x53,0x48,0x86,0xbb,0xaa,0xb8,0x30,0x5b,0xf5,0x0d,0xbc,0x7f,0x89,0x9b,0xfb,0x5f,0x01,},{0xb2,0xfc,0x46,0xad,0x47,0xaf,0x46,0x44,0x78,0xc1,0x99,0xe1,0xf8,0xbe,0x16,0x9f,0x1b,0xe6,0x32,0x7c,0x7f,0x9a,0x0a,0x66,0x89,0x37,0x1c,0xa9,0x4c,0xaf,0x04,0x06,0x4a,0x01,0xb2,0x2a,0xff,0x15,0x20,0xab,0xd5,0x89,0x51,0x34,0x16,0x03,0xfa,0xed,0x76,0x8c,0xf7,0x8c,0xe9,0x7a,0xe7,0xb0,0x38,0xab,0xfe,0x45,0x6a,0xa1,0x7c,0x09,},5,"\x18\xb6\xbe\xc0\x97"}, + {{0x78,0xae,0x9e,0xff,0xe6,0xf2,0x45,0xe9,0x24,0xa7,0xbe,0x63,0x04,0x11,0x46,0xeb,0xc6,0x70,0xdb,0xd3,0x06,0x0c,0xba,0x67,0xfb,0xc6,0x21,0x6f,0xeb,0xc4,0x45,0x46,},{0xfb,0xcf,0xbf,0xa4,0x05,0x05,0xd7,0xf2,0xbe,0x44,0x4a,0x33,0xd1,0x85,0xcc,0x54,0xe1,0x6d,0x61,0x52,0x60,0xe1,0x64,0x0b,0x2b,0x50,0x87,0xb8,0x3e,0xe3,0x64,0x3d,},{0x6e,0xd6,0x29,0xfc,0x1d,0x9c,0xe9,0xe1,0x46,0x87,0x55,0xff,0x63,0x6d,0x5a,0x3f,0x40,0xa5,0xd9,0xc9,0x1a,0xfd,0x93,0xb7,0x9d,0x24,0x18,0x30,0xf7,0xe5,0xfa,0x29,0x85,0x4b,0x8f,0x20,0xcc,0x6e,0xec,0xbb,0x24,0x8d,0xbd,0x8d,0x16,0xd1,0x4e,0x99,0x75,0x21,0x94,0xe4,0x90,0x4d,0x09,0xc7,0x4d,0x63,0x95,0x18,0x83,0x9d,0x23,0x00,},6,"\x89\x01\x0d\x85\x59\x72"}, + {{0x69,0x18,0x65,0xbf,0xc8,0x2a,0x1e,0x4b,0x57,0x4e,0xec,0xde,0x4c,0x75,0x19,0x09,0x3f,0xaf,0x0c,0xf8,0x67,0x38,0x02,0x34,0xe3,0x66,0x46,0x45,0xc6,0x1c,0x5f,0x79,},{0x98,0xa5,0xe3,0xa3,0x6e,0x67,0xaa,0xba,0x89,0x88,0x8b,0xf0,0x93,0xde,0x1a,0xd9,0x63,0xe7,0x74,0x01,0x3b,0x39,0x02,0xbf,0xab,0x35,0x6d,0x8b,0x90,0x17,0x8a,0x63,},{0x6e,0x0a,0xf2,0xfe,0x55,0xae,0x37,0x7a,0x6b,0x7a,0x72,0x78,0xed,0xfb,0x41,0x9b,0xd3,0x21,0xe0,0x6d,0x0d,0xf5,0xe2,0x70,0x37,0xdb,0x88,0x12,0xe7,0xe3,0x52,0x98,0x10,0xfa,0x55,0x52,0xf6,0xc0,0x02,0x09,0x85,0xca,0x17,0xa0,0xe0,0x2e,0x03,0x6d,0x7b,0x22,0x2a,0x24,0xf9,0x9b,0x77,0xb7,0x5f,0xdd,0x16,0xcb,0x05,0x56,0x81,0x07,},7,"\xb4\xa8\xf3\x81\xe7\x0e\x7a"}, + {{0x3b,0x26,0x51,0x6f,0xb3,0xdc,0x88,0xeb,0x18,0x1b,0x9e,0xd7,0x3f,0x0b,0xcd,0x52,0xbc,0xd6,0xb4,0xc7,0x88,0xe4,0xbc,0xaf,0x46,0x05,0x7f,0xd0,0x78,0xbe,0xe0,0x73,},{0xf8,0x1f,0xb5,0x4a,0x82,0x5f,0xce,0xd9,0x5e,0xb0,0x33,0xaf,0xcd,0x64,0x31,0x40,0x75,0xab,0xfb,0x0a,0xbd,0x20,0xa9,0x70,0x89,0x25,0x03,0x43,0x6f,0x34,0xb8,0x63,},{0xd6,0xad,0xde,0xc5,0xaf,0xb0,0x52,0x8a,0xc1,0x7b,0xb1,0x78,0xd3,0xe7,0xf2,0x88,0x7f,0x9a,0xdb,0xb1,0xad,0x16,0xe1,0x10,0x54,0x5e,0xf3,0xbc,0x57,0xf9,0xde,0x23,0x14,0xa5,0xc8,0x38,0x8f,0x72,0x3b,0x89,0x07,0xbe,0x0f,0x3a,0xc9,0x0c,0x62,0x59,0xbb,0xe8,0x85,0xec,0xc1,0x76,0x45,0xdf,0x3d,0xb7,0xd4,0x88,0xf8,0x05,0xfa,0x08,},8,"\x42\x84\xab\xc5\x1b\xb6\x72\x35"}, + {{0xed,0xc6,0xf5,0xfb,0xdd,0x1c,0xee,0x4d,0x10,0x1c,0x06,0x35,0x30,0xa3,0x04,0x90,0xb2,0x21,0xbe,0x68,0xc0,0x36,0xf5,0xb0,0x7d,0x0f,0x95,0x3b,0x74,0x5d,0xf1,0x92,},{0xc1,0xa4,0x9c,0x66,0xe6,0x17,0xf9,0xef,0x5e,0xc6,0x6b,0xc4,0xc6,0x56,0x4c,0xa3,0x3d,0xe2,0xa5,0xfb,0x5e,0x14,0x64,0x06,0x2e,0x6d,0x6c,0x62,0x19,0x15,0x5e,0xfd,},{0x2c,0x76,0xa0,0x4a,0xf2,0x39,0x1c,0x14,0x70,0x82,0xe3,0x3f,0xaa,0xcd,0xbe,0x56,0x64,0x2a,0x1e,0x13,0x4b,0xd3,0x88,0x62,0x0b,0x85,0x2b,0x90,0x1a,0x6b,0xc1,0x6f,0xf6,0xc9,0xcc,0x94,0x04,0xc4,0x1d,0xea,0x12,0xed,0x28,0x1d,0xa0,0x67,0xa1,0x51,0x38,0x66,0xf9,0xd9,0x64,0xf8,0xbd,0xd2,0x49,0x53,0x85,0x6c,0x50,0x04,0x29,0x01,},9,"\x67\x2b\xf8\x96\x5d\x04\xbc\x51\x46"}, + {{0x4e,0x7d,0x21,0xfb,0x3b,0x18,0x97,0x57,0x1a,0x44,0x58,0x33,0xbe,0x0f,0x9f,0xd4,0x1c,0xd6,0x2b,0xe3,0xaa,0x04,0x04,0x0f,0x89,0x34,0xe1,0xfc,0xbd,0xca,0xcd,0x45,},{0x31,0xb2,0x52,0x4b,0x83,0x48,0xf7,0xab,0x1d,0xfa,0xfa,0x67,0x5c,0xc5,0x38,0xe9,0xa8,0x4e,0x3f,0xe5,0x81,0x9e,0x27,0xc1,0x2a,0xd8,0xbb,0xc1,0xa3,0x6e,0x4d,0xff,},{0x28,0xe4,0x59,0x8c,0x41,0x5a,0xe9,0xde,0x01,0xf0,0x3f,0x9f,0x3f,0xab,0x4e,0x91,0x9e,0x8b,0xf5,0x37,0xdd,0x2b,0x0c,0xdf,0x6e,0x79,0xb9,0xe6,0x55,0x9c,0x94,0x09,0xd9,0x15,0x1a,0x4c,0x40,0xf0,0x83,0x19,0x39,0x37,0x62,0x7c,0x36,0x94,0x88,0x25,0x9e,0x99,0xda,0x5a,0x9f,0x0a,0x87,0x49,0x7f,0xa6,0x69,0x6a,0x5d,0xd6,0xce,0x08,},10,"\x33\xd7\xa7\x86\xad\xed\x8c\x1b\xf6\x91"}, + {{0xa9,0x80,0xf8,0x92,0xdb,0x13,0xc9,0x9a,0x3e,0x89,0x71,0xe9,0x65,0xb2,0xff,0x3d,0x41,0xea,0xfd,0x54,0x09,0x3b,0xc9,0xf3,0x4d,0x1f,0xd2,0x2d,0x84,0x11,0x5b,0xb6,},{0x44,0xb5,0x7e,0xe3,0x0c,0xdb,0x55,0x82,0x9d,0x0a,0x5d,0x4f,0x04,0x6b,0xae,0xf0,0x78,0xf1,0xe9,0x7a,0x7f,0x21,0xb6,0x2d,0x75,0xf8,0xe9,0x6e,0xa1,0x39,0xc3,0x5f,},{0x77,0xd3,0x89,0xe5,0x99,0x63,0x0d,0x93,0x40,0x76,0x32,0x95,0x83,0xcd,0x41,0x05,0xa6,0x49,0xa9,0x29,0x2a,0xbc,0x44,0xcd,0x28,0xc4,0x00,0x00,0xc8,0xe2,0xf5,0xac,0x76,0x60,0xa8,0x1c,0x85,0xb7,0x2a,0xf8,0x45,0x2d,0x7d,0x25,0xc0,0x70,0x86,0x1d,0xae,0x91,0x60,0x1c,0x78,0x03,0xd6,0x56,0x53,0x16,0x50,0xdd,0x4e,0x5c,0x41,0x00,},11,"\x34\x86\xf6\x88\x48\xa6\x5a\x0e\xb5\x50\x7d"}, + {{0x5b,0x5a,0x61,0x9f,0x8c,0xe1,0xc6,0x6d,0x7c,0xe2,0x6e,0x5a,0x2a,0xe7,0xb0,0xc0,0x4f,0xeb,0xcd,0x34,0x6d,0x28,0x6c,0x92,0x9e,0x19,0xd0,0xd5,0x97,0x3b,0xfe,0xf9,},{0x6f,0xe8,0x36,0x93,0xd0,0x11,0xd1,0x11,0x13,0x1c,0x4f,0x3f,0xba,0xaa,0x40,0xa9,0xd3,0xd7,0x6b,0x30,0x01,0x2f,0xf7,0x3b,0xb0,0xe3,0x9e,0xc2,0x7a,0xb1,0x82,0x57,},{0x0f,0x9a,0xd9,0x79,0x30,0x33,0xa2,0xfa,0x06,0x61,0x4b,0x27,0x7d,0x37,0x38,0x1e,0x6d,0x94,0xf6,0x5a,0xc2,0xa5,0xa9,0x45,0x58,0xd0,0x9e,0xd6,0xce,0x92,0x22,0x58,0xc1,0xa5,0x67,0x95,0x2e,0x86,0x3a,0xc9,0x42,0x97,0xae,0xc3,0xc0,0xd0,0xc8,0xdd,0xf7,0x10,0x84,0xe5,0x04,0x86,0x0b,0xb6,0xba,0x27,0x44,0x9b,0x55,0xad,0xc4,0x0e,},12,"\x5a\x8d\x9d\x0a\x22\x35\x7e\x66\x55\xf9\xc7\x85"}, + {{0x94,0x0c,0x89,0xfe,0x40,0xa8,0x1d,0xaf,0xbd,0xb2,0x41,0x6d,0x14,0xae,0x46,0x91,0x19,0x86,0x97,0x44,0x41,0x0c,0x33,0x03,0xbf,0xaa,0x02,0x41,0xda,0xc5,0x78,0x00,},{0xa2,0xeb,0x8c,0x05,0x01,0xe3,0x0b,0xae,0x0c,0xf8,0x42,0xd2,0xbd,0xe8,0xde,0xc7,0x38,0x6f,0x6b,0x7f,0xc3,0x98,0x1b,0x8c,0x57,0xc9,0x79,0x2b,0xb9,0x4c,0xf2,0xdd,},{0xd8,0xbb,0x64,0xaa,0xd8,0xc9,0x95,0x5a,0x11,0x5a,0x79,0x3a,0xdd,0xd2,0x4f,0x7f,0x2b,0x07,0x76,0x48,0x71,0x4f,0x49,0xc4,0x69,0x4e,0xc9,0x95,0xb3,0x30,0xd0,0x9d,0x64,0x0d,0xf3,0x10,0xf4,0x47,0xfd,0x7b,0x6c,0xb5,0xc1,0x4f,0x9f,0xe9,0xf4,0x90,0xbc,0xf8,0xcf,0xad,0xbf,0xd2,0x16,0x9c,0x8a,0xc2,0x0d,0x3b,0x8a,0xf4,0x9a,0x0c,},13,"\xb8\x7d\x38\x13\xe0\x3f\x58\xcf\x19\xfd\x0b\x63\x95"}, + {{0x9a,0xca,0xd9,0x59,0xd2,0x16,0x21,0x2d,0x78,0x9a,0x11,0x92,0x52,0xeb,0xfe,0x0c,0x96,0x51,0x2a,0x23,0xc7,0x3b,0xd9,0xf3,0xb2,0x02,0x29,0x2d,0x69,0x16,0xa7,0x38,},{0xcf,0x3a,0xf8,0x98,0x46,0x7a,0x5b,0x7a,0x52,0xd3,0x3d,0x53,0xbc,0x03,0x7e,0x26,0x42,0xa8,0xda,0x99,0x69,0x03,0xfc,0x25,0x22,0x17,0xe9,0xc0,0x33,0xe2,0xf2,0x91,},{0x6e,0xe3,0xfe,0x81,0xe2,0x3c,0x60,0xeb,0x23,0x12,0xb2,0x00,0x6b,0x3b,0x25,0xe6,0x83,0x8e,0x02,0x10,0x66,0x23,0xf8,0x44,0xc4,0x4e,0xdb,0x8d,0xaf,0xd6,0x6a,0xb0,0x67,0x10,0x87,0xfd,0x19,0x5d,0xf5,0xb8,0xf5,0x8a,0x1d,0x6e,0x52,0xaf,0x42,0x90,0x80,0x53,0xd5,0x5c,0x73,0x21,0x01,0x00,0x92,0x74,0x87,0x95,0xef,0x94,0xcf,0x06,},14,"\x55\xc7\xfa\x43\x4f\x5e\xd8\xcd\xec\x2b\x7a\xea\xc1\x73"}, + {{0xd5,0xae,0xee,0x41,0xee,0xb0,0xe9,0xd1,0xbf,0x83,0x37,0xf9,0x39,0x58,0x7e,0xbe,0x29,0x61,0x61,0xe6,0xbf,0x52,0x09,0xf5,0x91,0xec,0x93,0x9e,0x14,0x40,0xc3,0x00,},{0xfd,0x2a,0x56,0x57,0x23,0x16,0x3e,0x29,0xf5,0x3c,0x9d,0xe3,0xd5,0xe8,0xfb,0xe3,0x6a,0x7a,0xb6,0x6e,0x14,0x39,0xec,0x4e,0xae,0x9c,0x0a,0x60,0x4a,0xf2,0x91,0xa5,},{0xf6,0x8d,0x04,0x84,0x7e,0x5b,0x24,0x97,0x37,0x89,0x9c,0x01,0x4d,0x31,0xc8,0x05,0xc5,0x00,0x7a,0x62,0xc0,0xa1,0x0d,0x50,0xbb,0x15,0x38,0xc5,0xf3,0x55,0x03,0x95,0x1f,0xbc,0x1e,0x08,0x68,0x2f,0x2c,0xc0,0xc9,0x2e,0xfe,0x8f,0x49,0x85,0xde,0xc6,0x1d,0xcb,0xd5,0x4d,0x4b,0x94,0xa2,0x25,0x47,0xd2,0x44,0x51,0x27,0x1c,0x8b,0x00,},15,"\x0a\x68\x8e\x79\xbe\x24\xf8\x66\x28\x6d\x46\x46\xb5\xd8\x1c"}, + {{0x0a,0x47,0xd1,0x04,0x52,0xae,0x2f,0xeb,0xec,0x51,0x8a,0x1c,0x7c,0x36,0x28,0x90,0xc3,0xfc,0x1a,0x49,0xd3,0x4b,0x03,0xb6,0x46,0x7d,0x35,0xc9,0x04,0xa8,0x36,0x2d,},{0x34,0xe5,0xa8,0x50,0x8c,0x47,0x43,0x74,0x69,0x62,0xc0,0x66,0xe4,0xba,0xde,0xa2,0x20,0x1b,0x8a,0xb4,0x84,0xde,0x5c,0x4f,0x94,0x47,0x6c,0xcd,0x21,0x43,0x95,0x5b,},{0x2a,0x3d,0x27,0xdc,0x40,0xd0,0xa8,0x12,0x79,0x49,0xa3,0xb7,0xf9,0x08,0xb3,0x68,0x8f,0x63,0xb7,0xf1,0x4f,0x65,0x1a,0xac,0xd7,0x15,0x94,0x0b,0xdb,0xe2,0x7a,0x08,0x09,0xaa,0xc1,0x42,0xf4,0x7a,0xb0,0xe1,0xe4,0x4f,0xa4,0x90,0xba,0x87,0xce,0x53,0x92,0xf3,0x3a,0x89,0x15,0x39,0xca,0xf1,0xef,0x4c,0x36,0x7c,0xae,0x54,0x50,0x0c,},16,"\xc9\x42\xfa\x7a\xc6\xb2\x3a\xb7\xff\x61\x2f\xdc\x8e\x68\xef\x39"}, + {{0xf8,0x14,0x8f,0x75,0x06,0xb7,0x75,0xef,0x46,0xfd,0xc8,0xe8,0xc7,0x56,0x51,0x68,0x12,0xd4,0x7d,0x6c,0xfb,0xfa,0x31,0x8c,0x27,0xc9,0xa2,0x26,0x41,0xe5,0x6f,0x17,},{0x04,0x45,0xe4,0x56,0xda,0xcc,0x7d,0x5b,0x0b,0xbe,0xd2,0x3c,0x82,0x00,0xcd,0xb7,0x4b,0xdc,0xb0,0x3e,0x4c,0x7b,0x73,0xf0,0xa2,0xb9,0xb4,0x6e,0xac,0x5d,0x43,0x72,},{0x36,0x53,0xcc,0xb2,0x12,0x19,0x20,0x2b,0x84,0x36,0xfb,0x41,0xa3,0x2b,0xa2,0x61,0x8c,0x4a,0x13,0x34,0x31,0xe6,0xe6,0x34,0x63,0xce,0xb3,0xb6,0x10,0x6c,0x4d,0x56,0xe1,0xd2,0xba,0x16,0x5b,0xa7,0x6e,0xaa,0xd3,0xdc,0x39,0xbf,0xfb,0x13,0x0f,0x1d,0xe3,0xd8,0xe6,0x42,0x7d,0xb5,0xb7,0x19,0x38,0xdb,0x4e,0x27,0x2b,0xc3,0xe2,0x0b,},17,"\x73\x68\x72\x4a\x5b\x0e\xfb\x57\xd2\x8d\x97\x62\x2d\xbd\xe7\x25\xaf"}, + {{0x77,0xf8,0x86,0x91,0xc4,0xef,0xf2,0x3e,0xbb,0x73,0x64,0x94,0x70,0x92,0x95,0x1a,0x5f,0xf3,0xf1,0x07,0x85,0xb4,0x17,0xe9,0x18,0x82,0x3a,0x55,0x2d,0xab,0x7c,0x75,},{0x74,0xd2,0x91,0x27,0xf1,0x99,0xd8,0x6a,0x86,0x76,0xae,0xc3,0x3b,0x4c,0xe3,0xf2,0x25,0xcc,0xb1,0x91,0xf5,0x2c,0x19,0x1c,0xcd,0x1e,0x8c,0xca,0x65,0x21,0x3a,0x6b,},{0xfb,0xe9,0x29,0xd7,0x43,0xa0,0x3c,0x17,0x91,0x05,0x75,0x49,0x2f,0x30,0x92,0xee,0x2a,0x2b,0xf1,0x4a,0x60,0xa3,0xfc,0xac,0xec,0x74,0xa5,0x8c,0x73,0x34,0x51,0x0f,0xc2,0x62,0xdb,0x58,0x27,0x91,0x32,0x2d,0x6c,0x8c,0x41,0xf1,0x70,0x0a,0xdb,0x80,0x02,0x7e,0xca,0xbc,0x14,0x27,0x0b,0x70,0x34,0x44,0xae,0x3e,0xe7,0x62,0x3e,0x0a,},18,"\xbd\x8e\x05\x03\x3f\x3a\x8b\xcd\xcb\xf4\xbe\xce\xb7\x09\x01\xc8\x2e\x31"}, + {{0xab,0x6f,0x7a,0xee,0x6a,0x08,0x37,0xb3,0x34,0xba,0x5e,0xb1,0xb2,0xad,0x7f,0xce,0xcf,0xab,0x7e,0x32,0x3c,0xab,0x18,0x7f,0xe2,0xe0,0xa9,0x5d,0x80,0xef,0xf1,0x32,},{0x5b,0x96,0xdc,0xa4,0x97,0x87,0x5b,0xf9,0x66,0x4c,0x5e,0x75,0xfa,0xcf,0x3f,0x9b,0xc5,0x4b,0xae,0x91,0x3d,0x66,0xca,0x15,0xee,0x85,0xf1,0x49,0x1c,0xa2,0x4d,0x2c,},{0x73,0xbc,0xa6,0x4e,0x9d,0xd0,0xdb,0x88,0x13,0x8e,0xed,0xfa,0xfc,0xea,0x8f,0x54,0x36,0xcf,0xb7,0x4b,0xfb,0x0e,0x77,0x33,0xcf,0x34,0x9b,0xaa,0x0c,0x49,0x77,0x5c,0x56,0xd5,0x93,0x4e,0x1d,0x38,0xe3,0x6f,0x39,0xb7,0xc5,0xbe,0xb0,0xa8,0x36,0x51,0x0c,0x45,0x12,0x6f,0x8e,0xc4,0xb6,0x81,0x05,0x19,0x90,0x5b,0x0c,0xa0,0x7c,0x09,},19,"\x81\x71\x45\x6f\x8b\x90\x71\x89\xb1\xd7\x79\xe2\x6b\xc5\xaf\xbb\x08\xc6\x7a"}, + {{0x8d,0x13,0x5d,0xe7,0xc8,0x41,0x1b,0xbd,0xbd,0x1b,0x31,0xe5,0xdc,0x67,0x8f,0x2a,0xc7,0x10,0x9e,0x79,0x2b,0x60,0xf3,0x8c,0xd2,0x49,0x36,0xe8,0xa8,0x98,0xc3,0x2d,},{0x1c,0xa2,0x81,0x93,0x85,0x29,0x89,0x65,0x35,0xa7,0x71,0x4e,0x35,0x84,0x08,0x5b,0x86,0xef,0x9f,0xec,0x72,0x3f,0x42,0x81,0x9f,0xc8,0xdd,0x5d,0x8c,0x00,0x81,0x7f,},{0xa1,0xad,0xc2,0xbc,0x6a,0x2d,0x98,0x06,0x62,0x67,0x7e,0x7f,0xdf,0xf6,0x42,0x4d,0xe7,0xdb,0xa5,0x0f,0x57,0x95,0xca,0x90,0xfd,0xf3,0xe9,0x6e,0x25,0x6f,0x32,0x85,0xca,0xc7,0x1d,0x33,0x60,0x48,0x2e,0x99,0x3d,0x02,0x94,0xba,0x4e,0xc7,0x44,0x0c,0x61,0xaf,0xfd,0xf3,0x5f,0xe8,0x3e,0x6e,0x04,0x26,0x39,0x37,0xdb,0x93,0xf1,0x05,},20,"\x8b\xa6\xa4\xc9\xa1\x5a\x24\x4a\x9c\x26\xbb\x2a\x59\xb1\x02\x6f\x21\x34\x8b\x49"}, + {{0x0e,0x76,0x5d,0x72,0x0e,0x70,0x5f,0x93,0x66,0xc1,0xab,0x8c,0x3f,0xa8,0x4c,0x9a,0x44,0x37,0x0c,0x06,0x96,0x9f,0x80,0x32,0x96,0x88,0x4b,0x28,0x46,0xa6,0x52,0xa4,},{0x7f,0xae,0x45,0xdd,0x0a,0x05,0x97,0x10,0x26,0xd4,0x10,0xbc,0x49,0x7a,0xf5,0xbe,0x7d,0x08,0x27,0xa8,0x2a,0x14,0x5c,0x20,0x3f,0x62,0x5d,0xfc,0xb8,0xb0,0x3b,0xa8,},{0xbb,0x61,0xcf,0x84,0xde,0x61,0x86,0x22,0x07,0xc6,0xa4,0x55,0x25,0x8b,0xc4,0xdb,0x4e,0x15,0xee,0xa0,0x31,0x7f,0xf8,0x87,0x18,0xb8,0x82,0xa0,0x6b,0x5c,0xf6,0xec,0x6f,0xd2,0x0c,0x5a,0x26,0x9e,0x5d,0x5c,0x80,0x5b,0xaf,0xbc,0xc5,0x79,0xe2,0x59,0x0a,0xf4,0x14,0xc7,0xc2,0x27,0x27,0x3c,0x10,0x2a,0x10,0x07,0x0c,0xdf,0xe8,0x0f,},21,"\x1d\x56\x6a\x62\x32\xbb\xaa\xb3\xe6\xd8\x80\x4b\xb5\x18\xa4\x98\xed\x0f\x90\x49\x86"}, + {{0xdb,0x36,0xe3,0x26,0xd6,0x76,0xc2,0xd1,0x9c,0xc8,0xfe,0x0c,0x14,0xb7,0x09,0x20,0x2e,0xcf,0xc7,0x61,0xd2,0x70,0x89,0xeb,0x6e,0xa4,0xb1,0xbb,0x02,0x1e,0xcf,0xa7,},{0x48,0x35,0x9b,0x85,0x0d,0x23,0xf0,0x71,0x5d,0x94,0xbb,0x8b,0xb7,0x5e,0x7e,0x14,0x32,0x2e,0xaf,0x14,0xf0,0x6f,0x28,0xa8,0x05,0x40,0x3f,0xbd,0xa0,0x02,0xfc,0x85,},{0xb6,0xdc,0xd0,0x99,0x89,0xdf,0xba,0xc5,0x43,0x22,0xa3,0xce,0x87,0x87,0x6e,0x1d,0x62,0x13,0x4d,0xa9,0x98,0xc7,0x9d,0x24,0xb5,0x0b,0xd7,0xa6,0xa7,0x97,0xd8,0x6a,0x0e,0x14,0xdc,0x9d,0x74,0x91,0xd6,0xc1,0x4a,0x67,0x3c,0x65,0x2c,0xfb,0xec,0x9f,0x96,0x2a,0x38,0xc9,0x45,0xda,0x3b,0x2f,0x08,0x79,0xd0,0xb6,0x8a,0x92,0x13,0x00,},22,"\x1b\x0a\xfb\x0a\xc4\xba\x9a\xb7\xb7\x17\x2c\xdd\xc9\xeb\x42\xbb\xa1\xa6\x4b\xce\x47\xd4"}, + {{0xc8,0x99,0x55,0xe0,0xf7,0x74,0x1d,0x90,0x5d,0xf0,0x73,0x0b,0x3d,0xc2,0xb0,0xce,0x1a,0x13,0x13,0x4e,0x44,0xfe,0xf3,0xd4,0x0d,0x60,0xc0,0x20,0xef,0x19,0xdf,0x77,},{0xfd,0xb3,0x06,0x73,0x40,0x2f,0xaf,0x1c,0x80,0x33,0x71,0x4f,0x35,0x17,0xe4,0x7c,0xc0,0xf9,0x1f,0xe7,0x0c,0xf3,0x83,0x6d,0x6c,0x23,0x63,0x6e,0x3f,0xd2,0x28,0x7c,},{0x7e,0xf6,0x6e,0x5e,0x86,0xf2,0x36,0x08,0x48,0xe0,0x01,0x4e,0x94,0x88,0x0a,0xe2,0x92,0x0a,0xd8,0xa3,0x18,0x5a,0x46,0xb3,0x5d,0x1e,0x07,0xde,0xa8,0xfa,0x8a,0xe4,0xf6,0xb8,0x43,0xba,0x17,0x4d,0x99,0xfa,0x79,0x86,0x65,0x4a,0x08,0x91,0xc1,0x2a,0x79,0x44,0x55,0x66,0x93,0x75,0xbf,0x92,0xaf,0x4c,0xc2,0x77,0x0b,0x57,0x9e,0x0c,},23,"\x50\x7c\x94\xc8\x82\x0d\x2a\x57\x93\xcb\xf3\x44\x2b\x3d\x71\x93\x6f\x35\xfe\x3a\xfe\xf3\x16"}, + {{0x4e,0x62,0x62,0x7f,0xc2,0x21,0x14,0x24,0x78,0xae,0xe7,0xf0,0x07,0x81,0xf8,0x17,0xf6,0x62,0xe3,0xb7,0x5d,0xb2,0x9b,0xb1,0x4a,0xb4,0x7c,0xf8,0xe8,0x41,0x04,0xd6,},{0xb1,0xd3,0x98,0x01,0x89,0x20,0x27,0xd5,0x8a,0x8c,0x64,0x33,0x51,0x63,0x19,0x58,0x93,0xbf,0xc1,0xb6,0x1d,0xbe,0xca,0x32,0x60,0x49,0x7e,0x1f,0x30,0x37,0x11,0x07,},{0x83,0x6a,0xfa,0x76,0x4d,0x9c,0x48,0xaa,0x47,0x70,0xa4,0x38,0x8b,0x65,0x4e,0x97,0xb3,0xc1,0x6f,0x08,0x29,0x67,0xfe,0xbc,0xa2,0x7f,0x2f,0xc4,0x7d,0xdf,0xd9,0x24,0x4b,0x03,0xcf,0xc7,0x29,0x69,0x8a,0xcf,0x51,0x09,0x70,0x43,0x46,0xb6,0x0b,0x23,0x0f,0x25,0x54,0x30,0x08,0x9d,0xdc,0x56,0x91,0x23,0x99,0xd1,0x12,0x2d,0xe7,0x0a,},24,"\xd3\xd6\x15\xa8\x47\x2d\x99\x62\xbb\x70\xc5\xb5\x46\x6a\x3d\x98\x3a\x48\x11\x04\x6e\x2a\x0e\xf5"}, + {{0x6b,0x83,0xd7,0xda,0x89,0x08,0xc3,0xe7,0x20,0x5b,0x39,0x86,0x4b,0x56,0xe5,0xf3,0xe1,0x71,0x96,0xa3,0xfc,0x9c,0x2f,0x58,0x05,0xaa,0xd0,0xf5,0x55,0x4c,0x14,0x2d,},{0xd0,0xc8,0x46,0xf9,0x7f,0xe2,0x85,0x85,0xc0,0xee,0x15,0x90,0x15,0xd6,0x4c,0x56,0x31,0x1c,0x88,0x6e,0xdd,0xcc,0x18,0x5d,0x29,0x6d,0xbb,0x16,0x5d,0x26,0x25,0xd6,},{0x16,0xe4,0x62,0xa2,0x9a,0x6d,0xd4,0x98,0x68,0x5a,0x37,0x18,0xb3,0xee,0xd0,0x0c,0xc1,0x59,0x86,0x01,0xee,0x47,0x82,0x04,0x86,0x03,0x2d,0x6b,0x9a,0xcc,0x9b,0xf8,0x9f,0x57,0x68,0x4e,0x08,0xd8,0xc0,0xf0,0x55,0x89,0xcd,0xa2,0x88,0x2a,0x05,0xdc,0x4c,0x63,0xf9,0xd0,0x43,0x1d,0x65,0x52,0x71,0x08,0x12,0x43,0x30,0x03,0xbc,0x08,},25,"\x6a\xda\x80\xb6\xfa\x84\xf7\x03\x49\x20\x78\x9e\x85\x36\xb8\x2d\x5e\x46\x78\x05\x9a\xed\x27\xf7\x1c"}, + {{0x19,0xa9,0x1f,0xe2,0x3a,0x4e,0x9e,0x33,0xec,0xc4,0x74,0x87,0x8f,0x57,0xc6,0x4c,0xf1,0x54,0xb3,0x94,0x20,0x34,0x87,0xa7,0x03,0x5e,0x1a,0xd9,0xcd,0x69,0x7b,0x0d,},{0x2b,0xf3,0x2b,0xa1,0x42,0xba,0x46,0x22,0xd8,0xf3,0xe2,0x9e,0xcd,0x85,0xee,0xa0,0x7b,0x9c,0x47,0xbe,0x9d,0x64,0x41,0x2c,0x9b,0x51,0x0b,0x27,0xdd,0x21,0x8b,0x23,},{0x88,0x1f,0x5b,0x8c,0x5a,0x03,0x0d,0xf0,0xf7,0x5b,0x66,0x34,0xb0,0x70,0xdd,0x27,0xbd,0x1e,0xe3,0xc0,0x87,0x38,0xae,0x34,0x93,0x38,0xb3,0xee,0x64,0x69,0xbb,0xf9,0x76,0x0b,0x13,0x57,0x8a,0x23,0x7d,0x51,0x82,0x53,0x5e,0xde,0x12,0x12,0x83,0x02,0x7a,0x90,0xb5,0xf8,0x65,0xd6,0x3a,0x65,0x37,0xdc,0xa0,0x7b,0x44,0x04,0x9a,0x0f,},26,"\x82\xcb\x53\xc4\xd5\xa0\x13\xba\xe5\x07\x07\x59\xec\x06\xc3\xc6\x95\x5a\xb7\xa4\x05\x09\x58\xec\x32\x8c"}, + {{0x1d,0x5b,0x8c,0xb6,0x21,0x5c,0x18,0x14,0x16,0x66,0xba,0xee,0xfc,0xf5,0xd6,0x9d,0xad,0x5b,0xea,0x9a,0x34,0x93,0xdd,0xda,0xa3,0x57,0xa4,0x39,0x7a,0x13,0xd4,0xde,},{0x94,0xd2,0x3d,0x97,0x7c,0x33,0xe4,0x9e,0x5e,0x49,0x92,0xc6,0x8f,0x25,0xec,0x99,0xa2,0x7c,0x41,0xce,0x6b,0x91,0xf2,0xbf,0xa0,0xcd,0x82,0x92,0xfe,0x96,0x28,0x35,},{0x3a,0xcd,0x39,0xbe,0xc8,0xc3,0xcd,0x2b,0x44,0x29,0x97,0x22,0xb5,0x85,0x0a,0x04,0x00,0xc1,0x44,0x35,0x90,0xfd,0x48,0x61,0xd5,0x9a,0xae,0x74,0x96,0xac,0xb3,0xdf,0x73,0xfc,0x3f,0xdf,0x79,0x69,0xae,0x5f,0x50,0xba,0x47,0xdd,0xdc,0x43,0x52,0x46,0xe5,0xfd,0x37,0x6f,0x6b,0x89,0x1c,0xd4,0xc2,0xca,0xf5,0xd6,0x14,0xb6,0x17,0x0c,},27,"\xa9\xa8\xcb\xb0\xad\x58\x51\x24\xe5\x22\xab\xbf\xb4\x05\x33\xbd\xd6\xf4\x93\x47\xb5\x5b\x18\xe8\x55\x8c\xb0"}, + {{0x6a,0x91,0xb3,0x22,0x7c,0x47,0x22,0x99,0x08,0x9b,0xdc,0xe9,0x35,0x6e,0x72,0x6a,0x40,0xef,0xd8,0x40,0xf1,0x10,0x02,0x70,0x8b,0x7e,0xe5,0x5b,0x64,0x10,0x5a,0xc2,},{0x9d,0x08,0x4a,0xa8,0xb9,0x7a,0x6b,0x9b,0xaf,0xa4,0x96,0xdb,0xc6,0xf7,0x6f,0x33,0x06,0xa1,0x16,0xc9,0xd9,0x17,0xe6,0x81,0x52,0x0a,0x0f,0x91,0x43,0x69,0x42,0x7e,},{0xf5,0x87,0x54,0x23,0x78,0x1b,0x66,0x21,0x6c,0xb5,0xe8,0x99,0x8d,0xe5,0xd9,0xff,0xc2,0x9d,0x1d,0x67,0x10,0x70,0x54,0xac,0xe3,0x37,0x45,0x03,0xa9,0xc3,0xef,0x81,0x15,0x77,0xf2,0x69,0xde,0x81,0x29,0x67,0x44,0xbd,0x70,0x6f,0x1a,0xc4,0x78,0xca,0xf0,0x9b,0x54,0xcd,0xf8,0x71,0xb3,0xf8,0x02,0xbd,0x57,0xf9,0xa6,0xcb,0x91,0x01,},28,"\x5c\xb6\xf9\xaa\x59\xb8\x0e\xca\x14\xf6\xa6\x8f\xb4\x0c\xf0\x7b\x79\x4e\x75\x17\x1f\xba\x96\x26\x2c\x1c\x6a\xdc"}, + {{0x93,0xea,0xa8,0x54,0xd7,0x91,0xf0,0x53,0x72,0xce,0x72,0xb9,0x4f,0xc6,0x50,0x3b,0x2f,0xf8,0xae,0x68,0x19,0xe6,0xa2,0x1a,0xfe,0x82,0x5e,0x27,0xad,0xa9,0xe4,0xfb,},{0x16,0xce,0xe8,0xa3,0xf2,0x63,0x18,0x34,0xc8,0x8b,0x67,0x08,0x97,0xff,0x0b,0x08,0xce,0x90,0xcc,0x14,0x7b,0x45,0x93,0xb3,0xf1,0xf4,0x03,0x72,0x7f,0x7e,0x7a,0xd5,},{0xd8,0x34,0x19,0x7c,0x1a,0x30,0x80,0x61,0x4e,0x0a,0x5f,0xa0,0xaa,0xaa,0x80,0x88,0x24,0xf2,0x1c,0x38,0xd6,0x92,0xe6,0xff,0xbd,0x20,0x0f,0x7d,0xfb,0x3c,0x8f,0x44,0x40,0x2a,0x73,0x82,0x18,0x0b,0x98,0xad,0x0a,0xfc,0x8e,0xec,0x1a,0x02,0xac,0xec,0xf3,0xcb,0x7f,0xde,0x62,0x7b,0x9f,0x18,0x11,0x1f,0x26,0x0a,0xb1,0xdb,0x9a,0x07,},29,"\x32\xfe\x27\x99\x41\x24\x20\x21\x53\xb5\xc7\x0d\x38\x13\xfd\xee\x9c\x2a\xa6\xe7\xdc\x74\x3d\x4d\x53\x5f\x18\x40\xa5"}, + {{0x94,0x1c,0xac,0x69,0xfb,0x7b,0x18,0x15,0xc5,0x7b,0xb9,0x87,0xc4,0xd6,0xc2,0xad,0x2c,0x35,0xd5,0xf9,0xa3,0x18,0x2a,0x79,0xd4,0xba,0x13,0xea,0xb2,0x53,0xa8,0xad,},{0x23,0xbe,0x32,0x3c,0x56,0x2d,0xfd,0x71,0xce,0x65,0xf5,0xbb,0xa5,0x6a,0x74,0xa3,0xa6,0xdf,0xc3,0x6b,0x57,0x3d,0x2f,0x94,0xf6,0x35,0xc7,0xf9,0xb4,0xfd,0x5a,0x5b,},{0x0f,0x8f,0xad,0x1e,0x6b,0xde,0x77,0x1b,0x4f,0x54,0x20,0xea,0xc7,0x5c,0x37,0x8b,0xae,0x6d,0xb5,0xac,0x66,0x50,0xcd,0x2b,0xc2,0x10,0xc1,0x82,0x3b,0x43,0x2b,0x48,0xe0,0x16,0xb1,0x05,0x95,0x45,0x8f,0xfa,0xb9,0x2f,0x7a,0x89,0x89,0xb2,0x93,0xce,0xb8,0xdf,0xed,0x6c,0x24,0x3a,0x20,0x38,0xfc,0x06,0x65,0x2a,0xaa,0xf1,0x6f,0x02,},30,"\xbb\x31\x72\x79\x57\x10\xfe\x00\x05\x4d\x3b\x5d\xfe\xf8\xa1\x16\x23\x58\x2d\xa6\x8b\xf8\xe4\x6d\x72\xd2\x7c\xec\xe2\xaa"}, + {{0x1a,0xcd,0xbb,0x79,0x3b,0x03,0x84,0x93,0x46,0x27,0x47,0x0d,0x79,0x5c,0x3d,0x1d,0xd4,0xd7,0x9c,0xea,0x59,0xef,0x98,0x3f,0x29,0x5b,0x9b,0x59,0x17,0x9c,0xbb,0x28,},{0x3f,0x60,0xc7,0x54,0x1a,0xfa,0x76,0xc0,0x19,0xcf,0x5a,0xa8,0x2d,0xcd,0xb0,0x88,0xed,0x9e,0x4e,0xd9,0x78,0x05,0x14,0xae,0xfb,0x37,0x9d,0xab,0xc8,0x44,0xf3,0x1a,},{0xbe,0x71,0xef,0x48,0x06,0xcb,0x04,0x1d,0x88,0x5e,0xff,0xd9,0xe6,0xb0,0xfb,0xb7,0x3d,0x65,0xd7,0xcd,0xec,0x47,0xa8,0x9c,0x8a,0x99,0x48,0x92,0xf4,0xe5,0x5a,0x56,0x8c,0x4c,0xc7,0x8d,0x61,0xf9,0x01,0xe8,0x0d,0xbb,0x62,0x8b,0x86,0xa2,0x3c,0xcd,0x59,0x4e,0x71,0x2b,0x57,0xfa,0x94,0xc2,0xd6,0x7e,0xc2,0x66,0x34,0x87,0x85,0x07,},31,"\x7c\xf3\x4f\x75\xc3\xda\xc9\xa8\x04\xd0\xfc\xd0\x9e\xba\x9b\x29\xc9\x48\x4e\x8a\x01\x8f\xa9\xe0\x73\x04\x2d\xf8\x8e\x3c\x56"}, + {{0x8e,0xd7,0xa7,0x97,0xb9,0xce,0xa8,0xa8,0x37,0x0d,0x41,0x91,0x36,0xbc,0xdf,0x68,0x3b,0x75,0x9d,0x2e,0x3c,0x69,0x47,0xf1,0x7e,0x13,0xe2,0x48,0x5a,0xa9,0xd4,0x20,},{0xb4,0x9f,0x3a,0x78,0xb1,0xc6,0xa7,0xfc,0xa8,0xf3,0x46,0x6f,0x33,0xbc,0x0e,0x92,0x9f,0x01,0xfb,0xa0,0x43,0x06,0xc2,0xa7,0x46,0x5f,0x46,0xc3,0x75,0x93,0x16,0xd9,},{0x04,0x26,0x6c,0x03,0x3b,0x91,0xc1,0x32,0x2c,0xeb,0x34,0x46,0xc9,0x01,0xff,0xcf,0x3c,0xc4,0x0c,0x40,0x34,0xe8,0x87,0xc9,0x59,0x7c,0xa1,0x89,0x3b,0xa7,0x33,0x0b,0xec,0xbb,0xd8,0xb4,0x81,0x42,0xef,0x35,0xc0,0x12,0xc6,0xba,0x51,0xa6,0x6d,0xf9,0x30,0x8c,0xb6,0x26,0x8a,0xd6,0xb1,0xe4,0xb0,0x3e,0x70,0x10,0x24,0x95,0x79,0x0b,},32,"\xa7\x50\xc2\x32\x93\x3d\xc1\x4b\x11\x84\xd8\x6d\x8b\x4c\xe7\x2e\x16\xd6\x97\x44\xba\x69\x81\x8b\x6a\xc3\x3b\x1d\x82\x3b\xb2\xc3"}, + {{0xf2,0xab,0x39,0x6f,0xe8,0x90,0x6e,0x3e,0x56,0x33,0xe9,0x9c,0xab,0xcd,0x5b,0x09,0xdf,0x08,0x59,0xb5,0x16,0x23,0x0b,0x1e,0x04,0x50,0xb5,0x80,0xb6,0x5f,0x61,0x6c,},{0x8e,0xa0,0x74,0x24,0x51,0x59,0xa1,0x16,0xaa,0x71,0x22,0xa2,0x5e,0xc1,0x6b,0x89,0x1d,0x62,0x5a,0x68,0xf3,0x36,0x60,0x42,0x39,0x08,0xf6,0xbd,0xc4,0x4f,0x8c,0x1b,},{0xa0,0x6a,0x23,0xd9,0x82,0xd8,0x1a,0xb8,0x83,0xaa,0xe2,0x30,0xad,0xbc,0x36,0x8a,0x6a,0x99,0x77,0xf0,0x03,0xce,0xbb,0x00,0xd4,0xc2,0xe4,0x01,0x84,0x90,0x19,0x1a,0x84,0xd3,0xa2,0x82,0xfd,0xbf,0xb2,0xfc,0x88,0x04,0x6e,0x62,0xde,0x43,0xe1,0x5f,0xb5,0x75,0x33,0x6b,0x3c,0x8b,0x77,0xd1,0x9c,0xe6,0xa0,0x09,0xce,0x51,0xf5,0x0c,},33,"\x5a\x44\xe3\x4b\x74\x6c\x5f\xd1\x89\x8d\x55\x2a\xb3\x54\xd2\x8f\xb4\x71\x38\x56\xd7\x69\x7d\xd6\x3e\xb9\xbd\x6b\x99\xc2\x80\xe1\x87"}, + {{0x55,0x0a,0x41,0xc0,0x13,0xf7,0x9b,0xab,0x8f,0x06,0xe4,0x3a,0xd1,0x83,0x6d,0x51,0x31,0x27,0x36,0xa9,0x71,0x38,0x06,0xfa,0xfe,0x66,0x45,0x21,0x9e,0xaa,0x1f,0x9d,},{0xaf,0x6b,0x71,0x45,0x47,0x4d,0xc9,0x95,0x4b,0x9a,0xf9,0x3a,0x9c,0xdb,0x34,0x44,0x9d,0x5b,0x7c,0x65,0x1c,0x82,0x4d,0x24,0xe2,0x30,0xb9,0x00,0x33,0xce,0x59,0xc0,},{0x16,0xdc,0x1e,0x2b,0x9f,0xa9,0x09,0xee,0xfd,0xc2,0x77,0xba,0x16,0xeb,0xe2,0x07,0xb8,0xda,0x5e,0x91,0x14,0x3c,0xde,0x78,0xc5,0x04,0x7a,0x89,0xf6,0x81,0xc3,0x3c,0x4e,0x4e,0x34,0x28,0xd5,0xc9,0x28,0x09,0x59,0x03,0xa8,0x11,0xec,0x00,0x2d,0x52,0xa3,0x9e,0xd7,0xf8,0xb3,0xfe,0x19,0x27,0x20,0x0c,0x6d,0xd0,0xb9,0xab,0x3e,0x04,},34,"\x8b\xc4\x18\x5e\x50\xe5\x7d\x5f\x87\xf4\x75\x15\xfe\x2b\x18\x37\xd5\x85\xf0\xaa\xe9\xe1\xca\x38\x3b\x3e\xc9\x08\x88\x4b\xb9\x00\xff\x27"}, + {{0x19,0xac,0x3e,0x27,0x24,0x38,0xc7,0x2d,0xdf,0x7b,0x88,0x19,0x64,0x86,0x7c,0xb3,0xb3,0x1f,0xf4,0xc7,0x93,0xbb,0x7e,0xa1,0x54,0x61,0x3c,0x1d,0xb0,0x68,0xcb,0x7e,},{0xf8,0x5b,0x80,0xe0,0x50,0xa1,0xb9,0x62,0x0d,0xb1,0x38,0xbf,0xc9,0xe1,0x00,0x32,0x7e,0x25,0xc2,0x57,0xc5,0x92,0x17,0xb6,0x01,0xf1,0xf6,0xac,0x9a,0x41,0x3d,0x3f,},{0xea,0x85,0x5d,0x78,0x1c,0xbe,0xa4,0x68,0x2e,0x35,0x01,0x73,0xcb,0x89,0xe8,0x61,0x9c,0xcf,0xdd,0xb9,0x7c,0xdc,0xe1,0x6f,0x9a,0x2f,0x6f,0x68,0x92,0xf4,0x6d,0xbe,0x68,0xe0,0x4b,0x12,0xb8,0xd8,0x86,0x89,0xa7,0xa3,0x16,0x70,0xcd,0xff,0x40,0x9a,0xf9,0x8a,0x93,0xb4,0x9a,0x34,0x53,0x7b,0x6a,0xa0,0x09,0xd2,0xeb,0x8b,0x47,0x01,},35,"\x95\x87\x2d\x5f\x78\x9f\x95\x48\x4e\x30\xcb\xb0\xe1\x14\x02\x89\x53\xb1\x6f\x5c\x6a\x8d\x9f\x65\xc0\x03\xa8\x35\x43\xbe\xaa\x46\xb3\x86\x45"}, + {{0xca,0x26,0x7d,0xe9,0x6c,0x93,0xc2,0x38,0xfa,0xfb,0x12,0x79,0x81,0x20,0x59,0xab,0x93,0xac,0x03,0x05,0x96,0x57,0xfd,0x99,0x4f,0x8f,0xa5,0xa0,0x92,0x39,0xc8,0x21,},{0x01,0x73,0x70,0xc8,0x79,0x09,0x0a,0x81,0xc7,0xf2,0x72,0xc2,0xfc,0x80,0xe3,0xaa,0xc2,0xbc,0x60,0x3f,0xcb,0x37,0x9a,0xfc,0x98,0x69,0x11,0x60,0xab,0x74,0x5b,0x26,},{0xac,0x95,0x7f,0x82,0x33,0x5a,0xa7,0x14,0x1e,0x96,0xb5,0x9d,0x63,0xe3,0xcc,0xee,0x95,0xc3,0xa2,0xc4,0x7d,0x02,0x65,0x40,0xc2,0xaf,0x42,0xdc,0x95,0x33,0xd5,0xfd,0x81,0x82,0x7d,0x16,0x79,0xad,0x18,0x7a,0xea,0xf3,0x78,0x34,0x91,0x5e,0x75,0xb1,0x47,0xa9,0x28,0x68,0x06,0xc8,0x01,0x75,0x16,0xba,0x43,0xdd,0x05,0x1a,0x5e,0x0c,},36,"\xe0\x5f\x71\xe4\xe4\x9a\x72\xec\x55\x0c\x44\xa3\xb8\x5a\xca\x8f\x20\xff\x26\xc3\xee\x94\xa8\x0f\x1b\x43\x1c\x7d\x15\x4e\xc9\x60\x3e\xe0\x25\x31"}, + {{0x3d,0xff,0x5e,0x89,0x94,0x75,0xe7,0xe9,0x1d,0xd2,0x61,0x32,0x2f,0xab,0x09,0x98,0x0c,0x52,0x97,0x0d,0xe1,0xda,0x6e,0x2e,0x20,0x16,0x60,0xcc,0x4f,0xce,0x70,0x32,},{0xf3,0x01,0x62,0xba,0xc9,0x84,0x47,0xc4,0x04,0x2f,0xac,0x05,0xda,0x44,0x80,0x34,0x62,0x9b,0xe2,0xc6,0xa5,0x8d,0x30,0xdf,0xd5,0x78,0xba,0x9f,0xb5,0xe3,0x93,0x0b,},{0x5e,0xfe,0x7a,0x92,0xff,0x96,0x23,0x08,0x9b,0x3e,0x3b,0x78,0xf3,0x52,0x11,0x53,0x66,0xe2,0x6b,0xa3,0xfb,0x1a,0x41,0x62,0x09,0xbc,0x02,0x9e,0x9c,0xad,0xcc,0xd9,0xf4,0xaf,0xfa,0x33,0x35,0x55,0xa8,0xf3,0xa3,0x5a,0x9d,0x0f,0x7c,0x34,0xb2,0x92,0xca,0xe7,0x7e,0xc9,0x6f,0xa3,0xad,0xfc,0xaa,0xde,0xe2,0xd9,0xce,0xd8,0xf8,0x05,},37,"\x93\x8f\x0e\x77\x62\x1b\xf3\xea\x52\xc7\xc4\x91\x1c\x51\x57\xc2\xd8\xa2\xa8\x58\x09\x3e\xf1\x6a\xa9\xb1\x07\xe6\x9d\x98\x03\x7b\xa1\x39\xa3\xc3\x82"}, + {{0x9a,0x6b,0x84,0x78,0x64,0xe7,0x0c,0xfe,0x8b,0xa6,0xab,0x22,0xfa,0x0c,0xa3,0x08,0xc0,0xcc,0x8b,0xec,0x71,0x41,0xfb,0xca,0xa3,0xb8,0x1f,0x5d,0x1e,0x1c,0xfc,0xfc,},{0x34,0xad,0x0f,0xbd,0xb2,0x56,0x65,0x07,0xa8,0x1c,0x2b,0x1f,0x8a,0xa8,0xf5,0x3d,0xcc,0xaa,0x64,0xcc,0x87,0xad,0xa9,0x1b,0x90,0x3e,0x90,0x0d,0x07,0xee,0xe9,0x30,},{0x2a,0xb2,0x55,0x16,0x9c,0x48,0x9c,0x54,0xc7,0x32,0x23,0x2e,0x37,0xc8,0x73,0x49,0xd4,0x86,0xb1,0xeb,0xa2,0x05,0x09,0xdb,0xab,0xe7,0xfe,0xd3,0x29,0xef,0x08,0xfd,0x75,0xba,0x1c,0xd1,0x45,0xe6,0x7b,0x2e,0xa2,0x6c,0xb5,0xcc,0x51,0xca,0xb3,0x43,0xee,0xb0,0x85,0xfe,0x1f,0xd7,0xb0,0xec,0x4c,0x6a,0xfc,0xd9,0xb9,0x79,0xf9,0x05,},38,"\x83\x83\x67\x47\x11\x83\xc7\x1f\x7e\x71\x77\x24\xf8\x9d\x40\x1c\x3a\xd9\x86\x3f\xd9\xcc\x7a\xa3\xcf\x33\xd3\xc5\x29\x86\x0c\xb5\x81\xf3\x09\x3d\x87\xda"}, + {{0x57,0x5b,0xe0,0x7a,0xfc,0xa5,0xd0,0x63,0xc2,0x38,0xcd,0x9b,0x80,0x28,0x77,0x2c,0xc4,0x9c,0xda,0x34,0x47,0x14,0x32,0xa2,0xe1,0x66,0xe0,0x96,0xe2,0x21,0x9e,0xfc,},{0x94,0xe5,0xeb,0x4d,0x50,0x24,0xf4,0x9d,0x7e,0xbf,0x79,0x81,0x7c,0x8d,0xe1,0x14,0x97,0xdc,0x2b,0x55,0x62,0x2a,0x51,0xae,0x12,0x3f,0xfc,0x74,0x9d,0xbb,0x16,0xe0,},{0x58,0x27,0x1d,0x44,0x23,0x6f,0x3b,0x98,0xc5,0x8f,0xd7,0xae,0x0d,0x2f,0x49,0xef,0x2b,0x6e,0x3a,0xff,0xdb,0x22,0x5a,0xa3,0xba,0x55,0x5f,0x0e,0x11,0xcc,0x53,0xc2,0x3a,0xd1,0x9b,0xaf,0x24,0x34,0x65,0x90,0xd0,0x5d,0x7d,0x53,0x90,0x58,0x20,0x82,0xcf,0x94,0xd3,0x9c,0xad,0x65,0x30,0xab,0x93,0xd1,0x3e,0xfb,0x39,0x27,0x95,0x06,},39,"\x33\xe5\x91\x8b\x66\xd3\x3d\x55\xfe\x71\x7c\xa3\x43\x83\xea\xe7\x8f\x0a\xf8\x28\x89\xca\xf6\x69\x6e\x1a\xc9\xd9\x5d\x1f\xfb\x32\xcb\xa7\x55\xf9\xe3\x50\x3e"}, + {{0x15,0xff,0xb4,0x55,0x14,0xd4,0x34,0x44,0xd6,0x1f,0xcb,0x10,0x5e,0x30,0xe1,0x35,0xfd,0x26,0x85,0x23,0xdd,0xa2,0x0b,0x82,0x75,0x8b,0x17,0x94,0x23,0x11,0x04,0x41,},{0x17,0x72,0xc5,0xab,0xc2,0xd2,0x3f,0xd2,0xf9,0xd1,0xc3,0x25,0x7b,0xe7,0xbc,0x3c,0x1c,0xd7,0x9c,0xee,0x40,0x84,0x4b,0x74,0x9b,0x3a,0x77,0x43,0xd2,0xf9,0x64,0xb8,},{0x68,0x28,0xcd,0x76,0x24,0xe7,0x93,0xb8,0xa4,0xce,0xb9,0x6d,0x3c,0x2a,0x97,0x5b,0xf7,0x73,0xe5,0xff,0x66,0x45,0xf3,0x53,0x61,0x40,0x58,0x62,0x1e,0x58,0x83,0x52,0x89,0xe7,0xf3,0x1f,0x42,0xdf,0xe6,0xaf,0x6d,0x73,0x6f,0x26,0x44,0x51,0x1e,0x32,0x0c,0x0f,0xa6,0x98,0x58,0x2a,0x79,0x77,0x8d,0x18,0x73,0x0e,0xd3,0xe8,0xcb,0x08,},40,"\xda\x9c\x55\x59\xd0\xea\x51\xd2\x55\xb6\xbd\x9d\x76\x38\xb8\x76\x47\x2f\x94\x2b\x33\x0f\xc0\xe2\xb3\x0a\xea\x68\xd7\x73\x68\xfc\xe4\x94\x82\x72\x99\x1d\x25\x7e"}, + {{0xfe,0x05,0x68,0x64,0x29,0x43,0xb2,0xe1,0xaf,0xbf,0xd1,0xf1,0x0f,0xe8,0xdf,0x87,0xa4,0x23,0x6b,0xea,0x40,0xdc,0xe7,0x42,0x07,0x2c,0xb2,0x18,0x86,0xee,0xc1,0xfa,},{0x29,0x9e,0xbd,0x1f,0x13,0x17,0x7d,0xbd,0xb6,0x6a,0x91,0x2b,0xbf,0x71,0x20,0x38,0xfd,0xf7,0x3b,0x06,0xc3,0xac,0x02,0x0c,0x7b,0x19,0x12,0x67,0x55,0xd4,0x7f,0x61,},{0xd5,0x9e,0x6d,0xfc,0xc6,0xd7,0xe3,0xe2,0xc5,0x8d,0xec,0x81,0xe9,0x85,0xd2,0x45,0xe6,0x81,0xac,0xf6,0x59,0x4a,0x23,0xc5,0x92,0x14,0xf7,0xbe,0xd8,0x01,0x5d,0x81,0x3c,0x76,0x82,0xb6,0x0b,0x35,0x83,0x44,0x03,0x11,0xe7,0x2a,0x86,0x65,0xba,0x2c,0x96,0xde,0xc2,0x3c,0xe8,0x26,0xe1,0x60,0x12,0x7e,0x18,0x13,0x2b,0x03,0x04,0x04,},41,"\xc5\x9d\x08\x62\xec\x1c\x97\x46\xab\xcc\x3c\xf8\x3c\x9e\xeb\xa2\xc7\x08\x2a\x03\x6a\x8c\xb5\x7c\xe4\x87\xe7\x63\x49\x27\x96\xd4\x7e\x6e\x06\x3a\x0c\x1f\xec\xcc\x2d"}, + {{0x5e,0xcb,0x16,0xc2,0xdf,0x27,0xc8,0xcf,0x58,0xe4,0x36,0xa9,0xd3,0xaf,0xfb,0xd5,0x8e,0x95,0x38,0xa9,0x26,0x59,0xa0,0xf9,0x7c,0x4c,0x4f,0x99,0x46,0x35,0xa8,0xca,},{0xda,0x76,0x8b,0x20,0xc4,0x37,0xdd,0x3a,0xa5,0xf8,0x4b,0xb6,0xa0,0x77,0xff,0xa3,0x4a,0xb6,0x85,0x01,0xc5,0x35,0x2b,0x5c,0xc3,0xfd,0xce,0x7f,0xe6,0xc2,0x39,0x8d,},{0x1c,0x72,0x3a,0x20,0xc6,0x77,0x24,0x26,0xa6,0x70,0xe4,0xd5,0xc4,0xa9,0x7c,0x6e,0xbe,0x91,0x47,0xf7,0x1b,0xb0,0xa4,0x15,0x63,0x1e,0x44,0x40,0x6e,0x29,0x03,0x22,0xe4,0xca,0x97,0x7d,0x34,0x8f,0xe7,0x85,0x6a,0x8e,0xdc,0x23,0x5d,0x0f,0xe9,0x5f,0x7e,0xd9,0x1a,0xef,0xdd,0xf2,0x8a,0x77,0xe2,0xc7,0xdb,0xfd,0x8f,0x55,0x2f,0x0a,},42,"\x56\xf1\x32\x9d\x9a\x6b\xe2\x5a\x61\x59\xc7\x2f\x12\x68\x8d\xc8\x31\x4e\x85\xdd\x9e\x7e\x4d\xc0\x5b\xbe\xcb\x77\x29\xe0\x23\xc8\x6f\x8e\x09\x37\x35\x3f\x27\xc7\xed\xe9"}, + {{0xd5,0x99,0xd6,0x37,0xb3,0xc3,0x0a,0x82,0xa9,0x98,0x4e,0x2f,0x75,0x84,0x97,0xd1,0x44,0xde,0x6f,0x06,0xb9,0xfb,0xa0,0x4d,0xd4,0x0f,0xd9,0x49,0x03,0x9d,0x7c,0x84,},{0x67,0x91,0xd8,0xce,0x50,0xa4,0x46,0x89,0xfc,0x17,0x87,0x27,0xc5,0xc3,0xa1,0xc9,0x59,0xfb,0xee,0xd7,0x4e,0xf7,0xd8,0xe7,0xbd,0x3c,0x1a,0xb4,0xda,0x31,0xc5,0x1f,},{0xeb,0xf1,0x0d,0x9a,0xc7,0xc9,0x61,0x08,0x14,0x0e,0x7d,0xef,0x6f,0xe9,0x53,0x3d,0x72,0x76,0x46,0xff,0x5b,0x3a,0xf2,0x73,0xc1,0xdf,0x95,0x76,0x2a,0x66,0xf3,0x2b,0x65,0xa0,0x96,0x34,0xd0,0x13,0xf5,0x4b,0x5d,0xd6,0x01,0x1f,0x91,0xbc,0x33,0x6c,0xa8,0xb3,0x55,0xce,0x33,0xf8,0xcf,0xbe,0xc2,0x53,0x5a,0x4c,0x42,0x7f,0x82,0x05,},43,"\xa7\xc0\x4e\x8b\xa7\x5d\x0a\x03\xd8\xb1\x66\xad\x7a\x1d\x77\xe1\xb9\x1c\x7a\xaf\x7b\xef\xdd\x99\x31\x1f\xc3\xc5\x4a\x68\x4d\xdd\x97\x1d\x5b\x32\x11\xc3\xee\xaf\xf1\xe5\x4e"}, + {{0x30,0xab,0x82,0x32,0xfa,0x70,0x18,0xf0,0xce,0x6c,0x39,0xbd,0x8f,0x78,0x2f,0xe2,0xe1,0x59,0x75,0x8b,0xb0,0xf2,0xf4,0x38,0x6c,0x7f,0x28,0xcf,0xd2,0xc8,0x58,0x98,},{0xec,0xfb,0x6a,0x2b,0xd4,0x2f,0x31,0xb6,0x12,0x50,0xba,0x5d,0xe7,0xe4,0x6b,0x47,0x19,0xaf,0xdf,0xbc,0x66,0x0d,0xb7,0x1a,0x7b,0xd1,0xdf,0x7b,0x0a,0x3a,0xbe,0x37,},{0x9a,0xf8,0x85,0x34,0x4c,0xc7,0x23,0x94,0x98,0xf7,0x12,0xdf,0x80,0xbc,0x01,0xb8,0x06,0x38,0x29,0x1e,0xd4,0xa1,0xd2,0x8b,0xaa,0x55,0x45,0x01,0x7a,0x72,0xe2,0xf6,0x56,0x49,0xcc,0xf9,0x60,0x3d,0xa6,0xeb,0x5b,0xfa,0xb9,0xf5,0x54,0x3a,0x6c,0xa4,0xa7,0xaf,0x38,0x66,0x15,0x3c,0x76,0xbf,0x66,0xbf,0x95,0xde,0xf6,0x15,0xb0,0x0c,},44,"\x63\xb8\x0b\x79\x56\xac\xbe\xcf\x0c\x35\xe9\xab\x06\xb9\x14\xb0\xc7\x01\x4f\xe1\xa4\xbb\xc0\x21\x72\x40\xc1\xa3\x30\x95\xd7\x07\x95\x3e\xd7\x7b\x15\xd2\x11\xad\xaf\x9b\x97\xdc"}, + {{0x0d,0xdc,0xdc,0x87,0x2c,0x7b,0x74,0x8d,0x40,0xef,0xe9,0x6c,0x28,0x81,0xae,0x18,0x9d,0x87,0xf5,0x61,0x48,0xed,0x8a,0xf3,0xeb,0xbb,0xc8,0x03,0x24,0xe3,0x8b,0xdd,},{0x58,0x8d,0xda,0xdc,0xbc,0xed,0xf4,0x0d,0xf0,0xe9,0x69,0x7d,0x8b,0xb2,0x77,0xc7,0xbb,0x14,0x98,0xfa,0x1d,0x26,0xce,0x0a,0x83,0x5a,0x76,0x0b,0x92,0xca,0x7c,0x85,},{0xc1,0x79,0xc0,0x94,0x56,0xe2,0x35,0xfe,0x24,0x10,0x5a,0xfa,0x6e,0x8e,0xc0,0x46,0x37,0xf8,0xf9,0x43,0x81,0x7c,0xd0,0x98,0xba,0x95,0x38,0x7f,0x96,0x53,0xb2,0xad,0xd1,0x81,0xa3,0x14,0x47,0xd9,0x2d,0x1a,0x1d,0xdf,0x1c,0xeb,0x0d,0xb6,0x21,0x18,0xde,0x9d,0xff,0xb7,0xdc,0xd2,0x42,0x40,0x57,0xcb,0xdf,0xf5,0xd4,0x1d,0x04,0x03,},45,"\x65\x64\x1c\xd4\x02\xad\xd8\xbf\x3d\x1d\x67\xdb\xeb\x6d\x41\xde\xbf\xbe\xf6\x7e\x43\x17\xc3\x5b\x0a\x6d\x5b\xbb\xae\x0e\x03\x4d\xe7\xd6\x70\xba\x14\x13\xd0\x56\xf2\xd6\xf1\xde\x12"}, + {{0x89,0xf0,0xd6,0x82,0x99,0xba,0x0a,0x5a,0x83,0xf2,0x48,0xae,0x0c,0x16,0x9f,0x8e,0x38,0x49,0xa9,0xb4,0x7b,0xd4,0x54,0x98,0x84,0x30,0x5c,0x99,0x12,0xb4,0x66,0x03,},{0xab,0xa3,0xe7,0x95,0xaa,0xb2,0x01,0x2a,0xcc,0xea,0xdd,0x7b,0x3b,0xd9,0xda,0xee,0xed,0x6f,0xf5,0x25,0x8b,0xdc,0xd7,0xc9,0x36,0x99,0xc2,0xa3,0x83,0x6e,0x38,0x32,},{0x2c,0x69,0x1f,0xa8,0xd4,0x87,0xce,0x20,0xd5,0xd2,0xfa,0x41,0x55,0x91,0x16,0xe0,0xbb,0xf4,0x39,0x7c,0xf5,0x24,0x0e,0x15,0x25,0x56,0x18,0x35,0x41,0xd6,0x6c,0xf7,0x53,0x58,0x24,0x01,0xa4,0x38,0x8d,0x39,0x03,0x39,0xdb,0xef,0x4d,0x38,0x47,0x43,0xca,0xa3,0x46,0xf5,0x5f,0x8d,0xab,0xa6,0x8b,0xa7,0xb9,0x13,0x1a,0x8a,0x6e,0x0b,},46,"\x4f\x18\x46\xdd\x7a\xd5\x0e\x54\x5d\x4c\xfb\xff\xbb\x1d\xc2\xff\x14\x5d\xc1\x23\x75\x4d\x08\xaf\x4e\x44\xec\xc0\xbc\x8c\x91\x41\x13\x88\xbc\x76\x53\xe2\xd8\x93\xd1\xea\xc2\x10\x7d\x05"}, + {{0x0a,0x3c,0x18,0x44,0xe2,0xdb,0x07,0x0f,0xb2,0x4e,0x3c,0x95,0xcb,0x1c,0xc6,0x71,0x4e,0xf8,0x4e,0x2c,0xcd,0x2b,0x9d,0xd2,0xf1,0x46,0x0e,0xbf,0x7e,0xcf,0x13,0xb1,},{0x72,0xe4,0x09,0x93,0x7e,0x06,0x10,0xeb,0x5c,0x20,0xb3,0x26,0xdc,0x6e,0xa1,0xbb,0xbc,0x04,0x06,0x70,0x1c,0x5c,0xd6,0x7d,0x1f,0xbd,0xe0,0x91,0x92,0xb0,0x7c,0x01,},{0x87,0xf7,0xfd,0xf4,0x60,0x95,0x20,0x1e,0x87,0x7a,0x58,0x8f,0xe3,0xe5,0xaa,0xf4,0x76,0xbd,0x63,0x13,0x8d,0x8a,0x87,0x8b,0x89,0xd6,0xac,0x60,0x63,0x1b,0x34,0x58,0xb9,0xd4,0x1a,0x3c,0x61,0xa5,0x88,0xe1,0xdb,0x8d,0x29,0xa5,0x96,0x89,0x81,0xb0,0x18,0x77,0x6c,0x58,0x87,0x80,0x92,0x2f,0x5a,0xa7,0x32,0xba,0x63,0x79,0xdd,0x05,},47,"\x4c\x82\x74\xd0\xed\x1f\x74\xe2\xc8\x6c\x08\xd9\x55\xbd\xe5\x5b\x2d\x54\x32\x7e\x82\x06\x2a\x1f\x71\xf7\x0d\x53\x6f\xdc\x87\x22\xcd\xea\xd7\xd2\x2a\xae\xad\x2b\xfa\xa1\xad\x00\xb8\x29\x57"}, + {{0xc8,0xd7,0xa8,0x81,0x8b,0x98,0xdf,0xdb,0x20,0x83,0x9c,0x87,0x1c,0xb5,0xc4,0x8e,0x9e,0x94,0x70,0xca,0x3a,0xd3,0x5b,0xa2,0x61,0x3a,0x5d,0x31,0x99,0xc8,0xab,0x23,},{0x90,0xd2,0xef,0xbb,0xa4,0xd4,0x3e,0x6b,0x2b,0x99,0x2c,0xa1,0x60,0x83,0xdb,0xcf,0xa2,0xb3,0x22,0x38,0x39,0x07,0xb0,0xee,0x75,0xf3,0xe9,0x58,0x45,0xd3,0xc4,0x7f,},{0xfa,0x2e,0x99,0x44,0x21,0xae,0xf1,0xd5,0x85,0x66,0x74,0x81,0x3d,0x05,0xcb,0xd2,0xcf,0x84,0xef,0x5e,0xb4,0x24,0xaf,0x6e,0xcd,0x0d,0xc6,0xfd,0xbd,0xc2,0xfe,0x60,0x5f,0xe9,0x85,0x88,0x33,0x12,0xec,0xf3,0x4f,0x59,0xbf,0xb2,0xf1,0xc9,0x14,0x9e,0x5b,0x9c,0xc9,0xec,0xda,0x05,0xb2,0x73,0x11,0x30,0xf3,0xed,0x28,0xdd,0xae,0x0b,},48,"\x78\x3e\x33\xc3\xac\xbd\xbb\x36\xe8\x19\xf5\x44\xa7\x78\x1d\x83\xfc\x28\x3d\x33\x09\xf5\xd3\xd1\x2c\x8d\xcd\x6b\x0b\x3d\x0e\x89\xe3\x8c\xfd\x3b\x4d\x08\x85\x66\x1c\xa5\x47\xfb\x97\x64\xab\xff"}, + {{0xb4,0x82,0x70,0x36,0x12,0xd0,0xc5,0x86,0xf7,0x6c,0xfc,0xb2,0x1c,0xfd,0x21,0x03,0xc9,0x57,0x25,0x15,0x04,0xa8,0xc0,0xac,0x4c,0x86,0xc9,0xc6,0xf3,0xe4,0x29,0xff,},{0xfd,0x71,0x1d,0xc7,0xdd,0x3b,0x1d,0xfb,0x9d,0xf9,0x70,0x4b,0xe3,0xe6,0xb2,0x6f,0x58,0x7f,0xe7,0xdd,0x7b,0xa4,0x56,0xa9,0x1b,0xa4,0x3f,0xe5,0x1a,0xec,0x09,0xad,},{0x58,0x83,0x2b,0xde,0xb2,0x6f,0xea,0xfc,0x31,0xb4,0x62,0x77,0xcf,0x3f,0xb5,0xd7,0xa1,0x7d,0xfb,0x7c,0xcd,0x9b,0x1f,0x58,0xec,0xbe,0x6f,0xeb,0x97,0x96,0x66,0x82,0x8f,0x23,0x9b,0xa4,0xd7,0x52,0x19,0x26,0x0e,0xca,0xc0,0xac,0xf4,0x0f,0x0e,0x5e,0x25,0x90,0xf4,0xca,0xa1,0x6b,0xbb,0xcd,0x8a,0x15,0x5d,0x34,0x79,0x67,0xa6,0x07,},49,"\x29\xd7\x7a\xcf\xd9\x9c\x7a\x00\x70\xa8\x8f\xeb\x62\x47\xa2\xbc\xe9\x98\x4f\xe3\xe6\xfb\xf1\x9d\x40\x45\x04\x2a\x21\xab\x26\xcb\xd7\x71\xe1\x84\xa9\xa7\x5f\x31\x6b\x64\x8c\x69\x20\xdb\x92\xb8\x7b"}, + {{0x84,0xe5,0x0d,0xd9,0xa0,0xf1,0x97,0xe3,0x89,0x3c,0x38,0xdb,0xd9,0x1f,0xaf,0xc3,0x44,0xc1,0x77,0x6d,0x3a,0x40,0x0e,0x2f,0x0f,0x0e,0xe7,0xaa,0x82,0x9e,0xb8,0xa2,},{0x2c,0x50,0xf8,0x70,0xee,0x48,0xb3,0x6b,0x0a,0xc2,0xf8,0xa5,0xf3,0x36,0xfb,0x09,0x0b,0x11,0x30,0x50,0xdb,0xcc,0x25,0xe0,0x78,0x20,0x0a,0x6e,0x16,0x15,0x3e,0xea,},{0x69,0xe6,0xa4,0x49,0x1a,0x63,0x83,0x73,0x16,0xe8,0x6a,0x5f,0x4b,0xa7,0xcd,0x0d,0x73,0x1e,0xcc,0x58,0xf1,0xd0,0xa2,0x64,0xc6,0x7c,0x89,0xbe,0xfd,0xd8,0xd3,0x82,0x9d,0x8d,0xe1,0x3b,0x33,0xcc,0x0b,0xf5,0x13,0x93,0x17,0x15,0xc7,0x80,0x96,0x57,0xe2,0xbf,0xb9,0x60,0xe5,0xc7,0x64,0xc9,0x71,0xd7,0x33,0x74,0x60,0x93,0xe5,0x00,},50,"\xf3\x99\x2c\xde\x64\x93\xe6\x71\xf1\xe1\x29\xdd\xca\x80\x38\xb0\xab\xdb\x77\xbb\x90\x35\xf9\xf8\xbe\x54\xbd\x5d\x68\xc1\xae\xff\x72\x4f\xf4\x7d\x29\x34\x43\x91\xdc\x53\x61\x66\xb8\x67\x1c\xbb\xf1\x23"}, + {{0xb3,0x22,0xd4,0x65,0x77,0xa2,0xa9,0x91,0xa4,0xd1,0x69,0x82,0x87,0x83,0x2a,0x39,0xc4,0x87,0xef,0x77,0x6b,0x4b,0xff,0x03,0x7a,0x05,0xc7,0xf1,0x81,0x2b,0xde,0xec,},{0xeb,0x2b,0xca,0xdf,0xd3,0xee,0xc2,0x98,0x6b,0xaf,0xf3,0x2b,0x98,0xe7,0xc4,0xdb,0xf0,0x3f,0xf9,0x5d,0x8a,0xd5,0xff,0x9a,0xa9,0x50,0x6e,0x54,0x72,0xff,0x84,0x5f,},{0xc7,0xb5,0x51,0x37,0x31,0x7c,0xa2,0x1e,0x33,0x48,0x9f,0xf6,0xa9,0xbf,0xab,0x97,0xc8,0x55,0xdc,0x6f,0x85,0x68,0x4a,0x70,0xa9,0x12,0x5a,0x26,0x1b,0x56,0xd5,0xe6,0xf1,0x49,0xc5,0x77,0x4d,0x73,0x4f,0x2d,0x8d,0xeb,0xfc,0x77,0xb7,0x21,0x89,0x6a,0x82,0x67,0xc2,0x37,0x68,0xe9,0xba,0xdb,0x91,0x0e,0xef,0x83,0xec,0x25,0x88,0x02,},51,"\x19\xf1\xbf\x5d\xcf\x17\x50\xc6\x11\xf1\xc4\xa2\x86\x52\x00\x50\x4d\x82\x29\x8e\xdd\x72\x67\x1f\x62\xa7\xb1\x47\x1a\xc3\xd4\xa3\x0f\x7d\xe9\xe5\xda\x41\x08\xc5\x2a\x4c\xe7\x0a\x3e\x11\x4a\x52\xa3\xb3\xc5"}, + {{0x96,0x0c,0xab,0x50,0x34,0xb9,0x83,0x8d,0x09,0x8d,0x2d,0xcb,0xf4,0x36,0x4b,0xec,0x16,0xd3,0x88,0xf6,0x37,0x6d,0x73,0xa6,0x27,0x3b,0x70,0xf8,0x2b,0xbc,0x98,0xc0,},{0x5e,0x3c,0x19,0xf2,0x41,0x5a,0xcf,0x72,0x9f,0x82,0x9a,0x4e,0xbd,0x5c,0x40,0xe1,0xa6,0xbc,0x9f,0xbc,0xa9,0x57,0x03,0xa9,0x37,0x60,0x87,0xed,0x09,0x37,0xe5,0x1a,},{0x27,0xd4,0xc3,0xa1,0x81,0x1e,0xf9,0xd4,0x36,0x0b,0x3b,0xdd,0x13,0x3c,0x2c,0xcc,0x30,0xd0,0x2c,0x2f,0x24,0x82,0x15,0x77,0x6c,0xb0,0x7e,0xe4,0x17,0x7f,0x9b,0x13,0xfc,0x42,0xdd,0x70,0xa6,0xc2,0xfe,0xd8,0xf2,0x25,0xc7,0x66,0x3c,0x7f,0x18,0x2e,0x7e,0xe8,0xec,0xcf,0xf2,0x0d,0xc7,0xb0,0xe1,0xd5,0x83,0x4e,0xc5,0xb1,0xea,0x01,},52,"\xf8\xb2\x19\x62\x44\x7b\x0a\x8f\x2e\x42\x79\xde\x41\x1b\xea\x12\x8e\x0b\xe4\x4b\x69\x15\xe6\xcd\xa8\x83\x41\xa6\x8a\x0d\x81\x83\x57\xdb\x93\x8e\xac\x73\xe0\xaf\x6d\x31\x20\x6b\x39\x48\xf8\xc4\x8a\x44\x73\x08"}, + {{0xeb,0x77,0xb2,0x63,0x8f,0x23,0xee,0xbc,0x82,0xef,0xe4,0x5e,0xe9,0xe5,0xa0,0x32,0x66,0x37,0x40,0x1e,0x66,0x3e,0xd0,0x29,0x69,0x9b,0x21,0xe6,0x44,0x3f,0xb4,0x8e,},{0x9e,0xf2,0x76,0x08,0x96,0x1a,0xc7,0x11,0xde,0x71,0xa6,0xe2,0xd4,0xd4,0x66,0x3e,0xa3,0xec,0xd4,0x2f,0xb7,0xe4,0xe8,0x62,0x7c,0x39,0x62,0x2d,0xf4,0xaf,0x0b,0xbc,},{0x18,0xdc,0x56,0xd7,0xbd,0x9a,0xcd,0x4f,0x4d,0xaa,0x78,0x54,0x0b,0x4a,0xc8,0xff,0x7a,0xa9,0x81,0x5f,0x45,0xa0,0xbb,0xa3,0x70,0x73,0x1a,0x14,0xea,0xab,0xe9,0x6d,0xf8,0xb5,0xf3,0x7d,0xbf,0x8e,0xae,0x4c,0xb1,0x5a,0x64,0xb2,0x44,0x65,0x1e,0x59,0xd6,0xa3,0xd6,0x76,0x1d,0x9e,0x3c,0x50,0xf2,0xd0,0xcb,0xb0,0x9c,0x05,0xec,0x06,},53,"\x99\xe3\xd0\x09\x34\x00\x3e\xba\xfc\x3e\x9f\xdb\x68\x7b\x0f\x5f\xf9\xd5\x78\x2a\x4b\x1f\x56\xb9\x70\x00\x46\xc0\x77\x91\x56\x02\xc3\x13\x4e\x22\xfc\x90\xed\x7e\x69\x0f\xdd\xd4\x43\x3e\x20\x34\xdc\xb2\xdc\x99\xab"}, + {{0xb6,0x25,0xaa,0x89,0xd3,0xf7,0x30,0x87,0x15,0x42,0x7b,0x6c,0x39,0xbb,0xac,0x58,0xef,0xfd,0x3a,0x0f,0xb7,0x31,0x6f,0x7a,0x22,0xb9,0x9e,0xe5,0x92,0x2f,0x2d,0xc9,},{0x65,0xa9,0x9c,0x3e,0x16,0xfe,0xa8,0x94,0xec,0x33,0xc6,0xb2,0x0d,0x91,0x05,0xe2,0xa0,0x4e,0x27,0x64,0xa4,0x76,0x9d,0x9b,0xbd,0x4d,0x8b,0xac,0xfe,0xab,0x4a,0x2e,},{0x01,0xbb,0x90,0x1d,0x83,0xb8,0xb6,0x82,0xd3,0x61,0x4a,0xf4,0x6a,0x80,0x7b,0xa2,0x69,0x13,0x58,0xfe,0xb7,0x75,0x32,0x5d,0x34,0x23,0xf5,0x49,0xff,0x0a,0xa5,0x75,0x7e,0x4e,0x1a,0x74,0xe9,0xc7,0x0f,0x97,0x21,0xd8,0xf3,0x54,0xb3,0x19,0xd4,0xf4,0xa1,0xd9,0x14,0x45,0xc8,0x70,0xfd,0x0f,0xfb,0x94,0xfe,0xd6,0x46,0x64,0x73,0x0d,},54,"\xe0\x72\x41\xdb\xd3\xad\xbe\x61\x0b\xbe\x4d\x00\x5d\xd4\x67\x32\xa4\xc2\x50\x86\xec\xb8\xec\x29\xcd\x7b\xca\x11\x6e\x1b\xf9\xf5\x3b\xfb\xf3\xe1\x1f\xa4\x90\x18\xd3\x9f\xf1\x15\x4a\x06\x66\x8e\xf7\xdf\x5c\x67\x8e\x6a"}, + {{0xb1,0xc9,0xf8,0xbd,0x03,0xfe,0x82,0xe7,0x8f,0x5c,0x0f,0xb0,0x64,0x50,0xf2,0x7d,0xac,0xdf,0x71,0x64,0x34,0xdb,0x26,0x82,0x75,0xdf,0x3e,0x1d,0xc1,0x77,0xaf,0x42,},{0x7f,0xc8,0x8b,0x1f,0x7b,0x3f,0x11,0xc6,0x29,0xbe,0x67,0x1c,0x21,0x62,0x1f,0x5c,0x10,0x67,0x2f,0xaf,0xc8,0x49,0x2d,0xa8,0x85,0x74,0x20,0x59,0xee,0x67,0x74,0xcf,},{0x4b,0x22,0x99,0x51,0xef,0x26,0x2f,0x16,0x97,0x8f,0x79,0x14,0xbc,0x67,0x2e,0x72,0x26,0xc5,0xf8,0x37,0x9d,0x27,0x78,0xc5,0xa2,0xdc,0x0a,0x26,0x50,0x86,0x9f,0x7a,0xcf,0xbd,0x0b,0xcd,0x30,0xfd,0xb0,0x61,0x9b,0xb4,0x4f,0xc1,0xae,0x59,0x39,0xb8,0x7c,0xc3,0x18,0x13,0x30,0x09,0xc2,0x03,0x95,0xb6,0xc7,0xeb,0x98,0x10,0x77,0x01,},55,"\x33\x1d\xa7\xa9\xc1\xf8\x7b\x2a\xc9\x1e\xe3\xb8\x6d\x06\xc2\x91\x63\xc0\x5e\xd6\xf8\xd8\xa9\x72\x5b\x47\x1b\x7d\xb0\xd6\xac\xec\x7f\x0f\x70\x24\x87\x16\x3f\x5e\xda\x02\x0c\xa5\xb4\x93\xf3\x99\xe1\xc8\xd3\x08\xc3\xc0\xc2"}, + {{0x6d,0x8c,0xdb,0x2e,0x07,0x5f,0x3a,0x2f,0x86,0x13,0x72,0x14,0xcb,0x23,0x6c,0xeb,0x89,0xa6,0x72,0x8b,0xb4,0xa2,0x00,0x80,0x6b,0xf3,0x55,0x7f,0xb7,0x8f,0xac,0x69,},{0x57,0xa0,0x4c,0x7a,0x51,0x13,0xcd,0xdf,0xe4,0x9a,0x4c,0x12,0x46,0x91,0xd4,0x6c,0x1f,0x9c,0xdc,0x8f,0x34,0x3f,0x9d,0xcb,0x72,0xa1,0x33,0x0a,0xec,0xa7,0x1f,0xda,},{0xa6,0xcb,0xc9,0x47,0xf9,0xc8,0x7d,0x14,0x55,0xcf,0x1a,0x70,0x85,0x28,0xc0,0x90,0xf1,0x1e,0xce,0xe4,0x85,0x5d,0x1d,0xba,0xad,0xf4,0x74,0x54,0xa4,0xde,0x55,0xfa,0x4c,0xe8,0x4b,0x36,0xd7,0x3a,0x5b,0x5f,0x8f,0x59,0x29,0x8c,0xcf,0x21,0x99,0x2d,0xf4,0x92,0xef,0x34,0x16,0x3d,0x87,0x75,0x3b,0x7e,0x9d,0x32,0xf2,0xc3,0x66,0x0b,},56,"\x7f\x31\x8d\xbd\x12\x1c\x08\xbf\xdd\xfe\xff\x4f\x6a\xff\x4e\x45\x79\x32\x51\xf8\xab\xf6\x58\x40\x33\x58\x23\x89\x84\x36\x00\x54\xf2\xa8\x62\xc5\xbb\x83\xed\x89\x02\x5d\x20\x14\xa7\xa0\xce\xe5\x0d\xa3\xcb\x0e\x76\xbb\xb6\xbf"}, + {{0x47,0xad,0xc6,0xd6,0xbf,0x57,0x1e,0xe9,0x57,0x0c,0xa0,0xf7,0x5b,0x60,0x4a,0xc4,0x3e,0x30,0x3e,0x4a,0xb3,0x39,0xca,0x9b,0x53,0xca,0xcc,0x5b,0xe4,0x5b,0x2c,0xcb,},{0xa3,0xf5,0x27,0xa1,0xc1,0xf1,0x7d,0xfe,0xed,0x92,0x27,0x73,0x47,0xc9,0xf9,0x8a,0xb4,0x75,0xde,0x17,0x55,0xb0,0xab,0x54,0x6b,0x8a,0x15,0xd0,0x1b,0x9b,0xd0,0xbe,},{0x4e,0x8c,0x31,0x83,0x43,0xc3,0x06,0xad,0xbb,0xa6,0x0c,0x92,0xb7,0x5c,0xb0,0x56,0x9b,0x92,0x19,0xd8,0xa8,0x6e,0x5d,0x57,0x75,0x2e,0xd2,0x35,0xfc,0x10,0x9a,0x43,0xc2,0xcf,0x4e,0x94,0x2c,0xac,0xf2,0x97,0x27,0x9f,0xbb,0x28,0x67,0x53,0x47,0xe0,0x80,0x27,0x72,0x2a,0x4e,0xb7,0x39,0x5e,0x00,0xa1,0x74,0x95,0xd3,0x2e,0xdf,0x0b,},57,"\xce\x49\x7c\x5f\xf5\xa7\x79\x90\xb7\xd8\xf8\x69\x9e\xb1\xf5\xd8\xc0\x58\x2f\x70\xcb\x7a\xc5\xc5\x4d\x9d\x92\x49\x13\x27\x8b\xc6\x54\xd3\x7e\xa2\x27\x59\x0e\x15\x20\x22\x17\xfc\x98\xda\xc4\xc0\xf3\xbe\x21\x83\xd1\x33\x31\x57\x39"}, + {{0x3c,0x19,0xb5,0x0b,0x0f,0xe4,0x79,0x61,0x71,0x9c,0x38,0x1d,0x0d,0x8d,0xa9,0xb9,0x86,0x9d,0x31,0x2f,0x13,0xe3,0x29,0x8b,0x97,0xfb,0x22,0xf0,0xaf,0x29,0xcb,0xbe,},{0x0f,0x7e,0xda,0x09,0x14,0x99,0x62,0x5e,0x2b,0xae,0x85,0x36,0xea,0x35,0xcd,0xa5,0x48,0x3b,0xd1,0x6a,0x9c,0x7e,0x41,0x6b,0x34,0x1d,0x6f,0x2c,0x83,0x34,0x36,0x12,},{0xef,0xbd,0x41,0xf2,0x6a,0x5d,0x62,0x68,0x55,0x16,0xf8,0x82,0xb6,0xec,0x74,0xe0,0xd5,0xa7,0x18,0x30,0xd2,0x03,0xc2,0x31,0x24,0x8f,0x26,0xe9,0x9a,0x9c,0x65,0x78,0xec,0x90,0x0d,0x68,0xcd,0xb8,0xfa,0x72,0x16,0xad,0x0d,0x24,0xf9,0xec,0xbc,0x9f,0xfa,0x65,0x53,0x51,0x66,0x65,0x82,0xf6,0x26,0x64,0x53,0x95,0xa3,0x1f,0xa7,0x04,},58,"\x8d\xdc\xd6\x30\x43\xf5\x5e\xc3\xbf\xc8\x3d\xce\xae\x69\xd8\xf8\xb3\x2f\x4c\xdb\x6e\x2a\xeb\xd9\x4b\x43\x14\xf8\xfe\x72\x87\xdc\xb6\x27\x32\xc9\x05\x2e\x75\x57\xfe\x63\x53\x43\x38\xef\xb5\xb6\x25\x4c\x5d\x41\xd2\x69\x0c\xf5\x14\x4f"}, + {{0x34,0xe1,0xe9,0xd5,0x39,0x10,0x7e,0xb8,0x6b,0x39,0x3a,0x5c,0xce,0xa1,0x49,0x6d,0x35,0xbc,0x7d,0x5e,0x9a,0x8c,0x51,0x59,0xd9,0x57,0xe4,0xe5,0x85,0x2b,0x3e,0xb0,},{0x0e,0xcb,0x26,0x01,0xd5,0xf7,0x04,0x74,0x28,0xe9,0xf9,0x09,0x88,0x3a,0x12,0x42,0x00,0x85,0xf0,0x4e,0xe2,0xa8,0x8b,0x6d,0x95,0xd3,0xd7,0xf2,0xc9,0x32,0xbd,0x76,},{0x32,0xd2,0x29,0x04,0xd3,0xe7,0x01,0x2d,0x6f,0x5a,0x44,0x1b,0x0b,0x42,0x28,0x06,0x4a,0x5c,0xf9,0x5b,0x72,0x3a,0x66,0xb0,0x48,0xa0,0x87,0xec,0xd5,0x59,0x20,0xc3,0x1c,0x20,0x4c,0x3f,0x20,0x06,0x89,0x1a,0x85,0xdd,0x19,0x32,0xe3,0xf1,0xd6,0x14,0xcf,0xd6,0x33,0xb5,0xe6,0x32,0x91,0xc6,0xd8,0x16,0x6f,0x30,0x11,0x43,0x1e,0x09,},59,"\xa6\xd4\xd0\x54\x2c\xfe\x0d\x24\x0a\x90\x50\x7d\xeb\xac\xab\xce\x7c\xbb\xd4\x87\x32\x35\x3f\x4f\xad\x82\xc7\xbb\x7d\xbd\x9d\xf8\xe7\xd9\xa1\x69\x80\xa4\x51\x86\xd8\x78\x6c\x5e\xf6\x54\x45\xbc\xc5\xb2\xad\x5f\x66\x0f\xfc\x7c\x8e\xaa\xc0"}, + {{0x49,0xdd,0x47,0x3e,0xde,0x6a,0xa3,0xc8,0x66,0x82,0x4a,0x40,0xad,0xa4,0x99,0x6c,0x23,0x9a,0x20,0xd8,0x4c,0x93,0x65,0xe4,0xf0,0xa4,0x55,0x4f,0x80,0x31,0xb9,0xcf,},{0x78,0x8d,0xe5,0x40,0x54,0x4d,0x3f,0xeb,0x0c,0x91,0x92,0x40,0xb3,0x90,0x72,0x9b,0xe4,0x87,0xe9,0x4b,0x64,0xad,0x97,0x3e,0xb6,0x5b,0x46,0x69,0xec,0xf2,0x35,0x01,},{0xd2,0xfd,0xe0,0x27,0x91,0xe7,0x20,0x85,0x25,0x07,0xfa,0xa7,0xc3,0x78,0x90,0x40,0xd9,0xef,0x86,0x64,0x63,0x21,0xf3,0x13,0xac,0x55,0x7f,0x40,0x02,0x49,0x15,0x42,0xdd,0x67,0xd0,0x5c,0x69,0x90,0xcd,0xb0,0xd4,0x95,0x50,0x1f,0xbc,0x5d,0x51,0x88,0xbf,0xbb,0x84,0xdc,0x1b,0xf6,0x09,0x8b,0xee,0x06,0x03,0xa4,0x7f,0xc2,0x69,0x0f,},60,"\x3a\x53\x59\x4f\x3f\xba\x03\x02\x93\x18\xf5\x12\xb0\x84\xa0\x71\xeb\xd6\x0b\xae\xc7\xf5\x5b\x02\x8d\xc7\x3b\xfc\x9c\x74\xe0\xca\x49\x6b\xf8\x19\xdd\x92\xab\x61\xcd\x8b\x74\xbe\x3c\x0d\x6d\xcd\x12\x8e\xfc\x5e\xd3\x34\x2c\xba\x12\x4f\x72\x6c"}, + {{0x33,0x1c,0x64,0xda,0x48,0x2b,0x6b,0x55,0x13,0x73,0xc3,0x64,0x81,0xa0,0x2d,0x81,0x36,0xec,0xad,0xbb,0x01,0xab,0x11,0x4b,0x44,0x70,0xbf,0x41,0x60,0x7a,0xc5,0x71,},{0x52,0xa0,0x0d,0x96,0xa3,0x14,0x8b,0x47,0x26,0x69,0x2d,0x9e,0xff,0x89,0x16,0x0e,0xa9,0xf9,0x9a,0x5c,0xc4,0x38,0x9f,0x36,0x1f,0xed,0x0b,0xb1,0x6a,0x42,0xd5,0x21,},{0x22,0xc9,0x9a,0xa9,0x46,0xea,0xd3,0x9a,0xc7,0x99,0x75,0x62,0x81,0x0c,0x01,0xc2,0x0b,0x46,0xbd,0x61,0x06,0x45,0xbd,0x2d,0x56,0xdc,0xdc,0xba,0xac,0xc5,0x45,0x2c,0x74,0xfb,0xf4,0xb8,0xb1,0x81,0x3b,0x0e,0x94,0xc3,0x0d,0x80,0x8c,0xe5,0x49,0x8e,0x61,0xd4,0xf7,0xcc,0xbb,0x4c,0xc5,0xf0,0x4d,0xfc,0x61,0x40,0x82,0x5a,0x96,0x00,},61,"\x20\xe1\xd0\x5a\x0d\x5b\x32\xcc\x81\x50\xb8\x11\x6c\xef\x39\x65\x9d\xd5\xfb\x44\x3a\xb1\x56\x00\xf7\x8e\x5b\x49\xc4\x53\x26\xd9\x32\x3f\x28\x50\xa6\x3c\x38\x08\x85\x94\x95\xae\x27\x3f\x58\xa5\x1e\x9d\xe9\xa1\x45\xd7\x74\xb4\x0b\xa9\xd7\x53\xd3"}, + {{0x5c,0x0b,0x96,0xf2,0xaf,0x87,0x12,0x12,0x2c,0xf7,0x43,0xc8,0xf8,0xdc,0x77,0xb6,0xcd,0x55,0x70,0xa7,0xde,0x13,0x29,0x7b,0xb3,0xdd,0xe1,0x88,0x62,0x13,0xcc,0xe2,},{0x05,0x10,0xea,0xf5,0x7d,0x73,0x01,0xb0,0xe1,0xd5,0x27,0x03,0x9b,0xf4,0xc6,0xe2,0x92,0x30,0x0a,0x3a,0x61,0xb4,0x76,0x54,0x34,0xf3,0x20,0x3c,0x10,0x03,0x51,0xb1,},{0x06,0xe5,0xd8,0x43,0x6a,0xc7,0x70,0x5b,0x3a,0x90,0xf1,0x63,0x1c,0xdd,0x38,0xec,0x1a,0x3f,0xa4,0x97,0x78,0xa9,0xb9,0xf2,0xfa,0x5e,0xbe,0xa4,0xe7,0xd5,0x60,0xad,0xa7,0xdd,0x26,0xff,0x42,0xfa,0xfa,0x8b,0xa4,0x20,0x32,0x37,0x42,0x76,0x1a,0xca,0x69,0x04,0x94,0x0d,0xc2,0x1b,0xbe,0xf6,0x3f,0xf7,0x2d,0xaa,0xb4,0x5d,0x43,0x0b,},62,"\x54\xe0\xca\xa8\xe6\x39\x19\xca\x61\x4b\x2b\xfd\x30\x8c\xcf\xe5\x0c\x9e\xa8\x88\xe1\xee\x44\x46\xd6\x82\xcb\x50\x34\x62\x7f\x97\xb0\x53\x92\xc0\x4e\x83\x55\x56\xc3\x1c\x52\x81\x6a\x48\xe4\xfb\x19\x66\x93\x20\x6b\x8a\xfb\x44\x08\x66\x2b\x3c\xb5\x75"}, + {{0xde,0x84,0xf2,0x43,0x5f,0x78,0xde,0xdb,0x87,0xda,0x18,0x19,0x4f,0xf6,0xa3,0x36,0xf0,0x81,0x11,0x15,0x0d,0xef,0x90,0x1c,0x1a,0xc4,0x18,0x14,0x6e,0xb7,0xb5,0x4a,},{0xd3,0xa9,0x2b,0xba,0xa4,0xd6,0x3a,0xf7,0x9c,0x22,0x26,0xa7,0x23,0x6e,0x64,0x27,0x42,0x8d,0xf8,0xb3,0x62,0x42,0x7f,0x87,0x30,0x23,0xb2,0x2d,0x2f,0x5e,0x03,0xf2,},{0x47,0x1e,0xbc,0x97,0x3c,0xfd,0xac,0xee,0xc0,0x72,0x79,0x30,0x73,0x68,0xb7,0x3b,0xe3,0x5b,0xc6,0xf8,0xd8,0x31,0x2b,0x70,0x15,0x05,0x67,0x36,0x90,0x96,0x70,0x6d,0xc4,0x71,0x12,0x6c,0x35,0x76,0xf9,0xf0,0xeb,0x55,0x0d,0xf5,0xac,0x6a,0x52,0x51,0x81,0x11,0x00,0x29,0xdd,0x1f,0xc1,0x11,0x74,0xd1,0xaa,0xce,0xd4,0x8d,0x63,0x0f,},63,"\x20\x51\x35\xec\x7f\x41\x7c\x85\x80\x72\xd5\x23\x3f\xb3\x64\x82\xd4\x90\x6a\xbd\x60\xa7\x4a\x49\x8c\x34\x7f\xf2\x48\xdf\xa2\x72\x2c\xa7\x4e\x87\x9d\xe3\x31\x69\xfa\xdc\x7c\xd4\x4d\x6c\x94\xa1\x7d\x16\xe1\xe6\x30\x82\x4b\xa3\xe0\xdf\x22\xed\x68\xea\xab"}, + {{0xba,0x4d,0x6e,0x67,0xb2,0xce,0x67,0xa1,0xe4,0x43,0x26,0x49,0x40,0x44,0xf3,0x7a,0x44,0x2f,0x3b,0x81,0x72,0x5b,0xc1,0xf9,0x34,0x14,0x62,0x71,0x8b,0x55,0xee,0x20,},{0xf7,0x3f,0xa0,0x76,0xf8,0x4b,0x6d,0xb6,0x75,0xa5,0xfd,0xa5,0xad,0x67,0xe3,0x51,0xa4,0x1e,0x8e,0x7f,0x29,0xad,0xd1,0x68,0x09,0xca,0x01,0x03,0x87,0xe9,0xc6,0xcc,},{0x57,0xb9,0xd2,0xa7,0x11,0x20,0x7f,0x83,0x74,0x21,0xba,0xe7,0xdd,0x48,0xea,0xa1,0x8e,0xab,0x1a,0x9a,0x70,0xa0,0xf1,0x30,0x58,0x06,0xfe,0xe1,0x7b,0x45,0x8f,0x3a,0x09,0x64,0xb3,0x02,0xd1,0x83,0x4d,0x3e,0x0a,0xc9,0xe8,0x49,0x6f,0x00,0x0b,0x77,0xf0,0x08,0x3b,0x41,0xf8,0xa9,0x57,0xe6,0x32,0xfb,0xc7,0x84,0x0e,0xee,0x6a,0x06,},64,"\x4b\xaf\xda\xc9\x09\x9d\x40\x57\xed\x6d\xd0\x8b\xca\xee\x87\x56\xe9\xa4\x0f\x2c\xb9\x59\x80\x20\xeb\x95\x01\x95\x28\x40\x9b\xbe\xa3\x8b\x38\x4a\x59\xf1\x19\xf5\x72\x97\xbf\xb2\xfa\x14\x2f\xc7\xbb\x1d\x90\xdb\xdd\xde\x77\x2b\xcd\xe4\x8c\x56\x70\xd5\xfa\x13"}, + {{0x0d,0x13,0x1c,0x45,0xae,0xa6,0xf3,0xa4,0xe1,0xb9,0xa2,0xcf,0x60,0xc5,0x51,0x04,0x58,0x7e,0xfa,0xa8,0x46,0xb2,0x22,0xbf,0x0a,0x7b,0x74,0xce,0x7a,0x3f,0x63,0xb6,},{0x3c,0x67,0x29,0xdb,0xe9,0x3b,0x49,0x9c,0x4e,0x61,0x4a,0x2f,0x21,0xbe,0xb7,0x29,0x43,0x8d,0x49,0x8e,0x1a,0xc8,0xd1,0x4c,0xba,0xd9,0x71,0x7a,0x5d,0xbd,0x97,0xcd,},{0xa9,0xc5,0xee,0x86,0xfb,0x06,0xd9,0xe4,0x6b,0x37,0x9c,0x32,0xdd,0xa7,0xc9,0x2c,0x9c,0x13,0xdb,0x27,0x4d,0xc2,0x41,0x16,0xfb,0xdd,0x87,0x86,0x96,0x04,0x54,0x88,0xcc,0x75,0xa5,0x2f,0xff,0x67,0xd1,0xa5,0x11,0x3d,0x06,0xe3,0x33,0xac,0x67,0xff,0x66,0x4b,0x3f,0x2a,0x40,0x5f,0xa1,0xd1,0x4d,0xd5,0xbb,0xb9,0x74,0x09,0xb6,0x06,},65,"\xb4\x29\x1d\x08\xb8\x8f\xb2\xf7\xb8\xf9\x9d\x0d\xce\x40\x07\x9f\xcb\xab\x71\x8b\xbd\x8f\x4e\x8e\xab\xc3\xc1\x42\x8b\x6a\x07\x1f\xb2\xa3\xc8\xeb\xa1\xca\xcc\xcf\xa8\x71\xb3\x65\xc7\x08\xbe\xf2\x68\x5b\xc1\x3e\x6b\x80\xbc\x14\xa5\xf2\x49\x17\x0f\xfc\x56\xd0\x14"}, +}; + +bool TestCryptoSign() +{ + // https://github.com/jedisct1/libsodium/blob/master/test/default/sign.c + const unsigned int MAX_MESSAGE = 65; // Sync with test data + + byte pk[crypto_sign_PUBLICKEYBYTES]; + byte sk[crypto_sign_SECRETKEYBYTES]; + SecByteBlock sm(MAX_MESSAGE+crypto_sign_BYTES); + SecByteBlock rm(MAX_MESSAGE+crypto_sign_BYTES); + + bool pass = true, fail; int rc; + + for (unsigned int i=0; i(data.msg); + const word64 l = data.len; + word64 smlen; + + rc = crypto_sign(sm, &smlen, m, l, sk); + fail = (rc != 0); pass = !fail && pass; + + word64 s = STDMIN(smlen, (word64)crypto_sign_BYTES); + pass = (s >= crypto_sign_BYTES) && pass; + + fail = std::memcmp(sm, data.sig, (size_t)s) != 0; + pass = !fail && pass; + + word64 rmlen; + rc = crypto_sign_open(rm, &rmlen, sm, smlen, pk); + fail = (rc != 0); pass = !fail && pass; + + pass = (l == rmlen) && pass; + fail = std::memcmp(m, rm, (size_t)STDMIN(l, rmlen)) != 0; + pass = !fail && pass; + } + + return pass; +} + +bool TestCryptoSignKeys() +{ + // https://github.com/jedisct1/libsodium/blob/master/test/default/sign.c + const unsigned int MAX_TEST = 64; + const unsigned int MAX_MESSAGE = 4096; + + byte pk[crypto_sign_PUBLICKEYBYTES]; + byte sk[crypto_sign_SECRETKEYBYTES]; + + bool pass = true, fail; int rc; + + for (unsigned int i=0; i +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +bool TestIntegerBitops() +{ + std::cout << "\nTesting Integer bit operations...\n\n"; + + struct Bitops_TestTuple + { + // m,n are operands; a,o,x are and,or,xor results + const char *m, *n, *a, *o, *x; + }; + static const Bitops_TestTuple tests[] = { + { + "0xc2cea8a4", "0xb36e5794", "0x824e0084", "0xf3eeffb4", "0x71a0ff30" + }, + { + "0x436eb828", "0x1b375cb4", "0x3261820", "0x5b7ffcbc", "0x5859e49c" + }, + { + "0x1e5c0b28", "0x4fded465", "0xe5c0020", "0x5fdedf6d", "0x5182df4d" + }, + { + "0xeb71fde7", "0xf7bb47cf", "0xe33145c7", "0xfffbffef", "0x1ccaba28" + }, + { + "0xa6b0f01f", "0x8a8ca98", "0xa0c018", "0xaeb8fa9f", "0xae183a87" + }, + { + "0xa70bd8b7", "0x5c758cf5", "0x40188b5", "0xff7fdcf7", "0xfb7e5442" + }, + { + "0xf91af382", "0x718a9995", "0x710a9180", "0xf99afb97", "0x88906a17" + }, + { + "0xbd2a76ad", "0xddd8dfeb", "0x9d0856a9", "0xfdfaffef", "0x60f2a946" + }, + { + "0xd4b559cc", "0x91a53295", "0x90a51084", "0xd5b57bdd", "0x45106b59" + }, + { + "0x89434e9e", "0xa42fdaf9", "0x80034a98", "0xad6fdeff", "0x2d6c9467" + }, + { + "0xb947ac04", "0xd4201e52", "0x90000c00", "0xfd67be56", "0x6d67b256" + }, + { + "0xa83945c1", "0x3a9c5dba", "0x28184580", "0xbabd5dfb", "0x92a5187b" + }, + { + "0xbca38ffa", "0x881ba9fd", "0x880389f8", "0xbcbbafff", "0x34b82607" + }, + { + "0xfcd0b92", "0xeaad8534", "0xa8d0110", "0xefed8fb6", "0xe5608ea6" + }, + { + "0x50d160d0", "0x64646f75", "0x40406050", "0x74f56ff5", "0x34b50fa5" + }, + { + "0x165ccff8", "0x67d49127", "0x6548120", "0x77dcdfff", "0x71885edf" + }, + { + "0x8c4f4bbb7adaacb5", "0x2566b7a909b24aa9", "0x44603a9089208a1", "0xad6fffbb7bfaeebd", "0xa929fc127368e61c" + }, + { + "0x6f9ef50aafb31e8d", "0x7a93b2ccd1bbbff2", "0x6a92b00881b31e80", "0x7f9ff7ceffbbbfff", "0x150d47c67e08a17f" + }, + { + "0x4c99e967f8de5294", "0x1f4699e0c14e6974", "0xc008960c04e4014", "0x5fdff9e7f9de7bf4", "0x53df708739903be0" + }, + { + "0xcc55f5d6d3ea45c", "0x6805b4ddb6390c2f", "0x805145d2438040c", "0x6cc5ffddff3fac7f", "0x64c0eb80db07a873" + }, + { + "0x90620d1a012459e7", "0x89d31098ce3fed42", "0x8042001800244942", "0x99f31d9acf3ffde7", "0x19b11d82cf1bb4a5" + }, + { + "0xb87d1674e90a935a", "0x75ea466cbb782ac4", "0x30680664a9080240", "0xfdff567cfb7abbde", "0xcd9750185272b99e" + }, + { + "0x1f135732240701f0", "0x6aa09a1614bf4dd4", "0xa001212040701d0", "0x7fb3df3634bf4df4", "0x75b3cd2430b84c24" + }, + { + "0xc9a88d8300099a31", "0xdc8e91df745169ee", "0xc888818300010820", "0xddae9ddf7459fbff", "0x15261c5c7458f3df" + }, + { + "0xc8c828d15228b562", "0x43f86cffa3d15d80", "0x40c828d102001500", "0xcbf86cfff3f9fde2", "0x8b30442ef1f9e8e2" + }, + { + "0x41fdc0bc2009563f", "0x59dd1c417e3c07bc", "0x41dd00002008063c", "0x59fddcfd7e3d57bf", "0x1820dcfd5e355183" + }, + { + "0x9e2f78600c3a84e7", "0xac69a0e1fe7887b0", "0x8c2920600c3884a0", "0xbe6ff8e1fe7a87f7", "0x3246d881f2420357" + }, + { + "0xd424d1d9a955f617", "0x9608f5bde1c4d893", "0x9400d199a144d013", "0xd62cf5fde9d5fe97", "0x422c246448912e84" + }, + { + "0x1aa8b60a0627719a", "0x5b26e6aca95f5f60", "0x1a20a60800075100", "0x5baef6aeaf7f7ffa", "0x418e50a6af782efa" + }, + { + "0xcf5db499233fac00", "0xf33e7a29c3c33da8", "0xc31c300903032c00", "0xff7ffeb9e3ffbda8", "0x3c63ceb0e0fc91a8" + }, + { + "0x6b47c03d576e878d", "0x2032d13574d67da4", "0x2002c03554460584", "0x6b77d13d77feffad", "0x4b75110823b8fa29" + }, + { + "0xd47eeb3aefebf074", "0x6d7ba17a42c66b89", "0x447aa13a42c26000", "0xfd7feb7aefeffbfd", "0xb9054a40ad2d9bfd" + }, + { + "0x33ad9c5d20b03f5c05535f20a2941c8f4ae0f1f19500759151060dce39e5dfed41ec4f", + "0x277401dc000fde7eda4d60a5698935f7febd8fbe49e5d6f56ca2e7f6118380d3cd655da392df3ba6c1b13dc0119af34cfa1d18a65", + "0x10a9841c002016480453410020041c8640c0312191006411110401082924cfa1418845", + "0x277401dc000fde7eda4d60a5698935f7febfbfffcdf7dff7fde2f7f7f38ba9d3cdf5ffaf9fdf7ba7d9b53de0ddfbff5dfedd1ee6f", + "0x277401dc000fde7eda4d60a5698935f7febeb5678c37ddf69962b2c3e389a9920591f3ac8dc66ba198a42da0cd796d1104c90662a" + }, + { + "0xb6ea335c13111216862e370d12fb9c761a6266617f62a1904b0d7944ab3cddc71f11752ad9424b0", + "0xa6b380f048a9cbe45ff4ea824064c831eb03ff875e1e3e", + "0xa62200104028090410d480020044c831e1035285140430", + "0xb6ea335c13111216862e370d12fb9c761a6b7e6f7feabdbe4fff7fecaf3eddc71fb17ffafde3ebe", + "0xb6ea335c13111216862e370d12fb9c7610095e6e7be83d2e0ef237ec8f3a914401a14ad2aca3a8e" + }, + { + "0x8fb9486ad1f89ca5b3f6da9f0d5ef9ec328b8cc3e5122afbd8a67bd1b2b4ab5c548b90cf9fe1933a0362922f1e84ef0", + "0x10615f963dffc13718ed1ecdb9cfbef33148befeb91b190dc7e7d28d8821ff248ab26a34e1b89885c643e447c72", + "0x6051901ca58136188d0c4cb9cc32830040a412281b180443c192848800540080820a208138000082030404c70", + "0x8fb9586bdffebdfff3f7daff1fdff9efbefbbdcbfffebbfbd9affff7f2bdab7dffaf9afffff5f3ba9be7d66ffec7ef2", + "0x8fb9580b8e6ea15a72c1c272139340238c78bd8b5bec93e0c1abbc366039237dabaf1a7df5d572829be7546cfac3282" + }, + { + "0x10af96443b186faf790279bf3bbe0517d56ffc01e7fec8c88e765d48cc32333390224f4d762d1ba788c50801cba02524cb49", + "0x95d44e7344fb1701bace3ae83affbb6290bf282f7565b9a82c386823f5f213a53eccb2cfe5deb4dd040067a64ada8c1b6828599b96cc70647e7d19dc7dfba393addabe689ffbe1a36642bc9844b81c6c4c2e178", + "0x2c96442b084000000260ad288004028509b800c70640c080144548883032118022094d3608122408c1000181800400c148", + "0x95d44e7344fb1701bace3ae83affbb6290bf282f7565b9a82c386823f5f213a53ecdbaffe5dfb5dffef7f7a7dbfbbffb797d5fffd6de7fecfefdfffdfdffe3b3bffbbe6cffffe3f3fe7abcd8c4bcbe6e5e6eb79", + "0x95d44e7344fb1701bace3ae83affbb6290bf282f7565b9a82c386823f5f213a53ecdb836819d055bfef7f781d12937fb39550f6456d20f88f2f5feb9a97760b09ee3bc4c6b2c8372dc3a30c8c4a4a66e1e62a31" + }, + { + "0x5fc77dab8cd9c1da8c91eb7ba9c23ce85375b61bf3b9a8c4e4df7bc917aa8a14e747888c9756a2be2fd2e256e44194ce093a0185594de0dcf8340c45b6af7dbdc7682fbef6313f9f1cb234689d9f1ff603e1273faad89d0fe1ab57fbc7c32d29dce125fafc973754464b55ae5de58a8a5661c2065b95c2c94d7ec34", + "0xd4a9158961d4c11258cd047eda13d6804c16c3a374b7f4115bd835bde0b5", + "0x1080158800548100504504649012c480480081221420641158081495e034", + "0x5fc77dab8cd9c1da8c91eb7ba9c23ce85375b61bf3b9a8c4e4df7bc917aa8a14e747888c9756a2be2fd2e256e44194ce093a0185594de0dcf8340c45b6af7dbdc7682fbef6313f9f1cb234689d9f1ff603e1273faad89d0fe1ab57fbc7cf6fb9dcf73dfefdb7bfd447eff5bf7de5cbee7e77cb7f5b95ffcb5ffecb5", + "0x5fc77dab8cd9c1da8c91eb7ba9c23ce85375b61bf3b9a8c4e4df7bc917aa8a14e747888c9756a2be2fd2e256e44194ce093a0185594de0dcf8340c45b6af7dbdc7682fbef6313f9f1cb234689d9f1ff603e1273faad89d0fe1ab57fbc7ce67b8847738b6edb2bb8401a6f49335e14be66c5689791a807f4a16a0c81" + }, + { + "0x52cbea1f4d78445fb8f9267203f0f04bddf65b69b1acb0877143e77317f2d9679cb", + "0x331e156a1e1daa0039926a08ec80c2d7c1500bc435a53ebfc32fa398a3304fcd79d90725528e320add050da666b9de42b8307b", + "0x88421a41684412b839023200f0d00990725128a120a0805042666315e0090304b", + "0x331e156a1e1daa0039926a08ec80c2d7c1552ffeb5f5ffbfc7ffaf9ae7307fcf7dfddf65f69f3acbdd771dbe77b9ff6fbe79fb", + "0x331e156a1e1daa0039926a08ec80c2d7c155277a9451e93b86d42c0ac41070c27d64d840e41528c1d57219981188a16f2e49b0" + }, + { + "0xbde7e20f37c3ed822555d36050240dcfb5a9a3867d149cffe78e92b95573cbdde33a8c9495148e04cafa1325aae058b4a98c50f7019de1345de6dce12436bed4b86eca2d", + "0xee480b4096f0c1ac565d623dd53b62dba81c507d3c8e15372396fa49de0ecf074fb0ed1785f00f8094022ff50fc436a7cbd18de8ff317c33ea9bdbd8814a7658fcd1fd10b2ed10eaf7e4c2b8f409df3c36f1f0c986a49805a9ed08bbcd603e2eec9e18", + "0x547a00d1781e0020014022050040406a58981846814107c238a929950014a544038809410108c00caf20000a8e00894280450f00184a01005a0cc0020042014286c8a08", + "0xee480b4096f0c1ac565d623dd53b62dba81c507d3c8e15372396fa49de0ecfbfeff2ef37c7fd8fa5d5d36ff52fcdffb7ebf38ffdffbdfff7ee9bfbddf3cbfffbfeddfd95b6ef14eafff7e7baf459ffbdbef1f7c99fe5bc5deffde9bffffefebeeede3d", + "0xee480b4096f0c1ac565d623dd53b62dba81c507d3c8e15372396fa49de0ecfbaa852e220461d8da5c1d14fa52bc9f91262720b95ebad83d46409628df281abbbc65d6985a66314200df7e71214516b95baa107c81b45ac584f31e99ffbdeea96825435" + }, + { + "0x17ed0a1aa80542396e82ab79f6d4dda731d10f9487467fcfa5c8b501fa86488fbe268605c01beb257c9e301a42833d22965ea2ff0eda5f18427481a300a8f9aa81e76d774ea1dbed40268eca094bef627d2c206f6885fc12f71557bfda836", + "0x422340e8ff3b4177efa5f58111fe306aa602d8020164fa34c12acdb3de81e", + "0x2340604e21416540248480014a2062240000020004f810c10045b3da816", + "0x17ed0a1aa80542396e82ab79f6d4dda731d10f9487467fcfa5c8b501fa86488fbe268605c01beb257c9e301a42833d22965ea2ff0eda5f18427481a300a8f9aac3e76dffffbbdbffefa7ffcb19ffff6aff2ef86f69e5fe36f73fdfbfde83e", + "0x17ed0a1aa80542396e82ab79f6d4dda731d10f9487467fcfa5c8b501fa86488fbe268605c01beb257c9e301a42833d22965ea2ff0eda5f18427481a300a8f9aac3c42d9fb19a9a9aaf837b4b18b5df08db2ef86d69e10626363f9a0c04028" + }, + { + "0x290796408a0b8baa742b9d466afc4958528f7976fdce50caa83ed63285f58d200e4c65842ea24c3d4a3850a1824b61d25af9d3b41b9e64407a5262a75d9efd08481cfbc339ae26b0755438894b9e2298a35ed9", + "0x4cb6f7935f5cc586320c6ce957f82cff774cde7d4201735a5acd22190fcb1c9c16d1887a", + "0x4012f193141884040008406007580cfd00481c794201220210450018094b1c0010810858", + "0x290796408a0b8baa742b9d466afc4958528f7976fdce50caa83ed63285f58d200e4c65842ea24c3d4a3850a1824b61defeffd3ff5fdfe6727e7eebf7fdbeff7f4cdeffc339ff7efafd76398fcb9ebe9ef3defb", + "0x290796408a0b8baa742b9d466afc4958528f7976fdce50caa83ed63285f58d200e4c65842ea24c3d4a3850a1824b619eec0e40eb475be272763e8bf0a5b2027f04c2868138dd7ceab87621868082be8e72d6a3" + }, + { + "0x14e55ecb09d8c6827022df7c713c05a5d882e25782", + "0x2dbdb54cb6341fcea6f67cfaa5186aa0a91b9782e362cbb0dd0ef3cbc130ce0cb2ce7232c0562", + "0x10600e020898048060209c1000200124c002200502", + "0x2dbdb54cb6341fcea6f67cfaa5186aa0a91bdfd7eff2dfbcfd2ff3eff7f7dfccfadffa3ee57e2", + "0x2dbdb54cb6341fcea6f67cfaa5186aa0a91ad9d70fd2563cb529f1e636f7ddcce893fa1ce52e0" + }, + { + "0x2b0dfd23fc740e1759697bcba800aa1be7df28c59fe72b9869766ac34ecb4e5d0dbc74c2cbb5f734bb8d38dab59c3f22cdc706c657839580c2793c4c7660606548c048a697db3dfbad82e695c605", + "0x33080f6fd52aeca572f24a98ff19b9e7327c3b951ccfd8c9a6b9bd6f7c940079e4be88178a2a6d5a2b17", + "0x30007249108288030900a00cd0100c612001180004918482620206548800020849a0813880264100205", + "0x2b0dfd23fc740e1759697bcba800aa1be7df28c59fe72b9869766ac34ecb4e5d0dbc74c2fbbdff7fffaffcfff7fe7fbaffdfbfe777ffbf95defffccdf6f9fd6f7cd448fff7ffbdffafaaefdfef17", + "0x2b0dfd23fc740e1759697bcba800aa1be7df28c59fe72b9869766ac34ecb4e5d0dbc74c2f8bdf85b6ea7d47fc76e75ba32debf2165ffae15deb6e485d0d9dd0a345448df7365b5ec27a88bcfed12" + }, + { + "0xc0cc21922748d7626df1ab92b4ad4df1861050ca7de74adb92a140", + "0x3531a6880ccc47bc3826056efe912f3db02df9c0b6931e253ab9248f472359fe59218690f6781f35da89b8f1ff45cd5a1db9a414c9d7ec62ff5859a1572b1c1880a99aa74ebe8b12c68e791c11dd6cc0e5ed5", + "0xc40192054091400800898234a948b104004080410542c8020040", + "0x3531a6880ccc47bc3826056efe912f3db02df9c0b6931e253ab9248f472359fe59218690f6781f35da89b8f1ff45cd5a1db9a414c9d7ec6effda59a377af7e3edfbbbbaf4efedf1ae78f7dbfdffdedf9effd5", + "0x3531a6880ccc47bc3826056efe912f3db02df9c0b6931e253ab9248f472359fe59218690f6781f35da89b8f1ff45cd5a1db9a414c9d7ec6ef39a408323a66a3e5fb3238c046a540aa78b75bbcfa9c179cff95" + }, + { + "0x68cbb0a526d1fa61003e12401db51090fa4649b00b7be7465d0eb18f74c86157a919", + "0x1ca7d6f9bc3e11d3c365af63bf9499b6c7e9c569da7361f0214b8d", + "0x1610001c111080600641b00019a6464904218a704060010909", + "0x68cbb0a526d1fa7da7fefbfc3fb5d3d3ffef6bbf9ffbf7c7fdcff9df77e9f177eb9d", + "0x68cbb0a526d1fa7da7e8ebfc23a4c3539fe92a0f9fe25181b4cbd85507a99176e294" + }, + { + "0x210bef18d384992c5eb72e2b362c7296d9810f5ba9fd25e2d5648989d65095e45d1478f2a83140a0f68033a08fa3d7c392a3dc77e8e6aeba9ed76038e9e7825255fac990bf1098e6f9cba0", + "0xdb48641b3f63e5f1f41ff3b1578c4b190de42379d45cba03c4c6f34b1b14ea930fdff90dca53116710228e45b081fbddc9273a542e6f689642453adb91086bdb99681342113262d67f5517f2691024fe367459b01872549211067798063cc00b16c883b8cd2ffaa6d6116863f204bb23ce26c5bcdaf3e1b816dcf65ca", + "0x21014200d280002452a52800062c309681000113202d25e051640081024081644510008220010000660000208c00914080238c52e8a22c201686202049a20042445ac9803e108064c94180", + "0xdb48641b3f63e5f1f41ff3b1578c4b190de42379d45cba03c4c6f34b1b14ea930fdff90dca53116710228e45b081fbddc9273afeffef78dfd2c5fbfbf3bb6bdfb96d9b52f5baffd67f7d57faf99d65ff7e75d9f79f7ad7961b0f7f9b3e3cfa3f7ef9abbdcf7ffeeeffb9ed77f38ebf7bef27dfbcdbfbf1b99efffefea", + "0xdb48641b3f63e5f1f41ff3b1578c4b190de42379d45cba03c4c6f34b1b14ea930fdff90dca53116710228e45b081fbddc9252aeadfe250dfd080d1a973bb091cb0058b52e488fd04217841baf18d41f7683188f79758d7861b091f9b3c343a366af1a9850a5174cc3db88515f18a255beb039a1043f810b198b36ae6a" + }, + { + "0x143143205d76a7287d48be24db8fbfe37c291d82e103aa05cfc172fb920f0e8cc15c47de948b964e39be34a5b8a2610198c0c5b98543e6e727be153cfff0338f229cc22f029e04f766c62988634fee1a0a16880c93e5b10bada4018b6765b54c08f5710344dbfb9e9ad5dd7914cab496b22a6", + "0x2d58b8b513f4bceb8300f8b978e31c163f36155e9678bb0f221ee7cbcf7262b9d53c7a395ea916218fa2478baada74f3e69df63a7be0c9554c07004f9e4d869642bbd63a9fe07138a6aef7ad14c74231cf6401c597f9b6d15c266c42c28613838609bd4f4522c9eb65fc8456acc339c641ac7d7b7bc2c48c8f2", + "0x100201970a308140836045a8638a30c201c82c103220089c1307a100e0804010c0246808a924431a614a4382260011040050005024486060211143a902001208482270014044220c620004107e8120014000c02c080038184018947452048086570004488c31882418c79104a8084800a2", + "0x2d58b8b513f4bcffb343f8fd7ee73c7f7fbe35df9ffffb7f2b1fe7ebcffa67ffd57efbbb5faf9ee1dfe7df9fabde7efbfebdf7bafbe1c9ddccc7b9cfdfefe7b7febffefffff3ff3abeeeffaf9ec7f777cf6d89e7dfffbedb5eae6cd3e7b71bafa609bf6f65b7cdebf5fd8756fffbbfded5fd7d7ffbf6d6beaf6", + "0x2d58b8b513f4bcffb243d8e40e44346b7788318519c758730b03652accd86776144e81ab51a79ae0d3e5991f214c3aca58a95382d981c8cd8cc2b9caddab61b1fcaeeac56fd3fe1a3a6cd8af8ac3b557094d89a6d817acdb4aae60d12737182e22083628209785e3908d87127738a75c9471046fb176523ea54" + }, + { + "0x258e988b847b06b73462629161e28517f7b9ad7b5c19a9ad2c07f9a66f33fb2220fddb5a33b9cd5c2d63fd543efa1bef16e26b95484d70d0d7cfce28491ace0a608fb6cf9e97cb88d73c96c9150f9ef53c5e75bd68805fdce891e5935e9428ca67eba1e345148fcf2", + "0x1857c0e26e0476169cf804c8d5a431022cce0da75d7642a2414a900370f201f5073c7e700ff6626fbd8a104182954fa9f23a45474af5456a00e36f6a6c8162afdf7492d387a455dd8506167d5cc24e6861d7b480b1458230", + "0x1812c0a04000121280780040d12430020ccc05a319144082400a900360a000f10624385004d6000d3c880000808440a0003a44414874000800c16c0040816203c56412d2800455cc8106103548420c206092140011408030", + "0x258e988b847b06b73462629161e28517f7bdfd7f7ef9efed6dcff9eeef7bfb3222fdfbda77ffed7e2d77fd543fff3bff56f3eff748ff76f6ffdfef2c593bdefaffafb6dffebfdfdef73eb6ffb7cf9efffdff7dbd78fa5fddf8d1e5f7dfdc2ceee7fffbeb4f14dfef2", + "0x258e988b847b06b73462629161e28517f63cd1757af9eecc45c879eae269b83202313b80466ea9760977545409f53bf04691ac7248b216f62c176f2c51339af0ffac129bea389fde7732a03fb3c788dfc1a93c9050fa1a8130c184f48b580c2ce1f6daab4e00d7ec2" + }, + { + "0x328edc02c67d84bf095ac048e50c2dc29cffc08184b11e4da02904be14eccd317e9f6bdd6fe2b8233e8928d65d4ad434ef8a629cae6013bfb3c54be167e16371dc6412b62c2b1213424dfb7d391cea8a7494a28576ce823d8e111994182909efba7dd3533dbbe510dab4ac5ef", + "0x61a1365a1226597896c514f5bb16a064f6ff6982ac91ea568daa43e473aa63867bdb628e92e97ebd4f2091", + "0x4121224210201020968510918a00a04042284100a801c84001884180108a63865911228a92410ca94a0081", + "0x328edc02c67d84bf095ac048e50c2dc29cffc08184b11e4da02904be14eccd317e9f6bdd6fe2b8233e8928d65d4ad434ef8a629cae6013bfb3c54be167e16371dc661ab76dab3277d7cdff7d7f5ffbea76dfeff7feeecb3faf79dbb43e6f3befba7ffff73dfbef97fbf4fe5ff", + "0x328edc02c67d84bf095ac048e50c2dc29cffc08184b11e4da02904be14eccd317e9f6bdd6fe2b8233e8928d65d4ad434ef8a629cae6013bfb3c54be167e16371dc6208a5498a3076d5c4972c76475be072dbcd73eee44b232b79c330266e3349821a6ee51552cb8731605e57e" + }, + { + "0x37a92944b67fae733d201c024838975531bc3f748d98089eed38faed40c9463441cf48ac40e98097ce75db2bf0120ef69087a176d31d562cc99137c67e4a659cbb1298ba150aa191ced4089deee7048511de602414936af93cb2cef1b7ee801d9b75d961d33bb2958669b16193abf7b55ccfebac3a490415128dac92", + "0x6fb8d83d986c4604db1b9396493a0a68270806cdbcc3299a049ebe77bd6891258e6313c720fb1b30ae9c4387ba51db3325e15033d9e01d499707c138b4cf4b85032da65e9ce3aabc5effbf7003771476ff71e86f665d2d3e7578dfcbb8f08c1619f609ec147f0", + "0x88c811882c440490030014400a0008000804c51c822900008e2800380001218462008100780320a6184381280181102001102140801c4810004118a4024101022d824a0ce30a3c4801993001161432bb2148660214093a357855c8b8b080041040012810490", + "0x37a92944b67fae733d201c024838975531bc3f748d9efb9feff9feed60cdf7bd79efdbace6ebf097eeffdf3bf9b24ffff7fff7ffd35df63dfdf33ff7ff4aeddcbb7bbdbfb73aff95cffd9e9dfeff74fd13df6cf4bcd37afb7dfbcefbbfefefffff75ff71d77ff79f86fff5f3d3eff7bdfcffefacfb699f759ecdeff2", + "0x37a92944b67fae733d201c024838975531bc3f748d9ef3136ee17c292084f78d78abdb0ce66bf017a2ae171969b2471d77fc77ffc145b01df5e33877cd408c5883693da7a638ff84cde9969c3a7e74f902552cd0acc35823595b00cb1c2b6fe66c75ee109454458b009fd4b3404ca038a07464a4fb289b758c4ceb62" + }, + { + "0x1ab020d8beb54c354411f3a5658b5e5e87a896d7049c5eab20a302b6e35ca98364d7edd00eb3e209dcb035fe4b6eeace4e525229bf790c67bae63821e1282712d7c624efa64b3e5ad1a73aeb1033d4cd5949d63183173632445c9f488e74cd", + "0x4d706a200a7a70e0b6eeef2dbdb88779dd50af16e6405c17fd2c2efb5493cf13b730207a009a14ca150042af3e6b7f05230161a10073f87a56afede3c2cfd09857f78d7913cdd966e9a2e6e6e3", + "0x45000000a2a20a002a6e30ca9800451cd500e12e2005c10352c0a6a40824e1212202078000210c21000402826025704200120010052d02212ab0023c0cd5008563181111200404489008664c1", + "0x1ab020d8beb54c354411f3a5658b5e5e87a8dff76ebc5efb70e3b6feef7dbdbbe7fffdd0afb7e649dcb7fdfe6ffffedfcf53f739bf7b0cffbeee3d21e3af3f7bffc727efe7eb3e7bf9ff7eeffdf3d6cfd9d9d7f78f7f37ffdd7effeaeef6ef", + "0x1ab020d8beb54c354411f3a5658b5e5e87a8dba76ebc54d15043b4580c71143be3ae3080a1a5044980a7c8d26595be5d8141e5199f030cfdae2c2d21a3871979a8c307eec7ea3e2929dd6c44fdd0160289d181c60e6e25ff9d3a76ea68922e" + }, + { + "0x85993ec08ac960d46bcba87136f24042485c6d3e0a9973e828df60e537860d6bc83dafa7fb292beef466d0a939ab9da2b", + "0x4c9a310b11d6e4b4d29d7ede30fb42161fd6a58792440f416abda6df55913a8a26c35140524de5dd9519c30f19641f4f0863bfefc2ae6c89333dd77d6f688cffcbde281772cee0dac9bb0dd16b6c1d33fa7e39b2e781896dcc2b0aba3abedf1381f9f38eb210f5bd2001ea8453ceb136dc3915fabdc30709db0b1a07ec40be", + "0x811926c08a08601002c8803022a2004040180d1e0889210808d2000420040c6b002d83815b290820700490a1202a8402a", + "0x4c9a310b11d6e4b4d29d7ede30fb42161fd6a58792440f416abda6df55913a8a26c35140524de5dd9519c30f19641f4f0863bfefc2ae6c89333dd77d6f688cffcbde281772cee0dac9bb0dd16b6c1d7bfbfe39bef78dcffdfeaf1bff3ebeff97c7fbf3afb73ef7bdf60ffbfc73debdb7defb7ffabfffef4fff0b9b9ffddabf", + "0x4c9a310b11d6e4b4d29d7ede30fb42161fd6a58792440f416abda6df55913a8a26c35140524de5dd9519c30f19641f4f0863bfefc2ae6c89333dd77d6f688cffcbde281772cee0dac9bb0dd16b6c156a6992311e718ccfd176ac19d51ebafb96472a1327252e7730d60fb9fc33180db506c36a482f7de84fb601899d559a95" + }, + { + "0x4d9f3e8aae22123e382e7835d3d9d7e944a5c81cab3415fda40d0ec8fde8a50d8b21b2298f83a65bbdb10d120d302d8db4e9807715be0e", + "0x4dacc1a6f2cecd4179556cbbdfe1cedbc952de5232ff1fe1ae9c0c3bbfcd9087e4ed5bcd1f8c289b1456ef032d888", + "0xa48104308c4c004854008a93414eda4050cc02128a10c0a2180018b8080083c00051001300089b0410070109808", + "0x4d9f3e8aae22123e3cfefc3ffffdfffd57b5dedfbffe1dfdbc9d2fedffeff5ff9be9f2ebbfffff5bffffddbeddf8ef8db5edeef737fe8e", + "0x4d9f3e8aae22123e3cf4b42fbcf53b3d53309ed716ca09101898232ddec754f391c872ea347f7f53c3ffd8aedcc8ef0405acee87276686" + }, + { + "0x28d61d5ca1f56b4d3134009f478b17ac208a5b559d9c3726a7a16919e3b12ec6d61a142dc04d834141a9a4", + "0xb444947aba00d50e10326ebea7a2618a10144dde07c15c685d4785eae16d232eb741bc2a09b7cf794a33ed3598803ad61af", + "0xc00104a1e06a041020000445801404008050501c8c160222a16019c2a00a44d610002cc04980010121a4", + "0xb444947aba00d78f71f7eebff7b6f39b501dfdfeb7fbde68fdf7ddfbe37f6b7eb7d1be3b1bffef79eb73fd35d8b43ede9af", + "0xb444947aba00d78371e7a4a1f116b299501db9a6b6bb9e60f8f2dc33221f4954a1d022111b5ba218eb71313140b42ecc80b" + }, + { + "0x1b9a0b9c87fa234d05d06e18171cce3f8fc4adf7f75a402c4c5a281f46e714b96badab2184546aa11a7be482616cbb973da00e329628d3e692b69b43d34391884d87fcd64e2339fbb30044a370fffde97a128d1e5", + "0x7d641e556550c3ddb89ee553cbc0d8d92cdaec6519a2ff3bd792e0b309c24cb49056fb219ef4dfb2a72e76ac7df3407a44e55af5689e9c85c87e74d542dfb445f56a0a518c", + "0x78640a55655080008084a001c0405049049ac8201800462a1182a000000248b01052002108608d32212a60a43d30001804c05ac56082108588300440020fb4449520085184", + "0x1b9a0b9c87fa234d05d06e18171cce3fdfc5edf7f75e7dffcdfe7d3ffeef9dbbefafef719e7ffbbd7b7fefb2fd6cfbdf3defbe3bff6dfbeef2f7fbc7df7797ac4fd7ffd6cfebf9ffb7e74df77dfffdff7eb2ad1ed", + "0x1b9a0b9c87fa234d05d06e18171cce38598548a1a2567df7c5b47d23faea992ba6036d701e7b991c6355efb2fd4870de38cfbc2b796528cce051f1840c77962c03d25380c7caf1a734e709f75d04b9b62cb228069" + }, + { + "0x142cd4c71f04927a526ca430e542cd9432860", + "0x1337869f6c145daf15b226485ef3c48b8037bf7cb2cc9834153b90f55d4217a5e4a9ea133", + "0x142c90c41804103a106404000500c48022020", + "0x1337869f6c145daf15b226485ef3c48b8037bf7cf6cf9f34977bd2fdfd72f7e7edbdfa973", + "0x1337869f6c145daf15b226485ef3c48b8037ab50660b87308741c299f972f2e7293dd8953" + }, + { + "0x4f517f63e95a08284faaf4d4a290c334fc5d039e386727ddbb5d0a6d5fbb5540e97767023d60bedd158ed25051a6c56", + "0x9e2c9c6d2e3be2ad25733871aeba4ba64081294478f936f9c4fc45ada6bb2c098c98f21e709a88995cc3b0cf7e693f8e73f58f8f4735c81e8421182fc15426174f3b6da7b493135c", + "0x4f405a4269120008498a20c400808114cc190096200320c53b5808645318014040110200154020541186d2504120054", + "0x9e2c9c6d2e3be2ad25733871aeba4ba64081294478f936f9c4fd57ffbebfac8b8cfaff5f7abb8cbb5fc7f0ffffef7ffffbf5dfafd7fffd5e8eb77e7fe3d62fffdf7beda7b59b7f5e", + "0x9e2c9c6d2e3be2ad25733871aeba4ba64081294478f936f9c009525b982e8c8b08625d533ab384aa130660f69def4df3a8405f2992ce7d4a8ab66e5fe2822dfa9e638082b1897f0a" + }, + { + "0x1713f8f439c07e35b741ec9b0bca80149a7ef129c73c23c34b4515d29dc7dec711007fa395ced70f3bebc6d229edb75bf04231f2414e0a826f3edae4edcf770d59650cc252c6a2eff07fda9baa70938085d1e15144a451d26304d8f3df2406b8eb40f4fae3666780d2e54cd93a5f17439a4d3656dc5d48", + "0x328df4b64b0bd0fbea359666904ea4aa215b03727a70bda853b6cf612b12c3d56ee93b003bd00a7b9c1d6755f580b467deba33bf7f33da4c37fffe79e73e4381ad4bf1306d1b58f5eb276cae813d6f9153d1294c51098d37b3b80154da", + "0x108094864a0310006a219446900e20aa005201603250b00011b241400a0243144ae02900330008610c004244a080b067da9a22301300804021514420411243008843d12004184840e02260260100428140d1284c110188053210005448", + "0x1713f8f439c07e35b741ec9b0bca80149a7ef129c73c23c34b4537dffdf7dfcfd1fbffb797eed74fbfebe7db2bffff7bfdea73f6cf6f2b92effffeedffcf7fdd5b7f9cdf77d7f7eff47fdebbbbffffb3dfddf7fffefdf7fe6385fdfbff346fbbfbf5ffffefeee7bdfff55fd93b5f574b9f7fb7fedd5dda", + "0x1713f8f439c07e35b741ec9b0bca80149a7ef129c73c23c34b45275f697195ccc1fb959603a847419f41e7892a9fcd2b4dea62448e2f2190acebb40dd6cf4cdd531e90df3593576f4418042199cfecb35f9dd6aebaddb6ec208575b82e146ba3b3b51fdd8fc8e6bdbd741f081313464a177a85eedd0992" + }, + { + "0x68bc9c8f8257c6c88c0b2d46defc4539748fb906140acbf1a68820d1748bfc13ec84619f2b495d1ce74e0ca441a246497", + "0x2d30db90794c4b611858b19c973ea865904346738291751ba5fccc5cbf02c09876aca6bf23289174f545ad8039e0fbcefe359521dfc9681a7715e672fdc23cc446c7900851d2ed09568729c88bf9653c63f7e229893f31059e8b51924a54968d44e5bb26decae3159ce786d9b3a1454c6d6cb8108d22bd5111d2cc7eddb", + "0x68241c03824200880c0105068a50000854868904040a02d0828000906482d813a004400d2808100c220c0000408046493", + "0x2d30db90794c4b611858b19c973ea865904346738291751ba5fccc5cbf02c09876aca6bf23289174f545ad8039e0fbcefe359521dfc9681a7715e672fdc23cc446c7900851d2ed09568729c88bf9fdbceff7f7efc9bf3b2ddedffdd77b749fbd46f5bbefffeeeb35ddf78ffdb3edc56dff6ff95d9de7ff5db5d3ee7eddf", + "0x2d30db90794c4b611858b19c973ea865904346738291751ba5fccc5cbf02c09876aca6bf23289174f545ad8039e0fbcefe359521dfc9681a7715e672fdc23cc446c7900851d2ed09568729c88b91d9a0ec75b5ef41b33a28d855add77320193442f1b1ed2f6c6b354d930d25a04dc12df247f14d91c5f35db5936e3894c" + }, + { + "0x6eef644a36b1e052a413160909a537f81d46b2d330981f507d84737065541b5bb5faebfa8491dcd0347fbe498a501e254b91f6d82d6771a69d0aee5a490e2a44a8ba4f5da963d70b486f36f4a65f372a6a60522cac6e6a01d1a2da8743d5381", + "0x391d108a0ba169bb746b3d5816fa985288c230bdde7e3b8433f8d595b63f08a90448923f30926960cf736be42e377b087e68848af89d80d95122b942b0162153d9d665c0e3508d8a25c8862c0bb7ad4f00e4b1213326f5ce32433df12cb9", + "0x3004000a0a01280130601018127a8050080030098074038003300415003508090408800910800140cb6008a4002250081e688082701800d00020a000a004000380d4408021508482214802240332a406002080002220150a200034310081", + "0x6eeff5db3eb1fa56bfb756bbdda57ff99d6ebef33bddfff3fdc77ffd7d5f7bfbbffaeffba7f3ddf6b67fff7fbe52ff77fb97f6d86deff9fe9d9ffe7bdd2f2b66bdbfdf7ffd6ff70bd8ef7efce6dfbf7afef05e6fbe7f7a6fdde3feb7dfd7fb9", + "0x6eecf59b3e115a443fa450badc245851986e3ef03b45f8b3c5c74cfd3c0f78ab3f6aaf73a762d5f6a273497f3412fd52fb16105065c8f87e909ffc71dd252b26bd87d23bf56de20390cd6a7cc49f8c50be905c67be7d586e8d41feb49cc7f38" + }, + { + "0xa210334e6ffbec2fcfa42021075f84222c7", + "0x181b940df674ffa93b3346264fed88e40b8d8f252487bc1f2cb4c3284fa17145d2cd0c77102fc177898e53fb12c40525aeb017a57661a80a268f27b4c78cbb4bae0e96ed0065e32bc7dcb01be9cc4e6bd5db5e453e94855cb2d1d3f86e8218fe55035102fc10901add0eb539089af", + "0x821032440351002c0080000106150000087", + "0x181b940df674ffa93b3346264fed88e40b8d8f252487bc1f2cb4c3284fa17145d2cd0c77102fc177898e53fb12c40525aeb017a57661a80a268f27b4c78cbb4bae0e96ed0065e32bc7dcb01be9cc4e6bd5db5e453e94855cb2d1d3f86ea218ff5f6ffbeeffdfb43afd0fffbd2abef", + "0x181b940df674ffa93b3346264fed88e40b8d8f252487bc1f2cb4c3284fa17145d2cd0c77102fc177898e53fb12c40525aeb017a57661a80a268f27b4c78cbb4bae0e96ed0065e32bc7dcb01be9cc4e6bd5db5e453e94855cb2d1d3f86e2008cd1b6caaeed3df343afc09eabd2ab68" + }, + { + "0x2db0666cd0edeeab9e46e5b729521be3ece0714ffeefe18cd1b8b0f17e04c51b0d79fc6d428c22b9af63756", + "0x1c1d5f18453c10d365065465c676fb8b58cb436b88660a0e19c350feb1f6954caf029a43a3e59bb35ce0bdbf80a7b8ff4b4f5d7d133bd244df8813e9695b1a6af9cea293e5da9ce4f8e1035fc8ce4ca62ecbec89e89fe25053e4153899415f61c41fcb412f13b58ac70fb84077831497f", + "0x8906468c0014e888e44a426094009e08ce05043e4052088411820c01e00410b01318845028800318300156", + "0x1c1d5f18453c10d365065465c676fb8b58cb436b88660a0e19c350feb1f6954caf029a43a3e59bb35ce0bdbf80a7b8ff4b4f5d7d133bd244df8813e9695b1a6af9cea293e5ffbce6fcf1efffebde4ee7bfebfe9bebffe2715ffefff99dd1fff1f57fcfc53f1ffdfeef4fbc62ffaf77f7f", + "0x1c1d5f18453c10d365065465c676fb8b58cb436b88660a0e19c350feb1f6954caf029a43a3e59bb35ce0bdbf80a7b8ff4b4f5d7d133bd244df8813e9695b1a6af9cea293e5f72c829431eeb163500a4399e2be920b7302211c1afad91590e7d13561cf84341ecc76aa4d3462ce2c77e29" + }, + { + "0x33de1dc3fc5d6eeb5cbca27cc816a3727d1f9188400ea6b2c2799a40f7e611770b45cac7ed49fc0b66a46fcaf2393c0e03741bd08d26308fce62b0c56fbe44cb0949990bc3d4e5919ee1706dce518d6a06e865bdc26e761ef6723241b33583262bc4365103ba49dd17c0", + "0x148a80223564208532d09dd94cf189921325cad8f2a6a32568e36b2007f00866ce0c8e59034cac999f915817492737af76413832e2c4e840627b91b54766a1555e91b87b2692df16c41161184ac9a124d59aad5c06b1a61892cf5c0cd6cc628f764a161f1bdd6546cb51a1510eef5ddfbd", + "0x1121081d84c608910102048c812a222250881080006a00042480800510200240905804005492403262441083220040800601b9085062081444290806b2600cb004011010040c18104c1102d4c0081220080451c00464402867202001311812402c01001010a495d1780", + "0x148a8022356420b7fedddffd5dffebdebfa7fed8f6a7f37d7ff3eb600ff6bae6ff9eceffe75dff9bdfdbdfff49ff3feff66ffaf2fbfcee43767bd1bd6776afdf7eb1fd7fbed6df1fcd996bdbdeedb1bef5faedde57bdee1efaeffdcefefe7eff767a57bf3fdf676fcf77f153beefdddffd", + "0x148a8022356420b6eccd5e25119f62ceaf87b610e405d1587772e3600956baa4b796ceaee55ddb92da5b9ffa00db3cc9d22ef2c0dbf8e6431660413861562e9b3c217d1498d6141f8d886adb9e2c30ba34eac092573ccc1e7aaae1ceb8ba7c79047857ac2e5e436d0f67f052b4a680c87d" + }, + { + "0x683d881de1820ee9fbb71ccd74fd10e3a9ce71bd132955b9e9840d9259275498d2fae81b112416f37e9af907c319657d5d81623462b98d93818a23751a2196de6dd7c18e05960", + "0xa9a2ae43423e6c78cc59ceba6601f6d85397527c462767dceeb1ebc6ad425fb2810a2b7525", + "0xa880a002402e24688c104c300601d4d81203422800012018a2314182094046900008205120", + "0x683d881de1820ee9fbb71ccd74fd10e3a9ce71bd132955b9e9840d9259275498d2fafa3bf53437f7ff9efd9febbf657f7d857b7567fdeff7fdceeb7fbe6bd6ffffffd1aeb7d65", + "0x683d881de1820ee9fbb71ccd74fd10e3a9ce71bd132955b9e9840d9259275498d2f07231f5103515b9163c9b28bf056230045b41457defe5fc44c86ba64b42fb96ffd12cb2c45" + }, + { + "0xa827c5e2bd4293ed726065b32cac5c18d9df68b18300848f23f98c22fecd6b9fe7ed38a5adedd78f8dfe975d85c171f62b766947d7cd3d2ed3be52b50b792c0d6bb2701e28f22674a092e5ee0ec89bcd52680c6ae673a", + "0x1deac63a0a7ae71db949662f05aafcefed47a6c6dd5819dc82d250d978001903a1f19e1b8b44e76bd5899884bb97121fa13a63c33822314a486d29b59b66f141fd64af3414a3ea6bdca9b4362e704c744e8a12c1ab736636ca3aa9da4b75795f1a", + "0x202040a28c429068606045810c880c00099700018000040921b88402768d48998049382121e813860c328201048000d20b502047140d140ad30042340239080943226004004020202012a52602488388102004428471a", + "0x1deac63a0a7ae71db9496eaf7dfeffffed7ff7e6df5b3bdec7d3ddddfe8b1933a9f9fe3f9bc6efefd7b9fefefb9f5adffd7afbdff977f95e5f7f6bb7fff6fd7dfff6ef3ff5abfaffdee9f6bf2f71eeff6eef5ac9af7fe6fecbbefdfecbf7ff7f3a", + "0x1deac63a0a7ae71db9496cad79f4d73bc47971e0db032b164713dd448e8b0133a9b96c241386c887033066fa681d48c17c429b1cd157e9165f724b02fdf28c3d2eb6420ff188badc4e69628d0971aefb6ced58c8852d86da43867cfccbb3d73820" + }, + { + "0x1cc981657c8a20f5c777fc1df0e3cde0b23d434e043732dcaaa0758e009a8d1bf8591ff8db693d676eff2c39645b79c06b510ac22b1b47551eb728aa9404c24f2a6dee6bbdf2276759786f4116d21f4009dd6fb8e277976668bd021effecc797ca23682b97dbdffb93333834b8bb8fb68e922f42e3c00111", + "0x1e52f1e05fbedda88873e9984a7a19bfbfbe9ea43e30588f46317b5cadc8eb02d255875f1dde872476d05dec1164e46c7fcf3fd718fff34a80d4c6e951d10f6ae0225d00e3953e99e", + "0x61010a002b094200063608808400824b2a69ea43a10000644110254014821000015865b0c060124668050200164c4687c823682187db14a801002814181086a60200000221400110", + "0x1cc981657c8a20f5c777fc1df0e3cde0b23d434e043732dcaaa0758e009a8d1bf8591ff8db693d676eff2c39645b79c1ef7f1ec7fbffdfdd9fbfb9aeb7a5dbfffbedee6bfff7aff77b7fffcbdedebf6d2ddd7ff9fffff7676dbddedfffeec7d7fef3fd7b9ffffffb9f7f7eb5bdbbffbe8eb7ff4efbd3e99f", + "0x1cc981657c8a20f5c777fc1df0e3cde0b23d434e043732dcaaa0758e009a8d1bf8591ff8db693d676eff2c39645b79c18e7e14c7d0f69ddd9989b12e33a559b4d18404285ef7af933a6fda8bca5caf6d2c851a493f9fe52105b8dcdfe9a2815036d0955a1824eb539e7f56a1a5ab79188cb7ff4cda93e88f" + }, + { + "0xb77c8e0971a4f32bc9539c14b542ed2fa08e87560981cbdca4ccf4f7cc04fe7546a4a7eebe2592d131329fd591f66728a4179e", + "0x2fb77bc1694a8265e74ee9f41672fc681d72ea8eb65ef5807bcba4bc52ef9e381a4e4315a771497e506b734def1ca93dd519fe9e6944dd782380dff70b72798c", + "0x327c080970a08222485180108100ac02a08e0012080101842048745048004c6504a025c4182492410010180180d6670820118c", + "0x2fb77bc1694a8265e74ee9f416f7fcee1d73eeffbfdff79c7fffe6fd7fef9ebf5e4fc3dffff5cdfef7ef77ffff5eadbfffbfff9ef975fffff791fff72bf67f9e", + "0x2fb77bc1694a8265e74ee9f416c580e614034e7d9d97a61c6f7ee6517d4f10bf4c47c2de7bd5858aa7a777b39a5a0d9a3ba7db0cb875efe7f611299023d66e12" + }, + { + "0x89a0fbe80f4c622f45f4f7a15d8dc23bff17d939349f39cffa643af024db78243fc46c7948ab14ea12595e8a6cf2196ed4f353d9b1b8834b96fb61073301b99af019f042b2215e8cd5f31cf65123dab47d6b697a", + "0xc2b6f7a999af54a94c156f771b995b528", + "0x22215a8890f108944102d23039012128", + "0x89a0fbe80f4c622f45f4f7a15d8dc23bff17d939349f39cffa643af024db78243fc46c7948ab14ea12595e8a6cf2196ed4f353d9b1b8834b96fb61073301b99af019f04ebb6f7e9ddff75ef6d177fff5fdfffd7a", + "0x89a0fbe80f4c622f45f4f7a15d8dc23bff17d939349f39cffa643af024db78243fc46c7948ab14ea12595e8a6cf2196ed4f353d9b1b8834b96fb61073301b99af019f04e994e24154f06566290752dc5c4fedc52" + }, + { + "0x61cc2de53fe06a0381ce0dc4999795469453324c9036484632c257f02dddee71188198ed649bbe9ddae347178970bfbd3f1f28a787ee407a433f8473ba4fb77940227b769c9d555a8a70917ecfd038f80da4c6d5dc7211cc468c69a2275cfc119f145d2887543bbeb24", + "0x117135d192a9645062d1be59a1f8b151692159285e5877a0ae304521ad800f51fbba812d038e053cb79578c70cd34248a2b4026533bb961add83d9362893b74ce01695861c82b6f94f181feb4a957875c74cf1e7fe48dcc5196bf1214cc564f599168bf2fee1a07e617cfac992443fcdb28247", + "0x1c408050b000202018205c4811200420452124800340802200250302051ca71108010cd24008a09402243138960ad983d13208103644000411800402a4f947100223020148554508a1011648dc010900d0004c454421180408c29a20204e4118f04192003541b28204", + "0x117135d192a9645062d7bedbfffbff57e9395de8de59fff9fe794533adc90f75fffbad2d7f8eddfef795f8df8ed74bfbebfdae7573fb971bffd3f9f6aafbffece7b6b7fe5fbbb6fb7f9c1feffffdf9f5d7ecf7efffecfdc79febfb6d6ddde7f59dd6ebf6fee3f5ffe17dfbcdd2cc7fcfbbeb67", + "0x117135d192a9645062d7a29b7fab4f57c91945c88211eed9fa59001289490c357fd9ad087c8cd8e25084f0de82050bf34b69ac5142c30111265028c4a2ebc9a8e7b2a67e5bb91202388c1dccfdfcb1a092e456eee9a421c696eb2b6d2198a3d485d2e33464c3d5b1a0650b8c40cc4a8e096963" + }, + { + "0x1af3ce2ba6101f661c52430ae7280e3491d8d044a6621c3ef348c4e6e45fc6dfc91ec46b27214a9ebff52a0922fdebf1e895cd7cc4f428c64b7b3c4711b53f1f04f25b2f63ba70f281f52cb8149509f1ad38156397556eedf9e5c72388364cdba9112913", + "0x5c5811bd255dad9049ec956e6eeaa95895e56e1c5c03cbfe24ae065ac3f528fda51a966771d288dfe3aab7611232e6f6bde10cf0d97620ebde6370ab24dbdecd4d7783c05cc8579517951049f16b26cf1612f6344a669d93ac990a997dfb5180a07a75f6a20dc110fd5547e744cfe0b348cc1786d8c7f587dc83fd9e8fdb9", + "0xa00e02861011200452010885280a201010000426621c10c3088462041dc61708124429240042183c050801205169510095043044f02006434024411130091000925b25000a00a201602098100501502c30046203140cc1786584230834481b89002911", + "0x5c5811bd255dad9049ec956e6eeaa95895e56e1c5c03cbfe24ae07fffff7bafda5fef7e775f2aeffe3ebff7d9f36eef6bde3eff4dd7e6eeffe6ffcbbecdffeff5dffebff5ee8d7bfdfbf1ec9fdffeecf569ef6b7fbe6fd9bfff9fadf7dfbf7bba77f7dfff2cfc159fddf5ff7c5dff9f75eeedf9edcf7fd87fccfff9f9fdbb", + "0x5c5811bd255dad9049ec956e6eeaa95895e56e1c5c03cbfe24ae07f5ff17929ca4ecf7a255e226ad6349fe7c9f36ac909c22e3c455384eae220e8c3ac89d6cbf59de683f0e68c5bac92a0ec0adbcea80549e9283f9a2ec88ff68fad65849a7bb07755de9f0c64059adca5d34c599d9c61e22c81884b5cd04b84e470f9d4aa" + }, + { + "0xcd10bb69c381582eff7391a446db73312e738c6978564b350ca88e09cad650ef89dfb4cb00831c41d4739e957fdac00124348c91183da60b8f12dd3e349cad8b8d752fd9ea5613b1a41818032e0a2f2030790009a4fe9cdca54f96402b143e", + "0x7c4f944973a8882522976043833419c2c15b1531af1207b40092dd1e3c123a4cf06370c3111b", + "0x104d140010a888052007404202101180001801200a020030000009043c10180440024003101a", + "0xcd10bb69c381582eff7391a446db73312e738c6978564b350ca88e09cad650ef89dfb4cb00831c41d4739e957fdac00124348c91183da60b8f7edfbe7dffad8bad77bff9ebd737b9e6d95b173faf3f27b47992ddbefe9efeedfff770eb153f", + "0xcd10bb69c381582eff7391a446db73312e738c6978564b350ca88e09cad650ef89dfb4cb00831c41d4739e957fdac00124348c91183da60b8f6e92aa7def0503a857b8b9a9d527a866d943161fa53d27847992d4bac28ee6e9bff530e80525" + }, + { + "0x1cdc2579b3f1727c03a0f733c6a1a50025c8b51640ed21fb0e700f873d35c83797a14", + "0xe3e7298d39a9c7cd225125b1a01505e3d9ca63f8b494e4d7218b10e8bddc06984bbbe43e263f30f6a92a9d7", + "0x10042120110162580220f03084a085000100a0144004004b0a600e063d30c02102814", + "0xe3e7298d39a9c7cd225dfdb5f9b7f5f3fdcbe3ffb7d6e5f721afd8fdbfdcefb9fbbff43fa73f35febfbfbd7", + "0xe3e7298d39a9c7cd224df994d9a6f491a5c9c30f8752457221aed85dab9cebb9b0b59431a102053e9ebd3c3" + }, + { + "0x3ac7a7062a50d421ec7b732acfeafd988b5fe95661d371a7f2fdb5b9c1d37e304dd3a0dfcb995e9f99e1b86696b54df83fcd4e87764ffe27fbbd785875c31993f20f4628df79cbaeb50c3dfd132e20935f33ee0276c23f445dff5a075a8198907c1e248787fb28c44495d2e2ed677832432eeda5026afb91467cef4b8", + "0x12659e0b26181845981459681797ab57a50c5b4a34882e973f884d99c1e89c0457b99c9445be077039c60cffa057c608594d38423730d3eae76e8a8db6f946877e90bfecde4aaa320128ef3811cd31c3834e66fa7a61d1454778bf82781c091ae5fd348fd903d85116f83f331d84edaa925d1d65b0b30c1b7c6c69da380", + "0x20860306081044000459600287aa5580085b481400021127804d9181c0900410099080458a0150198000b820168408580d0842073043ea276a88081071420112900f44084a280200200c3811012000834e22ea0260c0054458bf0200180118807c14048103d800044015120084652812410c65a002081b104468ca080", + "0x127fdfaf263a58d5b9fc7b7b3fdfebffbd8f5feb76e9fff7bffafdbdf9e9df7e77fddfb4dfff9f7ebfdfedffe6d7f74df97ffd4eb776dffee7ffbffdfefdc79ffff2bfeefedffbfbafbdef3dfddf3fe3935f77fe7a77d37f477dffda7f5e899af5fd3eafdf87fb79d6fcbff3ffedeffab25f3fedb5b36efbfd6e7dff7b8", + "0x125f59ac20324891b9f8221b3d5841aa3d8704a362e9fde6987ab02c78294f7a67f44f349a759e2ea65fed47c6c17345a172f50cb0469c14c09537f5ee8c859eed62b0aaf695d3f9af9de305ecde1fe3101155147817137a032540d87f46888275812aab5e842379d2bcaae1ff698ad2a01e338815b166e0ed2a1535738" + }, + { + "0x39d2210d760b098917fd1293f0708ed6ffcd7686a4041e774a0f52e808524d686429da6774dd45dcf69abb4a7a48116d71f8e38074196cddf128b041a28cdc1e12cf755c7", + "0x59d65c9b948dab08f5c3604fb8b4d15085e4ae6ea8e762bbcceb904b3d9b5837977c4c9f2b9e9f3f8c6babd3b5e846ed8bdad898648bc4f8ccbea95d7a9cf5fd694e6b1a176058fbb30257aafa296741ab7181398c43a264a94972c08b4a5c56807a5f06b5b88eb420df822b43c43b400d0", + "0x284221095208080003c41080b0200c529cc5740004001a17400852a000520868202140237081018c42822008484000094058428070190495b008b00082800802000b400c0", + "0x59d65c9b948dab08f5c3604fb8b4d15085e4ae6ea8e762bbcceb904b3d9b5837977c4c9f2b9e9f3f8c6babd3b5f9d6ed8ffedb99ed9ffdfadffef9dffefffdffefee6f1e776a5ffbfb0a57effa6d6fdbef75dd7ddcf7baffeb7b7ad1ef7bfcf7807e5f6efdf9aeb461ff8eff5fd6ff755d7", + "0x59d65c9b948dab08f5c3604fb8b4d15085e4ae6ea8e762bbcceb904b3d9b5837977c4c9f2b9e9f3f8c6babd3b5d194cc86acd391ed9c39ea5f4ed9d3ac63388befea6f04602a57a95b0a05e7924d4e9bcc055c7c50b538dfe3333ad1e63ba4b5000e466a6849a604617d0ef75dd6f435517" + }, + { + "0xcf08fe64414998cc59938913e660f0f9b221f459cd8e04126cf902d0b6cea0edc26164b9d84e9ce7dfe058c1fe0fb452848616368c3", + "0x234286d14c1098ea9fd7f83508641ef3288da679fce09dd1359514ebf0dbcdc73b8f7f6171762d3d5df6492591c9386", + "0x4000910810806090d1b02100400c820000247900c094c0208500616099c84618875f6050402c0d145200041000082", + "0xcf08fe644149bbcedfd3cd13feeafffffa35fc7ddfff2c9feef9fef0bfdfb5fdd6ebf4fbddcfbfefffe179f7ff3ffdf6cda797ffbc7", + "0xcf08fe644149bb8edf42c5037e8a6f2e4a14fc3dd37d2c9fca80fe302b1f9578d68a94621589a768a08129b7d332e9a4cda387ffb45" + }, + { + "0x343e32e61b86c0c7cc895cf233ea3d5b5ad65435c1f87e034b59788a9af14ffae9249f1f3cfe0789abbe8edc8ce", + "0x63f7afb1dcebc9d65f9d468754ea558119988cb7d85e427003f2c1d9b360d2c75b97c1308ee3a7b5901044c6353e14f3e6b54a2ead64acdf914c6f7b6d4ed3205abdc78aa7bb47d548607b4ffe1db7331aac39c8bc7fcfd62238467352656a3ad04a423", + "0x241e10440b024046c00058b0038a251b42d4402041487e010311188818c00c7ac9040218047202012a3a8048002", + "0x63f7afb1dcebc9d65f9d468754ea558119988cb7d85e427003f2c1d9b360d2c75b97c1308ee3a7b5901044c6353e14f3e6b54a2ead64bcffb3ee7fffedcfdfa95efff7eabffb5fd75c75fbfffe1fff7b7aaebbf9ffffeff6bf3f7eff57edebbededecef", + "0x63f7afb1dcebc9d65f9d468754ea558119988cb7d85e427003f2c1d9b360d2c75b97c1308ee3a7b5901044c6353e14f3e6b54a2ead6498e1a3aa74fdad891fa9064ff4609ae01d031c55bab7801efc6a6226a339f38526f2bd277a8d55ecc1845e96ced" + }, + { + "0x981ba5db1da1fe952887e32cd21d51ba024022c8d837ec00f9772a111f87644012cee4a01f66d09ef168ebdfb91232e9e8f65d63ee7e6e050ae9707e7b15df4f8037b0d8d427f32429a45312a24081ed5a9c8ec22358f3621c961349638f30e049d00d513901fe065d5364f4cfca93f14a2b1b", + "0x1ba08accd8474ea8d9dc2f10d3c2c2edcbf9c3a909ab45", + "0x38000c048400c0019002e00514240e4cbc883a1082b01", + "0x981ba5db1da1fe952887e32cd21d51ba024022c8d837ec00f9772a111f87644012cee4a01f66d09ef168ebdfb91232e9e8f65d63ee7e6e050ae9707e7b15df4f8037b0d8d427f32429a45312a24081ed5a9c8ec22358f3621c9613497bafbaecd9d74ff9f9ddff16dfd3e6fdcffbd3f94bab5f", + "0x981ba5db1da1fe952887e32cd21d51ba024022c8d837ec00f9772a111f87644012cee4a01f66d09ef168ebdfb91232e9e8f65d63ee7e6e050ae9707e7b15df4f8037b0d8d427f32429a45312a24081ed5a9c8ec22358f3621c961349782fba2c919743f9e0ddd1168e91a6190433505843805e" + }, + { + "0x1d9992a4fce731fe937e70ec9efba437b1efa9e5459e3145f8c9142c6988eca9a61273750bcc1f00a64b32bab5a3a4c89858231f4fedce7a73bcc7285bbd18b328ccc298919f5511e973cd124f7e1c3912d52f4593c676f1c3f87a521", + "0x6e195204da93bdade43f0622217647326502417d70305d050d988", + "0x421810045011a921c412062200300210250001447030410008100", + "0x1d9992a4fce731fe937e70ec9efba437b1efa9e5459e3145f8c9142c6988eca9a61273750bcc1f00a64b32bab5a3a4c89858231f4fedce7a73bcc7285bbd18b328ccee99d39fdf93fdffed3f4f7e3d7f57f76f47d3ff76f1dffd7fda9", + "0x1d9992a4fce731fe937e70ec9efba437b1efa9e5459e3145f8c9142c6988eca9a61273750bcc1f00a64b32bab5a3a4c89858231f4fedce7a73bcc7285bbd18b328ccac81c39b8f8254de292d495c3d4f55e74a47d2bb06c19efd77ca9" + }, + { + "0x123b8aaf5660144d596f10574b4c232f267222596831", + "0x10ab460448ce805f18a3c1d64fc8cc0c02b2cd5f860d462e33602f09fd131e5468c86997e5a033729b2a03d3c284ee0111488ea", + "0x1021028c0600144801270012000c2028066000100820", + "0x10ab460448ce805f18a3c1d64fc8cc0c02b2cd5f860d462e33602f09fd133ffceafd6f97e5f5b7f39f7eb7d3f2f6ef2335de8fb", + "0x10ab460448ce805f18a3c1d64fc8cc0c02b2cd5f860d462e33602f09fd123decc23d0f96a175a5839e5eb711f076892334de0db" + }, + { + "0x17529608c59c36277d9e89f9b275032e62ab42b4dc006f1943e12b088c36657b02937109db797e2fbb83c984f507841be083c5e36dd04a8b7d3", + "0x1d556659e3b765044e08b1f7879bf057ef", + "0x1814004940304104080810368500a017c3", + "0x17529608c59c36277d9e89f9b275032e62ab42b4dc006f1943e12b088c36657b02937109db797e2fbbd7dfe5ff3ff65be4e3cfff7df9ff8f7ff", + "0x17529608c59c36277d9e89f9b275032e62ab42b4dc006f1943e12b088c36657b02937109db797e2fba569fe16b3cf24ba4634efc15a9f58e03c" + }, + { + "0x23ed0547893da2de2673832f9e6d988ce38c44a47495c1e0a714eb2f18ec455157cc20ea9da75cdcb0c4e9afa546efb3650b7e5cb7e659359d17fe79d2d5116bcd6c5cca45e0719d063e7df33f6788e5c6bd77c114340748cf553c5aa4992076953c4904181e24bb7c26a6e895d8b808c70133b52c9ca4a2266c2e2302bf777", + "0x3eaf5dd3cbba83558163fd16469a3d64905ff28ee65c15ff01f4d720b1ad669a893671bb614382f2331985333b0af52cbc0af22e50e4cb39d4ab3ad58127b3c481e692bb22dc0b497690e57e6fc84a87c2e1eb85e6c8bfc253fd497fc88", + "0x20aa1d83489880448123a50646922500105cb286401415170070d20011294408080241a061010232311105230800c42c340010240040cb11140a2091002691040104101a20980800268085582808420102a12884a48026400221003f400", + "0x23ed0547893da2de2673832f9e6d988ce38c44a47495c1e0a714eb2f18ec455157cc3eefddf7dffeb3d5e9effd56efbb7d6ffe5ff7eeff7d9dfffffdd7f5b1efeffeddfe75fb71df86fe7ffbbf77bbeff7bdffcbf63e57eccf7dfcfbbedda177b7fcc9e69abf26ff7f6ff6f8f5feffc8cf87f3f5ef9de6eabfee7fff4bfffff", + "0x23ed0547893da2de2673832f9e6d988ce38c44a47495c1e0a714eb2f18ec455157cc1e45c0749766339168cc5850a929586fee034568bf6988e8ff8d05f5a0c6abf6d5fc345b10de84cc4eeaba54b3ef3391cbcbe61a57ac046ce8f19e4ca15126f8c8e28aa50667776fd07870a6d7c08d86f154c719426a99ae7dde4bc0bff" + }, + { + "0x4881b1172db56487aa0b4362479871a57", + "0xd40bc374f241c2bb638ed6dea08d7885135052619d2f58523b3218b57371993a62bea6cfc8abf4abb8e4a96b0a38bbffffdd0bc5e5a6514f0db", + "0x4081210228b16487880b4160061041053", + "0xd40bc374f241c2bb638ed6dea08d7885135052619d2f58523b3218b57371993a62bea6cfc8abf4abb8eca9fb1f3dbfffffff0bc7e7e7d97fadf", + "0xd40bc374f241c2bb638ed6dea08d7885135052619d2f58523b3218b57371993a62bea6cfc8abf4abb8ac28da1d150e9b7877008687e1c93ea8c" + }, + { + "0x1e0e22b43b6de9f7ee3000e87eef492f84ee1bcd3f490cdbf35171b174335fe53afa9b752d9b1e1b0bd58d71d35687cb7b74", + "0xac57c7cfa532414e1182c7c499ffa996f7a28187f7f5d7586f0fd6b64e566bff1ff68daa60d7b650cfece99b8e2551941008aaa5ab966c526d584251600baf9f48d6b573e2779363363cea427961c0ac63d9c9abcc30976c3755b739dcbcccfbb7ae06b5deed54c59a5271caaa26134877898f75b065f3c72a8429ab5", + "0x40602140a4429948a30000876c3410b008c0bcc0f0908c0635160914411052518aa82612483181803510451105280421a34", + "0xac57c7cfa532414e1182c7c499ffa996f7a28187f7f5d7586f0fd6b64e566bff1ff68daa60d7b650cfece99b8e2551941008aaa5ab966c526d584251600baf9f48d6b573e2779363363cebe2fb6bc3beffdfffebcc3e97eef7d7ff7ffdbcdfffb7efbfb5dfff57c7bffe73efabb753d9f7e9bffdf8f7fff76afcbfbf5", + "0xac57c7cfa532414e1182c7c499ffa996f7a28187f7f5d7586f0fd6b64e566bff1ff68daa60d7b650cfece99b8e2551941008aaa5ab966c526d584251600baf9f48d6b573e2779363363ceba29b4a831abd46b748cc3e1082c3c74f773d001f0f2763b980c9f64386afac226503914191c6683fc8e8b2eef242f89e1c1" + }, + { + "0x46529c1d4b03b4a0efd29ce200ce9564cdc4fa4b53b9b6725e3fffe3454d6e53848fa573858f0bdbcf846d790a5bfc7470d0b8ac1d494804fa7048b869d5e016e389bf93cb959469dca3f4c5e93f8bcb7dbb64bcec19c8d9dbc5f2cecb285d81f5fefe99ff4564662c7cc275a40f0ea519adb2", + "0x1b10fed79bfd5e52ba14eea13cf223bfbeb5f42bd781083545c4306ed5f69250efc19707288aadf9df45b4056a293da0cfae076ee9b08e7a7058ef0a58e67149980cdc60a75825607ec4e531e9d036e71e3df52048853e3", + "0x1010d6c518485a523810e0a13cf0029790a5b4034701080041c4100045a6000086811601280889f91c01100408083d004e82002ca190864a40408c0818a4510888008440075825601ec4440060c004271a00f02040801a2", + "0x46529c1d4b03b4a0efd29ce200ce9564cdc4fa4b53b9b6725e3fffe3f54fef7bbfdfe57ba5cfebdbcfa67ffbeb5ffefd78d0bbfc5d4b4eedff796dbefdddf076ebabff9fffdfd47ffeb3fecdfbffffefffbbe7bfed9ff8fddfe7f6dfcbeddf8bf5fefe9fff4f777ebd7fee75e7df5ea599fff3", + "0x46529c1d4b03b4a0efd29ce200ce9564cdc4fa4b53b9b6725e3fffe2f442832a3b5a405824c1e1c800a65682e104bec908c03bf8410a4ee9a5196db695cc90646b23600e3fced43f7e302ec913dffd25e6b3831be997387c55a2e6574be59b8b807ca89e130b3778b17fac0447d05ca191fe51" + }, + { + "0x1c61ea1ba6135d29a669cc258f24a09ce0c6af1fa717", + "0x277557a8f45578e7730c64350cd3fd389bf96320fb3079402e9949062868fda63a6c371adf34952bd8fbf8a361671041556548ecabc7561f3febfcf26290dc819caa54b8eb26a7fb3a593202b2eb9a87fa214342ea4d639c3487882c7b6a03401d0715171c8ec44d45eff0c2571ca3f556d0d986fbeb5ff", + "0x10416008a4005408a60804218a24000c00802f1ea517", + "0x277557a8f45578e7730c64350cd3fd389bf96320fb3079402e9949062868fda63a6c371adf34952bd8fbf8a361671041556548ecabc7561f3febfcf26290dc819caa54b8eb26a7fb3a593202b2eb9a87fa214342ea4d639c3487882c7b6a03401d07d71fbdbee57dd7fff6ded75cf3ff5fdeddeefbfb7ff", + "0x277557a8f45578e7730c64350cd3fd389bf96320fb3079402e9949062868fda63a6c371adf34952bd8fbf8a361671041556548ecabc7561f3febfcf26290dc819caa54b8eb26a7fb3a593202b2eb9a87fa214342ea4d639c3487882c7b6a03401d06d309bd34a5789775965e954451bf5f1ed5ec0a112e8" + }, + { + "0x259856f9c56582b4f8056fdbd37332ff6684ad104683782087ef2b965fa2d22153ca880d735c116878afac5b2477b7f", + "0x1518494828299164e2ee455afe73cd24484df0def1e24c01926bdb2566d44e483a04bbdd5aeab159678305b6ade08cb5bc83e0e63a7bd9e2bb016c355f0fd9e94044e8e9dd380c64ea2f83d239d0987a6864dd1a07c9d742", + "0x20105268c4008210c8040e438331122b2004811040811800044e0a945380c20002c8080111080120000d80002415342", + "0x1518494828299164e2ee455afe73cd24484df0def1e24c01926bdb2566d44e483a04bbdd5aeab15967db85ffbdf6dcbfff83f6ffbf7ffbefff696ef55f6fffeb487efaf9fdfa2d66ff3fabd2fff5d97eefeeffdfb7cfff7f", + "0x1518494828299164e2ee455afe73cd24484df0def1e24c01926bdb2566d44e483a04bbdd5aeab15965da80d931b6d49ef303b61b874ceacd4d6926e45b67ee6b483a1a50b8c22146ff132b52eee5596cefee27dfb58eac3d" + }, + { + "0xd8526c4a399bb415b422ab254fb7c9a053c1507e3260aac195366c5fed9ff583053547f1b8f54561838e8d5fff273e25", + "0xdc8169197ca1b7f60394685c3438a5b9ff07c0deafe3d68064567be3d9ad3c577600e0d98c4bda37a6ed8175d437cded052bdf221c4c3d76221331061", + "0x4002480a30180400b42028044527882012c14076200008808434205a6c981501013446d010b540218082854221231021", + "0xdc8169197ca1b7f60394685c3dbda7fdff9ffbdfffe3feb274ff7ffbddbd3d57f726eafd9d5bfef7fefdff7df477ddff1fafdf761c7cfdf7fff373e65", + "0xdc8169197ca1b7f60394685c39bd837d5c9e7b9ff4a1fc3230ad0779dc9129509526ea759518bcf258347e2de46499921ea48b740474d5a3dde142e44" + }, + { + "0x47ac96c78ee0c7a9906ce5af63d0ad1b0420e1ca783cc6904ee84", + "0x630297e0f122e36f0c5f2f34efbb078c2f4c00e7c16f96cb054", + "0x20028780e002a1000c452f20c0a90304204000600046904a004", + "0x47ef96d7eef1e7ebff6cffaf77ffbf1f8c2fedcafffdef96cfed4", + "0x47cf94506e11e54aff60ba80573f161c880fadca9ffda90685ed0" + }, + { + "0x432a40ea48fcb8b8161bc19a26b544f54833bf5e005c7d1c19e8405c5464c8c139fdd9b627865e596c513fc68454827f070310dd7efe80306693ce441c89a74d91db5e27d6ba966aa1e109cc8385bd86a23d127cf609eea4118e0e1d9be83b561dcffb0ec3844d22", + "0x70d78d38ebcadb77733fc709a6d3b76576ca71acd7e3196640d6adc00225142070b943d5624a3a3d4e77a787d8221848ab06c5135", + "0x50c7880002481864410882008011b560744a212482021004401009c002211020402002c0400820214836838540001800a80044120", + "0x432a40ea48fcb8b8161bc19a26b544f54833bf5e005c7d1c19e8405c5464c8c139fdd9b627865e596c513fc68454827f070310df7ffed3befebfff773ffdf7dffdfb7e77febf9eeffff19fec8feffd86a27d527fff9dfff635afafddfffa7b7f9fefff8ef3ec5d37", + "0x432a40ea48fcb8b8161bc19a26b544f54833bf5e005c7d1c19e8405c5464c8c139fdd9b627865e596c513fc68454827f070310da738653beda3e79332f75d7d7fce02870ba1d8ca7dfd09fa88eef6186806c507bfd9dd3f2352dadc97c92432b9fee7f8473e81c17" + }, + { + "0x7c4c2d104ca2a5c080fbf1e717e47f848ff9be3555bcff60c07907ade9e334a556157dcd28ebbfd73367defdc4d8f5de60815360394e4de6e7535d356ccb8a2d896157ba65a7e8541a06e604454aef3e8cebfc7aedb48466eb65039cf17c13fcdb1b", + "0x2a73b2854f05d043d4e28e0b2634fd7023aaf3e57e58f213dd0693769", + "0x2a0100804e00404084e2880a2604ac50000262a45018c213c10681309", + "0x7c4c2d104ca2a5c080fbf1e717e47f848ff9be3555bcff60c07907ade9e334a556157dcd28ebbfd73367defdc4d8f5de60815360394e4de6e7535d356ccb8a2d896157ba65a7ef7f3a56f65d457fef3eecfbff7fffb6beefff77e79ff17dd3fdff7b", + "0x7c4c2d104ca2a5c080fbf1e717e47f848ff9be3555bcff60c07907ade9e334a556157dcd28ebbfd73367defdc4d8f5de60815360394e4de6e7535d356ccb8a2d896157ba65a54f6f325216594177a1166c599f353ab6bec9d532e613d041c395ec72" + }, + { + "0x3ee957090c3ab10e1c8af669f2093bba430a4322a741522d2ce1d20b07558298627de3dbbbef8828abc64195bad0f9f6acbb734a420d0d8dd330e90d23ab633826a612060eb95070758199006b547b24792d59f97c3191b2dee7a96e", + "0x7e30cfb7abf89648583c2f705f30abb997ded579a0de3172e2b546c920f92fbdf3bf5ffbd5d73620da518e7b4964a44505817d16c7028f4da494135d2589deffbfdb19f6a454f0431cda1884e51f48c67605f9f044e955a4f23da9dfa92af8dfba09ea6adf0390c", + "0x4e102090838a1061808e20122091028020a02228701502d2c415202050500802014424010480000284000949a4041348018114a420d018d42004904218921080600100406205010040091004b005a0478000989782090a28ce0290c", + "0x7e30cfb7abf89648583c2f73ffb5fbb9d7ffd5f9e8ff77ffe2b7ffed30fd3fbff7bf7ffbdfdf36b0ff59afff6ffebdffbff9ff9eff669f5fad9f9f7fefbffeffbfdbd9ffb75ef0d33efe3b86ef7f68e6ff95fff75cf9d5a6f77fbbdfbbffffdffb19fb6fff7b96e", + "0x7e30cfb7abf89648583c2f73b1a5db295475c598687157edc226fd6d105d1d9787aa7d291bca1690af09a7fd6eba99febb79ff9c7b669616099b8c37ee3eea5b9f0bc12b975a6091266c2b068f7e68a69d90fef71cf0c5a2477a1b983bff67487910f1473179062" + }, + { + "0x20265b43c9319cd56eac6a02cbf7913ba44b", + "0x995b92e854a8e0d548bfc02e18529b37790f0e4d9aaf36e7abc4a0f1e6d69489215aaa61b5863b1c86b3536b443dc639d1eb3db7789c2cb2f8cad1a74e5168ef33948c81a06fbad3b9ab0b7c84045cd1f77620ef43c7f2088d2901917bec5346a44f679be9491d273dbe5bf6e39095bb411cac63e38626013d671445c", + "0x20261901493010c0462c2802401390310448", + "0x995b92e854a8e0d548bfc02e18529b37790f0e4d9aaf36e7abc4a0f1e6d69489215aaa61b5863b1c86b3536b443dc639d1eb3db7789c2cb2f8cad1a74e5168ef33948c81a06fbad3b9ab0b7c84045cd1f77620ef43c7f2088d2901917bec5346a44f679be9491d273dbe5bf6e7b4bdbb59ddfeebe7a62ebf7d77be45f", + "0x995b92e854a8e0d548bfc02e18529b37790f0e4d9aaf36e7abc4a0f1e6d69489215aaa61b5863b1c86b3536b443dc639d1eb3db7789c2cb2f8cad1a74e5168ef33948c81a06fbad3b9ab0b7c84045cd1f77620ef43c7f2088d2901917bec5346a44f679be9491d273dbe59f48624a92858d1fa8925260abe4474ae017" + }, + { + "0x20a92c71c161a786989694109718416d7a291b8f9c71a5a71ee827e003a5a19cf2aa8faeecbfa231c330e2d4c747b75ccc4d43d8c37472b60", + "0xc2ba3ef844b62f020cd6e4b010499c2c28ab3c15ed2ef3114e5b806244e57be1a7d999a21399c1e950977f021c82a906bed39caeec6aa077628421f9d5dfed01b24fe857000e259537fbe07d6a83080080ae927512d4518f9a56f0a40376234855377d8ef40dcb6055bd8d351", + "0x20282071400021809096840092084045000801851471a0250a80000000a480141280018e8816a020033022404507350cc40d4340413400340", + "0xc2ba3ef844b62f020cd6e4b010499c2c28ab3c15ed2ef3114e5b806244e57be1a7d999a21399c1e950977f021c82a906bed39caeecebac77e3e5a7ffdddffd11b75fe97f7a2f3f9fbffbe5ff7eeb2fe083afb3fdf2fedfaffefff2b5c376e3dcd777ffdefc4dcbf8d7fdffb71", + "0xc2ba3ef844b62f020cd6e4b010499c2c28ab3c15ed2ef3114e5b806244e57be1a7d999a21399c1e950977f021c82a906bed39caeccc38c06a3e5867f4d4979112557a93a7a273e1aab8a45da746b2fe0830b33e9e07ede2176e95295c046c19c9270cad2384088b896c9ff831" + }, + { + "0xf6b7f399370d10b097b17e514f044d77a8f170148f4837033bb5d425f73a4079e1c7a9c3e69246f902d8c9fd27caad1e93d83578d4af8d3b7b1c02041c44917a22ed56f2562ac1426a356f8d31965e8e367b8929f3907b1dc6e73a8f3a566ca5c4e113e9d2c53770b110df51cf504701ff3fcea5b819b9bfc49f", + "0x61989df2b7097a6a84dc016aec2716d9cac359d2d799d90ec006a66efe3f1fd0851978c4cfe2f64b307b852e23f5dfdc2f63196e1076782a228a46f5f7d4e54afc1ad7abf1f8fef46edaad1706956f95eb95953bd4", + "0x990290097822808c0002c82510d08a8119521400000c40002222ec1612500001404005628401105a8426238109d0006319460032082a020804c4e110e142c41250a110d850c440420117068425900991950094", + "0xf6b7f399370d10b097b17e514f044d77a8f170148f4837033bb5d425f73a4079e1c7a9c3e6f3defdf2ffc9ff6fcefd1ffbfc377eddefcf7bfbdf9bdd1ec497fe6eff7fffd6afd97aeeffefff7bb67f8f3e7bfdffffbf7b1deef77eff3a76eee7f5f7d7eddafd3ff7bbf1ffffff7edfadff3fdfefbdfbbdbfffdf", + "0xf6b7f399370d10b097b17e514f044d77a8f170148f4837033bb5d425f73a4079e1c7a9c3e6f3de64f06fc0874d4e711ff934126e0d654e62a9cb9bdd128497dc4c1369ed86afd83aaefa8d7b7aa6250b18587cf62fbf1804a8f74cf71074e6e33116c70c98392da71ae127af3b3e9dace8395bca2df22c2aff4b" + }, + { + "0x31d126e874580b754389fad8b64aaa61cabb4f8eb6904fe7e504341ed903f7daa3e74d4da3afca80b2415672a", + "0x16fb17a0468c0afa6bad456efa4f9baf26860eda9d7c00c2520c8c9b6026fb50df59b8cb74f6d9be861052c5e831158e7ffd98746328ce11f91d9ea22f0803a8b059aea22d1715ca1abeae53a8bc6b8bfb9b6c9d24ae714767", + "0x11100e0745803440288e0189048aa20c0800a8a04904a22c10014008902e51a83c6080da1a6c880024114722", + "0x16fb17a0468c0afa6bad456efa4f9baf26860eda9d7c00c2520c8c9b6026fb50df59b8cb74f6d9be861052c5eb3d17eefffd98f77738dfbdfb7dbea63fabb7f8fb79aefe7f5757cbffbebf7faabe7fdffbbbfcbd2fae75676f", + "0x16fb17a0468c0afa6bad456efa4f9baf26860eda9d7c00c2520c8c9b6026fb50df59b8cb74f6d9be861052c5eb2c07e0f8b818c3371051bc7279340433a3b7505b30aa5c5347568bf72e912e02821f5f21a190352f8a64204d" + }, + { + "0xbf1a14e469c234b72d56324d100e016bc38cdf7158e35f230c047585e7b107acc8e222e7f19552541e59316affd90e96ca657b6112f5e8c786dfcff342fc46252fcdab10c632578540dbf6235f164bc5711924c7c6ba9da85ab", + "0x5dd3fb9a3de26cd89eb9517af6bb25678f149f906e8751a0c20d7646d21c17191237022a990e0156541e376986fd6a680c60228e5955df08bae5789c81751cdcafe5a2e72d45b09", + "0x5d5158821d220c001481413006a800620204919042041000000876400214020112210220880600564412026806252a480800020251054008b22158140145101824c582a20d00109", + "0xbf1a14e469c234b72d56324d100e016bc38cdff3fbfb7fe36cdcffbdf7fbf7bfede7aff7ff957ed75ff9f36fffdfde9edf7d7b7712fff9cf87dfdfff77fdc6fd6fedaf70e6be5fd5dfdbfee77f9ecbf57dddafe7e6ffbdedfab", + "0xbf1a14e469c234b72d56324d100e016bc38c82a2a37962c160dceb3cb6cbf117ed85adf36e053cd34ff9f367899fdc8add7c695610df71c987899bed7595c0d845a5a770e4bc0ed09fd34cc6278acab06dc58b22645db0edea2" + }, + }; + + bool opa=true, opo=true, opx=true; + + //////////////////// AND //////////////////// + + for (size_t i=0; i and + // Exponentiate(). It can easily consume all machine memory because it is an exponentiation + // without a modular reduction. + + // ****************************** DivideByZero ****************************** + + { + try { + Integer x = Integer(prng, 128) / Integer::Zero(); + result=false; + } catch (const Exception&) { + result=true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + // The 0*0 % 0 test. + { + try { + Integer x = 0; + Integer y = 0; + Integer z = ModularMultiplication(y, y, x); + result = false; + } + catch(const Integer::DivideByZero&) { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + // Another 0*0 % 0 test. + { + try { + Integer x = 0; + Integer y = 0; + Integer z = (y * y) % x; + result = false; + } + catch(const Integer::DivideByZero&) { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + // The 0^0 % 0 test. + { + try { + Integer x = 0; + Integer y = 0; + Integer z = ModularExponentiation(y, y, x); + result = false; + } + catch(const Integer::DivideByZero&) { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + // Another 0^0 % 0 test. + { + try { + Integer x = 0; + Integer y = 0; + Integer z = EuclideanDomainOf().Exponentiate(y, y) % x; + result = false; + } + catch(const Integer::DivideByZero&) { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + // Integer divide by 0 + { + try { + Integer r=1, q=1, a=1, d=0; + Integer::Divide(r, q, a, d); + result = false; + } + catch(const Integer::DivideByZero&) { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + // Another Integer divide by 0 + { + try { + Integer q=1, a=1; word r=1, d=0; + Integer::Divide(r, q, a, d); + result = false; + } + catch(const Integer::DivideByZero&) { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer DivideByZero\n"; + } + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Integer DivideByZero\n"; + + // ************************ RandomNumberNotFound ************************ + + try { + // A run of 71 composites; see http://en.wikipedia.org/wiki/Prime_gap + Integer x = Integer(GlobalRNG(), 31398, 31468, Integer::PRIME); + result=false; + } catch (const Exception&) { + result=true; + } + + pass = result && pass; + if (result) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Integer RandomNumberNotFound\n"; + + // ************************ Carmichael pseudo-primes ************************ + + result=true; + if (IsPrime(Integer("561"))) + result = false; + if (IsPrime(Integer("41041"))) + result = false; + if (IsPrime(Integer("321197185"))) + result = false; + if (IsPrime(Integer("5394826801"))) + result = false; + if (IsPrime(Integer("232250619601"))) + result = false; + if (IsPrime(Integer("974637772161"))) + result = false; + + pass = result && pass; + if (result) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Carmichael pseudo-primes\n"; + + // ****************************** Integer Double ****************************** + + try { + Integer x = Integer::One().Doubled(); + result = (x == Integer::Two()); + } catch (const Exception&) { + result=false; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer Doubled\n"; + + // ****************************** Integer Square ****************************** + + try { + Integer x = Integer::Two().Squared(); + result = (x == 4); + } catch (const Exception&) { + result=false; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer Squared\n"; + + try { + Integer x = Integer::Two().Squared(); + result = (x == 4) && x.IsSquare(); + } catch (const Exception&) { + result=false; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Integer IsSquare\n"; + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Squaring operations\n"; + + // ****************************** Integer GCD ****************************** + + { + for (unsigned int i=0; i<128; ++i) + { + Integer x, y; + switch(i%2) + { + case 0: + { + AlgorithmParameters params = + MakeParameters("BitLength", 256)("RandomNumberType", Integer::PRIME); + x.GenerateRandom(prng, params); + y.GenerateRandom(prng, params); + break; + } + case 1: + { + x = MaurerProvablePrime(prng, 256); + y = MihailescuProvablePrime(prng, 256); + } + } + + if (x != y) + { + result = (RelativelyPrime(x, y) == true); + pass = result && pass; + + if (!result) + std::cout << "FAILED: Integer GCD\n"; + } + } + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " GCD operations\n"; + } + + // ******************** Integer Modulo and InverseMod ******************** + + // http://github.com/weidai11/cryptopp/issues/602 + // The bug report that uncovered the InverseMod problems + { + Integer a("0x2F0500010000018000000000001C1C000000000000000A000B0000000000000000000000000000FDFFFFFF00000000"); + Integer b("0x3D2F050001"); + + result = (Integer("0x3529E4FEBC") == a.InverseMod(b)); + pass = result && pass; + if (!result) + std::cout << "FAILED: InverseMod operation\n"; + } + + // Integer Integer::InverseMod(const Integer &m) + // Large 'a' and 'm' + for (unsigned int i=0; i<128; ++i) + { + Integer a(prng, 1024), m(prng, 1024); + a++, m++; // make non-0 + + Integer x = a.InverseMod(m); + Integer y = (a % m).InverseMod(m); + Integer z = (a * y).Modulo(m); + + if (RelativelyPrime(a, m) == true) + result = (x == y) && (z == 1) && (ModularMultiplication(a, x, m) == 1); + else + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: InverseMod operation\n"; + } + + // Integer Integer::InverseMod(const Integer &m) + // Corner cases like 0, 2m-1 and 2m+1 + for (unsigned int i=0; i<128; ++i) + { + Integer a(prng, 1024), m(prng, 1024); + a++, m++; // make non-0 + + // Corner cases + int j = i % 12; + switch (j) + { + case 0: + a = -1; break; + case 1: + a = 0; break; + case 2: + a = 1; break; + case 3: + a = m-1; break; + case 4: + a = m; break; + case 5: + a = m+1; break; + case 6: + a = 2*m-1; break; + case 7: + a = 2*m; break; + case 8: + a = 2*m+1; break; + case 9: + a = (m<<256)-1; break; + case 10: + a = (m<<256); break; + case 11: + a = (m<<256)+1; break; + default: + ; + } + + Integer x = a.InverseMod(m); + Integer y = (a % m).InverseMod(m); + Integer z = (a * y).Modulo(m); + + if (RelativelyPrime(a, m) == true) + result = (x == y) && (z == 1) && (ModularMultiplication(a, x, m) == 1); + else + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: InverseMod operation\n"; + } + + // Integer Integer::InverseMod(const Integer &m) + // Large 'a', small 'm' + for (unsigned int i=0; i<128; ++i) + { + Integer a(prng, 4096), m(prng, 32); + a++, m++; // make non-0 + + Integer x = a.InverseMod(m); + Integer y = (a % m).InverseMod(m); + Integer z = (a * y).Modulo(m); + + if (RelativelyPrime(a, m) == true) + result = (x == y) && (z == 1) && (ModularMultiplication(a, x, m) == 1); + else + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: InverseMod operation\n"; + } + + // Integer Integer::InverseMod(word m) + // Small 'm' using word + for (unsigned int i=0; i<128; ++i) + { + Integer a(prng, 4096); word m; + prng.GenerateBlock((byte*)&m, sizeof(m)); + + a++; // make non-0 + if (m == 0) m++; + + // Avoid the conversion from word to long + Integer mi = Integer(Integer::POSITIVE, 0, m); + Integer ri = a % Integer(Integer::POSITIVE, 0, m); + + Integer x = Integer(Integer::POSITIVE, 0, a.InverseMod(m)); + Integer y = Integer(Integer::POSITIVE, 0, ri.InverseMod(m)); + Integer z = Integer(Integer::POSITIVE, 0, (a * y).Modulo(m)); + + if (GCD(a,mi) == 1) + result = (x == y) && (z == 1); + else + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: InverseMod operation\n"; + } + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " InverseMod operations\n"; + + // ****************************** Integer Divide ****************************** + + // Divide (Integer &r, Integer &q, const Integer &a, const Integer &d) + for (unsigned int i=0; i<128; ++i) + { + Integer r, q, a(prng, 1024), d(prng, 1024); + Integer::Divide(r, q, a, d); + + Integer xr = a % d; + Integer xq = a / d; + result = (r == xr) && (q == xq); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Divide operation\n"; + } + + // Divide (word &r, Integer &q, const Integer &a, word d) + for (unsigned int i=0; i<128; ++i) + { + word r, d = prng.GenerateWord32(); + Integer q, a(prng, 1024); + Integer::Divide(r, q, a, d); + + Integer xr = a % Integer(Integer::POSITIVE, 0, d); + Integer xq = a / Integer(Integer::POSITIVE, 0, d); + result = (Integer(Integer::POSITIVE, 0, r) == xr) && (q == xq); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Divide operation\n"; + } + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Divide operations\n"; + + // ****************************** Integer Power2 ****************************** + + { + Integer x, y; + + x = Integer::Power2(0); + result = (x == 1); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Power2 operation\n"; + + x = Integer::Power2(1); + result = (x == 2); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Power2 operation\n"; + } + + for (unsigned int i=0; i<128; i+=2) + { + Integer b = 2, m(prng, 2048); + + Integer x = EuclideanDomainOf().Exponentiate(b, i) % m; + Integer y = Integer::Power2(i) % m; + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Power2 operation\n"; + } + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Power2 operations\n"; + + // ****************************** Integer Exponentiation ****************************** + + { + word32 m = prng.GenerateWord32(); + if (m == 0) m++; + + Integer z = Integer::Zero(); + Integer x = ModularExponentiation(z, z, m); + Integer y = EuclideanDomainOf().Exponentiate(z, z) % m; + result = (x == y) && (x == 1); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + // The 0^0 % 0 test. + { + try + { + Integer x = 0; + Integer y = ModularExponentiation(x, x, x); + result = false; + } + catch(const Integer::DivideByZero&) + { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + // Another 0^0 % 0 test. + { + try + { + Integer x = 0; + Integer z = EuclideanDomainOf().Exponentiate(0, 0) % x; + result = false; + } + catch(const Integer::DivideByZero&) + { + result = true; + } + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + // Run the exponent 0 to 128 on base 0 + for (unsigned int i=0; i<128; i+=2) + { + Integer b = 0, m(prng, 2048); + + Integer x = ModularExponentiation(b, i, m); + Integer y = EuclideanDomainOf().Exponentiate(b, i) % m; + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + // Run the exponent 1 to 128 on base 2 + for (unsigned int i=0; i<128; i+=2) + { + Integer b = 1, m(prng, 2048); + + Integer x = ModularExponentiation(b, i, m); + Integer y = EuclideanDomainOf().Exponentiate(b, i) % m; + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + // Run the exponent 0 to 128 on base 2 + for (unsigned int i=0; i<128; i+=2) + { + Integer b = 2, m(prng, 2048); + + Integer x = ModularExponentiation(b, i, m); + Integer y = EuclideanDomainOf().Exponentiate(b, i) % m; + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + // Run the exponent 0 to 24 on random base + for (unsigned int i=0; i<24; ++i) + { + Integer b(prng, 32), m(prng, 2048); + + Integer x = ModularExponentiation(b, i, m); + Integer y = EuclideanDomainOf().Exponentiate(b, i) % m; + result = (x == y); + + pass = result && pass; + if (!result) + std::cout << "FAILED: Exponentiation operation\n"; + } + + if (pass) + std::cout << "passed:"; + else + std::cout << "FAILED:"; + std::cout << " Exponentiation operations\n"; + + return pass; +} +#endif + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat3.cpp b/external/ours/library/crypto/src/shared/original/validat3.cpp new file mode 100755 index 000000000..f941ce5c4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat3.cpp @@ -0,0 +1,1341 @@ +// validat3.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "rng.h" +#include "drbg.h" +#include "darn.h" +#include "osrng.h" +#include "rdrand.h" +#include "mersenne.h" +#include "padlkrng.h" +#include "randpool.h" + +#include "gzip.h" +#include "channels.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_VER >= 1500) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +bool ValidateAll(bool thorough) +{ + bool pass=TestSettings(); + pass=TestOS_RNG() && pass; + pass=TestRandomPool() && pass; +#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE) + pass=TestAutoSeededX917() && pass; +#endif + // pass=TestSecRandom() && pass; +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + pass=TestMersenne() && pass; +#endif +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) + pass=TestPadlockRNG() && pass; + pass=TestRDRAND() && pass; + pass=TestRDSEED() && pass; +#endif +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + pass=TestDARN() && pass; +#endif +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + // http://github.com/weidai11/cryptopp/issues/92 + pass=TestSecBlock() && pass; + // http://github.com/weidai11/cryptopp/issues/602 + pass=TestIntegerOps() && pass; + // http://github.com/weidai11/cryptopp/issues/336 + pass=TestIntegerBitops() && pass; + // http://github.com/weidai11/cryptopp/issues/64 + pass=TestPolynomialMod2() && pass; + // http://github.com/weidai11/cryptopp/issues/360 + pass=TestRounding() && pass; + // http://github.com/weidai11/cryptopp/issues/242 + pass=TestHuffmanCodes() && pass; + // http://github.com/weidai11/cryptopp/issues/346 + pass=TestASN1Parse() && pass; + pass=TestASN1Functions() && pass; + // https://github.com/weidai11/cryptopp/pull/334 + pass=TestStringSink() && pass; + // Always part of the self tests; call in Debug +# if defined(CRYPTOPP_ALTIVEC_AVAILABLE) + pass=TestAltivecOps() && pass; +# endif + // Always part of the self tests; call in Debug + pass=ValidateBaseCode() && pass; + // https://github.com/weidai11/cryptopp/issues/562 + pass=ValidateEncoder() && pass; + // Additional tests due to no coverage + pass=TestCompressors() && pass; + pass=TestSharing() && pass; + pass=TestEncryptors() && pass; + pass=TestX25519() && pass; + pass=TestEd25519() && pass; +#endif + + pass=ValidateCRC32() && pass; + pass=ValidateCRC32C() && pass; + pass=ValidateAdler32() && pass; + pass=ValidateMD2() && pass; +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + pass=ValidateMD4() && pass; +#endif + pass=ValidateMD5() && pass; + pass=ValidateSHA() && pass; + + pass=ValidateKeccak() && pass; + pass=ValidateSHA3() && pass; + pass=ValidateSHAKE() && pass; + pass=ValidateSHAKE_XOF() && pass; + + pass=ValidateLSH() && pass; + + pass=ValidateHashDRBG() && pass; + pass=ValidateHmacDRBG() && pass; + + pass=ValidateTiger() && pass; + pass=ValidateRIPEMD() && pass; + pass=ValidatePanama() && pass; + pass=ValidateWhirlpool() && pass; + + pass=ValidateSM3() && pass; + pass=ValidateBLAKE2s() && pass; + pass=ValidateBLAKE2b() && pass; + pass=ValidatePoly1305() && pass; + pass=ValidateSipHash() && pass; + + pass=ValidateHMAC() && pass; + pass=ValidateTTMAC() && pass; + + pass=ValidatePBKDF() && pass; + pass=ValidateHKDF() && pass; + pass=ValidateScrypt() && pass; + + pass=ValidateDES() && pass; + pass=ValidateCipherModes() && pass; + pass=ValidateIDEA() && pass; + pass=ValidateSAFER() && pass; + pass=ValidateRC2() && pass; + pass=ValidateARC4() && pass; + pass=ValidateRC5() && pass; + pass=ValidateBlowfish() && pass; + pass=ValidateThreeWay() && pass; + pass=ValidateGOST() && pass; + pass=ValidateSHARK() && pass; + pass=ValidateCAST() && pass; + pass=ValidateSquare() && pass; + pass=ValidateSKIPJACK() && pass; + pass=ValidateSEAL() && pass; + pass=ValidateRC6() && pass; + pass=ValidateMARS() && pass; + pass=ValidateRijndael() && pass; + pass=ValidateTwofish() && pass; + pass=ValidateSerpent() && pass; + pass=ValidateSHACAL2() && pass; + pass=ValidateARIA() && pass; + pass=ValidateCHAM() && pass; + pass=ValidateHIGHT() && pass; + pass=ValidateLEA() && pass; + pass=ValidateSIMECK() && pass; + pass=ValidateSIMON() && pass; + pass=ValidateSPECK() && pass; + pass=ValidateCamellia() && pass; + pass=ValidateSalsa() && pass; + pass=ValidateChaCha() && pass; + pass=ValidateChaChaTLS() && pass; + pass=ValidateSosemanuk() && pass; + pass=ValidateRabbit() && pass; + pass=ValidateHC128() && pass; + pass=ValidateHC256() && pass; + pass=RunTestDataFile("TestVectors/seed.txt") && pass; + pass=RunTestDataFile("TestVectors/threefish.txt") && pass; + pass=RunTestDataFile("TestVectors/kalyna.txt") && pass; + pass=RunTestDataFile("TestVectors/sm4.txt") && pass; + pass=ValidateVMAC() && pass; + pass=ValidateCCM() && pass; + pass=ValidateGCM() && pass; + pass=ValidateXTS() && pass; + pass=ValidateCMAC() && pass; + pass=RunTestDataFile("TestVectors/eax.txt") && pass; + + pass=ValidateBBS() && pass; + pass=ValidateDH() && pass; + pass=ValidateX25519() && pass; + pass=ValidateMQV() && pass; + pass=ValidateHMQV() && pass; + pass=ValidateFHMQV() && pass; + pass=ValidateRSA() && pass; + pass=ValidateElGamal() && pass; + pass=ValidateDLIES() && pass; + pass=ValidateNR() && pass; + pass=ValidateDSA(thorough) && pass; + pass=ValidateLUC() && pass; + pass=ValidateLUC_DH() && pass; + pass=ValidateLUC_DL() && pass; + pass=ValidateXTR_DH() && pass; + pass=ValidateRabin() && pass; + pass=ValidateRW() && pass; + pass=ValidateECP() && pass; + pass=ValidateEC2N() && pass; + pass=ValidateECP_Legacy_Encrypt() && pass; + pass=ValidateEC2N_Legacy_Encrypt() && pass; + pass=ValidateECDSA() && pass; + pass=ValidateECDSA_RFC6979() && pass; + pass=ValidateECGDSA(thorough) && pass; + pass=ValidateESIGN() && pass; + + pass=ValidateX25519() && pass; + pass=ValidateEd25519() && pass; + pass=ValidateNaCl() && pass; + + if (pass) + std::cout << "\nAll tests passed!\n"; + else + std::cout << "\nOops! Not all tests passed.\n"; + + return pass; +} + +bool TestSettings() +{ + bool pass = true; + + std::cout << "\nTesting Settings...\n\n"; + + word32 w; + const byte s[] = "\x01\x02\x03\x04"; + +#if (_MSC_VER >= 1400) + memcpy_s(&w, 4, s, 4); +#else + std::copy(s, s+4, reinterpret_cast(&w)); +#endif + + if (w == 0x04030201L) + { +#if (CRYPTOPP_LITTLE_ENDIAN) + std::cout << "passed: "; +#else + std::cout << "FAILED: "; + pass = false; +#endif + std::cout << "Your machine is little endian.\n"; + } + else if (w == 0x01020304L) + { +#if (CRYPTOPP_BIG_ENDIAN) + std::cout << "passed: "; +#else + std::cout << "FAILED: "; + pass = false; +#endif + std::cout << "Your machine is big endian.\n"; + } + else + { + std::cout << "FAILED: Your machine is neither big endian nor little endian.\n"; + pass = false; + } + + if (sizeof(void*) == 8) + { + std::cout << "passed: Your machine is 64-bit.\n"; + } + else if (sizeof(void*) == 4) + { + std::cout << "passed: Your machine is 32-bit.\n"; + } + else + { + std::cout << "FAILED: Your machine is neither 32-bit nor 64-bit.\n"; + pass = false; + } + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + // App and library versions, http://github.com/weidai11/cryptopp/issues/371 + const int v1 = LibraryVersion(); + const int v2 = HeaderVersion(); + if(v1/10 == v2/10) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "Library version (library): " << v1 << ", header version (app): " << v2 << "\n"; +#endif + + if (sizeof(byte) == 1) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "sizeof(byte) == " << sizeof(byte) << "\n"; + + if (sizeof(word16) == 2) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "sizeof(word16) == " << sizeof(word16) << "\n"; + + if (sizeof(word32) == 4) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "sizeof(word32) == " << sizeof(word32) << "\n"; + + if (sizeof(word64) == 8) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "sizeof(word64) == " << sizeof(word64) << "\n"; + +#ifdef CRYPTOPP_WORD128_AVAILABLE + if (sizeof(word128) == 16) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "sizeof(word128) == " << sizeof(word128) << "\n"; +#endif + + if (sizeof(word) == 2*sizeof(hword) +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + && sizeof(dword) == 2*sizeof(word) +#endif + ) + std::cout << "passed: "; + else + { + std::cout << "FAILED: "; + pass = false; + } + std::cout << "sizeof(hword) == " << sizeof(hword) << ", sizeof(word) == " << sizeof(word); +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + std::cout << ", sizeof(dword) == " << sizeof(dword); +#endif + std::cout << "\n"; + + const int cacheLineSize = GetCacheLineSize(); + if (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize)) + { + std::cout << "FAILED: "; + pass = false; + } + else + std::cout << "passed: "; + std::cout << "cacheLineSize == " << cacheLineSize << "\n"; + +#ifdef CRYPTOPP_CPUID_AVAILABLE + bool hasSSE2 = HasSSE2(); + bool hasSSSE3 = HasSSSE3(); + bool hasSSE41 = HasSSE41(); + bool hasSSE42 = HasSSE42(); + bool hasAVX = HasAVX(); + bool hasAVX2 = HasAVX2(); + bool hasAESNI = HasAESNI(); + bool hasCLMUL = HasCLMUL(); + bool hasRDRAND = HasRDRAND(); + bool hasRDSEED = HasRDSEED(); + bool hasSHA = HasSHA(); + bool isP4 = IsP4(); + + std::cout << "hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3; + std::cout << ", hasSSE4.1 == " << hasSSE41 << ", hasSSE4.2 == " << hasSSE42; + std::cout << ", hasAVX == " << hasAVX << ", hasAVX2 == " << hasAVX2; + std::cout << ", hasAESNI == " << hasAESNI << ", hasCLMUL == " << hasCLMUL; + std::cout << ", hasRDRAND == " << hasRDRAND << ", hasRDSEED == " << hasRDSEED; + std::cout << ", hasSHA == " << hasSHA << ", isP4 == " << isP4; + std::cout << "\n"; + +#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8) + +# if defined(__arm__) + bool hasARMv7 = HasARMv7(); + bool hasNEON = HasNEON(); + + std::cout << "passed: "; + std::cout << "hasARMv7 == " << hasARMv7 << ", hasNEON == " << hasNEON << "\n"; +# else // __arch32__ and __aarch64__ + bool hasCRC32 = HasCRC32(); + bool hasPMULL = HasPMULL(); + bool hasAES = HasAES(); + bool hasSHA1 = HasSHA1(); + bool hasSHA2 = HasSHA2(); + bool hasSHA3 = HasSHA3(); + bool hasSHA512 = HasSHA512(); + bool hasSM3 = HasSM3(); + bool hasSM4 = HasSM4(); + + std::cout << "passed: hasASIMD == 1"; + std::cout << ", hasCRC32 == " << hasCRC32 << ", hasAES == " << hasAES; + std::cout << ", hasPMULL == " << hasPMULL << ", hasSHA1 == " << hasSHA1; + std::cout << ", hasSHA2 == " << hasSHA2 << ", hasSHA3 == " << hasSHA3; + std::cout << ", hasSHA512 == " << hasSHA512 << ", hasSM3 == " << hasSM3; + std::cout << ", hasSM4 == " << hasSM4 << "\n"; +# endif + +#elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) + const bool hasAltivec = HasAltivec(); + const bool hasPower7 = HasPower7(); + const bool hasPower8 = HasPower8(); + const bool hasPower9 = HasPower9(); + const bool hasAES = HasAES(); + const bool hasPMULL = HasPMULL(); + const bool hasSHA256 = HasSHA256(); + const bool hasSHA512 = HasSHA512(); + const bool hasDARN = HasDARN(); + + std::cout << "passed: "; + std::cout << "hasAltivec == " << hasAltivec << ", hasPower7 == " << hasPower7; + std::cout << ", hasPower8 == " << hasPower8 << ", hasPower9 == " << hasPower9; + std::cout << ", hasAES == " << hasAES << ", hasPMULL == " << hasPMULL; + std::cout << ", hasSHA256 == " << hasSHA256 << ", hasSHA512 == " << hasSHA512; + std::cout << ", hasDARN == " << hasDARN << "\n"; + +#endif + + if (!pass) + { + std::cerr << "Some critical setting in config.h is in error. Please fix it and recompile.\n"; + std::abort(); + } + return pass; +} + +bool Test_RandomNumberGenerator(RandomNumberGenerator& prng, bool drain=false) +{ + bool pass = true, result = true; + const size_t GENERATE_SIZE = 1024*10, DISCARD_SIZE = 256, ENTROPY_SIZE = 32; + + if(drain) + { + RandomNumberSource(prng, UINT_MAX, true, new Redirector(TheBitBucket())); + } + + MeterFilter meter(new Redirector(TheBitBucket())); + RandomNumberSource(prng, GENERATE_SIZE, true, new Deflator(new Redirector(meter))); + + if (meter.GetTotalBytes() < GENERATE_SIZE) + { + pass = false; + result = false; + } + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " " << GENERATE_SIZE << " generated bytes compressed to "; + std::cout << meter.GetTotalBytes() << " bytes by DEFLATE\n"; + + try + { + pass = true; + if(prng.CanIncorporateEntropy()) + { + SecByteBlock entropy(ENTROPY_SIZE); + GlobalRNG().GenerateBlock(entropy, entropy.SizeInBytes()); + + prng.IncorporateEntropy(entropy, entropy.SizeInBytes()); + prng.IncorporateEntropy(entropy, entropy.SizeInBytes()-1); + prng.IncorporateEntropy(entropy, entropy.SizeInBytes()-2); + prng.IncorporateEntropy(entropy, entropy.SizeInBytes()-3); + } + } + catch (const Exception& /*ex*/) + { + pass = false; + result = false; + } + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " IncorporateEntropy with " << 4*ENTROPY_SIZE << " bytes\n"; + + try + { + word32 val = prng.GenerateWord32(); + val = prng.GenerateWord32((val & 0xff), 0xffffffff - (val & 0xff)); + + prng.GenerateBlock(reinterpret_cast(&val), 4); + prng.GenerateBlock(reinterpret_cast(&val), 3); + prng.GenerateBlock(reinterpret_cast(&val), 2); + prng.GenerateBlock(reinterpret_cast(&val), 1); + } + catch (const Exception&) + { + pass = false; + result = false; + } + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " GenerateWord32 and Crop\n"; + + try + { + pass = true; + prng.DiscardBytes(DISCARD_SIZE); + prng.DiscardBytes(DISCARD_SIZE-1); + prng.DiscardBytes(DISCARD_SIZE-2); + prng.DiscardBytes(DISCARD_SIZE-3); + } + catch (const Exception&) + { + pass = false; + result = false; + } + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " DiscardBytes with " << 4*DISCARD_SIZE << " bytes\n"; + + // Miscellaneous for code coverage + (void)prng.AlgorithmName(); // "unknown" + + CRYPTOPP_ASSERT(result); + return result; +} + +bool TestOS_RNG() +{ + bool pass = true; + + member_ptr rng; + +#ifdef BLOCKING_RNG_AVAILABLE + try {rng.reset(new BlockingRng);} + catch (const OS_RNG_Err &) {} + + if (rng.get()) + { + std::cout << "\nTesting operating system provided blocking random number generator...\n\n"; + + MeterFilter meter(new Redirector(TheBitBucket())); + RandomNumberSource test(*rng, UINT_MAX, false, new Deflator(new Redirector(meter))); + unsigned long total=0; + time_t t = time(NULLPTR), t1 = 0; + + // check that it doesn't take too long to generate a reasonable amount of randomness + while (total < 16 && (t1 < 10 || total*8 > (unsigned long)t1)) + { + test.Pump(1); + total += 1; + t1 = time(NULLPTR) - t; + } + + if (total < 16) + { + std::cout << "FAILED:"; + pass = false; + } + else + std::cout << "passed:"; + std::cout << " it took " << long(t1) << " seconds to generate " << total << " bytes" << std::endl; + + test.AttachedTransformation()->MessageEnd(); + + if (meter.GetTotalBytes() < total) + { + std::cout << "FAILED:"; + pass = false; + } + else + std::cout << "passed:"; + std::cout << " " << total << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n"; + + try + { + // Miscellaneous for code coverage + RandomNumberGenerator& prng = *rng.get(); + (void)prng.AlgorithmName(); + word32 result = prng.GenerateWord32(); + result = prng.GenerateWord32((result & 0xff), 0xffffffff - (result & 0xff)); + prng.GenerateBlock(reinterpret_cast(&result), 4); + prng.GenerateBlock(reinterpret_cast(&result), 3); + prng.GenerateBlock(reinterpret_cast(&result), 2); + prng.GenerateBlock(reinterpret_cast(&result), 1); + prng.GenerateBlock(reinterpret_cast(&result), 0); + pass = true; + } + catch (const Exception&) + { + pass = false; + } + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " GenerateWord32 and Crop\n"; + } + else + std::cout << "\nNo operating system provided blocking random number generator, skipping test." << std::endl; +#endif + +#ifdef NONBLOCKING_RNG_AVAILABLE + try {rng.reset(new NonblockingRng);} + catch (OS_RNG_Err &) {} + + if (rng.get()) + { + std::cout << "\nTesting operating system provided nonblocking random number generator...\n\n"; + + pass = Test_RandomNumberGenerator(*rng.get()) && pass; + } + else + std::cout << "\nNo operating system provided non-blocking random number generator, skipping test." << std::endl; +#endif + + CRYPTOPP_ASSERT(pass); + return pass; +} + +bool TestRandomPool() +{ + member_ptr prng; + bool pass=true; + + try {prng.reset(new RandomPool);} + catch (Exception &) {} + + if(prng.get()) + { + std::cout << "\nTesting RandomPool generator...\n\n"; + pass = Test_RandomNumberGenerator(*prng.get()) && pass; + } + +#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE) + try {prng.reset(new AutoSeededRandomPool);} + catch (Exception &) {} + + if(prng.get()) + { + std::cout << "\nTesting AutoSeeded RandomPool generator...\n\n"; + pass = Test_RandomNumberGenerator(*prng.get()) && pass; + } +#endif + + // Old, PGP 2.6 style RandomPool. Added because users were still having problems + // with it in 2017. The missing functionality was a barrier to upgrades. + try {prng.reset(new OldRandomPool);} + catch (Exception &) {} + + if(prng.get()) + { + std::cout << "\nTesting OldRandomPool generator...\n\n"; + pass = Test_RandomNumberGenerator(*prng.get()) && pass; + + // https://github.com/weidai11/cryptopp/issues/452 + byte actual[32], expected[32] = { + 0x41,0xD1,0xEF,0x8F,0x10,0x3C,0xE2,0x94, + 0x47,0xC0,0xC3,0x86,0x66,0xBC,0x86,0x09, + 0x57,0x77,0x73,0x91,0x57,0x4D,0x93,0x66, + 0xD1,0x13,0xE1,0xBA,0x07,0x49,0x8F,0x75 + }; + + prng.reset(new OldRandomPool); + RandomNumberGenerator& old = *prng.get(); + + SecByteBlock seed(384); + for (size_t i=0; i<384; ++i) + seed[i] = static_cast(i); + old.IncorporateEntropy(seed, seed.size()); + + old.GenerateBlock(actual, sizeof(actual)); + pass = (0 == std::memcmp(actual, expected, sizeof(expected))) && pass; + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Expected sequence from PGP-style RandomPool (circa 2007)\n"; + } + + return pass; +} + +#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE) +bool TestAutoSeededX917() +{ + // This tests Auto-Seeding and GenerateIntoBufferedTransformation. + std::cout << "\nTesting AutoSeeded X917 generator...\n\n"; + + AutoSeededX917RNG prng; + return Test_RandomNumberGenerator(prng); +} +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +bool TestMersenne() +{ + std::cout << "\nTesting Mersenne Twister...\n\n"; + + member_ptr rng; + bool pass = true; + + try {rng.reset(new MT19937ar);} + catch (const Exception &) {} + + if(rng.get()) + { + pass = Test_RandomNumberGenerator(*rng.get()); + } + + // Reset state + try {rng.reset(new MT19937ar);} + catch (const Exception &) {} + + if(rng.get()) + { + // First 10; http://create.stephan-brumme.com/mersenne-twister/ + word32 result[10], expected[10] = { + 0xD091BB5C, 0x22AE9EF6, 0xE7E1FAEE, 0xD5C31F79, + 0x2082352C, 0xF807B7DF, 0xE9D30005, 0x3895AFE1, + 0xA1E24BBA, 0x4EE4092B + }; + + rng->GenerateBlock(reinterpret_cast(result), sizeof(result)); + pass = (0 == std::memcmp(result, expected, sizeof(expected))) && pass; + + if (!pass) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Expected sequence from MT19937\n"; + } + + return pass; +} +#endif + +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +bool TestPadlockRNG() +{ + std::cout << "\nTesting Padlock RNG generator...\n\n"; + + member_ptr rng; + bool pass = true, fail; + + try {rng.reset(new PadlockRNG);} + catch (const PadlockRNG_Err &) {} + + if (rng.get()) + { + PadlockRNG& padlock = dynamic_cast(*rng.get()); + pass = Test_RandomNumberGenerator(padlock); + + // PadlockRNG does not accept entropy. However, the contract is no throw + const byte entropy[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + (void)padlock.IncorporateEntropy(entropy, sizeof(entropy)); + + SecByteBlock zero(16), one(16), t(16); + std::memset(zero, 0x00, zero.size()); + std::memset( one, 0xff, one.size()); + + // Cryptography Research, Inc tests + word32 oldDivisor = padlock.SetDivisor(0); + padlock.GenerateBlock(t, t.size()); + word32 msr = padlock.GetMSR(); + padlock.SetDivisor(oldDivisor); + + // Bit 6 should be set + fail = !(msr & (1 << 6U)); + pass &= !fail; + if (fail) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " VIA RNG is activated\n"; + + // Bit 13 should be unset + fail = !!(msr & (1 << 13U)); + pass &= !fail; + if (fail) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " von Neumann corrector is activated\n"; + + // Bit 14 should be unset + fail = !!(msr & (1 << 14U)); + pass &= !fail; + if (fail) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " String filter is deactivated\n"; + + // Bit 12:10 should be unset + fail = !!(msr & (0x7 << 10U)); + pass &= !fail; + if (fail) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Bias voltage is unmodified\n"; + + fail = false; + if (t == zero || t == one) + fail = true; + + pass &= !fail; + if (fail) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " All 0's or all 1's test\n"; + } + else + std::cout << "Padlock RNG generator not available, skipping test.\n"; + + return pass; +} + +bool TestRDRAND() +{ + std::cout << "\nTesting RDRAND generator...\n\n"; + + bool pass = true; + member_ptr rng; + + try {rng.reset(new RDRAND);} + catch (const RDRAND_Err &) {} + + if (rng.get()) + { + RDRAND& rdrand = dynamic_cast(*rng.get()); + pass = Test_RandomNumberGenerator(rdrand) && pass; + + // RDRAND does not accept entropy. However, the contract is no throw + const byte entropy[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + (void)rdrand.IncorporateEntropy(entropy, sizeof(entropy)); + + MaurerRandomnessTest maurer; + const unsigned int SIZE = 1024*10; + RandomNumberSource(rdrand, SIZE, true, new Redirector(maurer)); + + CRYPTOPP_ASSERT(0 == maurer.BytesNeeded()); + const double mv = maurer.GetTestValue(); + if (mv < 0.98f) + pass = false; + + std::ostringstream oss; + oss.flags(std::ios::fixed); + oss.precision(6); + + if (!pass) + oss << "FAILED:"; + else + oss << "passed:"; + oss << " Maurer Randomness Test returned value " << mv << "\n"; + std::cout << oss.str(); + } + else + std::cout << "RDRAND generator not available, skipping test.\n"; + + return pass; +} + +bool TestRDSEED() +{ + std::cout << "\nTesting RDSEED generator...\n\n"; + + bool pass = true; + member_ptr rng; + + try {rng.reset(new RDSEED);} + catch (const RDSEED_Err &) {} + + if (rng.get()) + { + RDSEED& rdseed = dynamic_cast(*rng.get()); + pass = Test_RandomNumberGenerator(rdseed) && pass; + + // RDSEED does not accept entropy. However, the contract is no throw + const byte entropy[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + (void)rdseed.IncorporateEntropy(entropy, sizeof(entropy)); + + MaurerRandomnessTest maurer; + const unsigned int SIZE = 1024*10; + RandomNumberSource(rdseed, SIZE, true, new Redirector(maurer)); + + CRYPTOPP_ASSERT(0 == maurer.BytesNeeded()); + const double mv = maurer.GetTestValue(); + if (mv < 0.98f) + pass = false; + + std::ostringstream oss; + oss.flags(std::ios::fixed); + oss.precision(6); + + if (!pass) + oss << "FAILED:"; + else + oss << "passed:"; + oss << " Maurer Randomness Test returned value " << mv << "\n"; + std::cout << oss.str(); + } + else + std::cout << "RDSEED generator not available, skipping test.\n"; + + return pass; +} +#endif // x86, x32, or x64 + +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) +bool TestDARN() +{ + std::cout << "\nTesting DARN generator...\n\n"; + + bool pass = true; + member_ptr rng; + + try {rng.reset(new DARN);} + catch (const DARN_Err &) {} + + if (rng.get()) + { + DARN& darn = dynamic_cast(*rng.get()); + pass = Test_RandomNumberGenerator(darn) && pass; + + // DARN does not accept entropy. However, the contract is no throw + const byte entropy[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + (void)darn.IncorporateEntropy(entropy, sizeof(entropy)); + + MaurerRandomnessTest maurer; + const unsigned int SIZE = 1024*10; + RandomNumberSource(darn, SIZE, true, new Redirector(maurer)); + + CRYPTOPP_ASSERT(0 == maurer.BytesNeeded()); + const double mv = maurer.GetTestValue(); + if (mv < 0.98f) + pass = false; + + std::ostringstream oss; + oss.flags(std::ios::fixed); + oss.precision(6); + + if (!pass) + oss << "FAILED:"; + else + oss << "passed:"; + oss << " Maurer Randomness Test returned value " << mv << "\n"; + std::cout << oss.str(); + } + else + std::cout << "DARN generator not available, skipping test.\n"; + + return pass; +} +#endif // PPC32 or PPC64 + +bool ValidateHashDRBG() +{ + std::cout << "\nTesting NIST Hash DRBGs...\n\n"; + bool pass=true, fail; + + // # CAVS 14.3 + // # DRBG800-90A information for "drbg_pr" + // # Generated on Tue Apr 02 15:32:09 2013 + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 0], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x16\x10\xb8\x28\xcc\xd2\x7d\xe0\x8c\xee\xa0\x32\xa2\x0e\x92\x08"; + const byte entropy2[] = "\x72\xd2\x8c\x90\x8e\xda\xf9\xa4\xd1\xe5\x26\xd8\xf2\xde\xd5\x44"; + const byte nonce[] = "\x49\x2c\xf1\x70\x92\x42\xf6\xb5"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(result, result.size()); + drbg.GenerateBlock(result, result.size()); + + const byte expected[] = "\x56\xF3\x3D\x4F\xDB\xB9\xA5\xB6\x4D\x26\x23\x44\x97\xE9\xDC\xB8\x77\x98\xC6\x8D" + "\x08\xF7\xC4\x11\x99\xD4\xBD\xDF\x97\xEB\xBF\x6C\xB5\x55\x0E\x5D\x14\x9F\xF4\xD5" + "\xBD\x0F\x05\xF2\x5A\x69\x88\xC1\x74\x36\x39\x62\x27\x18\x4A\xF8\x4A\x56\x43\x35" + "\x65\x8E\x2F\x85\x72\xBE\xA3\x33\xEE\xE2\xAB\xFF\x22\xFF\xA6\xDE\x3E\x22\xAC\xA2"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (COUNT=0, E=16, N=8)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 0], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x55\x08\x75\xb7\x4e\xc1\x1f\x90\x67\x78\xa3\x1a\x37\xa3\x29\xfd"; + const byte entropy2[] = "\x96\xc6\x39\xec\x14\x9f\x6b\x28\xe2\x79\x3b\xb9\x37\x9e\x60\x67"; + const byte nonce[] = "\x08\xdd\x8c\xd3\x5b\xfa\x00\x94"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(result, result.size()); + drbg.GenerateBlock(result, result.size()); + + const byte expected[] = "\xEE\x44\xC6\xCF\x2C\x0C\x73\xA8\xAC\x4C\xA5\x6C\x0E\x71\x2C\xA5\x50\x9A\x19\x5D" + "\xE4\x5B\x8D\x2B\xC9\x40\xA7\xDB\x66\xC3\xEB\x2A\xA1\xBD\xB4\xDD\x76\x85\x12\x45" + "\x80\x2E\x68\x05\x4A\xAB\xA8\x7C\xD6\x3A\xD3\xE5\xC9\x7C\x06\xE7\xA3\x9F\xF6\xF9" + "\x8E\xB3\xD9\x72\xD4\x11\x35\xE5\xE7\x46\x1B\x49\x9C\x56\x45\x6A\xBE\x7F\x77\xD4"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (COUNT=1, E=16, N=8)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 128], [ReturnedBitsLen = 640] + const byte entropy1[] = "\xd9\xba\xb5\xce\xdc\xa9\x6f\x61\x78\xd6\x45\x09\xa0\xdf\xdc\x5e"; + const byte entropy2[] = "\xc6\xba\xd0\x74\xc5\x90\x67\x86\xf5\xe1\xf3\x20\x99\xf5\xb4\x91"; + const byte nonce[] = "\xda\xd8\x98\x94\x14\x45\x0e\x01"; + const byte additional1[] = "\x3e\x6b\xf4\x6f\x4d\xaa\x38\x25\xd7\x19\x4e\x69\x4e\x77\x52\xf7"; + const byte additional2[] = "\x04\xfa\x28\x95\xaa\x5a\x6f\x8c\x57\x43\x34\x3b\x80\x5e\x5e\xa4"; + const byte additional3[] = "\xdf\x5d\xc4\x59\xdf\xf0\x2a\xa2\xf0\x52\xd7\x21\xec\x60\x72\x30"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16, additional1, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(additional2, 16, result, result.size()); + drbg.GenerateBlock(additional3, 16, result, result.size()); + + const byte expected[] = "\xC4\x8B\x89\xF9\xDA\x3F\x74\x82\x45\x55\x5D\x5D\x03\x3B\x69\x3D\xD7\x1A\x4D\xF5" + "\x69\x02\x05\xCE\xFC\xD7\x20\x11\x3C\xC2\x4E\x09\x89\x36\xFF\x5E\x77\xB5\x41\x53" + "\x58\x70\xB3\x39\x46\x8C\xDD\x8D\x6F\xAF\x8C\x56\x16\x3A\x70\x0A\x75\xB2\x3E\x59" + "\x9B\x5A\xEC\xF1\x6F\x3B\xAF\x6D\x5F\x24\x19\x97\x1F\x24\xF4\x46\x72\x0F\xEA\xBE"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=16)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 128], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x28\x00\x0f\xbf\xf0\x57\x22\xc8\x89\x93\x06\xc2\x9b\x50\x78\x0a"; + const byte entropy2[] = "\xd9\x95\x8e\x8c\x08\xaf\x5a\x41\x0e\x91\x9b\xdf\x40\x8e\x5a\x0a"; + const byte nonce[] = "\x11\x2f\x6e\x20\xc0\x29\xed\x3f"; + const byte additional1[] = "\x91\x1d\x96\x5b\x6e\x77\xa9\x6c\xfe\x3f\xf2\xd2\xe3\x0e\x2a\x86"; + const byte additional2[] = "\xcd\x44\xd9\x96\xab\x05\xef\xe8\x27\xd3\x65\x83\xf1\x43\x18\x2c"; + const byte additional3[] = "\x9f\x6a\x31\x82\x12\x18\x4e\x70\xaf\x5d\x00\x14\x1f\x42\x82\xf6"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16, additional1, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(additional2, 16, result, result.size()); + drbg.GenerateBlock(additional3, 16, result, result.size()); + + const byte expected[] = "\x54\x61\x65\x92\x1E\x71\x4A\xD1\x39\x02\x2F\x97\xD2\x65\x3F\x0D\x47\x69\xB1\x4A" + "\x3E\x6E\xEF\xA1\xA0\x16\xD6\x9E\xA9\x7F\x51\xD5\x81\xDC\xAA\xCF\x66\xF9\xB1\xE8" + "\x06\x94\x41\xD6\xB5\xC5\x44\x60\x54\x07\xE8\xE7\xDC\x1C\xD8\xE4\x70\xAD\x84\x77" + "\x5A\x65\x31\xBE\xE0\xFC\x81\x36\xE2\x8F\x0B\xFE\xEB\xE1\x98\x62\x7E\x98\xE0\xC1"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=16)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 128], [AdditionalInputLen = 0], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x0e\xd5\x4c\xef\x44\x5c\x61\x7d\x58\x86\xe0\x34\xc0\x97\x36\xd4"; + const byte entropy2[] = "\x0b\x90\x27\xb8\x01\xe7\xf7\x2e\xe6\xec\x50\x2b\x8b\x6b\xd7\x11"; + const byte nonce[] = "\x2c\x8b\x07\x13\x55\x6c\x91\x6f"; + const byte personalization[] = "\xf3\x37\x8e\xa1\x45\x34\x30\x41\x12\xe0\xee\x57\xe9\xb3\x4a\x4b"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8, personalization, 16); + drbg.IncorporateEntropy(entropy2, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(result, result.size()); + drbg.GenerateBlock(result, result.size()); + + const byte expected[] = "\x55\x37\x0E\xD4\xB7\xCA\xA4\xBB\x67\x3A\x0F\x58\x40\xB3\x9F\x76\x4E\xDA\xD2\x85" + "\xD5\x6F\x01\x8F\x2D\xA7\x54\x4B\x0E\x66\x39\x62\x35\x96\x1D\xB7\xF6\xDA\xFB\x30" + "\xB6\xC5\x68\xD8\x40\x6E\x2B\xD4\x3D\x23\xEB\x0F\x10\xBA\x5F\x24\x9C\xC9\xE9\x4A" + "\xD3\xA5\xF1\xDF\xA4\xF2\xB4\x80\x40\x91\xED\x8C\xD6\x6D\xE7\xB7\x53\xB2\x09\xD5"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=0, P=16)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 128], [AdditionalInputLen = 0], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x8f\x2a\x33\x9f\x5f\x45\x21\x30\xa4\x57\xa9\x6f\xcb\xe2\xe6\x36"; + const byte entropy2[] = "\x1f\xff\x9e\x4f\x4d\x66\x3a\x1f\x9e\x85\x4a\x15\x7d\xad\x97\xe0"; + const byte nonce[] = "\x0e\xd0\xe9\xa5\xa4\x54\x8a\xd0"; + const byte personalization[] = "\x45\xe4\xb3\xe2\x63\x87\x62\x57\x2c\x99\xe4\x03\x45\xd6\x32\x6f"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8, personalization, 16); + drbg.IncorporateEntropy(entropy2, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(result, result.size()); + drbg.GenerateBlock(result, result.size()); + + const byte expected[] = "\x4F\xE8\x96\x41\xF8\xD3\x95\xC4\x43\x6E\xFB\xF8\x05\x75\xA7\x69\x74\x6E\x0C\x5F" + "\x54\x14\x35\xB4\xE6\xA6\xB3\x40\x7C\xA2\xC4\x42\xA2\x2F\x66\x28\x28\xCF\x4A\xA8" + "\xDC\x16\xBC\x5F\x69\xE5\xBB\x05\xD1\x43\x8F\x80\xAB\xC5\x8F\x9C\x3F\x75\x57\xEB" + "\x44\x0D\xF5\x0C\xF4\x95\x23\x94\x67\x11\x55\x98\x14\x43\xFF\x13\x14\x85\x5A\xBC"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=0, P=16)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 128], [AdditionalInputLen = 16], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x48\xa1\xa9\x7c\xcc\x49\xd7\xcc\xf6\xe3\x78\xa2\xf1\x6b\x0f\xcd"; + const byte entropy2[] = "\xba\x5d\xa6\x79\x12\x37\x24\x3f\xea\x60\x50\xf5\xb9\x9e\xcd\xf5"; + const byte nonce[] = "\xb0\x91\xd2\xec\x12\xa8\x39\xfe"; + const byte personalization[] = "\x3d\xc1\x6c\x1a\xdd\x9c\xac\x4e\xbb\xb0\xb8\x89\xe4\x3b\x9e\x12"; + const byte additional1[] = "\xd1\x23\xe3\x8e\x4c\x97\xe8\x29\x94\xa9\x71\x7a\xc6\xf1\x7c\x08"; + const byte additional2[] = "\x80\x0b\xed\x97\x29\xcf\xad\xe6\x68\x0d\xfe\x53\xba\x0c\x1e\x28"; + const byte additional3[] = "\x25\x1e\x66\xb9\xe3\x85\xac\x1c\x17\xfb\x77\x1b\x5d\xc7\x6c\xf2"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8, personalization, 16); + drbg.IncorporateEntropy(entropy2, 16, additional1, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(additional2, 16, result, result.size()); + drbg.GenerateBlock(additional3, 16, result, result.size()); + + const byte expected[] = "\xA1\xB2\xEE\x86\xA0\xF1\xDA\xB7\x93\x83\x13\x3A\x62\x27\x99\x08\x95\x3A\x1C\x9A" + "\x98\x77\x60\x12\x11\x19\xCC\x78\xB8\x51\x2B\xD5\x37\xA1\x9D\xB9\x73\xCA\x39\x7A" + "\xDD\x92\x33\x78\x6D\x5D\x41\xFF\xFA\xE9\x80\x59\x04\x85\x21\xE2\x52\x84\xBC\x6F" + "\xDB\x97\xF3\x4E\x6A\x12\x7A\xCD\x41\x0F\x50\x68\x28\x46\xBE\x56\x9E\x9A\x6B\xC8"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=16, P=16)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 128], [AdditionalInputLen = 16], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x3b\xcb\xa8\x3b\x6d\xfb\x06\x79\x80\xef\xc3\x1e\xd2\x9e\x68\x57"; + const byte entropy2[] = "\x2f\xc9\x87\x49\x19\xcb\x52\x4a\x5b\xac\xf0\xcd\x96\x4e\xf8\x6e"; + const byte nonce[] = "\x23\xfe\x20\x9f\xac\x70\x45\xde"; + const byte personalization[] = "\xf2\x25\xf4\xd9\x6b\x9c\xab\x49\x1e\xab\x18\x14\xb2\x5e\x78\xef"; + const byte additional1[] = "\x57\x5b\x9a\x11\x32\x7a\xab\x89\x08\xfe\x46\x11\x9a\xed\x14\x5d"; + const byte additional2[] = "\x5d\x19\xcd\xed\xb7\xe3\x44\x66\x8e\x11\x42\x96\xa0\x38\xb1\x7f"; + const byte additional3[] = "\x2b\xaf\xa0\x15\xed\xdd\x5c\x76\x32\x75\x34\x35\xd1\x37\x72\xfb"; + + Hash_DRBG drbg(entropy1, 16, nonce, 8, personalization, 16); + drbg.IncorporateEntropy(entropy2, 16, additional1, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(additional2, 16, result, result.size()); + drbg.GenerateBlock(additional3, 16, result, result.size()); + + const byte expected[] = "\x1D\x12\xEB\x6D\x42\x60\xBD\xFB\xA7\x99\xB8\x53\xCC\x6F\x19\xB1\x64\xFE\x2F\x55" + "\xBA\xA2\x1C\x89\xD4\xD0\xE9\xB4\xBA\xD4\xE5\xF8\xC5\x30\x06\x41\xBA\xC4\x3D\x2B" + "\x73\x91\x27\xE9\x31\xC0\x55\x55\x11\xE8\xB6\x57\x02\x0D\xCE\x90\xAC\x31\xB9\x00" + "\x31\xC1\xD4\x4F\xE7\x12\x3B\xCC\x85\x16\x2F\x12\x8F\xB2\xDF\x84\x4E\xF7\x06\xBE"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=16, P=16)\n"; + } + + { + // [SHA-256], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128] + // [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 1024] + const byte entropy1[] = "\xf0\x5b\xab\x56\xc7\xac\x6e\xeb\x31\xa0\xcf\x8a\x8a\x06\x2a\x49\x17\x9a\xcf\x3c\x5b\x20\x4d\x60\xdd\x7a\x3e\xb7\x8f\x5d\x8e\x3b"; + const byte entropy2[] = "\x72\xd4\x02\xa2\x59\x7b\x98\xa3\xb8\xf5\x0b\x71\x6c\x63\xc6\xdb\xa7\x3a\x07\xe6\x54\x89\x06\x3f\x02\xc5\x32\xf5\xda\xc4\xd4\x18"; + const byte nonce[] = "\xa1\x45\x08\x53\x41\x68\xb6\x88\xf0\x5f\x1e\x41\x9c\x88\xcc\x30"; + const byte personalization[] = "\xa0\x34\x72\xf4\x04\x59\xe2\x87\xea\xcb\x21\x32\xc0\xb6\x54\x02\x7d\xa3\xe6\x69\x25\xb4\x21\x25\x54\xc4\x48\x18\x8c\x0e\x86\x01"; + const byte additional1[] = "\xb3\x0d\x28\xaf\xa4\x11\x6b\xbc\x13\x6e\x65\x09\xb5\x82\xa6\x93\xbc\x91\x71\x40\x46\xaa\x3c\x66\xb6\x77\xb3\xef\xf9\xad\xfd\x49"; + const byte additional2[] = "\x77\xfd\x1d\x68\xd6\xa4\xdd\xd5\xf3\x27\x25\x2d\x3f\x6b\xdf\xee\x8c\x35\xce\xd3\x83\xbe\xaf\xc9\x32\x77\xef\xf2\x1b\x6f\xf4\x1b"; + const byte additional3[] = "\x59\xa0\x1f\xf8\x6a\x58\x72\x1e\x85\xd2\xf8\x3f\x73\x99\xf1\x96\x4e\x27\xf8\x7f\xcd\x1b\xf5\xc1\xeb\xf3\x37\x10\x9b\x13\xbd\x24"; + + Hash_DRBG drbg(entropy1, 32, nonce, 16, personalization, 32); + drbg.IncorporateEntropy(entropy2, 32, additional1, 32); + + SecByteBlock result(128); + drbg.GenerateBlock(additional2, 32, result, result.size()); + drbg.GenerateBlock(additional3, 32, result, result.size()); + + const byte expected[] = "\xFF\x27\x96\x38\x5C\x32\xBF\x84\x3D\xFA\xBB\xF0\x3E\x70\x5A\x39\xCB\xA3\x4C\xF1" + "\x4F\xAE\xC3\x05\x63\xDF\x5A\xDD\xBD\x2D\x35\x83\xF5\x7E\x05\xF9\x40\x30\x56\x18" + "\xF2\x00\x88\x14\x03\xC2\xD9\x81\x36\x39\xE6\x67\x55\xDC\xFC\x4E\x88\xEA\x71\xDD" + "\xB2\x25\x2E\x09\x91\x49\x40\xEB\xE2\x3D\x63\x44\xA0\xF4\xDB\x5E\xE8\x39\xE6\x70" + "\xEC\x47\x24\x3F\xA0\xFC\xF5\x13\x61\xCE\x53\x98\xAA\xBF\xB4\x19\x1B\xFE\xD5\x00" + "\xE1\x03\x3A\x76\x54\xFF\xD7\x24\x70\x5E\x8C\xB2\x41\x7D\x92\x0A\x2F\x4F\x27\xB8" + "\x45\x13\x7F\xFB\x87\x90\xA9\x49"; + + fail = !!memcmp(result, expected, 1024/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA256/128/440 (C0UNT=0, E=32, N=16, A=32, P=32)\n"; + } + + { + // [SHA-256], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128] + // [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 1024] + const byte entropy1[] = "\xfe\x61\x50\x79\xf1\xad\x2a\x71\xea\x7f\x0f\x5a\x14\x34\xee\xc8\x46\x35\x54\x4a\x95\x6a\x4f\xbd\x64\xff\xba\xf6\x1d\x34\x61\x83"; + const byte entropy2[] = "\x18\x89\x7b\xd8\x3e\xff\x38\xab\xb5\x6e\x82\xa8\x1b\x8c\x5e\x59\x3c\x3d\x85\x62\x2a\xe2\x88\xe5\xb2\xc6\xc5\xd2\xad\x7d\xc9\x45"; + const byte nonce[] = "\x9d\xa7\x87\x56\xb7\x49\x17\x02\x4c\xd2\x00\x65\x11\x9b\xe8\x7e"; + const byte personalization[] = "\x77\x5d\xbf\x32\xf3\x5c\xf3\x51\xf4\xb8\x1c\xd3\xfa\x7f\x65\x0b\xcf\x31\x88\xa1\x25\x57\x0c\xdd\xac\xaa\xfe\xa1\x7b\x3b\x29\xbc"; + const byte additional1[] = "\xef\x96\xc7\x9c\xb1\x73\x1d\x82\x85\x0a\x6b\xca\x9b\x5c\x34\x39\xba\xd3\x4e\x4d\x82\x6f\x35\x9f\x61\x5c\xf6\xf2\xa3\x3e\x91\x05"; + const byte additional2[] = "\xaf\x25\xc4\x6e\x21\xfc\xc3\xaf\x1f\xbb\xf8\x76\xb4\x57\xab\x1a\x94\x0a\x85\x16\x47\x81\xa4\xab\xda\xc8\xab\xca\xd0\x84\xda\xae"; + const byte additional3[] = "\x59\x5b\x44\x94\x38\x86\x36\xff\x8e\x45\x1a\x0c\x42\xc8\xcc\x21\x06\x38\x3a\xc5\xa6\x30\x96\xb9\x14\x81\xb3\xa1\x2b\xc8\xcd\xf6"; + + Hash_DRBG drbg(entropy1, 32, nonce, 16, personalization, 32); + drbg.IncorporateEntropy(entropy2, 32, additional1, 32); + + SecByteBlock result(128); + drbg.GenerateBlock(additional2, 32, result, result.size()); + drbg.GenerateBlock(additional3, 32, result, result.size()); + + const byte expected[] = "\x8B\x1C\x9C\x76\xC4\x9B\x3B\xAE\xFD\x6E\xEB\x6C\xFF\xA3\xA1\x03\x3A\x8C\xAF\x09" + "\xFE\xBD\x44\x00\xFC\x0F\xD3\xA8\x26\x9C\xEE\x01\xAC\xE3\x73\x0E\xBE\xDA\x9A\xC6" + "\x23\x44\x6D\xA1\x56\x94\x29\xEC\x4B\xCD\x01\x84\x32\x25\xEF\x00\x91\x0B\xCC\xF3" + "\x06\x3B\x80\xF5\x46\xAC\xD2\xED\x5F\x70\x2B\x56\x2F\x21\x0A\xE9\x80\x87\x38\xAD" + "\xB0\x2A\xEB\x27\xF2\xD9\x20\x2A\x66\x0E\xF5\xC9\x20\x4A\xB4\x3C\xCE\xD6\x24\x97" + "\xDB\xB1\xED\x94\x12\x6A\x2F\x03\x98\x4A\xD4\xD1\x72\xF3\x7A\x66\x74\x7E\x2A\x5B" + "\xDE\xEF\x43\xBC\xB9\x8C\x49\x01"; + + fail = !!memcmp(result, expected, 1024/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA256/128/440 (C0UNT=1, E=32, N=16, A=32, P=32)\n"; + } + + { + // [SHA-512], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128] + // [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 2048] + const byte entropy1[] = "\x55\x4e\x8f\xfd\xc4\x9a\xd8\xf9\x9a\xe5\xd5\xf8\x1a\xf5\xda\xfb\x7f\x75\x53\xd7\xcb\x56\x8e\xa7\x3c\xc0\x82\xdd\x80\x76\x25\xc0"; + const byte entropy2[] = "\x78\x07\x3e\x86\x79\x4b\x10\x95\x88\xf4\x22\xf9\xbd\x04\x7e\xc0\xce\xab\xd6\x78\x6b\xdf\xe2\x89\xb3\x16\x43\x9c\x32\x2d\xb2\x59"; + const byte nonce[] = "\xf0\x89\x78\xde\x2d\xc2\xcd\xd9\xc0\xfd\x3d\x84\xd9\x8b\x8e\x8e"; + const byte personalization[] = "\x3e\x52\x7a\xb5\x81\x2b\x0c\x0e\x98\x2a\x95\x78\x93\x98\xd9\xeb\xf1\xb9\xeb\xd6\x1d\x02\x05\xed\x42\x21\x2d\x24\xb8\x37\xf8\x41"; + const byte additional1[] = "\xf2\x6b\xb1\xef\x30\xca\x8f\x97\xc0\x19\xd0\x79\xe5\xc6\x5e\xae\xd1\xa3\x9a\x52\xaf\x12\xe8\x28\xde\x03\x70\x79\x9a\x70\x11\x8b"; + const byte additional2[] = "\xb0\x9d\xb5\xa8\x45\xec\x79\x7a\x4b\x60\x7e\xe4\xd5\x58\x56\x70\x35\x20\x9b\xd8\xe5\x01\x6c\x78\xff\x1f\x6b\x93\xbf\x7c\x34\xca"; + const byte additional3[] = "\x45\x92\x2f\xb3\x5a\xd0\x6a\x84\x5f\xc9\xca\x16\x4a\x42\xbb\x59\x84\xb4\x38\x57\xa9\x16\x23\x48\xf0\x2f\x51\x61\x24\x35\xb8\x62"; + + Hash_DRBG drbg(entropy1, 32, nonce, 16, personalization, 32); + drbg.IncorporateEntropy(entropy2, 32, additional1, 32); + + SecByteBlock result(256); + drbg.GenerateBlock(additional2, 32, result, result.size()); + drbg.GenerateBlock(additional3, 32, result, result.size()); + + const byte expected[] = "\x1F\x20\x83\x9E\x22\x55\x3B\x1E\x6C\xD4\xF6\x3A\x47\xC3\x99\x54\x0F\x69\xA3\xBB" + "\x37\x47\xA0\x2A\x12\xAC\xC7\x00\x85\xC5\xCC\xF4\x7B\x12\x5A\x4A\xEA\xED\x2F\xE5" + "\x31\x51\x0D\xC1\x8E\x50\x29\xE2\xA6\xCB\x8F\x34\xBA\xDA\x8B\x47\x32\x33\x81\xF1" + "\x2D\xF6\x8B\x73\x8C\xFF\x15\xC8\x8E\x8C\x31\x48\xFA\xC3\xC4\x9F\x52\x81\x23\xC2" + "\x2A\x83\xBD\xF1\x44\xEF\x15\x49\x93\x44\x83\x6B\x37\x5D\xBB\xFF\x72\xD2\x86\x96" + "\x62\xF8\x4D\x12\x3B\x16\xCB\xAC\xA1\x00\x12\x1F\x94\xA8\xD5\xAE\x9A\x9E\xDA\xC8" + "\xD7\x6D\x59\x33\xFD\x55\xC9\xCC\x5B\xAD\x39\x73\xB5\x13\x8B\x96\xDF\xDB\xF5\x90" + "\x81\xDF\x68\x6A\x30\x72\x42\xF2\x74\xAE\x7F\x1F\x7F\xFE\x8B\x3D\x49\x38\x98\x34" + "\x7C\x63\x46\x6E\xAF\xFA\xCB\x06\x06\x08\xE6\xC8\x35\x3C\x68\xB8\xCC\x9D\x5C\xDF" + "\xDB\xC0\x41\x44\x48\xE6\x11\xD4\x78\x50\x81\x91\xED\x1D\x75\xF3\xBD\x79\xFF\x1E" + "\x37\xAF\xC6\x5D\x49\xD6\x5C\xAC\x5B\xCB\xD6\x91\x37\x51\xFA\x98\x70\xFC\x32\xB3" + "\xF2\x86\xE4\xED\x74\xF2\x5D\x8B\x6C\x4D\xB8\xDE\xD8\x4A\xD6\x5E\xD6\x6D\xAE\xB1" + "\x1B\xA2\x94\x52\x54\xAD\x3C\x3D\x25\xBD\x12\x46\x3C\xA0\x45\x9D"; + + fail = !!memcmp(result, expected, 2048/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA512/256/888 (C0UNT=0, E=32, N=16, A=32, P=32)\n"; + } + + { + // [SHA-512], [PredictionResistance = False], [EntropyInputLen = 256], [NonceLen = 128] + // [PersonalizationStringLen = 256], [AdditionalInputLen = 256], [ReturnedBitsLen = 2048] + const byte entropy1[] = "\x0c\x9f\xcd\x06\x21\x3c\xb2\xf6\x3c\xdf\x79\x76\x4b\x46\x74\xfc\xdf\x68\xb0\xff\xae\xc7\x21\x8a\xa2\xaf\x4e\x4c\xb9\xe6\x60\x78"; + const byte entropy2[] = "\x75\xb8\x49\x54\xdf\x30\x10\x16\x2c\x06\x8c\x12\xeb\x6c\x1d\x03\x64\x5c\xad\x10\x5c\xc3\x17\x69\xb2\x5a\xc1\x7c\xb8\x33\x5b\x45"; + const byte nonce[] = "\x43\x1c\x4d\x65\x93\x96\xad\xdc\xc1\x6d\x17\x9f\x7f\x57\x24\x4d"; + const byte personalization[] = "\x7e\x54\xbd\x87\xd2\x0a\x95\xd7\xc4\x0c\x3b\x1b\x32\x15\x26\xd2\x06\x67\xa4\xac\xc1\xaa\xfb\x55\x91\x68\x2c\xb5\xc9\xcd\x66\x05"; + const byte additional1[] = "\xd5\x74\x9e\x56\xfb\x5f\xf3\xf8\x2c\x73\x2b\x7a\x83\xe0\xde\x06\x85\x0b\xf0\x57\x50\xc8\x55\x60\x4a\x41\x4f\x86\xb1\x68\x14\x03"; + const byte additional2[] = "\x9a\x83\xbb\x06\xdf\x4d\x53\x89\xf5\x3f\x24\xff\xf7\xcd\x0c\xcf\x4f\xbe\x46\x79\x8e\xce\x82\xa8\xc4\x6b\x5f\x8e\x58\x32\x62\x23"; + const byte additional3[] = "\x48\x13\xc4\x95\x10\x99\xdd\x7f\xd4\x77\x3c\x9b\x8a\xa4\x1c\x3d\xb0\x93\x92\x50\xba\x23\x98\xef\x4b\x1b\xd2\x53\xc1\x61\xda\xc6"; + + Hash_DRBG drbg(entropy1, 32, nonce, 16, personalization, 32); + drbg.IncorporateEntropy(entropy2, 32, additional1, 32); + + SecByteBlock result(256); + drbg.GenerateBlock(additional2, 32, result, result.size()); + drbg.GenerateBlock(additional3, 32, result, result.size()); + + const byte expected[] = "\xE1\x7E\x4B\xEE\xD1\x65\x4F\xB2\xFC\xC8\xE8\xD7\xC6\x72\x7D\xD2\xE3\x15\x73\xC0" + "\x23\xC8\x55\x5D\x2B\xD8\x28\xD8\x31\xE4\xC9\x87\x42\x51\x87\x66\x43\x1F\x2C\xA4" + "\x73\xED\x4E\x50\x12\xC4\x50\x0E\x4C\xDD\x14\x73\xA2\xFB\xB3\x07\x0C\x66\x97\x4D" + "\x89\xDE\x35\x1C\x93\xE7\xE6\x8F\x20\x3D\x84\xE6\x73\x46\x0F\x7C\xF4\x3B\x6C\x02" + "\x23\x7C\x79\x6C\x86\xD9\x48\x80\x9C\x34\xCB\xA1\x23\xE7\xF7\x8A\x2E\x4B\x9D\x39" + "\xA5\x86\x1A\x73\x58\x28\x5A\x1D\x8D\x4A\xBD\x42\xD5\x49\x2B\xDF\x53\x1D\xE7\x4A" + "\x5F\x74\x09\x7F\xDC\x29\x7D\x58\x9C\x4B\xC5\x2F\x3B\x8F\xBF\x56\xCA\x48\x0A\x74" + "\xAE\xFF\xDD\x12\xE4\xF6\xAB\x83\x26\x4F\x52\x8A\x19\xBB\x91\x32\xA4\x42\xEC\x4F" + "\x3C\x76\xED\x9F\x03\xAA\x5E\x53\x79\x4C\xD0\x06\xD2\x1A\x42\x9D\xB1\xA7\xEC\xF7" + "\x5B\xD4\x03\x70\x1E\xF2\x47\x26\x48\xAC\x35\xEE\xD0\x58\x40\x94\x8C\x11\xD0\xEB" + "\x77\x39\x5A\xA3\xD5\xD0\xD3\xC3\x68\xE1\x75\xAA\xC0\x44\xEA\xD8\xDD\x13\x3F\xF9" + "\x7D\x21\x14\x34\xA5\x87\x43\xA4\x0A\x96\x77\x00\xCC\xCA\xB1\xDA\xC4\x39\xE0\x66" + "\x37\x05\x6E\xAC\xF2\xE6\xC6\xC5\x4F\x79\xD3\xE5\x6A\x3D\x36\x3F"; + + fail = !!memcmp(result, expected, 2048/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "Hash_DRBG SHA512/256/888 (C0UNT=1, E=32, N=16, A=32, P=32)\n"; + } + + return pass; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat4.cpp b/external/ours/library/crypto/src/shared/original/validat4.cpp new file mode 100755 index 000000000..e41c1c8b1 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat4.cpp @@ -0,0 +1,1813 @@ +// validat4.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "hex.h" +#include "base32.h" +#include "base64.h" + +#include "rc2.h" +#include "aes.h" +#include "des.h" +#include "rc5.h" +#include "rc6.h" +#include "3way.h" +#include "aria.h" +#include "cast.h" +#include "mars.h" +#include "idea.h" +#include "gost.h" +#include "seal.h" +#include "seed.h" +#include "safer.h" +#include "shark.h" +#include "square.h" +#include "serpent.h" +#include "shacal2.h" +#include "twofish.h" +#include "blowfish.h" +#include "camellia.h" +#include "skipjack.h" + +#include "arc4.h" +#include "salsa.h" +#include "chacha.h" +#include "rabbit.h" +#include "sosemanuk.h" + +#include "modes.h" +#include "cmac.h" +#include "dmac.h" +#include "hmac.h" +#include "vmac.h" +#include "ttmac.h" + +#include "drbg.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + + +bool ValidateHmacDRBG() +{ + std::cout << "\nTesting NIST HMAC DRBGs...\n\n"; + bool pass=true, fail; + + // # CAVS 14.3 + // # DRBG800-90A information for "drbg_pr" + // # Generated on Tue Apr 02 15:32:12 2013 + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 0], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x79\x34\x9b\xbf\x7c\xdd\xa5\x79\x95\x57\x86\x66\x21\xc9\x13\x83"; + const byte entropy2[] = "\xc7\x21\x5b\x5b\x96\xc4\x8e\x9b\x33\x8c\x74\xe3\xe9\x9d\xfe\xdf"; + const byte nonce[] = "\x11\x46\x73\x3a\xbf\x8c\x35\xc8"; + + HMAC_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(result, result.size()); + drbg.GenerateBlock(result, result.size()); + + const byte expected[] = "\xc6\xa1\x6a\xb8\xd4\x20\x70\x6f\x0f\x34\xab\x7f\xec\x5a\xdc\xa9\xd8\xca\x3a\x13" + "\x3e\x15\x9c\xa6\xac\x43\xc6\xf8\xa2\xbe\x22\x83\x4a\x4c\x0a\x0a\xff\xb1\x0d\x71" + "\x94\xf1\xc1\xa5\xcf\x73\x22\xec\x1a\xe0\x96\x4e\xd4\xbf\x12\x27\x46\xe0\x87\xfd" + "\xb5\xb3\xe9\x1b\x34\x93\xd5\xbb\x98\xfa\xed\x49\xe8\x5f\x13\x0f\xc8\xa4\x59\xb7"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "HMAC_DRBG SHA1/128/440 (COUNT=0, E=16, N=8)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 0], [ReturnedBitsLen = 640] + const byte entropy1[] = "\xee\x57\xfc\x23\x60\x0f\xb9\x02\x9a\x9e\xc6\xc8\x2e\x7b\x51\xe4"; + const byte entropy2[] = "\x84\x1d\x27\x6c\xa9\x51\x90\x61\xd9\x2d\x7d\xdf\xa6\x62\x8c\xa3"; + const byte nonce[] = "\x3e\x97\x21\xe4\x39\x3e\xf9\xad"; + + HMAC_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(result, result.size()); + drbg.GenerateBlock(result, result.size()); + + const byte expected[] = "\xee\x26\xa5\xc8\xef\x08\xa1\xca\x8f\x14\x15\x4d\x67\xc8\x8f\x5e\x7e\xd8\x21\x9d" + "\x93\x1b\x98\x42\xac\x00\x39\xf2\x14\x55\x39\xf2\x14\x2b\x44\x11\x7a\x99\x8c\x22" + "\xf5\x90\xf6\xc9\xb3\x8b\x46\x5b\x78\x3e\xcf\xf1\x3a\x77\x50\x20\x1f\x7e\xcf\x1b" + "\x8a\xb3\x93\x60\x4c\x73\xb2\x38\x93\x36\x60\x9a\xf3\x44\x0c\xde\x43\x29\x8b\x84"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "HMAC_DRBG SHA1/128/440 (COUNT=1, E=16, N=8)\n"; + } + + // ***************************************************** + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 16], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x7d\x70\x52\xa7\x76\xfd\x2f\xb3\xd7\x19\x1f\x73\x33\x04\xee\x8b"; + const byte entropy2[] = "\x49\x04\x7e\x87\x9d\x61\x09\x55\xee\xd9\x16\xe4\x06\x0e\x00\xc9"; + const byte nonce[] = "\xbe\x4a\x0c\xee\xdc\xa8\x02\x07"; + const byte additional1[] = "\xfd\x8b\xb3\x3a\xab\x2f\x6c\xdf\xbc\x54\x18\x11\x86\x1d\x51\x8d"; + const byte additional2[] = "\x99\xaf\xe3\x47\x54\x04\x61\xdd\xf6\xab\xeb\x49\x1e\x07\x15\xb4"; + const byte additional3[] = "\x02\xf7\x73\x48\x2d\xd7\xae\x66\xf7\x6e\x38\x15\x98\xa6\x4e\xf0"; + + HMAC_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16, additional1, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(additional2, 16, result, result.size()); + drbg.GenerateBlock(additional3, 16, result, result.size()); + + const byte expected[] = "\xa7\x36\x34\x38\x44\xfc\x92\x51\x13\x91\xdb\x0a\xdd\xd9\x06\x4d\xbe\xe2\x4c\x89" + "\x76\xaa\x25\x9a\x9e\x3b\x63\x68\xaa\x6d\xe4\xc9\xbf\x3a\x0e\xff\xcd\xa9\xcb\x0e" + "\x9d\xc3\x36\x52\xab\x58\xec\xb7\x65\x0e\xd8\x04\x67\xf7\x6a\x84\x9f\xb1\xcf\xc1" + "\xed\x0a\x09\xf7\x15\x50\x86\x06\x4d\xb3\x24\xb1\xe1\x24\xf3\xfc\x9e\x61\x4f\xcb"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "HMAC_DRBG SHA1/128/440 (COUNT=0, E=16, N=8, A=16)\n"; + } + + { + // [SHA-1], [PredictionResistance = False], [EntropyInputLen = 128], [NonceLen = 64] + // [PersonalizationStringLen = 0], [AdditionalInputLen = 16], [ReturnedBitsLen = 640] + const byte entropy1[] = "\x29\xc6\x2a\xfa\x3c\x52\x20\x8a\x3f\xde\xcb\x43\xfa\x61\x3f\x15"; + const byte entropy2[] = "\xbd\x87\xbe\x99\xd1\x84\x16\x54\x12\x31\x41\x40\xd4\x02\x71\x41"; + const byte nonce[] = "\x6c\x9e\xb5\x9a\xc3\xc2\xd4\x8b"; + const byte additional1[] = "\x43\x3d\xda\xf2\x59\xd1\x4b\xcf\x89\x76\x30\xcc\xaa\x27\x33\x8c"; + const byte additional2[] = "\x14\x11\x46\xd4\x04\xf2\x84\xc2\xd0\x2b\x6a\x10\x15\x6e\x33\x82"; + const byte additional3[] = "\xed\xc3\x43\xdb\xff\xe7\x1a\xb4\x11\x4a\xc3\x63\x9d\x44\x5b\x65"; + + HMAC_DRBG drbg(entropy1, 16, nonce, 8); + drbg.IncorporateEntropy(entropy2, 16, additional1, 16); + + SecByteBlock result(80); + drbg.GenerateBlock(additional2, 16, result, result.size()); + drbg.GenerateBlock(additional3, 16, result, result.size()); + + const byte expected[] = "\x8c\x73\x0f\x05\x26\x69\x4d\x5a\x9a\x45\xdb\xab\x05\x7a\x19\x75\x35\x7d\x65\xaf" + "\xd3\xef\xf3\x03\x32\x0b\xd1\x40\x61\xf9\xad\x38\x75\x91\x02\xb6\xc6\x01\x16\xf6" + "\xdb\x7a\x6e\x8e\x7a\xb9\x4c\x05\x50\x0b\x4d\x1e\x35\x7d\xf8\xe9\x57\xac\x89\x37" + "\xb0\x5f\xb3\xd0\x80\xa0\xf9\x06\x74\xd4\x4d\xe1\xbd\x6f\x94\xd2\x95\xc4\x51\x9d"; + + fail = !!memcmp(result, expected, 640/8); + pass = !fail && pass; + + std::cout << (fail ? "FAILED " : "passed ") << "HMAC_DRBG SHA1/128/440 (COUNT=1, E=16, N=8, A=16)\n"; + } + + return pass; +} + +class CipherFactory +{ +public: + virtual unsigned int BlockSize() const =0; + virtual unsigned int KeyLength() const =0; + + virtual BlockTransformation* NewEncryption(const byte *keyStr) const =0; + virtual BlockTransformation* NewDecryption(const byte *keyStr) const =0; +}; + +template class FixedRoundsCipherFactory : public CipherFactory +{ +public: + FixedRoundsCipherFactory(unsigned int keylen=0) : + m_keylen(keylen ? keylen : static_cast(E::DEFAULT_KEYLENGTH)) {} + + unsigned int BlockSize() const {return E::BLOCKSIZE;} + unsigned int KeyLength() const {return m_keylen;} + + BlockTransformation* NewEncryption(const byte *keyStr) const + {return new E(keyStr, m_keylen);} + BlockTransformation* NewDecryption(const byte *keyStr) const + {return new D(keyStr, m_keylen);} + + unsigned int m_keylen; +}; + +template class VariableRoundsCipherFactory : public CipherFactory +{ +public: + VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0) : + m_keylen(keylen ? keylen : static_cast(E::DEFAULT_KEYLENGTH)), + m_rounds(rounds ? rounds : static_cast(E::DEFAULT_ROUNDS)) {} + + unsigned int BlockSize() const {return static_cast(E::BLOCKSIZE);} + unsigned int KeyLength() const {return m_keylen;} + + BlockTransformation* NewEncryption(const byte *keyStr) const + {return new E(keyStr, m_keylen, m_rounds);} + BlockTransformation* NewDecryption(const byte *keyStr) const + {return new D(keyStr, m_keylen, m_rounds);} + + unsigned int m_keylen, m_rounds; +}; + +bool BlockTransformationTest(const CipherFactory &cg, BufferedTransformation &valdata, unsigned int tuples = 0xffff) +{ + HexEncoder output(new FileSink(std::cout)); + SecByteBlock plain(cg.BlockSize()), cipher(cg.BlockSize()), out(cg.BlockSize()), outplain(cg.BlockSize()); + SecByteBlock key(cg.KeyLength()); + bool pass=true, fail; + + while (valdata.MaxRetrievable() && tuples--) + { + (void)valdata.Get(key, cg.KeyLength()); + (void)valdata.Get(plain, cg.BlockSize()); + (void)valdata.Get(cipher, cg.BlockSize()); + + member_ptr transE(cg.NewEncryption(key)); + transE->ProcessBlock(plain, out); + fail = memcmp(out, cipher, cg.BlockSize()) != 0; + + member_ptr transD(cg.NewDecryption(key)); + transD->ProcessBlock(out, outplain); + fail=fail || memcmp(outplain, plain, cg.BlockSize()); + + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + output.Put(key, cg.KeyLength()); + std::cout << " "; + output.Put(outplain, cg.BlockSize()); + std::cout << " "; + output.Put(out, cg.BlockSize()); + std::cout << std::endl; + } + return pass; +} + +class FilterTester : public Unflushable +{ +public: + FilterTester(const byte *validOutput, size_t outputLen) + : validOutput(validOutput), outputLen(outputLen), counter(0), fail(false) {} + void PutByte(byte inByte) + { + if (counter >= outputLen || validOutput[counter] != inByte) + { + std::cerr << "incorrect output " << counter << ", " << (word16)validOutput[counter] << ", " << (word16)inByte << "\n"; + fail = true; + CRYPTOPP_ASSERT(false); + } + counter++; + } + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + CRYPTOPP_UNUSED(messageEnd), CRYPTOPP_UNUSED(blocking); + + while (length--) + FilterTester::PutByte(*inString++); + + if (messageEnd) + if (counter != outputLen) + { + fail = true; + CRYPTOPP_ASSERT(false); + } + + return 0; + } + bool GetResult() + { + return !fail; + } + + const byte *validOutput; + size_t outputLen, counter; + bool fail; +}; + +bool TestFilter(BufferedTransformation &bt, const byte *in, size_t inLen, const byte *out, size_t outLen) +{ + FilterTester *ft; + bt.Attach(ft = new FilterTester(out, outLen)); + + while (inLen) + { + size_t randomLen = GlobalRNG().GenerateWord32(0, (word32)inLen); + bt.Put(in, randomLen); + in += randomLen; + inLen -= randomLen; + } + bt.MessageEnd(); + return ft->GetResult(); +} + +bool ValidateDES() +{ + std::cout << "\nDES validation suite running...\n\n"; + + FileSource valdata(DataDir("TestData/descert.dat").c_str(), true, new HexDecoder); + bool pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata); + + std::cout << "\nTesting EDE2, EDE3, and XEX3 variants...\n\n"; + + FileSource valdata1(DataDir("TestData/3desval.dat").c_str(), true, new HexDecoder); + pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata1, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata1, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata1, 1) && pass; + + return pass; +} + +bool TestModeIV(SymmetricCipher &e, SymmetricCipher &d) +{ + SecByteBlock lastIV, iv(e.IVSize()); + StreamTransformationFilter filter(e, new StreamTransformationFilter(d)); + + // Enterprise Analysis finding on the stack based array + const int BUF_SIZE=20480U; + AlignedSecByteBlock plaintext(BUF_SIZE); + + for (unsigned int i=1; i cbcmac(key); + HashFilter cbcmacFilter(cbcmac); + fail = !TestFilter(cbcmacFilter, plain_3, sizeof(plain_3), mac1, sizeof(mac1)); + pass = pass && !fail; + std::cout << (fail ? "FAILED " : "passed ") << "CBC MAC" << std::endl; + + DMAC dmac(key); + HashFilter dmacFilter(dmac); + fail = !TestFilter(dmacFilter, plain_3, sizeof(plain_3), mac2, sizeof(mac2)); + pass = pass && !fail; + std::cout << (fail ? "FAILED " : "passed ") << "DMAC" << std::endl; + } + + return pass; +} + +bool ValidateIDEA() +{ + std::cout << "\nIDEA validation suite running...\n\n"; + + FileSource valdata(DataDir("TestData/ideaval.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +} + +bool ValidateSAFER() +{ + std::cout << "\nSAFER validation suite running...\n\n"; + + FileSource valdata(DataDir("TestData/saferval.dat").c_str(), true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(VariableRoundsCipherFactory(8,6), valdata, 4) && pass; + pass = BlockTransformationTest(VariableRoundsCipherFactory(16,12), valdata, 4) && pass; + pass = BlockTransformationTest(VariableRoundsCipherFactory(8,6), valdata, 4) && pass; + pass = BlockTransformationTest(VariableRoundsCipherFactory(16,10), valdata, 4) && pass; + return pass; +} + +bool ValidateRC2() +{ + std::cout << "\nRC2 validation suite running...\n\n"; + + FileSource valdata(DataDir("TestData/rc2val.dat").c_str(), true, new HexDecoder); + HexEncoder output(new FileSink(std::cout)); + SecByteBlock plain(RC2Encryption::BLOCKSIZE), cipher(RC2Encryption::BLOCKSIZE), out(RC2Encryption::BLOCKSIZE), outplain(RC2Encryption::BLOCKSIZE); + SecByteBlock key(128); + bool pass=true, fail; + + while (valdata.MaxRetrievable()) + { + byte keyLen, effectiveLen; + + (void)valdata.Get(keyLen); + (void)valdata.Get(effectiveLen); + (void)valdata.Get(key, keyLen); + (void)valdata.Get(plain, RC2Encryption::BLOCKSIZE); + (void)valdata.Get(cipher, RC2Encryption::BLOCKSIZE); + + member_ptr transE(new RC2Encryption(key, keyLen, effectiveLen)); + transE->ProcessBlock(plain, out); + fail = memcmp(out, cipher, RC2Encryption::BLOCKSIZE) != 0; + + member_ptr transD(new RC2Decryption(key, keyLen, effectiveLen)); + transD->ProcessBlock(out, outplain); + fail=fail || memcmp(outplain, plain, RC2Encryption::BLOCKSIZE); + + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + output.Put(key, keyLen); + std::cout << " "; + output.Put(outplain, RC2Encryption::BLOCKSIZE); + std::cout << " "; + output.Put(out, RC2Encryption::BLOCKSIZE); + std::cout << std::endl; + } + return pass; +} + +bool ValidateARC4() +{ + unsigned char Key0[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; + unsigned char Input0[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + unsigned char Output0[] = {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96}; + + unsigned char Key1[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + unsigned char Input1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Output1[]={0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79}; + + unsigned char Key2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Input2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Output2[]={0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a}; + + unsigned char Key3[]={0xef,0x01,0x23,0x45}; + unsigned char Input3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Output3[]={0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61}; + + unsigned char Key4[]={ 0x01,0x23,0x45,0x67,0x89,0xab, 0xcd,0xef }; + unsigned char Input4[] = + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01}; + unsigned char Output4[]= { + 0x75,0x95,0xc3,0xe6,0x11,0x4a,0x09,0x78,0x0c,0x4a,0xd4, + 0x52,0x33,0x8e,0x1f,0xfd,0x9a,0x1b,0xe9,0x49,0x8f, + 0x81,0x3d,0x76,0x53,0x34,0x49,0xb6,0x77,0x8d,0xca, + 0xd8,0xc7,0x8a,0x8d,0x2b,0xa9,0xac,0x66,0x08,0x5d, + 0x0e,0x53,0xd5,0x9c,0x26,0xc2,0xd1,0xc4,0x90,0xc1, + 0xeb,0xbe,0x0c,0xe6,0x6d,0x1b,0x6b,0x1b,0x13,0xb6, + 0xb9,0x19,0xb8,0x47,0xc2,0x5a,0x91,0x44,0x7a,0x95, + 0xe7,0x5e,0x4e,0xf1,0x67,0x79,0xcd,0xe8,0xbf,0x0a, + 0x95,0x85,0x0e,0x32,0xaf,0x96,0x89,0x44,0x4f,0xd3, + 0x77,0x10,0x8f,0x98,0xfd,0xcb,0xd4,0xe7,0x26,0x56, + 0x75,0x00,0x99,0x0b,0xcc,0x7e,0x0c,0xa3,0xc4,0xaa, + 0xa3,0x04,0xa3,0x87,0xd2,0x0f,0x3b,0x8f,0xbb,0xcd, + 0x42,0xa1,0xbd,0x31,0x1d,0x7a,0x43,0x03,0xdd,0xa5, + 0xab,0x07,0x88,0x96,0xae,0x80,0xc1,0x8b,0x0a,0xf6, + 0x6d,0xff,0x31,0x96,0x16,0xeb,0x78,0x4e,0x49,0x5a, + 0xd2,0xce,0x90,0xd7,0xf7,0x72,0xa8,0x17,0x47,0xb6, + 0x5f,0x62,0x09,0x3b,0x1e,0x0d,0xb9,0xe5,0xba,0x53, + 0x2f,0xaf,0xec,0x47,0x50,0x83,0x23,0xe6,0x71,0x32, + 0x7d,0xf9,0x44,0x44,0x32,0xcb,0x73,0x67,0xce,0xc8, + 0x2f,0x5d,0x44,0xc0,0xd0,0x0b,0x67,0xd6,0x50,0xa0, + 0x75,0xcd,0x4b,0x70,0xde,0xdd,0x77,0xeb,0x9b,0x10, + 0x23,0x1b,0x6b,0x5b,0x74,0x13,0x47,0x39,0x6d,0x62, + 0x89,0x74,0x21,0xd4,0x3d,0xf9,0xb4,0x2e,0x44,0x6e, + 0x35,0x8e,0x9c,0x11,0xa9,0xb2,0x18,0x4e,0xcb,0xef, + 0x0c,0xd8,0xe7,0xa8,0x77,0xef,0x96,0x8f,0x13,0x90, + 0xec,0x9b,0x3d,0x35,0xa5,0x58,0x5c,0xb0,0x09,0x29, + 0x0e,0x2f,0xcd,0xe7,0xb5,0xec,0x66,0xd9,0x08,0x4b, + 0xe4,0x40,0x55,0xa6,0x19,0xd9,0xdd,0x7f,0xc3,0x16, + 0x6f,0x94,0x87,0xf7,0xcb,0x27,0x29,0x12,0x42,0x64, + 0x45,0x99,0x85,0x14,0xc1,0x5d,0x53,0xa1,0x8c,0x86, + 0x4c,0xe3,0xa2,0xb7,0x55,0x57,0x93,0x98,0x81,0x26, + 0x52,0x0e,0xac,0xf2,0xe3,0x06,0x6e,0x23,0x0c,0x91, + 0xbe,0xe4,0xdd,0x53,0x04,0xf5,0xfd,0x04,0x05,0xb3, + 0x5b,0xd9,0x9c,0x73,0x13,0x5d,0x3d,0x9b,0xc3,0x35, + 0xee,0x04,0x9e,0xf6,0x9b,0x38,0x67,0xbf,0x2d,0x7b, + 0xd1,0xea,0xa5,0x95,0xd8,0xbf,0xc0,0x06,0x6f,0xf8, + 0xd3,0x15,0x09,0xeb,0x0c,0x6c,0xaa,0x00,0x6c,0x80, + 0x7a,0x62,0x3e,0xf8,0x4c,0x3d,0x33,0xc1,0x95,0xd2, + 0x3e,0xe3,0x20,0xc4,0x0d,0xe0,0x55,0x81,0x57,0xc8, + 0x22,0xd4,0xb8,0xc5,0x69,0xd8,0x49,0xae,0xd5,0x9d, + 0x4e,0x0f,0xd7,0xf3,0x79,0x58,0x6b,0x4b,0x7f,0xf6, + 0x84,0xed,0x6a,0x18,0x9f,0x74,0x86,0xd4,0x9b,0x9c, + 0x4b,0xad,0x9b,0xa2,0x4b,0x96,0xab,0xf9,0x24,0x37, + 0x2c,0x8a,0x8f,0xff,0xb1,0x0d,0x55,0x35,0x49,0x00, + 0xa7,0x7a,0x3d,0xb5,0xf2,0x05,0xe1,0xb9,0x9f,0xcd, + 0x86,0x60,0x86,0x3a,0x15,0x9a,0xd4,0xab,0xe4,0x0f, + 0xa4,0x89,0x34,0x16,0x3d,0xdd,0xe5,0x42,0xa6,0x58, + 0x55,0x40,0xfd,0x68,0x3c,0xbf,0xd8,0xc0,0x0f,0x12, + 0x12,0x9a,0x28,0x4d,0xea,0xcc,0x4c,0xde,0xfe,0x58, + 0xbe,0x71,0x37,0x54,0x1c,0x04,0x71,0x26,0xc8,0xd4, + 0x9e,0x27,0x55,0xab,0x18,0x1a,0xb7,0xe9,0x40,0xb0, + 0xc0}; + + member_ptr arc4; + bool pass=true, fail; + unsigned int i; + + std::cout << "\nARC4 validation suite running...\n\n"; + + arc4.reset(new Weak::ARC4(Key0, sizeof(Key0))); + arc4->ProcessString(Input0, sizeof(Input0)); + fail = memcmp(Input0, Output0, sizeof(Input0)) != 0; + std::cout << (fail ? "FAILED" : "passed") << " Test 0" << std::endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key1, sizeof(Key1))); + arc4->ProcessString(Key1, Input1, sizeof(Key1)); + fail = memcmp(Output1, Key1, sizeof(Key1)) != 0; + std::cout << (fail ? "FAILED" : "passed") << " Test 1" << std::endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key2, sizeof(Key2))); + for (i=0, fail=false; iProcessByte(Input2[i]) != Output2[i]) + fail = true; + std::cout << (fail ? "FAILED" : "passed") << " Test 2" << std::endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key3, sizeof(Key3))); + for (i=0, fail=false; iProcessByte(Input3[i]) != Output3[i]) + fail = true; + std::cout << (fail ? "FAILED" : "passed") << " Test 3" << std::endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key4, sizeof(Key4))); + for (i=0, fail=false; iProcessByte(Input4[i]) != Output4[i]) + fail = true; + std::cout << (fail ? "FAILED" : "passed") << " Test 4" << std::endl; + pass = pass && !fail; + + return pass; +} + +bool ValidateRC5() +{ + std::cout << "\nRC5 validation suite running...\n\n"; + bool pass1 = true, pass2 = true; + + RC5Encryption enc; // 0 to 2040-bits (255-bytes) + pass1 = RC5Encryption::DEFAULT_KEYLENGTH == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == 0 && pass1; + pass1 = enc.StaticGetValidKeyLength(254) == 254 && pass1; + pass1 = enc.StaticGetValidKeyLength(255) == 255 && pass1; + pass1 = enc.StaticGetValidKeyLength(256) == 255 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + RC5Decryption dec; + pass2 = RC5Decryption::DEFAULT_KEYLENGTH == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == 0 && pass2; + pass2 = dec.StaticGetValidKeyLength(254) == 254 && pass2; + pass2 = dec.StaticGetValidKeyLength(255) == 255 && pass2; + pass2 = dec.StaticGetValidKeyLength(256) == 255 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/rc5val.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(VariableRoundsCipherFactory(16, 12), valdata) && pass1 && pass2; +} + +bool ValidateRC6() +{ + std::cout << "\nRC6 validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + RC6Encryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + RC6Decryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/rc6val.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 2) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 2) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateMARS() +{ + std::cout << "\nMARS validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + MARSEncryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 56 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 56 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + MARSDecryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 56 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 56 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/marsval.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateRijndael() +{ + std::cout << "\nRijndael (AES) validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + RijndaelEncryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + RijndaelDecryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/rijndael.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass3; + pass3 = RunTestDataFile("TestVectors/aes.txt") && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateTwofish() +{ + std::cout << "\nTwofish validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + TwofishEncryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 32 && pass1; + + TwofishDecryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 32 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/twofishv.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateSerpent() +{ + std::cout << "\nSerpent validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + SerpentEncryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 32 && pass1; + + SerpentDecryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 32 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/serpentv.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 5) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 4) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 3) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateBlowfish() +{ + std::cout << "\nBlowfish validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true, fail; + + BlowfishEncryption enc1; // 32 to 448-bits (4 to 56-bytes) + pass1 = enc1.StaticGetValidKeyLength(3) == 4 && pass1; + pass1 = enc1.StaticGetValidKeyLength(4) == 4 && pass1; + pass1 = enc1.StaticGetValidKeyLength(5) == 5 && pass1; + pass1 = enc1.StaticGetValidKeyLength(8) == 8 && pass1; + pass1 = enc1.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc1.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc1.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc1.StaticGetValidKeyLength(56) == 56 && pass1; + pass1 = enc1.StaticGetValidKeyLength(57) == 56 && pass1; + pass1 = enc1.StaticGetValidKeyLength(60) == 56 && pass1; + pass1 = enc1.StaticGetValidKeyLength(64) == 56 && pass1; + pass1 = enc1.StaticGetValidKeyLength(128) == 56 && pass1; + + BlowfishDecryption dec1; // 32 to 448-bits (4 to 56-bytes) + pass2 = dec1.StaticGetValidKeyLength(3) == 4 && pass2; + pass2 = dec1.StaticGetValidKeyLength(4) == 4 && pass2; + pass2 = dec1.StaticGetValidKeyLength(5) == 5 && pass2; + pass2 = dec1.StaticGetValidKeyLength(8) == 8 && pass2; + pass2 = dec1.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec1.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec1.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec1.StaticGetValidKeyLength(56) == 56 && pass2; + pass2 = dec1.StaticGetValidKeyLength(57) == 56 && pass2; + pass2 = dec1.StaticGetValidKeyLength(60) == 56 && pass2; + pass2 = dec1.StaticGetValidKeyLength(64) == 56 && pass2; + pass2 = dec1.StaticGetValidKeyLength(128) == 56 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + HexEncoder output(new FileSink(std::cout)); + const char *key[]={"abcdefghijklmnopqrstuvwxyz", "Who is John Galt?"}; + byte *plain[]={(byte *)"BLOWFISH", (byte *)"\xfe\xdc\xba\x98\x76\x54\x32\x10"}; + byte *cipher[]={(byte *)"\x32\x4e\xd0\xfe\xf4\x13\xa2\x03", (byte *)"\xcc\x91\x73\x2b\x80\x22\xf6\x84"}; + byte out[8], outplain[8]; + + for (int i=0; i<2; i++) + { + ECB_Mode::Encryption enc2((byte *)key[i], strlen(key[i])); + enc2.ProcessData(out, plain[i], 8); + fail = memcmp(out, cipher[i], 8) != 0; + + ECB_Mode::Decryption dec2((byte *)key[i], strlen(key[i])); + dec2.ProcessData(outplain, cipher[i], 8); + fail = fail || memcmp(outplain, plain[i], 8); + pass3 = pass3 && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << '\"' << key[i] << '\"'; + for (int j=0; j<(signed int)(30-strlen(key[i])); j++) + std::cout << ' '; + output.Put(outplain, 8); + std::cout << " "; + output.Put(out, 8); + std::cout << std::endl; + } + return pass1 && pass2 && pass3; +} + +bool ValidateThreeWay() +{ + std::cout << "\n3-WAY validation suite running...\n\n"; + bool pass1 = true, pass2 = true; + + ThreeWayEncryption enc; // 96-bit only + pass1 = ThreeWayEncryption::KEYLENGTH == 12 && pass1; + pass1 = enc.StaticGetValidKeyLength(8) == 12 && pass1; + pass1 = enc.StaticGetValidKeyLength(12) == 12 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 12 && pass1; + + ThreeWayDecryption dec; // 96-bit only + pass2 = ThreeWayDecryption::KEYLENGTH == 12 && pass2; + pass2 = dec.StaticGetValidKeyLength(8) == 12 && pass2; + pass2 = dec.StaticGetValidKeyLength(12) == 12 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 12 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/3wayval.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata) && pass1 && pass2; +} + +bool ValidateGOST() +{ + std::cout << "\nGOST validation suite running...\n\n"; + bool pass1 = true, pass2 = true; + + GOSTEncryption enc; // 256-bit only + pass1 = GOSTEncryption::KEYLENGTH == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(40) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + + GOSTDecryption dec; // 256-bit only + pass2 = GOSTDecryption::KEYLENGTH == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(40) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/gostval.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata) && pass1 && pass2; +} + +bool ValidateSHARK() +{ + std::cout << "\nSHARK validation suite running...\n\n"; + bool pass1 = true, pass2 = true; + + SHARKEncryption enc; // 128-bit only + pass1 = SHARKEncryption::KEYLENGTH == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(15) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(17) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 16 && pass1; + + SHARKDecryption dec; // 128-bit only + pass2 = SHARKDecryption::KEYLENGTH == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(15) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(17) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 16 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/sharkval.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata) && pass1 && pass2; +} + +bool ValidateCAST() +{ + std::cout << "\nCAST-128 validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + CAST128Encryption enc1; // 40 to 128-bits (5 to 16-bytes) + pass1 = CAST128Encryption::DEFAULT_KEYLENGTH == 16 && pass1; + pass1 = enc1.StaticGetValidKeyLength(4) == 5 && pass1; + pass1 = enc1.StaticGetValidKeyLength(5) == 5 && pass1; + pass1 = enc1.StaticGetValidKeyLength(15) == 15 && pass1; + pass1 = enc1.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc1.StaticGetValidKeyLength(17) == 16 && pass1; + + CAST128Decryption dec1; // 40 to 128-bits (5 to 16-bytes) + pass2 = CAST128Decryption::DEFAULT_KEYLENGTH == 16 && pass2; + pass2 = dec1.StaticGetValidKeyLength(4) == 5 && pass2; + pass2 = dec1.StaticGetValidKeyLength(5) == 5 && pass2; + pass2 = dec1.StaticGetValidKeyLength(15) == 15 && pass2; + pass2 = dec1.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec1.StaticGetValidKeyLength(17) == 16 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource val128(DataDir("TestData/cast128v.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), val128, 1) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(10), val128, 1) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(5), val128, 1) && pass3; + + std::cout << "\nCAST-256 validation suite running...\n\n"; + bool pass4 = true, pass5 = true, pass6 = true; + + CAST256Encryption enc2; // 128, 160, 192, 224, or 256-bits (16 to 32-bytes, step 4) + pass1 = CAST128Encryption::DEFAULT_KEYLENGTH == 16 && pass1; + pass4 = enc2.StaticGetValidKeyLength(15) == 16 && pass4; + pass4 = enc2.StaticGetValidKeyLength(16) == 16 && pass4; + pass4 = enc2.StaticGetValidKeyLength(17) == 20 && pass4; + pass4 = enc2.StaticGetValidKeyLength(20) == 20 && pass4; + pass4 = enc2.StaticGetValidKeyLength(24) == 24 && pass4; + pass4 = enc2.StaticGetValidKeyLength(28) == 28 && pass4; + pass4 = enc2.StaticGetValidKeyLength(31) == 32 && pass4; + pass4 = enc2.StaticGetValidKeyLength(32) == 32 && pass4; + pass4 = enc2.StaticGetValidKeyLength(33) == 32 && pass4; + + CAST256Decryption dec2; // 128, 160, 192, 224, or 256-bits (16 to 32-bytes, step 4) + pass2 = CAST256Decryption::DEFAULT_KEYLENGTH == 16 && pass2; + pass5 = dec2.StaticGetValidKeyLength(15) == 16 && pass5; + pass5 = dec2.StaticGetValidKeyLength(16) == 16 && pass5; + pass5 = dec2.StaticGetValidKeyLength(17) == 20 && pass5; + pass5 = dec2.StaticGetValidKeyLength(20) == 20 && pass5; + pass5 = dec2.StaticGetValidKeyLength(24) == 24 && pass5; + pass5 = dec2.StaticGetValidKeyLength(28) == 28 && pass5; + pass5 = dec2.StaticGetValidKeyLength(31) == 32 && pass5; + pass5 = dec2.StaticGetValidKeyLength(32) == 32 && pass5; + pass5 = dec2.StaticGetValidKeyLength(33) == 32 && pass5; + std::cout << (pass4 && pass5 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource val256(DataDir("TestData/cast256v.dat").c_str(), true, new HexDecoder); + pass6 = BlockTransformationTest(FixedRoundsCipherFactory(16), val256, 1) && pass6; + pass6 = BlockTransformationTest(FixedRoundsCipherFactory(24), val256, 1) && pass6; + pass6 = BlockTransformationTest(FixedRoundsCipherFactory(32), val256, 1) && pass6; + + return pass1 && pass2 && pass3 && pass4 && pass5 && pass6; +} + +bool ValidateSquare() +{ + std::cout << "\nSquare validation suite running...\n\n"; + bool pass1 = true, pass2 = true; + + SquareEncryption enc; // 128-bits only + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(15) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(17) == 16 && pass1; + + SquareDecryption dec; // 128-bits only + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(15) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(17) == 16 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/squareva.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata) && pass1 && pass2; +} + +bool ValidateSKIPJACK() +{ + std::cout << "\nSKIPJACK validation suite running...\n\n"; + bool pass1 = true, pass2 = true; + + SKIPJACKEncryption enc; // 80-bits only + pass1 = enc.StaticGetValidKeyLength(8) == 10 && pass1; + pass1 = enc.StaticGetValidKeyLength(9) == 10 && pass1; + pass1 = enc.StaticGetValidKeyLength(10) == 10 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 10 && pass1; + + SKIPJACKDecryption dec; // 80-bits only + pass2 = dec.StaticGetValidKeyLength(8) == 10 && pass2; + pass2 = dec.StaticGetValidKeyLength(9) == 10 && pass2; + pass2 = dec.StaticGetValidKeyLength(10) == 10 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 10 && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/skipjack.dat").c_str(), true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata) && pass1 && pass2; +} + +bool ValidateSEAL() +{ + const byte input[] = {0x37,0xa0,0x05,0x95,0x9b,0x84,0xc4,0x9c,0xa4,0xbe,0x1e,0x05,0x06,0x73,0x53,0x0f,0x5f,0xb0,0x97,0xfd,0xf6,0xa1,0x3f,0xbd,0x6c,0x2c,0xde,0xcd,0x81,0xfd,0xee,0x7c}; + const byte key[] = {0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0}; + const byte iv[] = {0x01, 0x35, 0x77, 0xaf}; + byte output[32]; + + std::cout << "\nSEAL validation suite running...\n\n"; + + SEAL<>::Encryption seal(key, sizeof(key), iv); + unsigned int size = sizeof(input); + bool pass = true; + + memset(output, 1, size); + seal.ProcessString(output, input, size); + for (unsigned int i=0; iInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), (const byte *)&stars[0], false) + (Name::PaddingByte(), padding) + (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0) + (Name::Separator(), ConstByteArrayParameter(lineBreak)) + (Name::Terminator(), ConstByteArrayParameter(lineBreak)) + (Name::Log2Base(), 6, true))); +} + +class MyDecoder : public BaseN_Decoder +{ +public: + MyDecoder(BufferedTransformation *attachment = NULLPTR); + void IsolatedInitialize(const NameValuePairs ¶ms); + static const int * CRYPTOPP_API GetDecodingLookupArray(); +}; + +MyDecoder::MyDecoder(BufferedTransformation *attachment) + : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) +{ +} + +void MyDecoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDecodingLookupArray(), false)(Name::Log2Base(), 6, true))); +} + +struct MyDecoderAlphabet +{ + MyDecoderAlphabet() { + std::fill(tab, tab+COUNTOF(tab), '*'); + } + byte tab[64]; +}; + +struct MyDecoderArray +{ + MyDecoderArray() { + std::fill(tab, tab+COUNTOF(tab), -1); + } + int tab[256]; +}; + +const int * MyDecoder::GetDecodingLookupArray() +{ + static bool s_initialized = false; + static MyDecoderAlphabet s_alpha; + static MyDecoderArray s_array; + + MEMORY_BARRIER(); + if (!s_initialized) + { + InitializeDecodingLookupArray(s_array.tab, s_alpha.tab, COUNTOF(s_alpha.tab), false); + s_initialized = true; + MEMORY_BARRIER(); + } + return s_array.tab; +} + +bool ValidateEncoder() +{ + // The default encoder and decoder alphabet are bogus. They are a + // string of '*'. To round trip a string both IsolatedInitialize + // must be called and work correctly. + std::cout << "\nCustom encoder validation running...\n\n"; + bool pass = true; + + int lookup[256]; + const char alphabet[64+1] = + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz01234576789*"; + const char expected[] = + "ILcBMSgriDicmKmTi2oENCsuJTufN0yWjL1HnS8xKdaiOkeZK3gKock1ktmlo1q4LlsNPrAyGrG0gjO2gzQ5FQ=="; + + MyEncoder encoder; + std::string str1; + + AlgorithmParameters eparams = MakeParameters(Name::EncodingLookupArray(),(const byte*)alphabet) + (Name::InsertLineBreaks(), false); + encoder.IsolatedInitialize(eparams); + + encoder.Detach(new StringSink(str1)); + encoder.Put((const byte*) alphabet, 64); + encoder.MessageEnd(); + + MyDecoder decoder; + std::string str2; + + MyDecoder::InitializeDecodingLookupArray(lookup, (const byte*) alphabet, 64, false); + AlgorithmParameters dparams = MakeParameters(Name::DecodingLookupArray(),(const int*)lookup); + decoder.IsolatedInitialize(dparams); + + decoder.Detach(new StringSink(str2)); + decoder.Put(ConstBytePtr(str1), BytePtrSize(str1)); + decoder.MessageEnd(); + + pass = (str1 == std::string(expected)) && pass; + pass = (str2 == std::string(alphabet, 64)) && pass; + + std::cout << (pass ? "passed:" : "FAILED:"); + std::cout << " Encode and decode\n"; + + // Try forcing an empty message. This is the Monero bug + // at https://github.com/weidai11/cryptopp/issues/562. + { + MyDecoder decoder2; + SecByteBlock empty; + + AlgorithmParameters dparams2 = MakeParameters(Name::DecodingLookupArray(),(const int*)lookup); + decoder2.IsolatedInitialize(dparams2); + + decoder2.Detach(new Redirector(TheBitBucket())); + decoder2.Put(empty.BytePtr(), empty.SizeInBytes()); + decoder2.MessageEnd(); + + // Tame the optimizer + volatile lword size = decoder2.MaxRetrievable(); + lword shadow = size; + CRYPTOPP_UNUSED(shadow); + } + + std::cout << "passed: 0-length message\n"; + + return pass; +} + +bool ValidateSHACAL2() +{ + std::cout << "\nSHACAL-2 validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + SHACAL2Encryption enc; // 128 to 512-bits (16 to 64-bytes) + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(15) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 64 && pass1; + pass1 = enc.StaticGetValidKeyLength(65) == 64 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 64 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + SHACAL2Decryption dec; // 128 to 512-bits (16 to 64-bytes) + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(15) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 64 && pass2; + pass2 = dec.StaticGetValidKeyLength(65) == 64 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 64 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/shacal2v.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(64), valdata, 10) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateARIA() +{ + std::cout << "\nARIA validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + ARIAEncryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + ARIADecryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/aria.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 15) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 15) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 15) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateSIMECK() +{ + std::cout << "\nSIMECK validation suite running...\n"; + + return RunTestDataFile("TestVectors/simeck.txt"); +} + +bool ValidateCHAM() +{ + std::cout << "\nCHAM validation suite running...\n"; + + return RunTestDataFile("TestVectors/cham.txt"); +} + +bool ValidateHIGHT() +{ + std::cout << "\nHIGHT validation suite running...\n"; + + return RunTestDataFile("TestVectors/hight.txt"); +} + +bool ValidateLEA() +{ + std::cout << "\nLEA validation suite running...\n"; + + return RunTestDataFile("TestVectors/lea.txt"); +} + +bool ValidateSIMON() +{ + std::cout << "\nSIMON validation suite running...\n"; + + return RunTestDataFile("TestVectors/simon.txt"); +} + +bool ValidateSPECK() +{ + std::cout << "\nSPECK validation suite running...\n"; + + return RunTestDataFile("TestVectors/speck.txt"); +} + +bool ValidateCamellia() +{ + std::cout << "\nCamellia validation suite running...\n\n"; + bool pass1 = true, pass2 = true, pass3 = true; + + CamelliaEncryption enc; + pass1 = enc.StaticGetValidKeyLength(8) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(16) == 16 && pass1; + pass1 = enc.StaticGetValidKeyLength(24) == 24 && pass1; + pass1 = enc.StaticGetValidKeyLength(32) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(64) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(128) == 32 && pass1; + pass1 = enc.StaticGetValidKeyLength(0) == enc.MinKeyLength() && pass1; + pass1 = enc.StaticGetValidKeyLength(SIZE_MAX) == enc.MaxKeyLength() && pass1; + + CamelliaDecryption dec; + pass2 = dec.StaticGetValidKeyLength(8) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(16) == 16 && pass2; + pass2 = dec.StaticGetValidKeyLength(24) == 24 && pass2; + pass2 = dec.StaticGetValidKeyLength(32) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(64) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(128) == 32 && pass2; + pass2 = dec.StaticGetValidKeyLength(0) == dec.MinKeyLength() && pass2; + pass2 = dec.StaticGetValidKeyLength(SIZE_MAX) == dec.MaxKeyLength() && pass2; + std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n"; + + FileSource valdata(DataDir("TestData/camellia.dat").c_str(), true, new HexDecoder); + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 15) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 15) && pass3; + pass3 = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 15) && pass3; + return pass1 && pass2 && pass3; +} + +bool ValidateSalsa() +{ + std::cout << "\nSalsa validation suite running...\n"; + + return RunTestDataFile("TestVectors/salsa.txt"); +} + +bool ValidateChaCha() +{ + std::cout << "\nChaCha validation suite running...\n"; + + return RunTestDataFile("TestVectors/chacha.txt"); +} + +bool ValidateChaChaTLS() +{ + std::cout << "\nChaCha-TLS validation suite running...\n"; + + return RunTestDataFile("TestVectors/chacha_tls.txt"); +} + +bool ValidateSosemanuk() +{ + std::cout << "\nSosemanuk validation suite running...\n"; + return RunTestDataFile("TestVectors/sosemanuk.txt"); +} + +bool ValidateRabbit() +{ + std::cout << "\nRabbit validation suite running...\n"; + return RunTestDataFile("TestVectors/rabbit.txt"); +} + +bool ValidateHC128() +{ + std::cout << "\nHC-128 validation suite running...\n"; + return RunTestDataFile("TestVectors/hc128.txt"); +} + +bool ValidateHC256() +{ + std::cout << "\nHC-256 validation suite running...\n"; + return RunTestDataFile("TestVectors/hc256.txt"); +} + +bool ValidateVMAC() +{ + std::cout << "\nVMAC validation suite running...\n"; + return RunTestDataFile("TestVectors/vmac.txt"); +} + +bool ValidateCCM() +{ + std::cout << "\nAES/CCM validation suite running...\n"; + return RunTestDataFile("TestVectors/ccm.txt"); +} + +bool ValidateGCM() +{ + std::cout << "\nAES/GCM validation suite running...\n"; + std::cout << "\n2K tables:"; + bool pass = RunTestDataFile("TestVectors/gcm.txt", MakeParameters(Name::TableSize(), (int)2048)); + std::cout << "\n64K tables:"; + return RunTestDataFile("TestVectors/gcm.txt", MakeParameters(Name::TableSize(), (int)64*1024)) && pass; +} + +bool ValidateXTS() +{ + std::cout << "\nAES/XTS validation suite running...\n"; + return RunTestDataFile("TestVectors/xts.txt"); +} + +bool ValidateCMAC() +{ + std::cout << "\nCMAC validation suite running...\n"; + return RunTestDataFile("TestVectors/cmac.txt"); +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat5.cpp b/external/ours/library/crypto/src/shared/original/validat5.cpp new file mode 100755 index 000000000..a35b95626 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat5.cpp @@ -0,0 +1,2225 @@ +// validat5.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "aes.h" +#include "crc.h" +#include "adler32.h" + +#include "md2.h" +#include "md4.h" +#include "md5.h" + +#include "sha.h" +#include "sha3.h" +#include "shake.h" +#include "keccak.h" +#include "tiger.h" +#include "blake2.h" +#include "ripemd.h" +#include "siphash.h" +#include "poly1305.h" +#include "whrlpool.h" +#include "lsh.h" + +#include "pssr.h" +#include "hkdf.h" +#include "scrypt.h" +#include "pwdbased.h" + +#include "cmac.h" +#include "dmac.h" +#include "hmac.h" +#include "ttmac.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +struct HashTestTuple +{ + HashTestTuple(const char *input, const char *output, unsigned int repeatTimes=1) + : input((byte *)input), output((byte *)output), inputLen(strlen(input)), repeatTimes(repeatTimes) {} + + HashTestTuple(const char *input, unsigned int inputLen, const char *output, unsigned int repeatTimes) + : input((byte *)input), output((byte *)output), inputLen(inputLen), repeatTimes(repeatTimes) {} + + const byte *input, *output; + size_t inputLen; + unsigned int repeatTimes; +}; + +bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsigned int testSetSize) +{ + bool pass=true, fail; + std::ostringstream oss; + + SecByteBlock digest(md.DigestSize()); + for (unsigned int i=0; i r', +// where 'r' is rate and acts like a blockSize, then TruncatedFinal acts +// like a traditional KDF and applies KeccakF1600 core function multiple +// times on state to create the stream. Regarding the NIST test vectors, +// the SHAKE128 KATs do not engage 'd > r'. However, the SHAKE256 KATs +// do engage it. +bool ValidateSHAKE_XOF() +{ + std::cout << "\nSHAKE XOF validation suite running...\n"; + bool pass = true, fail; + + ////// NIST test vectors SHAKE128VariableOut.rsp ////// + + // SHAKE128, COUNT = 0 (first test) + { + std::string m, msg = "84e950051876050dc851fbd99e6247b8"; + std::string o, out = "8599bd89f63a848c49ca593ec37a12c6"; + std::string r; + + StringSource(msg, true, new HexDecoder(new StringSink(m))); + StringSource(out, true, new HexDecoder(new StringSink(o))); + r.resize(o.size()); + + SHAKE128 hash((unsigned int)o.size()); + hash.Update(ConstBytePtr(m), BytePtrSize(m)); + hash.TruncatedFinal(BytePtr(r), BytePtrSize(r)); + + fail = r != o; + pass = pass & !fail; + + if (fail) + std::cout << "FAILED " << "SHAKE128 test COUNT=0" << std::endl; + + pass = pass && !fail; + } + + // SHAKE128, COUNT = 1125 (last test) + { + std::string m, msg = "0a13ad2c7a239b4ba73ea6592ae84ea9"; + std::string o, out = "5feaf99c15f48851943ff9baa6e5055d 8377f0dd347aa4dbece51ad3a6d9ce0c" + "01aee9fe2260b80a4673a909b532adcd d1e421c32d6460535b5fe392a58d2634" + "979a5a104d6c470aa3306c400b061db9 1c463b2848297bca2bc26d1864ba49d7" + "ff949ebca50fbf79a5e63716dc82b600 bd52ca7437ed774d169f6bf02e464879" + "56fba2230f34cd2a0485484d"; + std::string r; + + StringSource(msg, true, new HexDecoder(new StringSink(m))); + StringSource(out, true, new HexDecoder(new StringSink(o))); + r.resize(o.size()); + + SHAKE128 hash((unsigned int)o.size()); + hash.Update(ConstBytePtr(m), BytePtrSize(m)); + hash.TruncatedFinal(BytePtr(r), BytePtrSize(r)); + + fail = r != o; + pass = pass & !fail; + + if (fail) + std::cout << "FAILED " << "SHAKE128 test COUNT=1125" << std::endl; + + pass = pass && !fail; + } + + ////// NIST test vectors SHAKE256VariableOut.rsp ////// + + // SHAKE256, COUNT = 0 (first test) + { + std::string m, msg = "c61a9188812ae73994bc0d6d4021e31b f124dc72669749111232da7ac29e61c4"; + std::string o, out = "23ce"; + std::string r; + + StringSource(msg, true, new HexDecoder(new StringSink(m))); + StringSource(out, true, new HexDecoder(new StringSink(o))); + r.resize(o.size()); + + SHAKE256 hash((unsigned int)o.size()); + hash.Update(ConstBytePtr(m), BytePtrSize(m)); + hash.TruncatedFinal(BytePtr(r), BytePtrSize(r)); + + fail = r != o; + pass = pass & !fail; + + if (fail) + std::cout << "FAILED " << "SHAKE256 test COUNT=0" << std::endl; + + pass = pass && !fail; + } + + // SHAKE256, COUNT = 1245 (last test) + { + std::string m, msg = "8d8001e2c096f1b88e7c9224a086efd4 797fbf74a8033a2d422a2b6b8f6747e4"; + std::string o, out = "2e975f6a8a14f0704d51b13667d8195c 219f71e6345696c49fa4b9d08e9225d3" + "d39393425152c97e71dd24601c11abcf a0f12f53c680bd3ae757b8134a9c10d4" + "29615869217fdd5885c4db174985703a 6d6de94a667eac3023443a8337ae1bc6" + "01b76d7d38ec3c34463105f0d3949d78 e562a039e4469548b609395de5a4fd43" + "c46ca9fd6ee29ada5efc07d84d553249 450dab4a49c483ded250c9338f85cd93" + "7ae66bb436f3b4026e859fda1ca57143 2f3bfc09e7c03ca4d183b741111ca048" + "3d0edabc03feb23b17ee48e844ba2408 d9dcfd0139d2e8c7310125aee801c61a" + "b7900d1efc47c078281766f361c5e611 1346235e1dc38325666c"; + std::string r; + + StringSource(msg, true, new HexDecoder(new StringSink(m))); + StringSource(out, true, new HexDecoder(new StringSink(o))); + r.resize(o.size()); + + SHAKE256 hash((unsigned int)o.size()); + hash.Update(ConstBytePtr(m), BytePtrSize(m)); + hash.TruncatedFinal(BytePtr(r), BytePtrSize(r)); + + fail = r != o; + pass = pass & !fail; + + if (fail) + std::cout << "FAILED " << "SHAKE256 test COUNT=0" << std::endl; + + pass = pass && !fail; + } + + std::cout << (!pass ? "FAILED " : "passed ") << "SHAKE XOF message digests" << std::endl; + + return pass; +} + +bool ValidateTiger() +{ + std::cout << "\nTiger validation suite running...\n\n"; + + HashTestTuple testSet[] = + { + HashTestTuple("", "\x32\x93\xac\x63\x0c\x13\xf0\x24\x5f\x92\xbb\xb1\x76\x6e\x16\x16\x7a\x4e\x58\x49\x2d\xde\x73\xf3"), + HashTestTuple("a", "\x77\xBE\xFB\xEF\x2E\x7E\xF8\xAB\x2E\xC8\xF9\x3B\xF5\x87\xA7\xFC\x61\x3E\x24\x7F\x5F\x24\x78\x09"), + HashTestTuple("abc", "\x2a\xab\x14\x84\xe8\xc1\x58\xf2\xbf\xb8\xc5\xff\x41\xb5\x7a\x52\x51\x29\x13\x1c\x95\x7b\x5f\x93"), + HashTestTuple("Tiger", "\xdd\x00\x23\x07\x99\xf5\x00\x9f\xec\x6d\xeb\xc8\x38\xbb\x6a\x27\xdf\x2b\x9d\x6f\x11\x0c\x79\x37"), + HashTestTuple("message digest", "\xD9\x81\xF8\xCB\x78\x20\x1A\x95\x0D\xCF\x30\x48\x75\x1E\x44\x1C\x51\x7F\xCA\x1A\xA5\x5A\x29\xF6"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\x8d\xce\xa6\x80\xa1\x75\x83\xee\x50\x2b\xa3\x8a\x3c\x36\x86\x51\x89\x0f\xfb\xcc\xdc\x49\xa8\xcc"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "\xf7\x1c\x85\x83\x90\x2a\xfb\x87\x9e\xdf\xe6\x10\xf8\x2c\x0d\x47\x86\xa3\xa5\x34\x50\x44\x86\xb5"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", "\x48\xce\xeb\x63\x08\xb8\x7d\x46\xe9\x5d\x65\x61\x12\xcd\xf1\x8d\x97\x91\x5f\x97\x65\x65\x89\x57"), + HashTestTuple("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", "\x8a\x86\x68\x29\x04\x0a\x41\x0c\x72\x9a\xd2\x3f\x5a\xda\x71\x16\x03\xb3\xcd\xd3\x57\xe4\xc1\x5e"), + HashTestTuple("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", "\xce\x55\xa6\xaf\xd5\x91\xf5\xeb\xac\x54\x7f\xf8\x4f\x89\x22\x7f\x93\x31\xda\xb0\xb6\x11\xc8\x89"), + HashTestTuple("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.", "\x63\x1a\xbd\xd1\x03\xeb\x9a\x3d\x24\x5b\x6d\xfd\x4d\x77\xb2\x57\xfc\x74\x39\x50\x1d\x15\x68\xdd"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "\xc5\x40\x34\xe5\xb4\x3e\xb8\x00\x58\x48\xa7\xe0\xae\x6a\xac\x76\xe4\xff\x59\x0a\xe7\x15\xfd\x25") + }; + + Tiger tiger; + + return HashModuleTest(tiger, testSet, COUNTOF(testSet)); +} + +bool ValidateRIPEMD() +{ + HashTestTuple testSet128[] = + { + HashTestTuple("", "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e\xcb\x61\x0f\x18\xf6\xb3\x8b\x46"), + HashTestTuple("a", "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7\xcf\xc7\x85\xe7\x2f\x57\x8d\x33"), + HashTestTuple("abc", "\xc1\x4a\x12\x19\x9c\x66\xe4\xba\x84\x63\x6b\x0f\x69\x14\x4c\x77"), + HashTestTuple("message digest", "\x9e\x32\x7b\x3d\x6e\x52\x30\x62\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5\x10\x71\x49\x22\xb3\x71\x83\x4e"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d\xdc\x22\xe8\x8b\x49\x13\x3a\x06"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f\xae\xa4\x62\x4c\x60\xc5\xc7\x02"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x3f\x45\xef\x19\x47\x32\xc2\xdb\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x4a\x7f\x57\x23\xf9\x54\xeb\xa1\x21\x6c\x9d\x8f\x63\x20\x43\x1f", 15625) + }; + + HashTestTuple testSet160[] = + { + HashTestTuple("", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31"), + HashTestTuple("a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe"), + HashTestTuple("abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc"), + HashTestTuple("message digest", "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83\x25\xdc\x15\x28", 15625) + }; + + HashTestTuple testSet256[] = + { + HashTestTuple("", "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18\x77\xfc\x52\xd6\x4d\x30\xe3\x7a\x2d\x97\x74\xfb\x1e\x5d\x02\x63\x80\xae\x01\x68\xe3\xc5\x52\x2d"), + HashTestTuple("a", "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9\x0a\x91\xba\xb7\x0a\x1e\xba\x0c\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf\xcd\x88\x3a\x91\x34\x69\x29\x25"), + HashTestTuple("abc", "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb\xce\xf5\xca\x2d\x03\xe6\xdb\xa1\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e\x1e\x42\xd2\xe9\x75\x45\x9b\x65"), + HashTestTuple("message digest", "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a\x51\x4d\x5c\x91\x4c\x39\x2c\x90\x18\xc7\xc4\x6b\xc1\x44\x65\x55\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\x64\x9d\x30\x34\x75\x1e\xa2\x16\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc\x78\x96\x11\x8a\x51\x97\x96\x87\x82\xdd\x1f\xd9\x7d\x8d\x51\x33"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x38\x43\x04\x55\x83\xaa\xc6\xc8\xc8\xd9\x12\x85\x73\xe7\xa9\x80\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\x57\x40\xa4\x08\xac\x16\xb7\x20\xb8\x44\x24\xae\x93\x1c\xbb\x1f\xe3\x63\xd1\xd0\xbf\x40\x17\xf1\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x06\xfd\xcc\x7a\x40\x95\x48\xaa\xf9\x13\x68\xc0\x6a\x62\x75\xb5\x53\xe3\xf0\x99\xbf\x0e\xa4\xed\xfd\x67\x78\xdf\x89\xa8\x90\xdd"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\xac\x95\x37\x44\xe1\x0e\x31\x51\x4c\x15\x0d\x4d\x8d\x7b\x67\x73\x42\xe3\x33\x99\x78\x82\x96\xe4\x3a\xe4\x85\x0c\xe4\xf9\x79\x78", 15625) + }; + + HashTestTuple testSet320[] = + { + HashTestTuple("", "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8"), + HashTestTuple("a", "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d"), + HashTestTuple("abc", "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d"), + HashTestTuple("message digest", "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09"), + HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4"), + HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42"), + HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\xbd\xee\x37\xf4\x37\x1e\x20\x64\x6b\x8b\x0d\x86\x2d\xda\x16\x29\x2a\xe3\x6f\x40\x96\x5e\x8c\x85\x09\xe6\x3d\x1d\xbd\xde\xcc\x50\x3e\x2b\x63\xeb\x92\x45\xbb\x66", 15625) + }; + + bool pass = true; + + std::cout << "\nRIPEMD-128 validation suite running...\n\n"; + RIPEMD128 md128; + pass = HashModuleTest(md128, testSet128, COUNTOF(testSet128)) && pass; + + std::cout << "\nRIPEMD-160 validation suite running...\n\n"; + RIPEMD160 md160; + pass = HashModuleTest(md160, testSet160, COUNTOF(testSet160)) && pass; + + std::cout << "\nRIPEMD-256 validation suite running...\n\n"; + RIPEMD256 md256; + pass = HashModuleTest(md256, testSet256, COUNTOF(testSet256)) && pass; + + std::cout << "\nRIPEMD-320 validation suite running...\n\n"; + RIPEMD320 md320; + pass = HashModuleTest(md320, testSet320, COUNTOF(testSet320)) && pass; + + return pass; +} + +#ifdef CRYPTOPP_REMOVED +bool ValidateHAVAL() +{ + HashTestTuple testSet[] = + { + HashTestTuple("", "\xC6\x8F\x39\x91\x3F\x90\x1F\x3D\xDF\x44\xC7\x07\x35\x7A\x7D\x70"), + HashTestTuple("a", "\x4D\xA0\x8F\x51\x4A\x72\x75\xDB\xC4\xCE\xCE\x4A\x34\x73\x85\x98\x39\x83\xA8\x30"), + HashTestTuple("HAVAL", "\x0C\x13\x96\xD7\x77\x26\x89\xC4\x67\x73\xF3\xDA\xAC\xA4\xEF\xA9\x82\xAD\xBF\xB2\xF1\x46\x7E\xEA"), + HashTestTuple("0123456789", "\xBE\xBD\x78\x16\xF0\x9B\xAE\xEC\xF8\x90\x3B\x1B\x9B\xC6\x72\xD9\xFA\x42\x8E\x46\x2B\xA6\x99\xF8\x14\x84\x15\x29"), + HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xC9\xC7\xD8\xAF\xA1\x59\xFD\x9E\x96\x5C\xB8\x3F\xF5\xEE\x6F\x58\xAE\xDA\x35\x2C\x0E\xFF\x00\x55\x48\x15\x3A\x61\x55\x1C\x38\xEE"), + HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xB4\x5C\xB6\xE6\x2F\x2B\x13\x20\xE4\xF8\xF1\xB0\xB2\x73\xD4\x5A\xDD\x47\xC3\x21\xFD\x23\x99\x9D\xCF\x40\x3A\xC3\x76\x36\xD9\x63") + }; + + bool pass=true; + + std::cout << "\nHAVAL validation suite running...\n\n"; + { + HAVAL3 md(16); + pass = HashModuleTest(md, testSet+0, 1) && pass; + } + { + HAVAL3 md(20); + pass = HashModuleTest(md, testSet+1, 1) && pass; + } + { + HAVAL4 md(24); + pass = HashModuleTest(md, testSet+2, 1) && pass; + } + { + HAVAL4 md(28); + pass = HashModuleTest(md, testSet+3, 1) && pass; + } + { + HAVAL5 md(32); + pass = HashModuleTest(md, testSet+4, 1) && pass; + } + { + HAVAL5 md(32); + pass = HashModuleTest(md, testSet+5, 1) && pass; + } + + return pass; +} +#endif + +bool ValidatePanama() +{ + std::cout << "\nPanama validation suite running...\n"; + return RunTestDataFile("TestVectors/panama.txt"); +} + +bool ValidateWhirlpool() +{ + std::cout << "\nWhirlpool validation suite running...\n"; + return RunTestDataFile("TestVectors/whrlpool.txt"); +} + +bool ValidateLSH() +{ + std::cout << "\nLSH validation suite running...\n"; + return RunTestDataFile("TestVectors/lsh.txt"); +} + +#ifdef CRYPTOPP_REMOVED +bool ValidateMD5MAC() +{ + const byte keys[2][MD5MAC::KEYLENGTH]={ + {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}, + {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}}; + + const char *TestVals[7]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + + const byte output[2][7][MD5MAC::DIGESTSIZE]={ + {{0x1f,0x1e,0xf2,0x37,0x5c,0xc0,0xe0,0x84,0x4f,0x98,0xe7,0xe8,0x11,0xa3,0x4d,0xa8}, + {0x7a,0x76,0xee,0x64,0xca,0x71,0xef,0x23,0x7e,0x26,0x29,0xed,0x94,0x52,0x73,0x65}, + {0xe8,0x01,0x3c,0x11,0xf7,0x20,0x9d,0x13,0x28,0xc0,0xca,0xa0,0x4f,0xd0,0x12,0xa6}, + {0xc8,0x95,0x53,0x4f,0x22,0xa1,0x74,0xbc,0x3e,0x6a,0x25,0xa2,0xb2,0xef,0xd6,0x30}, + {0x91,0x72,0x86,0x7e,0xb6,0x00,0x17,0x88,0x4c,0x6f,0xa8,0xcc,0x88,0xeb,0xe7,0xc9}, + {0x3b,0xd0,0xe1,0x1d,0x5e,0x09,0x4c,0xb7,0x1e,0x35,0x44,0xac,0xa9,0xb8,0xbf,0xa2}, + {0x93,0x37,0x16,0x64,0x44,0xcc,0x95,0x35,0xb7,0xd5,0xb8,0x0f,0x91,0xe5,0x29,0xcb}}, + {{0x2f,0x6e,0x73,0x13,0xbf,0xbb,0xbf,0xcc,0x3a,0x2d,0xde,0x26,0x8b,0x59,0xcc,0x4d}, + {0x69,0xf6,0xca,0xff,0x40,0x25,0x36,0xd1,0x7a,0xe1,0x38,0x03,0x2c,0x0c,0x5f,0xfd}, + {0x56,0xd3,0x2b,0x6c,0x34,0x76,0x65,0xd9,0x74,0xd6,0xf7,0x5c,0x3f,0xc6,0xf0,0x40}, + {0xb8,0x02,0xb2,0x15,0x4e,0x59,0x8b,0x6f,0x87,0x60,0x56,0xc7,0x85,0x46,0x2c,0x0b}, + {0x5a,0xde,0xf4,0xbf,0xf8,0x04,0xbe,0x08,0x58,0x7e,0x94,0x41,0xcf,0x6d,0xbd,0x57}, + {0x18,0xe3,0x49,0xa5,0x24,0x44,0xb3,0x0e,0x5e,0xba,0x5a,0xdd,0xdc,0xd9,0xf1,0x8d}, + {0xf2,0xb9,0x06,0xa5,0xb8,0x4b,0x9b,0x4b,0xbe,0x95,0xed,0x32,0x56,0x4e,0xe7,0xeb}}}; + + byte digest[MD5MAC::DIGESTSIZE]; + bool pass=true, fail; + std::ostringstream oss; + + oss << "\nMD5MAC validation suite running...\n"; + + for (int k=0; k<2; k++) + { + MD5MAC mac(keys[k]); + oss << "\nKEY: "; + for (int j=0;j XMACC_MD5; + + const byte keys[2][XMACC_MD5::KEYLENGTH]={ + {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb}, + {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98}}; + + const word32 counters[2]={0xccddeeff, 0x76543210}; + + const char *TestVals[7]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + + const byte output[2][7][XMACC_MD5::DIGESTSIZE]={ + {{0xcc,0xdd,0xef,0x00,0xfa,0x89,0x54,0x92,0x86,0x32,0xda,0x2a,0x3f,0x29,0xc5,0x52,0xa0,0x0d,0x05,0x13}, + {0xcc,0xdd,0xef,0x01,0xae,0xdb,0x8b,0x7b,0x69,0x71,0xc7,0x91,0x71,0x48,0x9d,0x18,0xe7,0xdf,0x9d,0x5a}, + {0xcc,0xdd,0xef,0x02,0x5e,0x01,0x2e,0x2e,0x4b,0xc3,0x83,0x62,0xc2,0xf4,0xe6,0x18,0x1c,0x44,0xaf,0xca}, + {0xcc,0xdd,0xef,0x03,0x3e,0xa9,0xf1,0xe0,0x97,0x91,0xf8,0xe2,0xbe,0xe0,0xdf,0xf3,0x41,0x03,0xb3,0x5a}, + {0xcc,0xdd,0xef,0x04,0x2e,0x6a,0x8d,0xb9,0x72,0xe3,0xce,0x9f,0xf4,0x28,0x45,0xe7,0xbc,0x80,0xa9,0xc7}, + {0xcc,0xdd,0xef,0x05,0x1a,0xd5,0x40,0x78,0xfb,0x16,0x37,0xfc,0x7a,0x1d,0xce,0xb4,0x77,0x10,0xb2,0xa0}, + {0xcc,0xdd,0xef,0x06,0x13,0x2f,0x11,0x47,0xd7,0x1b,0xb5,0x52,0x36,0x51,0x26,0xb0,0x96,0xd7,0x60,0x81}}, + {{0x76,0x54,0x32,0x11,0xe9,0xcb,0x74,0x32,0x07,0x93,0xfe,0x01,0xdd,0x27,0xdb,0xde,0x6b,0x77,0xa4,0x56}, + {0x76,0x54,0x32,0x12,0xcd,0x55,0x87,0x5c,0xc0,0x35,0x85,0x99,0x44,0x02,0xa5,0x0b,0x8c,0xe7,0x2c,0x68}, + {0x76,0x54,0x32,0x13,0xac,0xfd,0x87,0x50,0xc3,0x8f,0xcd,0x58,0xaa,0xa5,0x7e,0x7a,0x25,0x63,0x26,0xd1}, + {0x76,0x54,0x32,0x14,0xe3,0x30,0xf5,0xdd,0x27,0x2b,0x76,0x22,0x7f,0xaa,0x90,0x73,0x6a,0x48,0xdb,0x00}, + {0x76,0x54,0x32,0x15,0xfc,0x57,0x00,0x20,0x7c,0x9d,0xf6,0x30,0x6f,0xbd,0x46,0x3e,0xfb,0x8a,0x2c,0x60}, + {0x76,0x54,0x32,0x16,0xfb,0x0f,0xd3,0xdf,0x4c,0x4b,0xc3,0x05,0x9d,0x63,0x1e,0xba,0x25,0x2b,0xbe,0x35}, + {0x76,0x54,0x32,0x17,0xc6,0xfe,0xe6,0x5f,0xb1,0x35,0x8a,0xf5,0x32,0x7a,0x80,0xbd,0xb8,0x72,0xee,0xae}}}; + + // Coverity finding, also see http://stackoverflow.com/a/34509163/608639. + StreamState ss(std::cout); + + byte digest[XMACC_MD5::DIGESTSIZE]; + bool pass=true, fail; + + std::cout << "\nXMACC/MD5 validation suite running...\n"; + + for (int k=0; k<2; k++) + { + XMACC_MD5 mac(keys[k], counters[k]); + std::cout << "\nKEY: "; + for (int j=0;j pbkdf; + + std::cout << "\nPKCS #12 PBKDF validation suite running...\n\n"; + pass = TestPBKDF(pbkdf, testSet, COUNTOF(testSet)) && pass; + } + + { + // from draft-ietf-smime-password-03.txt, at http://www.imc.org/draft-ietf-smime-password + PBKDF_TestTuple testSet[] = + { + {0, 5, "70617373776f7264", "1234567878563412", "D1DAA78615F287E6"}, + {0, 500, "416C6C206E2D656E746974696573206D75737420636F6D6D756E69636174652077697468206F74686572206E2d656E74697469657320766961206E2D3120656E746974656568656568656573", "1234567878563412","6A8970BF68C92CAEA84A8DF28510858607126380CC47AB2D"} + }; + + PKCS5_PBKDF2_HMAC pbkdf; + + std::cout << "\nPKCS #5 PBKDF2 validation suite running...\n\n"; + pass = TestPBKDF(pbkdf, testSet, COUNTOF(testSet)) && pass; + } + + return pass; +} + +struct HKDF_TestTuple +{ + const char *hexSecret, *hexSalt, *hexInfo, *hexExpected; + size_t len; +}; + +bool TestHKDF(KeyDerivationFunction &kdf, const HKDF_TestTuple *testSet, unsigned int testSetSize) +{ + bool pass = true; + + for (unsigned int i=0; i") : ""); + std::cout << " "; + std::cout << (tuple.hexInfo ? (strlen(tuple.hexInfo) ? tuple.hexInfo : "<0-LEN INFO>") : ""); + std::cout << " "; + enc.Put(derived, derived.size()); + std::cout << std::endl; + } + + return pass; +} + +bool ValidateHKDF() +{ + bool pass = true; + + { + // SHA-1 from RFC 5869, Appendix A, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #4 + {"0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "085a01ea1b10f36933068b56efa5ad81 a4f14b822f5b091568a9cdd4f155fda2 c22e422478d305f3f896", 42}, + // Test Case #5 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "0bd770a74d1160f7c9f12cd5912a06eb ff6adcae899d92191fe4305673ba2ffe 8fa3f1a4e5ad79f3f334b3b202b2173c 486ea37ce3d397ed034c7f9dfeb15c5e 927336d0441f4c4300e2cff0d0900b52 d3b4", 82}, + // Test Case #6 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "0ac1af7002b3d761d1e55298da9d0506 b9ae52057220a306e07b6b87e8df21d0 ea00033de03984d34918", 42}, + // Test Case #7 + {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", NULLPTR, "", "2c91117204d745f3500d636a62f64f0 ab3bae548aa53d423b0d1f27ebba6f5e5 673a081d70cce7acfc48", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(SHA-1) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; + } + + { + // SHA-256 from RFC 5869, Appendix A, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #1 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "3cb25f25faacd57a90434f64d0362f2a 2d2d0a90cf1a5a4c5db02d56ecc4c5bf 34007208d5b887185865", 42}, + // Test Case #2 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "b11e398dc80327a1c8e7f78c596a4934 4f012eda2d4efad8a050cc4c19afa97c 59045a99cac7827271cb41c65e590e09 da3275600c2f09b8367793a9aca3db71 cc30c58179ec3e87c14c01d5c1f3434f 1d87", 82}, + // Test Case #3 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "8da4e775a563c18f715f802a063c5a31 b8a11f5c5ee1879ec3454e5f3c738d2d 9d201395faa4b61a96c8", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(SHA-256) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; + } + + { + // SHA-512, Crypto++ generated, based on RFC 5869, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "832390086CDA71FB47625BB5CEB168E4 C8E26A1A16ED34D9FC7FE92C14815793 38DA362CB8D9F925D7CB", 42}, + // Test Case #0 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "CE6C97192805B346E6161E821ED16567 3B84F400A2B514B2FE23D84CD189DDF1 B695B48CBD1C8388441137B3CE28F16A A64BA33BA466B24DF6CFCB021ECFF235 F6A2056CE3AF1DE44D572097A8505D9E 7A93", 82}, + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "F5FA02B18298A72A8C23898A8703472C 6EB179DC204C03425C970E3B164BF90F FF22D04836D0E2343BAC", 42}, + // Test Case #0 + {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", NULLPTR, "", "1407D46013D98BC6DECEFCFEE55F0F90 B0C7F63D68EB1A80EAF07E953CFC0A3A 5240A155D6E4DAA965BB", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(SHA-512) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; + } + + { + // Whirlpool, Crypto++ generated, based on RFC 5869, https://tools.ietf.org/html/rfc5869 + const HKDF_TestTuple testSet[] = + { + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9", "0D29F74CCD8640F44B0DD9638111C1B5 766EFED752AF358109E2E7C9CD4A28EF 2F90B2AD461FBA0744D4", 42}, + // Test Case #0 + {"000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 303132333435363738393a3b3c3d3e3f 404142434445464748494a4b4c4d4e4f", "606162636465666768696a6b6c6d6e6f 707172737475767778797a7b7c7d7e7f 808182838485868788898a8b8c8d8e8f 909192939495969798999a9b9c9d9e9f a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf c0c1c2c3c4c5c6c7c8c9cacbcccdcecf d0d1d2d3d4d5d6d7d8d9dadbdcdddedf e0e1e2e3e4e5e6e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "4EBE4FE2DCCEC42661699500BE279A99 3FED90351E19373B3926FAA3A410700B2 BBF77E254CF1451AE6068D64A0904D96 6F4FF25498445A501B88F50D21E3A68A8 90E09445DC5886DD00E7F4F7C58A5121 70", 82}, + // Test Case #0 + {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "", "110632D0F7AEFAC31771FC66C22BB346 2614B81E4B04BA7F2B662E0BD694F564 58615F9A9CB56C57ECF2", 42}, + // Test Case #0 + {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" /*key*/, NULLPTR /*salt*/, "" /*info*/, "4089286EBFB23DD8A02F0C9DAA35D538 EB09CD0A8CBAB203F39083AA3E0BD313 E6F91E64F21A187510B0", 42} + }; + + HKDF hkdf; + + std::cout << "\nRFC 5869 HKDF(Whirlpool) validation suite running...\n\n"; + pass = TestHKDF(hkdf, testSet, COUNTOF(testSet)) && pass; + } + + return pass; +} + +struct Scrypt_TestTuple +{ + const char * passwd; + const char * salt; + word64 n; + word32 r; + word32 p; + const char * expect; +}; + +bool TestScrypt(KeyDerivationFunction &pbkdf, const Scrypt_TestTuple *testSet, unsigned int testSetSize) +{ + bool pass = true; + + for (unsigned int i=0; i::StaticAlgorithmName() != "Poly1305(AES)"); + std::cout << (fail ? "FAILED " : "passed ") << "algorithm name\n"; + pass = pass && !fail; + } + + // Test data from http://cr.yp.to/mac/poly1305-20050329.pdf + const Poly1305_TestTuples tests[] = + { + // Appendix B, Test 1 + { + "\xec\x07\x4c\x83\x55\x80\x74\x17\x01\x42\x5b\x62\x32\x35\xad\xd6" // Key + "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00", + "\xf3\xf6", // Message + "\xfb\x44\x73\x50\xc4\xe8\x68\xc5\x2a\xc3\x27\x5c\xf9\xd4\x32\x7e", // Nonce + "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde", // Digest + 32, 2, 16, 16 + }, + // Appendix B, Test 2 + { + "\x75\xde\xaa\x25\xc0\x9f\x20\x8e\x1d\xc4\xce\x6b\x5c\xad\x3f\xbf" // Key + "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc", + "", // Message + "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc", // Nonce + "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7", // Digest + 32, 0, 16, 16 + }, + // Appendix B, Test 3 + { + "\x6a\xcb\x5f\x61\xa7\x17\x6d\xd3\x20\xc5\xc1\xeb\x2e\xdc\xdc\x74" // Key + "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08", + "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24" // Message + "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36", + "\xae\x21\x2a\x55\x39\x97\x29\x59\x5d\xea\x45\x8b\xc6\x21\xff\x0e", // Nonce + "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe", // Digest + 32, 32, 16, 16 + }, + // Appendix B, Test 4 + { + "\xe1\xa5\x66\x8a\x4d\x5b\x66\xa5\xf6\x8c\xc5\x42\x4e\xd5\x98\x2d" // Key + "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07", + "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1" // Message + "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0" + "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67" + "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9", + "\x9a\xe8\x31\xe7\x43\x97\x8d\x3a\x23\x52\x7c\x71\x28\x14\x9e\x3a", // Nonce + "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b", // Digest + 32, 63, 16, 16 + } + }; + + unsigned int count = 0; + byte digest[Poly1305::DIGESTSIZE]; + + // Positive tests + for (unsigned int i=0; i poly1305((const byte*)tests[i].key, tests[i].klen); + poly1305.Resynchronize((const byte*)tests[i].nonce, (int)tests[i].nlen); + poly1305.Update((const byte*)tests[i].message, tests[i].mlen); + poly1305.Final(digest); + + fail = memcmp(digest, tests[i].digest, tests[i].dlen) != 0; + if (fail) + { + std::cout << "FAILED " << "Poly1305 test set " << count << std::endl; + } + + count++; + pass = pass && !fail; + } + + // Positive tests + for (unsigned int i=0; i poly1305((const byte*)tests[i].key, tests[i].klen,(const byte*)tests[i].nonce, (int)tests[i].nlen); + poly1305.Update((const byte*)tests[i].message, tests[i].mlen); + poly1305.Final(digest); + + fail = memcmp(digest, tests[i].digest, tests[i].dlen) != 0; + if (fail) + { + std::cout << "FAILED " << "Poly1305 test set " << count << std::endl; + } + + count++; + pass = pass && !fail; + } + + // Negative tests + for (unsigned int i=0; i poly1305((const byte*)tests[i].key, tests[i].klen); + poly1305.Resynchronize((const byte*)tests[i].nonce, (int)tests[i].nlen); + poly1305.Update((const byte*)tests[i].message, tests[i].mlen); + poly1305.Final(digest); + + unsigned int next = (i+1) % COUNTOF(tests); + fail = memcmp(digest, tests[next].digest, tests[next].dlen) == 0; + if (fail) + { + std::cout << "FAILED " << "Poly1305 test set " << count << std::endl; + } + + count++; + pass = pass && !fail; + } + + std::cout << (!pass ? "FAILED " : "passed ") << count << " message authentication codes" << std::endl; + + return pass; +} + +bool ValidateSipHash() +{ + std::cout << "\nSipHash validation suite running...\n\n"; + bool fail, pass = true, pass1=true, pass2=true, pass3=true, pass4=true; + + { + fail = (SipHash<2,4>::StaticAlgorithmName() != "SipHash-2-4"); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-2-4 algorithm name\n"; + pass = pass && !fail; + + fail = (SipHash<2,4, false>::DIGESTSIZE != 8); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-2-4 64-bit digest size\n"; + pass = pass && !fail; + + fail = (SipHash<2,4, true>::DIGESTSIZE != 16); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-2-4 128-bit digest size\n"; + pass = pass && !fail; + + fail = (SipHash<4,8>::StaticAlgorithmName() != "SipHash-4-8"); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-4-8 algorithm name\n"; + pass = pass && !fail; + + fail = (SipHash<4,8, false>::DIGESTSIZE != 8); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-4-8 64-bit digest size\n"; + pass = pass && !fail; + + fail = (SipHash<4,8, true>::DIGESTSIZE != 16); + std::cout << (fail ? "FAILED " : "passed ") << "SipHash-4-8 128-bit digest size\n"; + pass = pass && !fail; + } + + // Siphash-2-4, 64-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<2,4, false> hash(key, 16); + byte digest[SipHash<2,4, false>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = memcmp("\x31\x0E\x0E\xDD\x47\xDB\x6F\x72", digest, COUNTOF(digest)) != 0; + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = memcmp("\xFD\x67\xDC\x93\xC5\x39\xF8\x74", digest, COUNTOF(digest)) != 0; + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = memcmp("\x37\xD1\x01\x8B\xF5\x00\x02\xAB", digest, COUNTOF(digest)) != 0; + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = memcmp("\x62\x24\x93\x9A\x79\xF5\xF5\x93", digest, COUNTOF(digest)) != 0; + pass1 = !fail && pass1; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = memcmp("\xB0\xE4\xA9\x0B\xDF\x82\x00\x9E", digest, COUNTOF(digest)) != 0; + pass1 = !fail && pass1; + + std::cout << (pass1 ? "passed " : "FAILED ") << "SipHash-2-4 64-bit MAC\n"; + pass = pass1 && pass; + } + + // Siphash-2-4, 128-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<2,4, true> hash(key, 16); + byte digest[SipHash<2,4, true>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = memcmp("\xA3\x81\x7F\x04\xBA\x25\xA8\xE6\x6D\xF6\x72\x14\xC7\x55\x02\x93", digest, COUNTOF(digest)) != 0; + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = memcmp("\xDA\x87\xC1\xD8\x6B\x99\xAF\x44\x34\x76\x59\x11\x9B\x22\xFC\x45", digest, COUNTOF(digest)) != 0; + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = memcmp("\xA1\xF1\xEB\xBE\xD8\xDB\xC1\x53\xC0\xB8\x4A\xA6\x1F\xF0\x82\x39", digest, COUNTOF(digest)) != 0; + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = memcmp("\x3B\x62\xA9\xBA\x62\x58\xF5\x61\x0F\x83\xE2\x64\xF3\x14\x97\xB4", digest, COUNTOF(digest)) != 0; + pass3 = !fail && pass3; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = memcmp("\x26\x44\x99\x06\x0A\xD9\xBA\xAB\xC4\x7F\x8B\x02\xBB\x6D\x71\xED", digest, COUNTOF(digest)) != 0; + pass3 = !fail && pass3; + + std::cout << (pass3 ? "passed " : "FAILED ") << "SipHash-2-4 128-bit MAC\n"; + pass = pass3 && pass; + } + + // Siphash-4-8, 64-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<4, 8, false> hash(key, 16); + byte digest[SipHash<4, 8, false>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = memcmp("\x41\xDA\x38\x99\x2B\x05\x79\xC8", digest, COUNTOF(digest)) != 0; + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = memcmp("\x51\xB8\x95\x52\xF9\x14\x59\xC8", digest, COUNTOF(digest)) != 0; + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = memcmp("\x47\xD7\x3F\x71\x5A\xBE\xFD\x4E", digest, COUNTOF(digest)) != 0; + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = memcmp("\x20\xB5\x8B\x9C\x07\x2F\xDB\x50", digest, COUNTOF(digest)) != 0; + pass2 = !fail && pass2; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = memcmp("\x36\x31\x9A\xF3\x5E\xE1\x12\x53", digest, COUNTOF(digest)) != 0; + pass2 = !fail && pass2; + + std::cout << (pass2 ? "passed " : "FAILED ") << "SipHash-4-8 64-bit MAC\n"; + pass = pass2 && pass; + } + + // Siphash-4-8, 128-bit MAC + { + const byte key[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; + SipHash<4, 8, true> hash(key, 16); + byte digest[SipHash<4, 8, true>::DIGESTSIZE]; + + hash.Update((const byte*)"", 0); + hash.Final(digest); + fail = memcmp("\x1F\x64\xCE\x58\x6D\xA9\x04\xE9\xCF\xEC\xE8\x54\x83\xA7\x0A\x6C", digest, COUNTOF(digest)) != 0; + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00", 1); + hash.Final(digest); + fail = memcmp("\x47\x34\x5D\xA8\xEF\x4C\x79\x47\x6A\xF2\x7C\xA7\x91\xC7\xA2\x80", digest, COUNTOF(digest)) != 0; + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06", 7); + hash.Final(digest); + fail = memcmp("\xED\x00\xE1\x3B\x18\x4B\xF1\xC2\x72\x6B\x8B\x54\xFF\xD2\xEE\xE0", digest, COUNTOF(digest)) != 0; + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07", 8); + hash.Final(digest); + fail = memcmp("\xA7\xD9\x46\x13\x8F\xF9\xED\xF5\x36\x4A\x5A\x23\xAF\xCA\xE0\x63", digest, COUNTOF(digest)) != 0; + pass4 = !fail && pass4; + + hash.Update((const byte*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08", 9); + hash.Final(digest); + fail = memcmp("\x9E\x73\x14\xB7\x54\x5C\xEC\xA3\x8B\x9A\x55\x49\xE4\xFB\x0B\xE8", digest, COUNTOF(digest)) != 0; + pass4 = !fail && pass4; + + std::cout << (pass4 ? "passed " : "FAILED ") << "SipHash-4-8 128-bit MAC\n"; + pass = pass4 && pass; + } + + return pass; +} + +struct BLAKE2_TestTuples +{ + const char *key, *message, *digest; + size_t klen, mlen, dlen; +}; + +bool ValidateBLAKE2s() +{ + std::cout << "\nBLAKE2s validation suite running...\n\n"; + bool fail, pass = true; + + { + fail = strcmp(BLAKE2s::StaticAlgorithmName(), "BLAKE2s") != 0; + std::cout << (fail ? "FAILED " : "passed ") << "algorithm name\n"; + pass = pass && !fail; + } + + const BLAKE2_TestTuples tests[] = { + { + NULLPTR, + NULLPTR, + "\x8F\x38", + 0, 0, 2 + }, + { + NULLPTR, + NULLPTR, + "\x36\xE9\xD2\x46", + 0, 0, 4 + }, + { + NULLPTR, + NULLPTR, + "\xEF\x2A\x8B\x78\xDD\x80\xDA\x9C", + 0, 0, 8 + }, + { + NULLPTR, + NULLPTR, + "\x64\x55\x0D\x6F\xFE\x2C\x0A\x01\xA1\x4A\xBA\x1E\xAD\xE0\x20\x0C", + 0, 0, 16 + }, + { + NULLPTR, + NULLPTR, + "\x69\x21\x7A\x30\x79\x90\x80\x94\xE1\x11\x21\xD0\x42\x35\x4A\x7C\x1F\x55\xB6\x48\x2C\xA1\xA5\x1E\x1B\x25\x0D\xFD\x1E\xD0\xEE\xF9", + 0, 0, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x25\xEC\xB2\xF6\xA7\x81\x82\x57\x5D\x4B\xD7\x02\x72\x6D\xE1\x82\xBB\x1E\x21\xA8\x5D\x51\x34\xAD\xA2\x25\x8D\x7E\x21\x38\x03\xA7", + 0, 15, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD4\x1C\x69\x87\x29\x7E\xDE\x4F\x08\x9B\x66\x9B\xC7\x0E\x62\xB9\xFA\xFA\x1C\x37\xCC\x31\x29\x22\xE0\xEA\x63\xE2\xE5\x85\xAA\x9F", + 0, 16, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE0\xAD\xF2\xCC\x1F\x1F\x55\x3A\xE6\xC3\xCD\x3D\xF7\x68\xEA\x66\x9C\x32\xBE\x1D\x37\xF9\xA2\x61\xD4\x4F\x45\x26\x69\xD0\xD3\xA4", + 0, 17, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x10\x42\x65\x1C\x86\x15\xC4\x87\x69\x41\x19\x1F\xB6\xD5\xC5\x1D\xEB\x4C\xA1\x8C\xAF\xEF\xEB\x79\x69\x62\x87\x0D\x6A\x5D\xEE\x20", + 0, 31, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\xB1\xC5\xDD\xDF\xB5\x7C\x48\xC5\xB0\xB3\xF5\xBE\x5B\x47\x6D\xBB\xF5\xA3\x5C\x21\xD3\xDD\x94\x13\xA1\x04\xB8\x14\xF9\x2D\x4B", + 0, 32, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x7E\x82\x07\x49\x14\x62\x11\x96\xC5\xE8\xF3\xCB\x0F\x21\x7B\x37\xAE\x9B\x64\x58\xF4\x66\x01\xB9\x21\x23\xAC\x48\x64\x30\x83\x8F", + 0, 33, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x90\xB5\xA2\x5E\x8E\xA8\xA0\xC8\x74\x85\xAE\x18\x08\x9D\x92\xEB\x14\x5A\x5D\x4E\x2C\x60\x7B\xCB\x4B\x94\xD1\x0F\xAE\x59\x33\xC1", + 0, 63, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x71\x27\x28\x45\x9E\x67\xD7\xED\xB7\xAE\xFA\x88\xFF\x5C\x7E\x7B\x5D\xA9\x94\xA1\xC3\xB1\x7B\x64\xFB\xC1\x4E\x47\xCA\xDA\x45\xDD", + 0, 64, 32 + }, + { + NULLPTR, + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x58\x72\x3B\xB1\xBE\x18\x33\x12\x31\x5E\x6E\xF7\xF2\xB1\x84\x60\x97\x2C\x19\xD3\x01\xAF\x42\x00\xAB\xDB\x04\x26\xFC\xB0\xC1\xF8", + 0, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x9A\xD4\x81\xEF\x81\x6C\xAC\xB6\x59\x35\x8E\x6D\x6B\x73\xF1\xE5\xAC\x71\xD6\x6E\x8B\x12\x6B\x73\xD9\xD9\x7D\x2F\xA7\xA4\x61\xB4", + 15, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x61\x8C\xBE\x19\x4B\x28\xDC\xA3\x8B\xE5\x1A\x79\x37\x45\xB4\x66\x3D\xF1\x9D\xB5\x8F\xFF\xEF\xC4\x5D\x37\x82\x25\x93\xEB\xE2\x93", + 15, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF3\xEC\x81\x61\x44\x5C\x6E\x2E\xE6\x52\x6A\xCA\x5F\xD9\x25\x74\x2A\x33\xB9\x1F\xEF\x0F\x7E\x54\x4F\x50\xC2\xFB\x04\x3C\x52\xD2", + 15, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF4\x81\x43\x6E\x2F\x4C\x5D\x09\x21\x73\x24\xDA\xA6\x23\x9E\xFD\xF8\x82\xCE\x0E\x3E\x4C\xB4\x17\xCC\x27\xCD\x1A\xAE\x90\x9B\x94", + 15, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x99\x5E\x74\x8E\x96\xFE\xC0\x39\x5B\x73\xA3\xC0\x4E\xC7\xF7\xBE\x89\x83\xCD\x18\x24\x60\x60\x7B\xBC\xF5\x50\xF5\x84\xD1\x71\x6B", + 15, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x21\x6E\xB9\xE2\xE4\xAF\x94\x5F\x6A\xA3\xD2\xCA\x25\x72\xFB\x8F\xDB\x95\x2F\xAC\x1C\x69\xC1\x26\x28\x31\x63\x16\x25\xA5\x2C\xF8", + 15, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE3\x71\x9F\xD8\xAE\x68\xC8\xC4\x5D\x17\xDD\x21\x33\xBB\xE1\x61\x51\x22\xC2\x3B\x00\x6E\xDD\x66\x7E\x2A\x0A\x6B\x77\xA9\x0B\x8D", + 15, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD3\xF8\x5F\x1B\xBE\x9C\x53\xCB\x7F\x5F\x5F\x62\x4D\x06\x36\x8F\xF8\x15\xA7\xF5\xEB\x77\xC6\xC5\xB4\x81\x15\x01\x82\x8D\x9D\x40", + 15, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xBF\xA3\xDA\x09\xF9\xDE\x1B\xE6\x57\x4B\x55\x82\x85\x69\x79\xA1\x89\xD6\xF4\x15\x8B\x03\xFA\xAC\x6E\x00\x80\x26\xF1\x6B\xA1\x28", + 15, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x77\x45\xEA\x51\x24\x46\x53\x19\x6F\xE4\xED\x6B\x54\x5C\x9B\x95\x88\xF5\xD4\x2B\x4C\x3E\xE6\xB7\xA1\xA3\x9F\xC4\x3A\x27\x1E\x45", + 15, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\xFD\x61\x6D\xA6\x8E\xEF\x10\x24\x16\xC7\xBD\x7D\xC8\xCA\xF8\x2B\x3D\x92\x7B\xCB\xDD\x06\x8E\x7C\xCA\xA7\x72\x76\xCE\x6C\x8C\xD4", + 16, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x10\x18\x97\x28\xFB\x05\x1D\xA0\xA8\xD6\x8F\x1C\xAD\x81\xFC\x7C\xA2\x6D\x41\x4B\xAA\x0C\x2A\x95\xB7\xF4\xEF\x9A\x67\xB5\x26\x5F", + 16, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x9E\x3B\x50\xF3\xB5\xF4\xC9\xB3\x57\x03\x74\xF1\xB3\xA0\x4B\x3C\xC1\x71\xB4\x30\x42\xE4\x65\x90\xE5\xE2\x8A\x4D\xBA\xCD\xB1\x9F", + 16, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x69\x70\x88\xAB\x61\x39\x46\xEA\x3B\xEB\x98\x98\x78\xCD\x8E\xF1\xB5\x7E\x81\xFC\x42\x7D\x46\xB8\xDA\x85\xD2\xEB\xB8\x56\xE4\xAC", + 16, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xD2\xDA\xAC\x63\x09\xF1\x81\xBB\xCC\x06\x0D\xCC\xB8\xFA\x67\x08\x14\xD4\x6A\x50\xD7\x4F\xBF\x3B\x4A\x2E\x39\x4D\x45\x55\x27\x2F", + 16, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEB\xB0\xF3\x27\xC3\xC4\x35\x97\x4F\x89\x73\x5A\x4D\xEB\xBB\x4C\x7C\xE9\x0C\x3E\x13\xEB\x07\x83\x74\x67\x0A\x86\xA7\xF4\xA8\x73", + 16, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC8\x96\xC3\x3A\x26\x77\x02\x84\x5D\x95\x1B\x0D\x9F\x5C\x07\xC5\x6D\x21\x5D\x7E\x20\xF1\x2F\xE0\x45\xE3\x50\x42\x9D\x58\xB0\xEA", + 16, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x8A\x3C\x9F\xA4\xAC\x78\x82\xA7\x08\x76\xB9\xE1\xED\x22\x9B\x43\x45\xF4\xD4\x01\x76\xC4\xED\x5D\xA4\x5A\x41\xDE\x28\xB8\x09\x6C", + 16, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x2D\x0C\x97\xBE\xD2\xF2\x13\x40\xB9\xC8\x15\x91\x6A\x55\x86\x7A\x43\xB1\xFD\xC7\x04\x08\x1B\x58\x37\x09\x12\x80\x40\x99\x7C\xED", + 16, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF7\xC0\x08\xE1\x31\x52\x9B\x71\x87\x51\xCF\xFF\x8B\x08\xA3\x14\x32\x08\x06\x8C\x22\xAD\x83\x97\x71\x95\xC5\x2C\xFC\x66\xA4\xAD", + 16, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\xD0\xCE\x8E\x8D\xA0\xBA\xA4\x26\x0E\xD3\x1F\xD1\x7B\x78\xE6\x18\x15\xC6\xFF\xD8\x5A\xDB\x41\x8A\xE7\x36\xF0\xE7\xB9\x87\x2B\x6A", + 17, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xCB\xE4\x63\xEB\x6B\x24\x6C\x08\x55\x84\x36\x30\x8E\xFA\xC1\x6B\x97\x43\xD7\x1F\x1F\x3E\x96\xBA\x7E\x87\xF2\x42\x3E\xF5\x69\x5E", + 17, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEF\x39\x55\x9D\x92\x20\xDC\xB6\x8C\x21\x79\xD6\x7C\x51\xB7\x36\xAC\x4E\xFC\xA1\xDE\x66\xC7\xED\x40\xBF\x23\x15\xD1\x25\x82\x4B", + 17, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE3\x3E\x44\x7B\xA2\x7F\x69\x21\x09\x57\x79\x72\xE7\x4B\xE0\xC7\xCD\x54\xDC\xCD\x55\x60\x75\x61\x82\x66\xD7\x5B\x6F\x60\xDD\x73", + 17, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xA9\xC4\x29\x2F\x5B\x49\x9A\xE0\x71\xE7\xFD\x65\x98\x53\x42\xC0\xC0\xF1\x75\xBC\xB5\x7B\x5C\xA1\x61\xFC\x8B\x45\x44\x54\xEC\x06", + 17, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x29\x60\xBD\x05\x28\xEA\xF1\xA9\x43\xEF\x2D\x87\xC7\xB5\x27\x47\x33\xBA\xC8\x0C\x9F\x1C\xF5\x72\x62\x4C\xA7\x9E\x10\x23\x66\x76", + 17, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xE2\xF1\x33\x23\x9D\xD8\xBC\x60\x1F\xB7\xD8\x21\xF5\x13\x98\xE2\x5C\x24\x0E\xC0\x60\x18\xB4\x0B\x93\xF1\x04\x25\xC5\xEC\x20\x14", + 17, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEB\x4F\x8D\xB3\xF5\x03\x72\x55\x72\xCE\xF3\x91\x22\xCD\xEA\x5A\xC4\x9A\xD0\x42\xE1\xC4\x62\x90\xCE\x11\x9E\xFD\x11\xDB\xCA\x23", + 17, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xB5\x9A\xA7\x74\xDA\xB8\xDE\x5C\xBB\xC3\x5A\xFC\xF0\xD7\xAF\x51\x1E\x0F\x05\x45\xDB\xDA\xB7\xA4\xA6\x52\xB2\x9E\x0E\x23\x14\x3D", + 17, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x69\xA2\x95\x6C\x87\xED\x22\x76\x0A\x53\x75\x6D\x28\xF4\xCD\xC5\xF7\xF9\x88\x51\x73\xA7\xD9\x44\x0C\x96\xB1\x5F\xE5\x57\xFE\xE3", + 17, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x39\x4A\xB9\x85\xDD\xFF\x59\x59\x84\x5A\xF7\x54\xD6\xFC\x19\xFB\x94\x0E\xAE\xA4\xEA\x70\x54\x3E\x0D\x7E\x9D\xC7\x8A\x22\x77\x3B", + 31, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x1B\x46\x57\xC0\x48\x26\x7B\xC6\x17\xEC\xD5\x76\x89\xEE\x81\xE5\x5B\xE0\xAC\xCE\xB7\x5D\x33\x2A\xAF\xB6\xE2\xF6\xC0\xBB\x93\xE6", + 31, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x53\xB3\x3A\x58\x98\xD2\x0D\x25\x61\x5A\x0C\xF5\x74\x7F\x44\x2F\x51\x70\x31\x66\x5E\x41\x5E\xBC\xF5\xF0\x03\x12\x98\x12\x90\xCC", + 31, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0B\x2C\x2A\x74\x72\x12\x18\xE1\xCE\xCD\x8A\x7E\xFC\xCE\x8D\x57\xBE\x42\x1A\xCC\xA2\x20\x24\x33\xC5\x1E\x31\x54\x1F\xB6\x45\xBD", + 31, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEF\x13\x95\xD4\x42\xC9\x9A\x04\xFE\xF0\x11\xE9\x72\xA9\x37\x74\x3E\x14\xC4\x4C\x58\x0C\xAC\x81\x4A\x75\x73\x35\x05\xC0\x81\x32", + 31, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0D\x35\xCF\x7F\x82\x08\x1E\x1B\xE9\x1E\x75\xE1\x96\x05\x9F\xBD\x63\x94\x8E\xE0\x71\xEF\x53\xDE\x79\xC6\x68\x21\xD6\x8A\x5A\xE4", + 31, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x74\x0D\xCB\x50\x59\x59\xB9\x48\x52\x2B\x0B\x2A\x1F\xFC\x4F\x12\xF5\x9F\x49\x11\xED\x43\x61\xA6\x38\x8D\xF9\x35\x5C\xCD\x18\xBB", + 31, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xDD\x48\xE5\xE8\x86\x8E\x61\xFF\x8A\x85\xC6\x5A\xB8\x5A\x32\xD2\x2A\x9C\xA2\xC8\xDC\xB9\xD6\x0A\x44\xD3\xF1\xB4\x8B\x5B\xD3\x80", + 31, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x81\xEF\xAD\x79\x16\xE4\x29\x02\xDB\x89\x8D\xF2\xA4\x6D\xB4\xC4\x2A\x8C\xC6\x7E\xDE\x9B\xF7\x63\xB2\x10\xED\x15\xED\x0A\x0E\x3C", + 31, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEB\x54\xC4\x8A\x8F\x92\x53\x4D\xDF\x1D\x78\xCA\x98\x38\xF9\x10\xE4\x05\xCD\x6D\xB6\x82\x3B\x76\xB7\x82\x3A\xD2\x20\x77\xD4\x89", + 31, 65, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + NULLPTR, + "\x18\xE3\xCE\x19\x98\x7B\xA5\x0B\x30\xDD\x14\x4C\x16\xF2\x26\x55\xEB\xA3\x14\x09\xD6\x62\x10\xBC\x38\xBB\xC1\x4B\x5D\xAB\x05\x19", + 32, 0, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x10\x9D\x6C\xB3\x37\x9C\x9E\x2B\xC9\x1C\xF9\x79\x7A\x46\xEA\xFA\x78\x5C\xA1\x54\x83\xBD\xC2\x67\x31\xFA\x66\xAC\x5D\x4C\xE7\xAB", + 32, 15, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x76\x83\x9A\x8F\xBC\x20\x81\xD6\x09\x5C\x97\x46\xD3\xD6\xA4\xC4\xC1\x17\x8E\x3B\x14\xFC\xFD\x8F\x72\x20\xEF\xC6\x0B\xD3\xFF\x42", + 32, 16, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\x0C\x05\xE6\x8F\xD6\xA6\xA1\xD9\xFC\xDA\x3C\xCB\x49\x02\xA5\xF9\x5D\x80\x9E\x89\xF6\xA2\x15\x74\x48\x84\x87\x77\x47\x6D\xBB", + 32, 17, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x98\x79\xD8\x91\x48\xB3\x12\x10\xE8\x49\x73\x38\x1B\xFA\x6C\xCA\x85\x59\xF9\xF9\xFE\xD3\xF2\x98\x9E\x9D\x5C\xE8\x1E\x59\xB3\x46", + 32, 31, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC7\x41\x7E\x23\xDD\x7D\xB0\x84\xCA\x64\x26\x5A\xE0\x98\xD7\xF2\x29\xE4\x4C\x88\xC9\xF9\x15\x00\x19\x73\xC7\xCF\x95\xF5\x30\x68", + 32, 32, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\x0F\xDA\x45\x55\xAC\x8F\xB0\x17\x1D\xF2\x41\x54\xFB\x41\x26\x16\x0C\x00\x84\x49\x3D\x54\xAE\x9F\x13\xD4\xE5\x11\x2B\x42\xB5\xF5", + 32, 33, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xF1\x1B\x54\x05\xCE\x3A\xEB\xA1\x1B\x49\x99\x43\xBF\x2C\x73\x10\x0E\x35\x6B\xEA\x40\xAC\xE5\xBC\xD8\xD5\xB0\xAE\xB2\x8E\xFB\x05", + 32, 63, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xEA\xAF\xA4\xBE\xD6\x9D\x98\x73\x5E\xDF\xFC\x35\xFD\xB8\x26\x18\xAC\x15\x9E\x2B\xB2\xF9\x36\xEC\x51\x58\x1E\xD8\x53\xB7\x11\x10", + 32, 64, 32 + }, + { + "\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61", + "\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A\x7A", + "\xC3\x0A\xE0\xAB\xFA\x38\x3C\x3F\xBC\x44\xD3\x2A\x4F\xC8\xFA\x86\xF2\x15\x9E\x83\x75\x65\xE4\x78\x63\xED\xEF\x31\x79\xEC\x00\x21", + 32, 65, 32 + } + }; + + { + byte digest[BLAKE2s::DIGESTSIZE]; + for (unsigned int i=0; i +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough) +{ + bool pass = true, fail; + + fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "cryptosystem key validation\n"; + + const byte message[] = "test message"; + const int messageLen = 12; + SecByteBlock ciphertext(priv.CiphertextLength(messageLen)); + SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size())); + + pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext); + fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen); + fail = fail || memcmp(message, plaintext, messageLen); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "encryption and decryption\n"; + + return pass; +} + +bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d) +{ + if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed simple key agreement domain parameters validation" << std::endl; + else + { + std::cout << "FAILED simple key agreement domain parameters invalid" << std::endl; + return false; + } + + SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength()); + SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength()); + SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); + + d.GenerateKeyPair(GlobalRNG(), priv1, pub1); + d.GenerateKeyPair(GlobalRNG(), priv2, pub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1))) + { + std::cout << "FAILED simple key agreement failed" << std::endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) + { + std::cout << "FAILED simple agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed simple key agreement" << std::endl; + return true; +} + +bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d) +{ + if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid" << std::endl; + return false; + } + + SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength()); + SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength()); + SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength()); + SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength()); + SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); + + d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1); + d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2); + d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1); + d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1)) + { + std::cout << "passed authenticated key agreement protocol execution" << std::endl; + } + else + { + std::cout << "FAILED authenticated key agreement protocol execution" << std::endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + return true; +} + +bool AuthenticatedKeyAgreementWithRolesValidate(AuthenticatedKeyAgreementDomain &initiator, AuthenticatedKeyAgreementDomain &recipient) +{ + if (initiator.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (initiator)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (initiator)" << std::endl; + return false; + } + + if (recipient.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (recipient)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (recipient)" << std::endl; + return false; + } + + if (initiator.StaticPrivateKeyLength() != recipient.StaticPrivateKeyLength() || + initiator.EphemeralPrivateKeyLength() != recipient.EphemeralPrivateKeyLength() || + initiator.StaticPublicKeyLength() != recipient.StaticPublicKeyLength() || + initiator.EphemeralPublicKeyLength() != recipient.EphemeralPublicKeyLength() || + initiator.AgreedValueLength() != recipient.AgreedValueLength()) + { + std::cout << "FAILED authenticated key agreement domain parameter consistency" << std::endl; + return false; + } + else + { + std::cout << "passed authenticated key agreement domain parameter consistency" << std::endl; + } + + SecByteBlock spriv1(initiator.StaticPrivateKeyLength()), spriv2(recipient.StaticPrivateKeyLength()); + SecByteBlock epriv1(initiator.EphemeralPrivateKeyLength()), epriv2(recipient.EphemeralPrivateKeyLength()); + SecByteBlock spub1(initiator.StaticPublicKeyLength()), spub2(recipient.StaticPublicKeyLength()); + SecByteBlock epub1(initiator.EphemeralPublicKeyLength()), epub2(recipient.EphemeralPublicKeyLength()); + SecByteBlock val1(initiator.AgreedValueLength()), val2(recipient.AgreedValueLength()); + + initiator.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1); + recipient.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2); + initiator.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1); + recipient.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (initiator.Agree(val1, spriv1, epriv1, spub2, epub2) && recipient.Agree(val2, spriv2, epriv2, spub1, epub1)) + { + std::cout << "passed authenticated key agreement protocol execution" << std::endl; + } + else + { + std::cout << "FAILED authenticated key agreement protocol execution" << std::endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), initiator.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement shared secret" << std::endl; + return true; +} + +bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough) +{ + bool pass = true, fail; + + fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "signature key validation\n"; + + const byte message[] = "test message"; + const int messageLen = 12; + + SecByteBlock signature(priv.MaxSignatureLength()); + size_t signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature); + fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "signature and verification\n"; + + ++signature[0]; + fail = pub.VerifyMessage(message, messageLen, signature, signatureLength); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "checking invalid signature" << std::endl; + + if (priv.MaxRecoverableLength() > 0) + { + signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULLPTR, 0, signature); + SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength)); + DecodingResult result = pub.RecoverMessage(recovered, NULLPTR, 0, signature, signatureLength); + fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "signature and verification with recovery" << std::endl; + + ++signature[0]; + result = pub.RecoverMessage(recovered, NULLPTR, 0, signature, signatureLength); + fail = result.isValidCoding; + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "recovery with invalid signature" << std::endl; + } + + return pass; +} + +bool ValidateBBS() +{ + std::cout << "\nBlumBlumShub validation suite running...\n\n"; + + Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351"); + Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231"); + Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431"); + BlumBlumShub bbs(p, q, seed); + bool pass = true, fail; + int j; + + const byte output1[] = { + 0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9, + 0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE}; + const byte output2[] = { + 0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7, + 0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1}; + + byte buf[20]; + std::ostringstream oss; + + bbs.GenerateBlock(buf, 20); + fail = memcmp(output1, buf, 20) != 0; + pass = pass && !fail; + + oss << (fail ? "FAILED " : "passed "); + for (j=0;j<20;j++) + oss << std::setw(2) << std::setfill('0') << std::hex << (int)buf[j]; + oss << std::endl; + + bbs.Seek(10); + bbs.GenerateBlock(buf, 10); + fail = memcmp(output1+10, buf, 10) != 0; + pass = pass && !fail; + + oss << (fail ? "FAILED " : "passed "); + for (j=0;j<10;j++) + oss << std::setw(2) << std::setfill('0') << std::hex << (int)buf[j]; + oss << std::endl; + + bbs.Seek(1234567); + bbs.GenerateBlock(buf, 20); + fail = memcmp(output2, buf, 20) != 0; + pass = pass && !fail; + + oss << (fail ? "FAILED " : "passed "); + for (j=0;j<20;j++) + oss << std::setw(2) << std::setfill('0') << std::hex << (int)buf[j]; + oss << std::endl; + + std::cout << oss.str(); + return pass; +} + +bool ValidateECP() +{ + // Remove word recommend. Some ECP curves may not be recommended depending + // on whom you ask. ECP is more descriptive item in this case. + std::cout << "\nTesting SEC 2, NIST and Brainpool ECP curves...\n\n"; + bool pass = true; OID oid; + + while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).GetValues().empty()) + { + DL_GroupParameters_EC params(oid); + pass = params.Validate(GlobalRNG(), 2); + + // Test addition of identity element + DL_GroupParameters_EC::Element e1; + e1 = params.GetCurve().Add(e1, e1); + pass = params.IsIdentity(e1) && pass; + + // Test doubling of identity element + DL_GroupParameters_EC::Element e2; + e2 = params.GetCurve().Double(e2); + pass = params.IsIdentity(e2) && pass; + + // Test multiplication of identity element + DL_GroupParameters_EC::Element e3; + Integer two = Integer::Two(); + e3 = params.GetCurve().Multiply(two, e3); + pass = params.IsIdentity(e3) && pass; + + std::cout << (pass ? "passed" : "FAILED") << " " << std::dec << params.GetCurve().GetField().MaxElementBitLength() << " bits\n"; + } + + std::cout << "\nECP validation suite running...\n\n"; + return ValidateECP_Agreement() && ValidateECP_Encrypt() && ValidateECP_NULLDigest_Encrypt() && ValidateECP_Sign() && pass; +} + +bool ValidateEC2N() +{ + // Remove word recommend. Binary curves may not be recommended depending + // on whom you ask. EC2N is more descriptive item in this case. + std::cout << "\nTesting SEC 2 EC2N curves...\n\n"; + bool pass = true; OID oid; + +#if 1 // TODO: turn this back on when I make EC2N faster for pentanomial basis + while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).GetValues().empty()) + { + DL_GroupParameters_EC params(oid); + pass = params.Validate(GlobalRNG(), 2); + + // Test addition of identity element + DL_GroupParameters_EC::Element e1; + e1 = params.GetCurve().Add(e1, e1); + pass = params.IsIdentity(e1) && pass; + + // Test doubling of identity element + DL_GroupParameters_EC::Element e2; + e2 = params.GetCurve().Double(e2); + pass = params.IsIdentity(e2) && pass; + + // Test multiplication of identity element + DL_GroupParameters_EC::Element e3; + Integer two = Integer::Two(); + e3 = params.GetCurve().Multiply(two, e3); + pass = params.IsIdentity(e3) && pass; + + std::cout << (pass ? "passed" : "FAILED") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits\n"; + } +#endif + + std::cout << "\nEC2N validation suite running...\n\n"; + return ValidateEC2N_Agreement() && ValidateEC2N_Encrypt() && ValidateEC2N_Sign() && pass; +} + +bool ValidateRSA() +{ + std::cout << "\nRSA validation suite running...\n\n"; + return ValidateRSA_Encrypt() && ValidateRSA_Sign(); +} + +bool ValidateLUC() +{ + std::cout << "\nLUC validation suite running...\n\n"; + return ValidateLUC_Encrypt() && ValidateLUC_Sign(); +} + +bool ValidateLUC_DL() +{ + // Prologue printed in each function + return ValidateLUC_DL_Encrypt() && ValidateLUC_DL_Sign(); +} + +bool ValidateRabin() +{ + std::cout << "\nRabin validation suite running...\n\n"; + return ValidateRabin_Encrypt() && ValidateRabin_Sign(); +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat7.cpp b/external/ours/library/crypto/src/shared/original/validat7.cpp new file mode 100755 index 000000000..32db7e4db --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat7.cpp @@ -0,0 +1,705 @@ +// validat7.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "asn.h" +#include "oids.h" + +#include "sha.h" +#include "sha3.h" + +#include "dh.h" +#include "luc.h" +#include "mqv.h" +#include "xtr.h" +#include "hmqv.h" +#include "pubkey.h" +#include "xtrcrypt.h" +#include "eccrypto.h" + +// Curve25519 +#include "xed25519.h" +#include "donna.h" +#include "naclite.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +ANONYMOUS_NAMESPACE_BEGIN + +inline bool operator==(const x25519& lhs, const x25519& rhs) +{ + // This is a hack because the KeyAgreement classes do not make it easy to access the PrivateKey + ByteQueue q1, q2; + lhs.DEREncodePrivateKey(q1); + rhs.DEREncodePrivateKey(q2); + + return q1 == q2; +} + +inline bool operator!=(const x25519& lhs, const x25519& rhs) +{ + return !operator==(lhs, rhs); +} + +ANONYMOUS_NAMESPACE_END + +bool ValidateDH() +{ + std::cout << "\nDH validation suite running...\n\n"; + + FileSource f(DataDir("TestData/dh1024.dat").c_str(), true, new HexDecoder); + DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateX25519() +{ + std::cout << "\nx25519 validation suite running...\n\n"; + + FileSource f(DataDir("TestData/x25519.dat").c_str(), true, new HexDecoder); + x25519 dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateMQV() +{ + std::cout << "\nMQV validation suite running...\n\n"; + + FileSource f(DataDir("TestData/mqv1024.dat").c_str(), true, new HexDecoder); + MQV mqv(f); + return AuthenticatedKeyAgreementValidate(mqv); +} + +bool ValidateHMQV() +{ + std::cout << "\nHMQV validation suite running...\n\n"; + bool success = true, fail; + + FileSource f256(DataDir("TestData/hmqv256.dat").c_str(), true, new HexDecoder); + FileSource f384(DataDir("TestData/hmqv384.dat").c_str(), true, new HexDecoder); + FileSource f512(DataDir("TestData/hmqv512.dat").c_str(), true, new HexDecoder); + + ///////////////////////// + + std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; + + ECHMQV256 hmqvB256(false); + hmqvB256.AccessGroupParameters().BERDecode(f256); + const OID oid = ASN1::secp256r1(); + ECHMQV< ECP >::Domain hmqvA256(oid, true /*client*/); + + fail = !AuthenticatedKeyAgreementWithRolesValidate(hmqvA256, hmqvB256); + success = !fail && success; + if (fail == false) + std::cout << "passed authenticated key agreement" << std::endl; + else + std::cout << "FAILED authenticated key agreement" << std::endl; + + ///////////////////////// + + std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; + + ECHMQV384 hmqvB384(false); + hmqvB384.AccessGroupParameters().BERDecode(f384); + const OID oid384 = ASN1::secp384r1(); + ECHMQV384 hmqvA384(oid384, true /*client*/); + + fail = !AuthenticatedKeyAgreementWithRolesValidate(hmqvA384, hmqvB384); + success = !fail && success; + if (fail == false) + std::cout << "passed authenticated key agreement" << std::endl; + else + std::cout << "FAILED authenticated key agreement" << std::endl; + + ///////////////////////// + + std::cout << "HMQV with NIST P-521 and SHA-512:" << std::endl; + + ECHMQV512 hmqvB521(false); + hmqvB521.AccessGroupParameters().BERDecode(f512); + const OID oid521 = ASN1::secp521r1(); + ECHMQV512 hmqvA521(oid521, true /*client*/); + + fail = !AuthenticatedKeyAgreementWithRolesValidate(hmqvA521, hmqvB521); + success = !fail && success; + if (fail == false) + std::cout << "passed authenticated key agreement" << std::endl; + else + std::cout << "FAILED authenticated key agreement" << std::endl; + + return success; +} + +bool ValidateFHMQV() +{ + std::cout << "\nFHMQV validation suite running...\n\n"; + bool success = true, fail; + + FileSource f256(DataDir("TestData/fhmqv256.dat").c_str(), true, new HexDecoder); + FileSource f384(DataDir("TestData/fhmqv384.dat").c_str(), true, new HexDecoder); + FileSource f512(DataDir("TestData/fhmqv512.dat").c_str(), true, new HexDecoder); + + ///////////////////////// + + std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; + + ECFHMQV256 fhmqvB256(false); + fhmqvB256.AccessGroupParameters().BERDecode(f256); + const OID oid = ASN1::secp256r1(); + ECFHMQV< ECP >::Domain fhmqvA256(oid, true /*client*/); + + fail = !AuthenticatedKeyAgreementWithRolesValidate(fhmqvA256, fhmqvB256); + success = !fail && success; + if (fail == false) + std::cout << "passed authenticated key agreement" << std::endl; + else + std::cout << "FAILED authenticated key agreement" << std::endl; + + ///////////////////////// + + std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; + + ECHMQV384 fhmqvB384(false); + fhmqvB384.AccessGroupParameters().BERDecode(f384); + const OID oid384 = ASN1::secp384r1(); + ECHMQV384 fhmqvA384(oid384, true /*client*/); + + fail = !AuthenticatedKeyAgreementWithRolesValidate(fhmqvA384, fhmqvB384); + success = !fail && success; + if (fail == false) + std::cout << "passed authenticated key agreement" << std::endl; + else + std::cout << "FAILED authenticated key agreement" << std::endl; + + ///////////////////////// + + std::cout << "FHMQV with NIST P-521 and SHA-512:" << std::endl; + + ECHMQV512 fhmqvB521(false); + fhmqvB521.AccessGroupParameters().BERDecode(f512); + const OID oid521 = ASN1::secp521r1(); + ECHMQV512 fhmqvA521(oid521, true /*client*/); + + fail = !AuthenticatedKeyAgreementWithRolesValidate(fhmqvA521, fhmqvB521); + success = !fail && success; + if (fail == false) + std::cout << "passed authenticated key agreement" << std::endl; + else + std::cout << "FAILED authenticated key agreement" << std::endl; + + return success; +} + +bool ValidateLUC_DH() +{ + std::cout << "\nLUC-DH validation suite running...\n\n"; + + FileSource f(DataDir("TestData/lucd512.dat").c_str(), true, new HexDecoder); + LUC_DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateXTR_DH() +{ + std::cout << "\nXTR-DH validation suite running...\n\n"; + + FileSource f(DataDir("TestData/xtrdh171.dat").c_str(), true, new HexDecoder); + XTR_DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateECP_Agreement() +{ + ECDH::Domain ecdhc(ASN1::secp192r1()); + ECMQV::Domain ecmqvc(ASN1::secp192r1()); + bool pass = SimpleKeyAgreementValidate(ecdhc); + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + std::cout << "Turning on point compression..." << std::endl; + ecdhc.AccessGroupParameters().SetPointCompression(true); + ecmqvc.AccessGroupParameters().SetPointCompression(true); + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + return pass; +} + +bool ValidateEC2N_Agreement() +{ + ECDH::Domain ecdhc(ASN1::sect193r1()); + ECMQV::Domain ecmqvc(ASN1::sect193r1()); + bool pass = SimpleKeyAgreementValidate(ecdhc); + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + std::cout << "Turning on point compression..." << std::endl; + ecdhc.AccessGroupParameters().SetPointCompression(true); + ecmqvc.AccessGroupParameters().SetPointCompression(true); + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + return pass; +} + +// TestX25519 is slighty more comprehensive than ValidateX25519 +// because it cross-validates against Bernstein's NaCL library. +// TestX25519 called in Debug builds. +bool TestX25519() +{ + std::cout << "\nTesting curve25519 Key Agreements...\n\n"; + const unsigned int AGREE_COUNT = 64; + bool pass = true, fail; + + size_t i = 0; + unsigned int failed = 0; + + SecByteBlock priv1(32), priv2(32), pub1(32), pub2(32), share1(32), share2(32); + for (i=0, failed=0; i +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +ANONYMOUS_NAMESPACE_BEGIN + +inline byte* C2B(char* ptr) { + return reinterpret_cast(ptr); +} + +inline const byte* C2B(const char* ptr) { + return reinterpret_cast(ptr); +} + +inline bool operator==(const RSA::PrivateKey& lhs, const RSA::PrivateKey& rhs) { + return lhs.GetModulus() == rhs.GetModulus() && + lhs.GetPublicExponent() == rhs.GetPublicExponent() && + lhs.GetPrivateExponent() == rhs.GetPrivateExponent(); +} + +inline bool operator!=(const RSA::PrivateKey& lhs, const RSA::PrivateKey& rhs) { + return !operator==(lhs, rhs); +} + +inline bool operator==(const RSA::PublicKey& lhs, const RSA::PublicKey& rhs) { + return lhs.GetModulus() == rhs.GetModulus() && + lhs.GetPublicExponent() == rhs.GetPublicExponent(); +} + +inline bool operator!=(const RSA::PublicKey& lhs, const RSA::PublicKey& rhs) { + return !operator==(lhs, rhs); +} + +inline bool operator==(const LUC::PrivateKey& lhs, const LUC::PrivateKey& rhs) { + return lhs.GetModulus() == rhs.GetModulus() && + lhs.GetPublicExponent() == rhs.GetPublicExponent() && + lhs.GetPrime1() == rhs.GetPrime1() && + lhs.GetPrime2() == rhs.GetPrime2() && + lhs.GetMultiplicativeInverseOfPrime2ModPrime1() == rhs.GetMultiplicativeInverseOfPrime2ModPrime1(); +} + +inline bool operator!=(const LUC::PrivateKey& lhs, const LUC::PrivateKey& rhs) { + return !operator==(lhs, rhs); +} + +inline bool operator==(const LUC::PublicKey& lhs, const LUC::PublicKey& rhs) { + return lhs.GetModulus() == rhs.GetModulus() && + lhs.GetPublicExponent() == rhs.GetPublicExponent(); +} + +inline bool operator!=(const LUC::PublicKey& lhs, const LUC::PublicKey& rhs) { + return !operator==(lhs, rhs); +} + +inline bool operator==(const Rabin::PrivateKey& lhs, const Rabin::PrivateKey& rhs) { + return lhs.GetModulus() == rhs.GetModulus() && + lhs.GetQuadraticResidueModPrime1() == rhs.GetQuadraticResidueModPrime1() && + lhs.GetQuadraticResidueModPrime2() == rhs.GetQuadraticResidueModPrime2() && + lhs.GetPrime1() == rhs.GetPrime1() && + lhs.GetPrime2() == rhs.GetPrime2() && + lhs.GetMultiplicativeInverseOfPrime2ModPrime1() == rhs.GetMultiplicativeInverseOfPrime2ModPrime1(); +} + +inline bool operator!=(const Rabin::PrivateKey& lhs, const Rabin::PrivateKey& rhs) { + return !operator==(lhs, rhs); +} + +inline bool operator==(const Rabin::PublicKey& lhs, const Rabin::PublicKey& rhs) { + return lhs.GetModulus() == rhs.GetModulus() && + lhs.GetQuadraticResidueModPrime1() == rhs.GetQuadraticResidueModPrime1() && + lhs.GetQuadraticResidueModPrime2() == rhs.GetQuadraticResidueModPrime2(); +} + +inline bool operator!=(const Rabin::PublicKey& lhs, const Rabin::PublicKey& rhs) { + return !operator==(lhs, rhs); +} + +ANONYMOUS_NAMESPACE_END + +bool ValidateRSA_Encrypt() +{ + // Must be large enough for RSA-3072 to test SHA3_256 + byte out[256], outPlain[128]; + bool pass = true, fail; + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + { + FileSource keys(DataDir("TestData/rsa1024.dat").c_str(), true, new HexDecoder); + RSA::PrivateKey rsaPriv; rsaPriv.Load(keys); + RSA::PublicKey rsaPub(rsaPriv); + + const Integer& n = rsaPriv.GetModulus(); + const Integer& e = rsaPriv.GetPublicExponent(); + const Integer& d = rsaPriv.GetPrivateExponent(); + + RSA::PrivateKey rsaPriv2; + rsaPriv2.Initialize(n, e, d); + + fail = (rsaPriv != rsaPriv2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "RSA::PrivateKey initialization\n"; + + RSA::PublicKey rsaPub2; + rsaPub2.Initialize(n, e); + + fail = (rsaPub != rsaPub2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "RSA::PublicKey initialization\n"; + } + { + FileSource keys(DataDir("TestData/rsa1024.dat").c_str(), true, new HexDecoder); + RSA::PrivateKey rsaPriv; rsaPriv.Load(keys); + + ByteQueue q; + rsaPriv.DEREncodePrivateKey(q); + + RSA::PrivateKey rsaPriv2; + rsaPriv2.BERDecodePrivateKey(q, true, q.MaxRetrievable()); + + fail = (rsaPriv != rsaPriv2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "RSA::PrivateKey encoding and decoding\n"; + } +#endif + + { + FileSource keys(DataDir("TestData/rsa1024.dat").c_str(), true, new HexDecoder); + RSAES_PKCS1v15_Decryptor rsaPriv(keys); + RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv); + + fail = !CryptoSystemValidate(rsaPriv, rsaPub); + pass = pass && !fail; + } + { + RSAES >::Decryptor rsaPriv(GlobalRNG(), 512); + RSAES >::Encryptor rsaPub(rsaPriv); + + fail = !CryptoSystemValidate(rsaPriv, rsaPub); + pass = pass && !fail; + } + { + const byte plain[] = + "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; + const byte encrypted[] = + "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" + "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" + "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" + "\x62\x51"; + const byte oaepSeed[] = + "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2" + "\xf0\x6c\xb5\x8f"; + ByteQueue bq; + bq.Put(oaepSeed, 20); + FixedRNG rng(bq); + + FileSource privFile(DataDir("TestData/rsa400pv.dat").c_str(), true, new HexDecoder); + FileSource pubFile(DataDir("TestData/rsa400pb.dat").c_str(), true, new HexDecoder); + RSAES_OAEP_SHA_Decryptor rsaPriv; + rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0); + RSAES_OAEP_SHA_Encryptor rsaPub(pubFile); + + memset(out, 0, 50); + memset(outPlain, 0, 8); + rsaPub.Encrypt(rng, plain, 8, out); + DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain); + fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "PKCS 2.0 encryption and decryption\n"; + } + + return pass; +} + +bool ValidateLUC_Encrypt() +{ + bool pass = true, fail; + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + { + FileSource keys(DataDir("TestData/luc1024.dat").c_str(), true, new HexDecoder); + LUC::PrivateKey lucPriv; lucPriv.BERDecode(keys); + LUC::PublicKey lucPub(lucPriv); + + const Integer& n = lucPriv.GetModulus(); + const Integer& e = lucPriv.GetPublicExponent(); + const Integer& p = lucPriv.GetPrime1(); + const Integer& q = lucPriv.GetPrime2(); + const Integer& u = lucPriv.GetMultiplicativeInverseOfPrime2ModPrime1(); + + LUC::PrivateKey lucPriv2; + lucPriv2.Initialize(n, e, p, q, u); + + fail = (lucPriv != lucPriv2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "LUC::PrivateKey initialization\n"; + + LUC::PublicKey lucPub2; + lucPub2.Initialize(n, e); + + fail = (lucPub != lucPub2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "LUC::PublicKey initialization\n"; + } + { + FileSource keys(DataDir("TestData/luc1024.dat").c_str(), true, new HexDecoder); + LUC::PrivateKey lucPriv; lucPriv.BERDecode(keys); + + ByteQueue q; + lucPriv.DEREncode(q); + + LUC::PrivateKey lucPriv2; + lucPriv2.BERDecode(q); + + fail = (lucPriv != lucPriv2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "LUC::PrivateKey encoding and decoding\n"; + } + { + FileSource keys(DataDir("TestData/luc1024.dat").c_str(), true, new HexDecoder); + LUC::PrivateKey lucPriv; lucPriv.BERDecode(keys); + LUC::PublicKey lucPub(lucPriv); + + ByteQueue q; + lucPub.DEREncode(q); + + LUC::PublicKey lucPub2; + lucPub2.BERDecode(q); + + fail = (lucPub != lucPub2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "LUC::PublicKey encoding and decoding\n"; + } +#endif + + LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512); + LUCES_OAEP_SHA_Encryptor pub(priv); + fail = !CryptoSystemValidate(priv, pub); + pass = pass && !fail; + + return pass; +} + +bool ValidateLUC_DL_Encrypt() +{ + std::cout << "\nLUC-IES validation suite running...\n\n"; + + FileSource fc(DataDir("TestData/lucc512.dat").c_str(), true, new HexDecoder); + LUC_IES<>::Decryptor privC(fc); + LUC_IES<>::Encryptor pubC(privC); + return CryptoSystemValidate(privC, pubC); +} + +bool ValidateRabin_Encrypt() +{ + bool pass = true, fail; + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) + { + FileSource keys(DataDir("TestData/rabi1024.dat").c_str(), true, new HexDecoder); + Rabin::PrivateKey rabinPriv; rabinPriv.BERDecode(keys); + Rabin::PublicKey rabinPub(rabinPriv); + + const Integer& n = rabinPriv.GetModulus(); + const Integer& r = rabinPriv.GetQuadraticResidueModPrime1(); + const Integer& s = rabinPriv.GetQuadraticResidueModPrime2(); + const Integer& p = rabinPriv.GetPrime1(); + const Integer& q = rabinPriv.GetPrime2(); + const Integer& u = rabinPriv.GetMultiplicativeInverseOfPrime2ModPrime1(); + + Rabin::PrivateKey rabinPriv2; + rabinPriv2.Initialize(n, r, s, p, q, u); + + fail = (rabinPriv != rabinPriv2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "Rabin::PrivateKey initialization\n"; + + Rabin::PublicKey rabinPub2; + rabinPub2.Initialize(n, r, s); + + fail = (rabinPub != rabinPub2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "Rabin::PublicKey initialization\n"; + } + { + FileSource keys(DataDir("TestData/rabi1024.dat").c_str(), true, new HexDecoder); + Rabin::PrivateKey rabinPriv; rabinPriv.BERDecode(keys); + + ByteQueue q; + rabinPriv.DEREncode(q); + + Rabin::PrivateKey rabinPriv2; + rabinPriv2.BERDecode(q); + + fail = (rabinPriv != rabinPriv2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "Rabin::PrivateKey encoding and decoding\n"; + } + { + FileSource keys(DataDir("TestData/rabi1024.dat").c_str(), true, new HexDecoder); + Rabin::PrivateKey rabinPriv; rabinPriv.BERDecode(keys); + Rabin::PublicKey rabinPub(rabinPriv); + + ByteQueue q; + rabinPub.DEREncode(q); + + Rabin::PublicKey rabinPub2; + rabinPub2.BERDecode(q); + + fail = (rabinPub != rabinPub2); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "Rabin::PublicKey encoding and decoding\n"; + } +#endif + + FileSource f(DataDir("TestData/rabi1024.dat").c_str(), true, new HexDecoder); + RabinES >::Decryptor priv(f); + RabinES >::Encryptor pub(priv); + fail = !CryptoSystemValidate(priv, pub); + pass = pass && !fail; + + return pass; +} + +bool ValidateECP_Encrypt() +{ + ECIES::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1()); + ECIES::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.GetKey().DEREncode(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.GetKey().DEREncode(bq); + + cpub.AccessKey().Precompute(); + cpriv.AccessKey().Precompute(); + bool pass = CryptoSystemValidate(cpriv, cpub); + + std::cout << "Turning on point compression..." << std::endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + + return pass; +} + +// https://github.com/weidai11/cryptopp/issues/856 +// Not to be confused with NullHash in trunhash.h. +class NULL_Hash : public CryptoPP::IteratedHashWithStaticTransform + +{ +public: + static void InitState(HashWordType *state) { + CRYPTOPP_UNUSED(state); + } + static void Transform(CryptoPP::word32 *digest, const CryptoPP::word32 *data) { + CRYPTOPP_UNUSED(digest); CRYPTOPP_UNUSED(data); + } + static const char *StaticAlgorithmName() { + return "NULL_Hash"; + } +}; + +// https://github.com/weidai11/cryptopp/issues/856 +template +struct ECIES_NULLDigest + : public DL_ES< + DL_Keys_EC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, + ECIES > +{ + // TODO: fix this after name is standardized + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES-NULLDigest";} +}; + +bool ValidateECP_NULLDigest_Encrypt() +{ + ECIES_NULLDigest::Decryptor cpriv(GlobalRNG(), ASN1::secp256k1()); + ECIES_NULLDigest::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.GetKey().DEREncode(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.GetKey().DEREncode(bq); + + cpub.AccessKey().Precompute(); + cpriv.AccessKey().Precompute(); + bool pass = CryptoSystemValidate(cpriv, cpub); + + std::cout << "Turning on point compression..." << std::endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + + return pass; +} + +// Ensure interop with Crypto++ 5.6.4 and earlier +bool ValidateECP_Legacy_Encrypt() +{ + std::cout << "\nLegacy ECIES ECP validation suite running...\n\n"; + bool pass = true; + { + FileSource fc(DataDir("TestData/ecies_p160.dat").c_str(), true, new HexDecoder); + ECIES::Decryptor privC(fc); + ECIES::Encryptor pubC(privC); + + pass = CryptoSystemValidate(privC, pubC) && pass; + + // Test data generated by Crypto++ 5.6.2. + // Also see https://github.com/weidai11/cryptopp/pull/857. + const std::string plain = "Yoda said, Do or do not. There is no try."; + const std::string cipher = + "\x04\xF6\xC1\xB1\xFA\xAC\x8A\xD5\xD3\x96\xE7\x13\xAE\xBD\x0C\xCE" + "\x15\xCF\x44\x54\x08\x63\xCC\xBF\x89\x4D\xD0\xB8\x38\xA1\x3A\xB2" + "\x90\x75\x86\x82\x7F\x9D\x95\x26\xA5\x74\x13\x3A\x74\x63\x11\x71" + "\x70\x4C\x01\xA4\x08\x04\x95\x69\x6A\x91\xF0\xC0\xA4\xBD\x1E\xAA" + "\x59\x57\xB8\xA9\xD2\xF7\x7C\x98\xE3\xC5\xE3\xF4\x4F\xA7\x6E\x73" + "\x83\xF3\x1E\x05\x73\xA4\xEE\x63\x55\xFD\x6D\x31\xBB\x9E\x36\x4C" + "\x79\xD0\x76\xC0\x0D\xE9"; + + std::string recover; + recover.resize(privC.MaxPlaintextLength(cipher.size())); + + DecodingResult result = privC.Decrypt(GlobalRNG(), C2B(&cipher[0]), cipher.size(), C2B(&recover[0])); + if (result.isValidCoding) + recover.resize(result.messageLength); + else + recover.resize(0); + + pass = (plain == recover) && pass; + std::cout << (pass ? "passed " : "FAILED "); + std::cout << "decryption known answer\n"; + } + return pass; +} + +// Ensure interop with Crypto++ 5.6.4 and earlier +bool ValidateEC2N_Legacy_Encrypt() +{ + std::cout << "\nLegacy ECIES EC2N validation suite running...\n\n"; + bool pass = true; + { + FileSource fc(DataDir("TestData/ecies_t163.dat").c_str(), true, new HexDecoder); + ECIES::Decryptor privC(fc); + ECIES::Encryptor pubC(privC); + + pass = CryptoSystemValidate(privC, pubC) && pass; + + // Test data generated by Crypto++ 5.6.2. + // Also see https://github.com/weidai11/cryptopp/pull/857. + const std::string plain = "Yoda said, Do or do not. There is no try."; + const std::string cipher = + "\x04\x01\x3F\x64\x94\x6A\xBE\x2B\x7E\x48\x67\x63\xA2\xD4\x01\xEF" + "\x2B\x13\x1C\x9A\x1B\x7C\x07\x4B\x89\x78\x6C\x65\x51\x1C\x1A\x4E" + "\x20\x7F\xB5\xBF\x12\x3B\x6E\x0A\x87\xFD\xB7\x94\xEF\x4B\xED\x40" + "\xD4\x7A\xCF\xB6\xFC\x9B\x6D\xB0\xB8\x43\x99\x7E\x37\xC1\xF0\xC0" + "\x95\xD4\x80\xE1\x8B\x84\xAE\x64\x9F\xA5\xBA\x32\x95\x8A\xD1\xBE" + "\x7F\xDE\x7E\xA9\xE6\x59\xBF\x89\xA6\xE9\x9F\x5B\x64\xB4\xDD\x0E" + "\x76\xB6\x82\xF6\xA9\xAD\xB5\xC4"; + + std::string recover; + recover.resize(privC.MaxPlaintextLength(cipher.size())); + + DecodingResult result = privC.Decrypt(GlobalRNG(), C2B(&cipher[0]), cipher.size(), C2B(&recover[0])); + if (result.isValidCoding) + recover.resize(result.messageLength); + else + recover.resize(0); + + pass = (plain == recover) && pass; + std::cout << (pass ? "passed " : "FAILED "); + std::cout << "decryption known answer\n"; + } + return pass; +} + +bool ValidateEC2N_Encrypt() +{ + // DEREncode() changed to Save() at Issue 569. + ECIES::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1()); + ECIES::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.AccessMaterial().Save(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.AccessMaterial().Save(bq); + bool pass = CryptoSystemValidate(cpriv, cpub); + + std::cout << "Turning on point compression..." << std::endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + + return pass; +} + +bool ValidateElGamal() +{ + std::cout << "\nElGamal validation suite running...\n\n"; + bool pass = true; + { + // Data from https://github.com/weidai11/cryptopp/issues/876. + const std::string encodedPublicKey = + "MHYwTwYGKw4HAgEBMEUCIQDebUvQDd9UPMmD27BJ ovZSIgWfexL0SWkfJQPMLsJvMwIgDy/kEthwO6Q+" + "L8XHnzumnEKs+txH8QkQD+M/8u82ql0DIwACIAY6 rfW+BTcRZ9QAJovgoB8DgNLJ8ocqOeF4nEBB0DHH"; + StringSource decodedPublicKey(encodedPublicKey, true, new Base64Decoder); + + ElGamal::PublicKey publicKey; + publicKey.Load(decodedPublicKey); + pass = publicKey.Validate(GlobalRNG(), 3) && pass; + } + { + // Data from https://github.com/weidai11/cryptopp/issues/876. + const std::string encodedPrivateKey = + "MHkCAQAwTwYGKw4HAgEBMEUCIQDebUvQDd9UPMmD 27BJovZSIgWfexL0SWkfJQPMLsJvMwIgDy/kEthw" + "O6Q+L8XHnzumnEKs+txH8QkQD+M/8u82ql0EIwIh AJb0S4TZLvApTVjXZyocPJ5tUgWgRqScXm5vNqu2" + "YqdM"; + StringSource decodedPrivateKey(encodedPrivateKey, true, new Base64Decoder); + + ElGamal::PrivateKey privateKey; + privateKey.Load(decodedPrivateKey); + pass = privateKey.Validate(GlobalRNG(), 3) && pass; + } + { + FileSource fc(DataDir("TestData/elgc1024.dat").c_str(), true, new HexDecoder); + ElGamalDecryptor privC(fc); + ElGamalEncryptor pubC(privC); + privC.AccessKey().Precompute(); + ByteQueue queue; + privC.AccessKey().SavePrecomputation(queue); + privC.AccessKey().LoadPrecomputation(queue); + + pass = CryptoSystemValidate(privC, pubC) && pass; + } + return pass; +} + +bool ValidateDLIES() +{ + std::cout << "\nDLIES validation suite running...\n\n"; + bool pass = true; + { + FileSource fc(DataDir("TestData/dlie1024.dat").c_str(), true, new HexDecoder); + DLIES<>::Decryptor privC(fc); + DLIES<>::Encryptor pubC(privC); + pass = CryptoSystemValidate(privC, pubC) && pass; + } + { + std::cout << "Generating new encryption key..." << std::endl; + DLIES<>::GroupParameters gp; + gp.GenerateRandomWithKeySize(GlobalRNG(), 128); + DLIES<>::Decryptor decryptor; + decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp); + DLIES<>::Encryptor encryptor(decryptor); + + pass = CryptoSystemValidate(decryptor, encryptor) && pass; + } + return pass; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validat9.cpp b/external/ours/library/crypto/src/shared/original/validat9.cpp new file mode 100755 index 000000000..735afe51c --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validat9.cpp @@ -0,0 +1,704 @@ +// validat9.cpp - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017. +// Source files split in July 2018 to expedite compiles. + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "cryptlib.h" +#include "cpu.h" +#include "validate.h" + +#include "asn.h" +#include "oids.h" + +#include "md2.h" +#include "md4.h" +#include "md5.h" + +#include "sha.h" +#include "sha3.h" +#include "pssr.h" +#include "ripemd.h" +#include "whrlpool.h" + +#include "rw.h" +#include "dsa.h" +#include "luc.h" +#include "rsa.h" +#include "esign.h" +#include "rabin.h" +#include "pubkey.h" +#include "eccrypto.h" + +// Curve25519 +#include "xed25519.h" +#include "donna.h" +#include "naclite.h" + +#include +#include +#include + +// Aggressive stack checking with VS2005 SP1 and above. +#if (_MSC_FULL_VER >= 140050727) +# pragma strict_gs_check (on) +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4505 4355) +#endif + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +bool ValidateRSA_Sign() +{ + // Must be large enough for RSA-3072 to test SHA3_256 + byte out[256]; + bool pass = true, fail; + + { + const char plain[] = "Everyone gets Friday off."; + const byte signature[] = + "\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84" + "\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21" + "\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b" + "\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1"; + + FileSource keys(DataDir("TestData/rsa512a.dat").c_str(), true, new HexDecoder); + Weak::RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys); + Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv); + + size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out); + CRYPTOPP_ASSERT(signatureLength <= sizeof(out)); + fail = memcmp(signature, out, signatureLength) != 0; + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "signature check against test vector\n"; + + fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "verification check against test vector\n"; + + out[10]++; + fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "invalid signature verification\n"; + } + ///// + { + const char plain[] = "Everyone gets Friday off."; + const byte signature[] = + "\x2e\x87\xda\x1f\xe4\xda\x1d\x7a\xb7\xf2\x42\x36\xe9\xc0\x4e\xab\x3f\x03\x71\xe1" + "\x2b\xc5\x3c\xbf\x21\x21\xa8\xd6\x28\xb0\x08\xfd\x9c\xf6\x94\xbd\x37\x32\xda\xfc" + "\x42\x1c\x8e\xdb\x8a\x81\x90\x46\x45\xb4\xde\x9e\xce\x90\xfe\xa1\xfd\xbc\x5a\xce" + "\xca\x59\x89\x93\xc0\x0f\x2f\xf1\x13\xb0\xf5\x3d\xa3\x9a\x85\xb7\x40\xd9\x34\x88" + "\x29\xb2\x4a\x0f\x9b\xbe\x22\x3a\x5b\x54\x51\xb7\xf0\x10\x72\x50\xc4\x2a\xe9\xe4" + "\xc3\x82\xeb\x32\x33\x14\xb6\xf2\x7b\x30\x7a\xbf\xc2\xf3\x0f\x4d\x72\xa0\x8d\xa1" + "\xc6\xce\xd0\xa3\x3c\xf7\x23\x4b\xb7\x2c\x5e\xca\x83\x01\xc7\x5c\xd5\xd0\xd1\x94" + "\x43\xf0\xad\xa2\xe6\x72\x2b\x13\x39\xb2\x4b\x25\x91\x3a\x4f\x53\x05\x00\x8c\xc7" + "\xcf\x4f\x11\x64\xe6\xf4\x1a\x4d\x90\x7e\xf1\xfe\xed\xec\x8d\xbb\x00\x31\x2e\x03" + "\xbe\x87\x84\x60\xfb\x5e\xef\x9d\x18\x2c\x28\x3d\xaa\x67\x80\xa3\x62\x07\x06\x5e" + "\xce\xee\x3b\xd0\x78\xb5\x98\x38\x1e\xe8\x62\x19\x9c\xc3\xd4\xf7\xc2\xc5\x00\xf0" + "\xeb\x89\x65\x53\x35\xe7\x13\x7e\xbb\x26\xb0\x76\x9c\xf2\x80\xaa\xe1\xb1\x0a\xa6" + "\x47\xfc\x5f\xe0\x7f\x82\xd7\x83\x41\xc3\x50\xa1\xe0\x0e\x1a\xe4"; + + FileSource keys(DataDir("TestData/rsa2048a.dat").c_str(), true, new HexDecoder); + RSASS::Signer rsaPriv(keys); + RSASS::Verifier rsaPub(rsaPriv); + + size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out); + CRYPTOPP_ASSERT(signatureLength <= sizeof(out)); + fail = memcmp(signature, out, signatureLength) != 0; + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "signature check against test vector\n"; + + fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "verification check against test vector\n"; + + out[10]++; + fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "invalid signature verification\n"; + } + + return pass; +} + +bool ValidateNR() +{ + std::cout << "\nNR validation suite running...\n\n"; + bool pass = true; + { + FileSource f(DataDir("TestData/nr2048.dat").c_str(), true, new HexDecoder); + NR::Signer privS(f); + privS.AccessKey().Precompute(); + NR::Verifier pubS(privS); + + pass = SignatureValidate(privS, pubS) && pass; + } + { + std::cout << "Generating new signature key..." << std::endl; + NR::Signer privS(GlobalRNG(), 256); + NR::Verifier pubS(privS); + + pass = SignatureValidate(privS, pubS) && pass; + } + return pass; +} + +bool ValidateDSA(bool thorough) +{ + std::cout << "\nDSA validation suite running...\n\n"; + + bool pass = true; + FileSource fs1(DataDir("TestData/dsa1024.dat").c_str(), true, new HexDecoder); + DSA::Signer priv(fs1); + DSA::Verifier pub(priv); + FileSource fs2(DataDir("TestData/dsa1024b.dat").c_str(), true, new HexDecoder); + DSA::Verifier pub1(fs2); + CRYPTOPP_ASSERT(pub.GetKey() == pub1.GetKey()); + pass = SignatureValidate(priv, pub, thorough) && pass; + + return pass; +} + +bool ValidateLUC_Sign() +{ + FileSource f(DataDir("TestData/luc1024.dat").c_str(), true, new HexDecoder); + LUCSSA_PKCS1v15_SHA_Signer priv(f); + LUCSSA_PKCS1v15_SHA_Verifier pub(priv); + return SignatureValidate(priv, pub); +} + +bool ValidateLUC_DL_Sign() +{ + std::cout << "\nLUC-HMP validation suite running...\n\n"; + + FileSource f(DataDir("TestData/lucs512.dat").c_str(), true, new HexDecoder); + LUC_HMP::Signer privS(f); + LUC_HMP::Verifier pubS(privS); + return SignatureValidate(privS, pubS); +} + +bool ValidateRabin_Sign() +{ + FileSource f(DataDir("TestData/rabi1024.dat").c_str(), true, new HexDecoder); + RabinSS::Signer priv(f); + RabinSS::Verifier pub(priv); + return SignatureValidate(priv, pub); +} + +bool ValidateRW() +{ + std::cout << "\nRW validation suite running...\n\n"; + + FileSource f(DataDir("TestData/rw1024.dat").c_str(), true, new HexDecoder); + RWSS::Signer priv(f); + RWSS::Verifier pub(priv); + + return SignatureValidate(priv, pub); +} + +bool ValidateECP_Sign() +{ + ECDSA::Signer spriv(GlobalRNG(), ASN1::secp192r1()); + ECDSA::Verifier spub(spriv); + ByteQueue bq; + spriv.GetKey().DEREncode(bq); + spub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + spub.GetKey().DEREncode(bq); + spriv.AccessKey().BERDecode(bq); + spub.AccessKey().BERDecode(bq); + + spriv.AccessKey().Precompute(); + ByteQueue queue; + spriv.AccessKey().SavePrecomputation(queue); + spriv.AccessKey().LoadPrecomputation(queue); + + return SignatureValidate(spriv, spub); +} + +bool ValidateEC2N_Sign() +{ + // DEREncode() changed to Save() at Issue 569. + ECDSA::Signer spriv(GlobalRNG(), ASN1::sect193r1()); + ECDSA::Verifier spub(spriv); + ByteQueue bq; + spriv.AccessMaterial().Save(bq); + spub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + spub.AccessMaterial().Save(bq); + spriv.AccessMaterial().Load(bq); + spub.AccessMaterial().Load(bq); + + spriv.AccessKey().Precompute(); + ByteQueue queue; + spriv.AccessKey().SavePrecomputation(queue); + spriv.AccessKey().LoadPrecomputation(queue); + + return SignatureValidate(spriv, spub); +} + +bool ValidateECDSA() +{ + std::cout << "\nECDSA validation suite running...\n\n"; + + // from Sample Test Vectors for P1363 + GF2NT gf2n(191, 9, 0); + byte a[]="\x28\x66\x53\x7B\x67\x67\x52\x63\x6A\x68\xF5\x65\x54\xE1\x26\x40\x27\x6B\x64\x9E\xF7\x52\x62\x67"; + byte b[]="\x2E\x45\xEF\x57\x1F\x00\x78\x6F\x67\xB0\x08\x1B\x94\x95\xA3\xD9\x54\x62\xF5\xDE\x0A\xA1\x85\xEC"; + EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24)); + + EC2N::Point P; + bool result = ec.DecodePoint(P, (byte *)"\x04\x36\xB3\xDA\xF8\xA2\x32\x06\xF9\xC4\xF2\x99\xD7\xB2\x1A\x9C\x36\x91\x37\xF2\xC8\x4A\xE1\xAA\x0D" + "\x76\x5B\xE7\x34\x33\xB3\xF9\x5E\x33\x29\x32\xE7\x0E\xA2\x45\xCA\x24\x18\xEA\x0E\xF9\x80\x18\xFB", ec.EncodedPointSize()); + CRYPTOPP_ASSERT(result); CRYPTOPP_UNUSED(result); + + Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H"); + Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH"); + EC2N::Point Q(ec.Multiply(d, P)); + ECDSA::Signer priv(ec, P, n, d); + ECDSA::Verifier pub(priv); + + Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH"); + Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H"); + const byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30" + "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e"; + Integer r(sig, 24); + Integer s(sig+24, 24); + + Integer rOut, sOut; + bool fail, pass=true; + + priv.RawSign(k, h, rOut, sOut); + fail = (rOut != r) || (sOut != s); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "signature check against test vector\n"; + + fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "verification check against test vector\n"; + + fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig)); + pass = pass && !fail; + + pass = SignatureValidate(priv, pub) && pass; + + return pass; +} + +bool ValidateECDSA_RFC6979() +{ + std::cout << "\nRFC6979 deterministic ECDSA validation suite running...\n\n"; + + DL_Algorithm_ECDSA_RFC6979 sign; + + const Integer x("09A4D6792295A7F730FC3F2B49CBC0F62E862272Fh"); + const Integer e("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BFh"); + const Integer q("4000000000000000000020108A2E0CC0D99F8A5EFh"); + const Integer k("23AF4074C90A02B3FE61D286D5C87F425E6BDD81Bh"); + const Integer &k_out = sign.GenerateRandom(x, q, e); + + bool pass = (k_out == k); + + std::cout << (pass ? "passed " : "FAILED "); + std::cout << "deterministic k generation against test vector\n"; + + return pass; +} + +// from http://www.teletrust.de/fileadmin/files/oid/ecgdsa_final.pdf +bool ValidateECGDSA(bool thorough) +{ + std::cout << "\nECGDSA validation suite running...\n\n"; + + bool fail, pass=true; + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function RIPEMD-160 (p. 10) + if (thorough) + { + const OID oid = ASN1::brainpoolP192r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 80F2425E 89B4F585 F27F3536 ED834D68 E3E492DE 08FE84B9"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 577EF842 B32FDE45 79727FFF 02F7A280 74ADC4EF"); + Integer k("0x 22C17C2A 367DD85A B8A365ED 06F19C43 F9ED1834 9A9BC044"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 2D017BE7 F117FF99 4ED6FC63 CA5B4C7A 0430E9FA 095DAFC4"); + Integer sExp("0x C02B5CC5 C51D5411 060BF024 5049F824 839F671D 78A1BBF1"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function RIPEMD-160"; + const size_t len = strlen((char*)msg); + + byte signature[48]; + r.Encode(signature+0, 24); + s.Encode(signature+24, 24); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP192r1 using RIPEMD-160\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function RIPEMD-160 (p. 13) + if (thorough) + { + const OID oid = ASN1::brainpoolP256r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 47B3A278 62DEF037 49ACF0D6 00E69F9B 851D01ED AEFA531F 4D168E78 7307F4D8"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 00000000 00000000 577EF842 B32FDE45 79727FFF 02F7A280 74ADC4EF"); + Integer k("0x 908E3099 776261A4 558FF7A9 FA6DFFE0 CA6BB3F9 CB35C2E4 E1DC73FD 5E8C08A3"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 62CCD1D2 91E62F6A 4FFBD966 C66C85AA BA990BB6 AB0C087D BD54A456 CCC84E4C"); + Integer sExp("0x 9119719B 08EEA0D6 BC56E4D1 D37369BC F3768445 EF65CAE4 A37BF6D4 3BD01646"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function RIPEMD-160"; + const size_t len = strlen((char*)msg); + + byte signature[64]; + r.Encode(signature+0, 32); + s.Encode(signature+32, 32); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP256r1 using RIPEMD-160\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function RIPEMD-160 (p. 16) + if (thorough) + { + const OID oid = ASN1::brainpoolP320r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 48683594 5A3A284F FC52629A D48D8F37 F4B2E993 9C52BC72 362A9961 40192AEF 7D2AAFF0 C73A51C5"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 00000000 00000000 00000000 00000000 577EF842 B32FDE45 79727FFF 02F7A280 74ADC4EF"); + Integer k("0x C70BC00A 77AD7872 5D36CEEC 27D6F956 FB546EEF 6DC90E35 31452BD8 7ECE8A4A 7AD730AD C299D81B"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 3C925969 FAB22F7A E7B8CC5D 50CB0867 DFDB2CF4 FADA3D49 0DF75D72 F7563186 419494C9 8F9C82A6"); + Integer sExp("0x 06AB5250 B31A8E93 56194894 61733200 E4FD5C12 75C0AB37 E7E41149 5BAAE145 41DF6DE6 66B8CA56"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function RIPEMD-160"; + const size_t len = strlen((char*)msg); + + byte signature[80]; + r.Encode(signature+0, 40); + s.Encode(signature+40, 40); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP320r1 using RIPEMD-160\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-1 (p. 19) + { + const OID oid = ASN1::brainpoolP192r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 80F2425E 89B4F585 F27F3536 ED834D68 E3E492DE 08FE84B9"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 CF00CD42 CAA80DDF 8DDEBDFD 32F2DA15 11B53F29"); + Integer k("0x 22C17C2A 367DD85A B8A365ED 06F19C43 F9ED1834 9A9BC044"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 2D017BE7 F117FF99 4ED6FC63 CA5B4C7A 0430E9FA 095DAFC4"); + Integer sExp("0x 18FD604E 5F00F55B 3585C052 8C319A2B 05B8F2DD EE9CF1A6"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function SHA-1"; + const size_t len = strlen((char*)msg); + + byte signature[48]; + r.Encode(signature+0, 24); + s.Encode(signature+24, 24); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP192r1 using SHA-1\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-224 (p. 23) + { + const OID oid = ASN1::brainpoolP320r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 48683594 5A3A284F FC52629A D48D8F37 F4B2E993 9C52BC72 362A9961 40192AEF 7D2AAFF0 C73A51C5"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 00000000 00000000 92AE8A0E 8D08EADE E9426378 714FF3E0 1957587D 2876FA70 D40E3144"); + Integer k("0x C70BC00A 77AD7872 5D36CEEC 27D6F956 FB546EEF 6DC90E35 31452BD8 7ECE8A4A 7AD730AD C299D81B"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 3C925969 FAB22F7A E7B8CC5D 50CB0867 DFDB2CF4 FADA3D49 0DF75D72 F7563186 419494C9 8F9C82A6"); + Integer sExp("0x 6EA191CA 0D468AC3 E9568768 9338357C 7D0BACB3 F1D87E0D EC05F635 B7ADB842 75AA0086 60F812CF"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function SHA-224"; + const size_t len = strlen((char*)msg); + + byte signature[80]; + r.Encode(signature+0, 40); + s.Encode(signature+40, 40); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP320r1 using SHA-224\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-256 (p. 27) + { + const OID oid = ASN1::brainpoolP320r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 48683594 5A3A284F FC52629A D48D8F37 F4B2E993 9C52BC72 362A9961 40192AEF 7D2AAFF0 C73A51C5"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 00000000 37ED8AA9 4AE667DB BB753330 E050EB8E 12195807 ECDC4FB1 0E0662B4 22C219D7"); + Integer k("0x C70BC00A 77AD7872 5D36CEEC 27D6F956 FB546EEF 6DC90E35 31452BD8 7ECE8A4A 7AD730AD C299D81B"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 3C925969 FAB22F7A E7B8CC5D 50CB0867 DFDB2CF4 FADA3D49 0DF75D72 F7563186 419494C9 8F9C82A6"); + Integer sExp("0x 24370797 A9D11717 BBBB2B76 2E08ECD0 7DD7E033 F544E47C BF3C6D16 FD90B51D CC2E4DD8 E6ECD8CD"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function SHA-256"; + const size_t len = strlen((char*)msg); + + byte signature[80]; + r.Encode(signature+0, 40); + s.Encode(signature+40, 40); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP320r1 using SHA-256\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-384 (p. 34) + { + const OID oid = ASN1::brainpoolP512r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 92006A98 8AF96D91 57AADCF8 62716962 7CE2ECC4 C58ECE5C 1A0A8642 11AB764C 04236FA0 160857A7 8E71CCAE 4D79D52E 5A69A457 8AF50658 1F598FA9 B4F7DA68"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 00000000 00000000 00000000 00000000 68FEAB7D 8BF8A779 4466E447 5959946B 2136C084 A86090CA 8070C980 68B1250D 88213190 6B7E0CB8 475F9054 E9290C2E"); + Integer k("0x 6942B01D 5901BEC1 506BB874 9618E22E C0FCD7F3 5159D51E D53BA77A 78752128 A58232AD 8E0E021A FDE1477F F4C74FDF FE88AE2D 15D89B56 F6D73C03 77631D2B"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 0104918B 2B32B1A5 49BD43C3 0092953B 4164CA01 A1A97B5B 0756EA06 3AC16B41 B88A1BAB 4538CD7D 8466180B 3E3F5C86 46AC4A45 F564E9B6 8FEE72ED 00C7AC48"); + Integer sExp("0x 3D233E9F D9EB152E 889F4F7C F325B464 0894E5EA 44C51443 54305CD4 BF70D234 8257C2DB E06C5544 92CE9FDD 6861A565 77B53E5E E80E6062 31A4CF06 8FA1EC21"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function SHA-384"; + const size_t len = strlen((char*)msg); + + byte signature[128]; + r.Encode(signature+0, 64); + s.Encode(signature+64, 64); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP512r1 using SHA-384\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + // 2.4.1 Examples of ECGDSA over GF(p) with the hash function SHA-512 (p. 38) + { + const OID oid = ASN1::brainpoolP512r1(); + DL_GroupParameters_EC params(oid); + Integer x("0x 92006A98 8AF96D91 57AADCF8 62716962 7CE2ECC4 C58ECE5C 1A0A8642 11AB764C 04236FA0 160857A7 8E71CCAE 4D79D52E 5A69A457 8AF50658 1F598FA9 B4F7DA68"); + ECGDSA::Signer signer(params, x); + ECGDSA::Verifier verifier(signer); + + Integer e("0x 1A95EF81 D213BD3B 8191E7FE 7F5BFD43 F51E3EE5 A4FD3D08 4A7C9BB5 411F4649 746AEBC6 623D4DEA 7E02DC5A 85E24AF2 96B5A555 AD470413 71E4BF64 380F3E34"); + Integer k("0x 6942B01D 5901BEC1 506BB874 9618E22E C0FCD7F3 5159D51E D53BA77A 78752128 A58232AD 8E0E021A FDE1477F F4C74FDF FE88AE2D 15D89B56 F6D73C03 77631D2B"); + + Integer r, s; + signer.RawSign(k, e, r, s); + + Integer rExp("0x 0104918B 2B32B1A5 49BD43C3 0092953B 4164CA01 A1A97B5B 0756EA06 3AC16B41 B88A1BAB 4538CD7D 8466180B 3E3F5C86 46AC4A45 F564E9B6 8FEE72ED 00C7AC48"); + Integer sExp("0x 17A011F8 DD7B5665 2B27AA6D 6E7BDF3C 7C23B5FA 32910FBA A107E627 0E1CA8A7 A263F661 8E6098A0 D6CD6BA1 C03544C5 425875EC B3418AF5 A3EE3F32 143E48D2"); + + fail = (r != rExp) || (s != sExp); + pass = pass && !fail; + + const byte msg[] = "Example of ECGDSA with the hash function SHA-512"; + const size_t len = strlen((char*)msg); + + byte signature[128]; + r.Encode(signature+0, 64); + s.Encode(signature+64, 64); + + fail = !verifier.VerifyMessage(msg, len, signature, sizeof(signature)); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "brainpoolP512r1 using SHA-512\n"; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + } + + return pass; +} + +bool ValidateESIGN() +{ + std::cout << "\nESIGN validation suite running...\n\n"; + + bool pass = true, fail; + + const char plain[] = "test"; + const byte signature[] = + "\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37" + "\xFE\xBC\x76\x3F\xF1\x84\xF6\x59\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F" + "\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88" + "\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A\x74\x02\x37\x0E\xED\x0A\x06\xAD" + "\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C" + "\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28"; + + FileSource keys(DataDir("TestData/esig1536.dat").c_str(), true, new HexDecoder); + ESIGN::Signer signer(keys); + ESIGN::Verifier verifier(signer); + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength()); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "verification check against test vector\n"; + + std::cout << "Generating signature key from seed..." << std::endl; + signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512)); + verifier = signer; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + return pass; +} + +bool ValidateEd25519() +{ + std::cout << "\ned25519 validation suite running...\n\n"; + bool pass = true, fail; + + const char plain[] = "test"; + const byte signature[] = + "\x91\x12\x44\x91\xA5\x99\xF8\x49\xBA\xB2\xC4\xF2\xBA\x0B\xAA\x99" + "\xC8\xC5\xF5\x19\xDC\x07\xD4\x4C\xF7\x31\xDE\x2F\x2B\x81\xB2\x81" + "\xF6\xA7\xDE\x33\x29\xCA\x45\xAC\x69\x2A\x80\xB7\xDB\x7F\x07\x37" + "\x77\xC4\xBF\xC5\x45\x79\x3A\xAC\xB5\x16\xAE\x4E\xD9\x16\x95\x0E"; + + FileSource keys(DataDir("TestData/ed25519.dat").c_str(), true, new HexDecoder); + ed25519::Signer signer(keys); + ed25519::Verifier verifier(signer); + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength()); + pass = pass && !fail; + + std::cout << (fail ? "FAILED " : "passed "); + std::cout << "verification check against test vector\n"; + + return pass; +} + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/validate.h b/external/ours/library/crypto/src/shared/original/validate.h new file mode 100755 index 000000000..d55e48f79 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/validate.h @@ -0,0 +1,395 @@ +// validate.h - originally written and placed in the public domain by Wei Dai +// CryptoPP::Test namespace added by JW in February 2017 + +#ifndef CRYPTOPP_VALIDATE_H +#define CRYPTOPP_VALIDATE_H + +#include "cryptlib.h" +#include "misc.h" +#include "files.h" +#include "argnames.h" +#include "algparam.h" +#include "hex.h" + +#include +#include +#include +#include +#include + +NAMESPACE_BEGIN(CryptoPP) +NAMESPACE_BEGIN(Test) + +// A hint to help locate TestData/ and TestVectors/ after install. Due to +// execve the path can be malicious. If the path is ficticous then we move +// onto the next potential path. Also note we only read from the path; we +// never write through it. Storage for the string is in test.cpp. +extern std::string g_argvPathHint; + +bool ValidateAll(bool thorough); +bool TestSettings(); +bool TestOS_RNG(); +// bool TestSecRandom(); +bool TestRandomPool(); +#if !defined(NO_OS_DEPENDENCE) +bool TestAutoSeededX917(); +#endif +#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) +bool TestRDRAND(); +bool TestRDSEED(); +bool TestPadlockRNG(); +#endif +#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) +bool TestDARN(); +#endif +bool ValidateBaseCode(); +bool ValidateEncoder(); +bool ValidateCRC32(); +bool ValidateCRC32C(); +bool ValidateAdler32(); +bool ValidateMD2(); +bool ValidateMD4(); +bool ValidateMD5(); +bool ValidateSHA(); +bool ValidateSHA2(); +bool ValidateSHA3(); +bool ValidateSHAKE(); // output <= r, where r is blocksize +bool ValidateSHAKE_XOF(); // output > r, needs hand crafted tests +bool ValidateKeccak(); +bool ValidateTiger(); +bool ValidateRIPEMD(); +bool ValidatePanama(); +bool ValidateWhirlpool(); +bool ValidateLSH(); + +bool ValidateSM3(); +bool ValidateBLAKE2s(); +bool ValidateBLAKE2b(); +bool ValidatePoly1305(); +bool ValidateSipHash(); + +bool ValidateHMAC(); +bool ValidateTTMAC(); + +bool ValidateCipherModes(); +bool ValidatePBKDF(); +bool ValidateHKDF(); +bool ValidateScrypt(); + +bool ValidateDES(); +bool ValidateIDEA(); +bool ValidateSAFER(); +bool ValidateRC2(); +bool ValidateARC4(); + +bool ValidateRC5(); +bool ValidateBlowfish(); +bool ValidateBlowfishCompat(); +bool ValidateThreeWay(); +bool ValidateGOST(); +bool ValidateSHARK(); +bool ValidateSEAL(); +bool ValidateCAST(); +bool ValidateSquare(); +bool ValidateSKIPJACK(); +bool ValidateRC6(); +bool ValidateMARS(); +bool ValidateRijndael(); +bool ValidateTwofish(); +bool ValidateSerpent(); +bool ValidateSHACAL2(); +bool ValidateARIA(); +bool ValidateSIMECK(); +bool ValidateCHAM(); +bool ValidateHIGHT(); +bool ValidateLEA(); +bool ValidateSIMON(); +bool ValidateSPECK(); +bool ValidateCamellia(); + +bool ValidateHC128(); +bool ValidateHC256(); +bool ValidateRabbit(); +bool ValidateSalsa(); +bool ValidateChaCha(); +bool ValidateChaChaTLS(); +bool ValidateSosemanuk(); + +bool ValidateVMAC(); +bool ValidateCCM(); +bool ValidateGCM(); +bool ValidateXTS(); +bool ValidateCMAC(); + +bool ValidateBBS(); +bool ValidateDH(); +bool ValidateMQV(); +bool ValidateHMQV(); +bool ValidateFHMQV(); +bool ValidateRSA(); +bool ValidateElGamal(); +bool ValidateDLIES(); +bool ValidateNR(); +bool ValidateDSA(bool thorough); +bool ValidateLUC(); +bool ValidateLUC_DL(); +bool ValidateLUC_DH(); +bool ValidateXTR_DH(); +bool ValidateRabin(); +bool ValidateRW(); +bool ValidateECP(); +bool ValidateEC2N(); +bool ValidateECDSA(); +bool ValidateECDSA_RFC6979(); +bool ValidateECGDSA(bool thorough); +bool ValidateESIGN(); + +bool ValidateHashDRBG(); +bool ValidateHmacDRBG(); + +bool TestX25519(); +bool TestEd25519(); +bool ValidateX25519(); +bool ValidateEd25519(); +bool ValidateNaCl(); + +// If CRYPTOPP_DEBUG or CRYPTOPP_COVERAGE is in effect, then perform additional tests +#if (defined(CRYPTOPP_DEBUG) || defined(CRYPTOPP_COVERAGE)) && !defined(CRYPTOPP_IMPORTS) +# define CRYPTOPP_EXTENDED_VALIDATION 1 +#endif + +#if defined(CRYPTOPP_EXTENDED_VALIDATION) +// http://github.com/weidai11/cryptopp/issues/92 +bool TestSecBlock(); +// http://github.com/weidai11/cryptopp/issues/64 +bool TestPolynomialMod2(); +// http://github.com/weidai11/cryptopp/issues/336 +bool TestIntegerBitops(); +// http://github.com/weidai11/cryptopp/issues/602 +bool TestIntegerOps(); +// http://github.com/weidai11/cryptopp/issues/360 +bool TestRounding(); +// http://github.com/weidai11/cryptopp/issues/242 +bool TestHuffmanCodes(); +// http://github.com/weidai11/cryptopp/issues/346 +bool TestASN1Parse(); +bool TestASN1Functions(); +// https://github.com/weidai11/cryptopp/pull/334 +bool TestStringSink(); +// Additional tests due to no coverage +bool TestCompressors(); +bool TestEncryptors(); +bool TestMersenne(); +bool TestSharing(); +# if defined(CRYPTOPP_ALTIVEC_AVAILABLE) +bool TestAltivecOps(); +# endif +#endif + +class FixedRNG : public RandomNumberGenerator +{ +public: + FixedRNG(BufferedTransformation &source) : m_source(source) {} + + void GenerateBlock(byte *output, size_t size) + { + m_source.Get(output, size); + } + +private: + BufferedTransformation &m_source; +}; + +// Safer functions on Windows for C&A, http://github.com/weidai11/cryptopp/issues/55 +inline std::string TimeToString(const time_t& t) +{ +#if (CRYPTOPP_MSC_VERSION >= 1400) + tm localTime; + char timeBuf[64]; + errno_t err; + + err = ::localtime_s(&localTime, &t); + CRYPTOPP_ASSERT(err == 0); + err = ::asctime_s(timeBuf, sizeof(timeBuf), &localTime); + CRYPTOPP_ASSERT(err == 0); + + std::string str(err == 0 ? timeBuf : ""); +#elif defined(__MINGW32__) || defined(__MINGW64__) + char* timeString = ::asctime(::localtime(&t)); + std::string str(timeString ? timeString : ""); +#elif (_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || defined(_POSIX_SOURCE)) + tm localTime; + char timeBuf[64]; + char* timeString = ::asctime_r(::localtime_r(&t, &localTime), timeBuf); + std::string str(timeString ? timeString : ""); +#else + char* timeString = ::asctime(::localtime(&t)); + std::string str(timeString ? timeString : ""); +#endif + + // Cleanup whitespace + std::string::size_type pos = 0; + while (!str.empty() && std::isspace(str[str.length()-1])) + {str.erase(str.end()-1);} + while (!str.empty() && std::string::npos != (pos = str.find(" ", pos))) + {str.erase(pos, 1);} + + return str; +} + +// Coverity finding +template +inline T StringToValue(const std::string& str) +{ + std::istringstream iss(str); + + // Arbitrary, but we need to clear a Coverity finding TAINTED_SCALAR + if (iss.str().length() > 25) + throw InvalidArgument(str + "' is too long"); + + T value; + iss >> std::noskipws >> value; + + // Use fail(), not bad() + if (iss.fail()) + throw InvalidArgument(str + "' is not a value"); + + if (NON_NEGATIVE && value < 0) + throw InvalidArgument(str + "' is negative"); + + return value; +} + +// Coverity finding +template<> +inline int StringToValue(const std::string& str) +{ + Integer n(str.c_str()); + long l = n.ConvertToLong(); + + int r; + if (!SafeConvert(l, r)) + throw InvalidArgument(str + "' is not an integer value"); + + return r; +} + +inline std::string AddSeparator(std::string str) +{ + if (str.empty()) return ""; + const char last = str[str.length()-1]; + if (last != '/' && last != '\\') + return str + "/"; + return str; +} + +// Use CRYPTOPP_DATA_DIR last. The problem this sidesteps is, finding an +// old version of Crypto++ library in CRYPTOPP_DATA_DIR when the library +// has been staged in DESTDIR. Using CRYPTOPP_DATA_DIR first only works +// as expected when CRYPTOPP_DATA_DIR is empty before an install. We +// encountered this problem rather quickly during testing of Crypto++ 8.1 +// when Crypto++ 8.0 was installed locally. It took some time to realize +// where the old test data was coming from. +static std::string GetDataDir() +{ + std::ifstream file; + std::string name, filename = "TestData/usage.dat"; + +#ifndef CRYPTOPP_DISABLE_DATA_DIR_SEARCH + // Look in $ORIGIN/../share/. This is likely a Linux install directory. + name = AddSeparator(g_argvPathHint) + std::string("../share/cryptopp/") + filename; + file.open(name.c_str()); + if (file.is_open()) + return AddSeparator(g_argvPathHint) + std::string("../share/cryptopp/"); +#endif +#ifndef CRYPTOPP_DISABLE_DATA_DIR_SEARCH + // Look in current working directory + name = AddSeparator(g_argvPathHint) + filename; + file.open(name.c_str()); + if (file.is_open()) + return AddSeparator(g_argvPathHint); +#endif +#ifdef CRYPTOPP_DATA_DIR + // Honor CRYPTOPP_DATA_DIR. This is likely an install directory if it is not "./". + name = AddSeparator(CRYPTOPP_DATA_DIR) + filename; + file.open(name.c_str()); + if (file.is_open()) + return AddSeparator(CRYPTOPP_DATA_DIR); +#endif + return "./"; +} + +inline std::string DataDir(const std::string& filename) +{ + std::string name; + std::ifstream file; + +#if CRYPTOPP_CXX11_STATIC_INIT + static std::string path = AddSeparator(GetDataDir()); + name = path + filename; + file.open(name.c_str()); + if (file.is_open()) + return name; +#else + // Avoid static initialization problems + name = AddSeparator(GetDataDir()) + filename; + file.open(name.c_str()); + if (file.is_open()) + return name; +#endif + + // This will cause the expected exception in the caller + return filename; +} + +// Definition in test.cpp +RandomNumberGenerator& GlobalRNG(); + +// Definition in datatest.cpp +bool RunTestDataFile(const char *filename, const NameValuePairs &overrideParameters=g_nullNameValuePairs, bool thorough=true); + +// Definitions in validat6.cpp +bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false); +bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d); +bool AuthenticatedKeyAgreementWithRolesValidate(AuthenticatedKeyAgreementDomain &initiator, AuthenticatedKeyAgreementDomain &recipient); +bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d); +bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false); + +// Miscellaneous PK definitions in validat6.cpp +// Key Agreement definitions in validat7.cpp +// Encryption and Decryption definitions in validat8.cpp +// Sign and Verify definitions in validat9.cpp + +bool ValidateECP(); +bool ValidateEC2N(); + +bool ValidateRSA_Encrypt(); +bool ValidateRSA_Sign(); + +bool ValidateLUC_Encrypt(); +bool ValidateLUC_Sign(); + +bool ValidateLUC_DL_Encrypt(); +bool ValidateLUC_DL_Sign(); + +bool ValidateRabin_Encrypt(); +bool ValidateRabin_Sign(); + +bool ValidateECP(); +bool ValidateECP_Agreement(); +bool ValidateECP_Encrypt(); +bool ValidateECP_Sign(); + +bool ValidateECP_Legacy_Encrypt(); +bool ValidateEC2N_Legacy_Encrypt(); +bool ValidateECP_NULLDigest_Encrypt(); + +bool ValidateEC2N(); +bool ValidateEC2N_Agreement(); +bool ValidateEC2N_Encrypt(); +bool ValidateEC2N_Sign(); + +NAMESPACE_END // Test +NAMESPACE_END // CryptoPP + +#endif diff --git a/external/ours/library/crypto/src/shared/original/vmac.cpp b/external/ours/library/crypto/src/shared/original/vmac.cpp new file mode 100755 index 000000000..c625c6bb4 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/vmac.cpp @@ -0,0 +1,894 @@ +// vmac.cpp - originally written and placed in the public domain by Wei Dai +// based on Ted Krovetz's public domain vmac.c and draft-krovetz-vmac-01.txt + +#include "pch.h" +#include "config.h" + +#include "vmac.h" +#include "cpu.h" +#include "argnames.h" +#include "secblock.h" + +#if defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64 +#include +#endif + +#if defined(CRYPTOPP_DISABLE_VMAC_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4731) +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +#if defined(CRYPTOPP_WORD128_AVAILABLE) && !defined(CRYPTOPP_X64_ASM_AVAILABLE) +using CryptoPP::word128; +using CryptoPP::word64; +# define VMAC_BOOL_WORD128 1 +#else +using CryptoPP::word64; +# define VMAC_BOOL_WORD128 0 +#endif + +#ifdef __BORLANDC__ +#define const // Turbo C++ 2006 workaround +#endif +const word64 p64 = W64LIT(0xfffffffffffffeff); /* 2^64 - 257 prime */ +const word64 m62 = W64LIT(0x3fffffffffffffff); /* 62-bit mask */ +const word64 m63 = W64LIT(0x7fffffffffffffff); /* 63-bit mask */ +const word64 m64 = W64LIT(0xffffffffffffffff); /* 64-bit mask */ +const word64 mpoly = W64LIT(0x1fffffff1fffffff); /* Poly key mask */ +#ifdef __BORLANDC__ +#undef const +#endif + +#if VMAC_BOOL_WORD128 +// workaround GCC Bug 31690: ICE with const __uint128_t and C++ front-end +# if defined(__powerpc__) && defined (CRYPTOPP_GCC_VERSION) && (CRYPTOPP_GCC_VERSION < 50300) +# define m126 ((word128(m62)<<64)|m64) +# else +const word128 m126 = (word128(m62)<<64)|m64; /* 126-bit mask */ +# endif +#endif + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void VMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms) +{ + int digestLength = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize()); + if (digestLength != 8 && digestLength != 16) + throw InvalidArgument("VMAC: DigestSize must be 8 or 16"); + m_is128 = digestLength == 16; + + m_L1KeyLength = params.GetIntValueWithDefault(Name::L1KeyLength(), 128); + if (m_L1KeyLength <= 0 || m_L1KeyLength % 128 != 0) + throw InvalidArgument("VMAC: L1KeyLength must be a positive multiple of 128"); + + AllocateBlocks(); + + BlockCipher &cipher = AccessCipher(); + cipher.SetKey(userKey, keylength, params); + const unsigned int blockSize = cipher.BlockSize(); + const unsigned int blockSizeInWords = blockSize / sizeof(word64); + SecBlock > out(blockSizeInWords); + AlignedSecByteBlock in; + in.CleanNew(blockSize); + size_t i; + + /* Fill nh key */ + in[0] = 0x80; + cipher.AdvancedProcessBlocks(in, NULLPTR, (byte *)m_nhKey(), m_nhKeySize()*sizeof(word64), cipher.BT_InBlockIsCounter); + ConditionalByteReverse(BIG_ENDIAN_ORDER, m_nhKey(), m_nhKey(), m_nhKeySize()*sizeof(word64)); + + /* Fill poly key */ + in[0] = 0xC0; + in[15] = 0; + for (i = 0; i <= (size_t)m_is128; i++) + { + cipher.ProcessBlock(in, out.BytePtr()); + m_polyState()[i*4+2] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()) & mpoly; + m_polyState()[i*4+3] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()+8) & mpoly; + in[15]++; + } + + /* Fill ip key */ + in[0] = 0xE0; + in[15] = 0; + word64 *l3Key = m_l3Key(); + CRYPTOPP_ASSERT(IsAlignedOn(l3Key,GetAlignmentOf())); + + for (i = 0; i <= (size_t)m_is128; i++) + do + { + cipher.ProcessBlock(in, out.BytePtr()); + l3Key[i*2+0] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()); + l3Key[i*2+1] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()+8); + in[15]++; + } while ((l3Key[i*2+0] >= p64) || (l3Key[i*2+1] >= p64)); + + m_padCached = false; + size_t nonceLength; + const byte *nonce = GetIVAndThrowIfInvalid(params, nonceLength); + Resynchronize(nonce, (int)nonceLength); +} + +void VMAC_Base::GetNextIV(RandomNumberGenerator &rng, byte *IV) +{ + SimpleKeyingInterface::GetNextIV(rng, IV); + IV[0] &= 0x7f; +} + +void VMAC_Base::Resynchronize(const byte *nonce, int len) +{ + size_t length = ThrowIfInvalidIVLength(len); + size_t s = IVSize(); + byte *storedNonce = m_nonce(); + + if (m_is128) + { + memset(storedNonce, 0, s-length); + memcpy(storedNonce+s-length, nonce, length); + AccessCipher().ProcessBlock(storedNonce, m_pad()); + } + else + { + if (m_padCached && (storedNonce[s-1] | 1) == (nonce[length-1] | 1)) + { + m_padCached = VerifyBufsEqual(storedNonce+s-length, nonce, length-1); + for (size_t i=0; m_padCached && i>64); rl = word64(p);} + #define AccumulateNH(a, b, c) a += word128(b)*(c) + #define Multiply128(r, i1, i2) r = word128(word64(i1)) * word64(i2) +#else + #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) && (defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)) + #define MUL32(a, b) __emulu(word32(a), word32(b)) + #else + #define MUL32(a, b) ((word64)((word32)(a)) * (word32)(b)) + #endif + #if defined(CRYPTOPP_X64_ASM_AVAILABLE) + #define DeclareNH(a) word64 a##0=0, a##1=0 + #define MUL64(rh,rl,i1,i2) asm ("mulq %3" : "=a"(rl), "=d"(rh) : "a"(i1), "g"(i2) : "cc"); + #define AccumulateNH(a, b, c) asm ("mulq %3; addq %%rax, %0; adcq %%rdx, %1" : "+r"(a##0), "+r"(a##1) : "a"(b), "g"(c) : "%rdx", "cc"); + #define ADD128(rh,rl,ih,il) asm ("addq %3, %1; adcq %2, %0" : "+r"(rh),"+r"(rl) : "r"(ih),"r"(il) : "cc"); + #elif defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64 + #define DeclareNH(a) word64 a##0=0, a##1=0 + #define MUL64(rh,rl,i1,i2) (rl) = _umul128(i1,i2,&(rh)); + #define AccumulateNH(a, b, c) {\ + word64 ph, pl;\ + pl = _umul128(b,c,&ph);\ + a##0 += pl;\ + a##1 += ph + (a##0 < pl);} + #else + #define VMAC_BOOL_32BIT 1 + #define DeclareNH(a) word64 a##0=0, a##1=0, a##2=0 + #define MUL64(rh,rl,i1,i2) \ + { word64 _i1 = (i1), _i2 = (i2); \ + word64 m1= MUL32(_i1,_i2>>32); \ + word64 m2= MUL32(_i1>>32,_i2); \ + rh = MUL32(_i1>>32,_i2>>32); \ + rl = MUL32(_i1,_i2); \ + ADD128(rh,rl,(m1 >> 32),(m1 << 32)); \ + ADD128(rh,rl,(m2 >> 32),(m2 << 32)); \ + } + #define AccumulateNH(a, b, c) {\ + word64 p = MUL32(b, c);\ + a##1 += word32((p)>>32);\ + a##0 += word32(p);\ + p = MUL32((b)>>32, c);\ + a##2 += word32((p)>>32);\ + a##1 += word32(p);\ + p = MUL32((b)>>32, (c)>>32);\ + a##2 += p;\ + p = MUL32(b, (c)>>32);\ + a##1 += word32(p);\ + a##2 += word32(p>>32);} + #endif +#endif +#ifndef VMAC_BOOL_32BIT + #define VMAC_BOOL_32BIT 0 +#endif +#ifndef ADD128 + #define ADD128(rh,rl,ih,il) \ + { word64 _il = (il); \ + (rl) += (_il); \ + (rh) += (ih) + ((rl) < (_il)); \ + } +#endif + +template +void VMAC_Base::VHASH_Update_Template(const word64 *data, size_t blocksRemainingInWord64) +{ + CRYPTOPP_ASSERT(IsAlignedOn(m_polyState(),GetAlignmentOf())); + CRYPTOPP_ASSERT(IsAlignedOn(m_nhKey(),GetAlignmentOf())); + + #define INNER_LOOP_ITERATION(j) {\ + word64 d0 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+0]);\ + word64 d1 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+1]);\ + AccumulateNH(nhA, d0+nhK[i+2*j+0], d1+nhK[i+2*j+1]);\ + if (T_128BitTag)\ + AccumulateNH(nhB, d0+nhK[i+2*j+2], d1+nhK[i+2*j+3]);\ + } + + size_t L1KeyLengthInWord64 = m_L1KeyLength / 8; + size_t innerLoopEnd = L1KeyLengthInWord64; + const word64 *nhK = m_nhKey(); + word64 *polyS = (word64*)(void*)m_polyState(); + bool isFirstBlock = true; + size_t i; + + #if !VMAC_BOOL_32BIT + #if VMAC_BOOL_WORD128 + word128 a1=0, a2=0; + #else + word64 ah1=0, al1=0, ah2=0, al2=0; + #endif + word64 kh1, kl1, kh2, kl2; + kh1=(polyS+0*4+2)[0]; kl1=(polyS+0*4+2)[1]; + if (T_128BitTag) + { + kh2=(polyS+1*4+2)[0]; kl2=(polyS+1*4+2)[1]; + } + #endif + + do + { + DeclareNH(nhA); + DeclareNH(nhB); + + i = 0; + if (blocksRemainingInWord64 < L1KeyLengthInWord64) + { + if (blocksRemainingInWord64 % 8) + { + innerLoopEnd = blocksRemainingInWord64 % 8; + for (; i> 32); + nh1[0] = word32(nhA1); + nh2[0] = (nhA2 + (nhA1 >> 32)) & m62; + + if (T_128BitTag) + { + nh0[1] = word32(nhB0); + nhB1 += (nhB0 >> 32); + nh1[1] = word32(nhB1); + nh2[1] = (nhB2 + (nhB1 >> 32)) & m62; + } + + #define a0 (((word32 *)(polyS+i*4))[2+NativeByteOrder::ToEnum()]) + #define a1 (*(((word32 *)(polyS+i*4))+3-NativeByteOrder::ToEnum())) // workaround for GCC 3.2 + #define a2 (((word32 *)(polyS+i*4))[0+NativeByteOrder::ToEnum()]) + #define a3 (*(((word32 *)(polyS+i*4))+1-NativeByteOrder::ToEnum())) + #define aHi ((polyS+i*4)[0]) + #define k0 (((word32 *)(polyS+i*4+2))[2+NativeByteOrder::ToEnum()]) + #define k1 (*(((word32 *)(polyS+i*4+2))+3-NativeByteOrder::ToEnum())) + #define k2 (((word32 *)(polyS+i*4+2))[0+NativeByteOrder::ToEnum()]) + #define k3 (*(((word32 *)(polyS+i*4+2))+1-NativeByteOrder::ToEnum())) + #define kHi ((polyS+i*4+2)[0]) + + if (isFirstBlock) + { + isFirstBlock = false; + if (m_isFirstBlock) + { + m_isFirstBlock = false; + for (i=0; i<=(size_t)T_128BitTag; i++) + { + word64 t = (word64)nh0[i] + k0; + a0 = (word32)t; + t = (t >> 32) + nh1[i] + k1; + a1 = (word32)t; + aHi = (t >> 32) + nh2[i] + kHi; + } + continue; + } + } + for (i=0; i<=(size_t)T_128BitTag; i++) + { + word64 p, t; + word32 t2; + + p = MUL32(a3, 2*k3); + p += nh2[i]; + p += MUL32(a0, k2); + p += MUL32(a1, k1); + p += MUL32(a2, k0); + t2 = (word32)p; + p >>= 32; + p += MUL32(a0, k3); + p += MUL32(a1, k2); + p += MUL32(a2, k1); + p += MUL32(a3, k0); + t = (word64(word32(p) & 0x7fffffff) << 32) | t2; + p >>= 31; + p += nh0[i]; + p += MUL32(a0, k0); + p += MUL32(a1, 2*k3); + p += MUL32(a2, 2*k2); + p += MUL32(a3, 2*k1); + t2 = (word32)p; + p >>= 32; + p += nh1[i]; + p += MUL32(a0, k1); + p += MUL32(a1, k0); + p += MUL32(a2, 2*k3); + p += MUL32(a3, 2*k2); + a0 = t2; + a1 = (word32)p; + aHi = (p >> 32) + t; + } + + #undef a0 + #undef a1 + #undef a2 + #undef a3 + #undef aHi + #undef k0 + #undef k1 + #undef k2 + #undef k3 + #undef kHi + #else // #if VMAC_BOOL_32BIT + if (isFirstBlock) + { + isFirstBlock = false; + if (m_isFirstBlock) + { + m_isFirstBlock = false; + #if VMAC_BOOL_WORD128 + #define first_poly_step(a, kh, kl, m) a = (m & m126) + ((word128(kh) << 64) | kl) + + first_poly_step(a1, kh1, kl1, nhA); + if (T_128BitTag) + first_poly_step(a2, kh2, kl2, nhB); + #else + #define first_poly_step(ah, al, kh, kl, mh, ml) {\ + mh &= m62;\ + ADD128(mh, ml, kh, kl); \ + ah = mh; al = ml;} + + first_poly_step(ah1, al1, kh1, kl1, nhA1, nhA0); + if (T_128BitTag) + first_poly_step(ah2, al2, kh2, kl2, nhB1, nhB0); + #endif + continue; + } + else + { + #if VMAC_BOOL_WORD128 + a1 = (word128((polyS+0*4)[0]) << 64) | (polyS+0*4)[1]; + #else + ah1=(polyS+0*4)[0]; al1=(polyS+0*4)[1]; + #endif + if (T_128BitTag) + { + #if VMAC_BOOL_WORD128 + a2 = (word128((polyS+1*4)[0]) << 64) | (polyS+1*4)[1]; + #else + ah2=(polyS+1*4)[0]; al2=(polyS+1*4)[1]; + #endif + } + } + } + + #if VMAC_BOOL_WORD128 + #define poly_step(a, kh, kl, m) \ + { word128 t1, t2, t3, t4;\ + Multiply128(t2, a>>64, kl);\ + Multiply128(t3, a, kh);\ + Multiply128(t1, a, kl);\ + Multiply128(t4, a>>64, 2*kh);\ + t2 += t3;\ + t4 += t1;\ + t2 += t4>>64;\ + a = (word128(word64(t2)&m63) << 64) | word64(t4);\ + t2 *= 2;\ + a += m & m126;\ + a += t2>>64;} + + poly_step(a1, kh1, kl1, nhA); + if (T_128BitTag) + poly_step(a2, kh2, kl2, nhB); + #else + #define poly_step(ah, al, kh, kl, mh, ml) \ + { word64 t1h, t1l, t2h, t2l, t3h, t3l, z=0; \ + /* compute ab*cd, put bd into result registers */ \ + MUL64(t2h,t2l,ah,kl); \ + MUL64(t3h,t3l,al,kh); \ + MUL64(t1h,t1l,ah,2*kh); \ + MUL64(ah,al,al,kl); \ + /* add together ad + bc */ \ + ADD128(t2h,t2l,t3h,t3l); \ + /* add 2 * ac to result */ \ + ADD128(ah,al,t1h,t1l); \ + /* now (ah,al), (t2l,2*t2h) need summing */ \ + /* first add the high registers, carrying into t2h */ \ + ADD128(t2h,ah,z,t2l); \ + /* double t2h and add top bit of ah */ \ + t2h += t2h + (ah >> 63); \ + ah &= m63; \ + /* now add the low registers */ \ + mh &= m62; \ + ADD128(ah,al,mh,ml); \ + ADD128(ah,al,z,t2h); \ + } + + poly_step(ah1, al1, kh1, kl1, nhA1, nhA0); + if (T_128BitTag) + poly_step(ah2, al2, kh2, kl2, nhB1, nhB0); + #endif + #endif // #if VMAC_BOOL_32BIT + } while (blocksRemainingInWord64); + + #if VMAC_BOOL_WORD128 + (polyS+0*4)[0]=word64(a1>>64); (polyS+0*4)[1]=word64(a1); + if (T_128BitTag) + { + (polyS+1*4)[0]=word64(a2>>64); (polyS+1*4)[1]=word64(a2); + } + #elif !VMAC_BOOL_32BIT + (polyS+0*4)[0]=ah1; (polyS+0*4)[1]=al1; + if (T_128BitTag) + { + (polyS+1*4)[0]=ah2; (polyS+1*4)[1]=al2; + } + #endif +} + +inline void VMAC_Base::VHASH_Update(const word64 *data, size_t blocksRemainingInWord64) +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 + if (HasSSE2()) + { + VHASH_Update_SSE2(data, blocksRemainingInWord64, 0); + if (m_is128) + VHASH_Update_SSE2(data, blocksRemainingInWord64, 1); + m_isFirstBlock = false; + } + else +#endif + { + if (m_is128) + VHASH_Update_Template(data, blocksRemainingInWord64); + else + VHASH_Update_Template(data, blocksRemainingInWord64); + } +} + +size_t VMAC_Base::HashMultipleBlocks(const word64 *data, size_t length) +{ + size_t remaining = ModPowerOf2(length, m_L1KeyLength); + VHASH_Update(data, (length-remaining)/8); + return remaining; +} + +word64 L3Hash(const word64 *input, const word64 *l3Key, size_t len) +{ + word64 rh, rl, t, z=0; + word64 p1 = input[0], p2 = input[1]; + word64 k1 = l3Key[0], k2 = l3Key[1]; + + /* fully reduce (p1,p2)+(len,0) mod p127 */ + t = p1 >> 63; + p1 &= m63; + ADD128(p1, p2, len, t); + /* At this point, (p1,p2) is at most 2^127+(len<<64) */ + t = (p1 > m63) + ((p1 == m63) & (p2 == m64)); + ADD128(p1, p2, z, t); + p1 &= m63; + + /* compute (p1,p2)/(2^64-2^32) and (p1,p2)%(2^64-2^32) */ + t = p1 + (p2 >> 32); + t += (t >> 32); + t += (word32)t > 0xfffffffeU; + p1 += (t >> 32); + p2 += (p1 << 32); + + /* compute (p1+k1)%p64 and (p2+k2)%p64 */ + p1 += k1; + p1 += (0 - (p1 < k1)) & 257; + p2 += k2; + p2 += (0 - (p2 < k2)) & 257; + + /* compute (p1+k1)*(p2+k2)%p64 */ + MUL64(rh, rl, p1, p2); + t = rh >> 56; + ADD128(t, rl, z, rh); + rh <<= 8; + ADD128(t, rl, z, rh); + t += t << 8; + rl += t; + rl += (0 - (rl < t)) & 257; + rl += (0 - (rl > p64-1)) & 257; + return rl; +} + +void VMAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + CRYPTOPP_ASSERT(IsAlignedOn(DataBuf(),GetAlignmentOf())); + CRYPTOPP_ASSERT(IsAlignedOn(m_polyState(),GetAlignmentOf())); + size_t len = ModPowerOf2(GetBitCountLo()/8, m_L1KeyLength); + + if (len) + { + memset(m_data()+len, 0, (0-len)%16); + VHASH_Update(DataBuf(), ((len+15)/16)*2); + len *= 8; // convert to bits + } + else if (m_isFirstBlock) + { + // special case for empty string + m_polyState()[0] = m_polyState()[2]; + m_polyState()[1] = m_polyState()[3]; + if (m_is128) + { + m_polyState()[4] = m_polyState()[6]; + m_polyState()[5] = m_polyState()[7]; + } + } + + if (m_is128) + { + word64 t[2]; + t[0] = L3Hash(m_polyState(), m_l3Key(), len) + GetWord(true, BIG_ENDIAN_ORDER, m_pad()); + t[1] = L3Hash(m_polyState()+4, m_l3Key()+2, len) + GetWord(true, BIG_ENDIAN_ORDER, m_pad()+8); + if (size == 16) + { + PutWord(false, BIG_ENDIAN_ORDER, mac, t[0]); + PutWord(false, BIG_ENDIAN_ORDER, mac+8, t[1]); + } + else + { + t[0] = ConditionalByteReverse(BIG_ENDIAN_ORDER, t[0]); + t[1] = ConditionalByteReverse(BIG_ENDIAN_ORDER, t[1]); + memcpy(mac, t, size); + } + } + else + { + word64 t = L3Hash(m_polyState(), m_l3Key(), len); + t += GetWord(true, BIG_ENDIAN_ORDER, m_pad() + (m_nonce()[IVSize()-1]&1) * 8); + if (size == 8) + PutWord(false, BIG_ENDIAN_ORDER, mac, t); + else + { + t = ConditionalByteReverse(BIG_ENDIAN_ORDER, t); + memcpy(mac, &t, size); + } + } +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/vmac.h b/external/ours/library/crypto/src/shared/original/vmac.h new file mode 100755 index 000000000..44fe09fcc --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/vmac.h @@ -0,0 +1,91 @@ +// vmac.h - originally written and placed in the public domain by Wei Dai + +/// \file vmac.h +/// \brief Classes for the VMAC message authentication code +/// \since Crypto++ 5.5 + +#ifndef CRYPTOPP_VMAC_H +#define CRYPTOPP_VMAC_H + +#include "cryptlib.h" +#include "iterhash.h" +#include "seckey.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_VMAC_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief VMAC message authentication code base class +/// \since Crypto++ 5.5 +class VMAC_Base : public IteratedHashBase +{ +public: + std::string AlgorithmName() const {return std::string("VMAC(") + GetCipher().AlgorithmName() + ")-" + IntToString(DigestSize()*8);} + std::string AlgorithmProvider() const {return GetCipher().AlgorithmProvider();} + unsigned int IVSize() const {return GetCipher().BlockSize();} + unsigned int MinIVLength() const {return 1;} + void Resynchronize(const byte *nonce, int length=-1); + void GetNextIV(RandomNumberGenerator &rng, byte *IV); + unsigned int DigestSize() const {return m_is128 ? 16 : 8;}; + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + void TruncatedFinal(byte *mac, size_t size); + unsigned int BlockSize() const {return m_L1KeyLength;} + ByteOrder GetByteOrder() const {return LITTLE_ENDIAN_ORDER;} + unsigned int OptimalDataAlignment() const; + +protected: + virtual BlockCipher & AccessCipher() =0; + virtual int DefaultDigestSize() const =0; + const BlockCipher & GetCipher() const {return const_cast(this)->AccessCipher();} + void HashEndianCorrectedBlock(const word64 *data); + size_t HashMultipleBlocks(const word64 *input, size_t length); + void Init() {} + word64* StateBuf() {return NULLPTR;} + word64* DataBuf() {return (word64 *)(void*)m_data();} + + void VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64, int tagPart); + template + void VHASH_Update_Template(const word64 *data, size_t blockRemainingInWord128); + void VHASH_Update(const word64 *data, size_t blocksRemainingInWord128); + + CRYPTOPP_BLOCK_1(polyState, word64, (m_is128 ? 8 : 4)) + CRYPTOPP_BLOCK_2(nhKey, word64, m_L1KeyLength/sizeof(word64) + 2*m_is128) + CRYPTOPP_BLOCK_3(data, byte, m_L1KeyLength) + CRYPTOPP_BLOCK_4(l3Key, word64, (m_is128 ? 4 : 2)) + CRYPTOPP_BLOCK_5(nonce, byte, IVSize()) + CRYPTOPP_BLOCK_6(pad, byte, IVSize()) + CRYPTOPP_BLOCKS_END(6) + + bool m_is128, m_padCached, m_isFirstBlock; + unsigned int m_L1KeyLength; +}; + +/// \brief VMAC message authentication code +/// \tparam T_BlockCipher block cipher +/// \tparam T_DigestBitSize digest size, in bits +/// \details VMAC is a block cipher-based message authentication code algorithm +/// using a universal hash proposed by Ted Krovetz and Wei Dai in April 2007. The +/// algorithm was designed for high performance backed by a formal analysis. +/// \details The implementation is based on Ted Krovetz's public domain vmac.c +/// and draft-krovetz-vmac-01.txt. +/// \sa VMAC. +/// \since Crypto++ 5.5 +template +class VMAC : public SimpleKeyingInterfaceImpl > +{ +public: + static std::string StaticAlgorithmName() {return std::string("VMAC(") + T_BlockCipher::StaticAlgorithmName() + ")-" + IntToString(T_DigestBitSize);} + +private: + BlockCipher & AccessCipher() {return m_cipher;} + int DefaultDigestSize() const {return T_DigestBitSize/8;} + typename T_BlockCipher::Encryption m_cipher; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/wake.cpp b/external/ours/library/crypto/src/shared/original/wake.cpp new file mode 100755 index 000000000..f4e43dc17 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/wake.cpp @@ -0,0 +1,111 @@ +// wake.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "wake.h" +#include "smartptr.h" + +ANONYMOUS_NAMESPACE_BEGIN + +const unsigned int TT[8]= { + 0x726a8f3b, 0xe69a3b5c, 0xd3c71fe5, 0xab3c73d2, + 0x4d3a8eb3, 0x0396d6e8, 0x3d4c2f7a, 0x9ee27cf3 +} ; + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void WAKE_TestInstantiations() +{ + WAKE_OFB<>::Encryption x2; + WAKE_OFB<>::Decryption x4; +} +#endif + +inline word32 WAKE_Base::M(word32 x, word32 y) +{ + word32 w = x+y; + return (w>>8) ^ t[w & 0xff]; +} + +void WAKE_Base::GenKey(word32 k0, word32 k1, word32 k2, word32 k3) +{ + // this code is mostly copied from David Wheeler's paper "A Bulk Data Encryption Algorithm" + signed int x, z, p; + + t[0] = k0; + t[1] = k1; + t[2] = k2; + t[3] = k3; + for (p=4 ; p<256 ; p++) + { + x=t[p-4]+t[p-1] ; // fill t + t[p]= (x>>3) ^ TT[x&7] ; + } + + for (p=0 ; p<23 ; p++) + t[p]+=t[p+89] ; // mix first entries + x=t[33] ; z=t[59] | 0x01000001 ; + z=z&0xff7fffff ; + for (p=0 ; p<256 ; p++) { //change top byte to + x=(x&0xff7fffff)+z ; // a permutation etc + t[p]=(t[p] & 0x00ffffff) ^ x ; } + + t[256]=t[0] ; + byte y=byte(x); + for (p=0 ; p<256 ; p++) { // further change perm. + t[p]=t[y=byte(t[p^y]^y)] ; // and other digits + t[y]=t[p+1] ; } +} + +template +void WAKE_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length); + word32 k0, k1, k2, k3; + BlockGetAndPut::Get(key)(r3)(r4)(r5)(r6)(k0)(k1)(k2)(k3); + GenKey(k0, k1, k2, k3); +} + +// OFB +template +void WAKE_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#define WAKE_OUTPUT(x)\ + while (iterationCount--)\ + {\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, r6);\ + r3 = M(r3, r6);\ + r4 = M(r4, r3);\ + r5 = M(r5, r4);\ + r6 = M(r6, r5);\ + output += 4;\ + if (!(x & INPUT_NULL))\ + input += 4;\ + } + + typedef word32 WordType; + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(WAKE_OUTPUT, 0); +} +/* +template +void WAKE_ROFB_Policy::Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) +{ + KeystreamOutput keystreamOperation(operation, output, input); + + while (iterationCount--) + { + keystreamOperation(r6); + r3 = M(r3, r6); + r4 = M(r4, r3); + r5 = M(r5, r4); + r6 = M(r6, r5); + } +} +*/ +template class WAKE_Policy; +template class WAKE_Policy; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/wake.h b/external/ours/library/crypto/src/shared/original/wake.h new file mode 100755 index 000000000..adecd30f8 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/wake.h @@ -0,0 +1,59 @@ +// wake.h - originally written and placed in the public domain by Wei Dai + +/// \file wake.h +/// \brief Classes for WAKE stream cipher + +#ifndef CRYPTOPP_WAKE_H +#define CRYPTOPP_WAKE_H + +#include "seckey.h" +#include "secblock.h" +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief WAKE stream cipher information +/// \tparam B Endianness of the stream cipher +/// \since Crypto++ 1.0 +template +struct WAKE_OFB_Info : public FixedKeyLength<32> +{ + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == LITTLE_ENDIAN_ORDER ? "WAKE-OFB-LE" : "WAKE-OFB-BE";} +}; + +class CRYPTOPP_NO_VTABLE WAKE_Base +{ +protected: + word32 M(word32 x, word32 y); + void GenKey(word32 k0, word32 k1, word32 k2, word32 k3); + + word32 t[257]; + word32 r3, r4, r5, r6; +}; + +/// \brief WAKE stream cipher operation +/// \tparam B Endianness of the stream cipher +/// \since Crypto++ 1.0 +template +class CRYPTOPP_NO_VTABLE WAKE_Policy : public AdditiveCipherConcretePolicy, protected WAKE_Base +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + // OFB + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + bool CipherIsRandomAccess() const {return false;} +}; + +/// \brief WAKE stream cipher +/// \tparam B Endianness of the stream cipher +/// \since Crypto++ 1.0 +template +struct WAKE_OFB : public WAKE_OFB_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, WAKE_OFB_Info > Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/whrlpool.cpp b/external/ours/library/crypto/src/shared/original/whrlpool.cpp new file mode 100755 index 000000000..4a52a0dde --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/whrlpool.cpp @@ -0,0 +1,730 @@ +// whrlpool.cpp - originally modified by Kevin Springle from Paulo Barreto and Vincent Rijmen's +// public domain code, whirlpool.c. Updated to Whirlpool version 3.0, optimized +// and SSE version added by WD. All modifications are placed in the public domain. +// +// This is the original introductory comment: + +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * @author Paulo S.L.M. Barreto + * @author Vincent Rijmen. + * + * @version 3.0 (2003.03.12) + * + * ============================================================================= + * + * Differences from version 2.1: + * + * - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2, 9). + * + * ============================================================================= + * + * Differences from version 2.0: + * + * - Generation of ISO/IEC 10118-3 test vectors. + * - Bug fix: nonzero carry was ignored when tallying the data length + * (this bug apparently only manifested itself when feeding data + * in pieces rather than in a single chunk at once). + * - Support for MS Visual C++ 64-bit integer arithmetic. + * + * Differences from version 1.0: + * + * - Original S-box replaced by the tweaked, hardware-efficient version. + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "pch.h" +#include "config.h" + +#if CRYPTOPP_MSC_VERSION +# pragma warning(disable: 4127) +#endif + +#include "whrlpool.h" +#include "misc.h" +#include "cpu.h" + +#if defined(CRYPTOPP_DISABLE_WHIRLPOOL_ASM) +# undef CRYPTOPP_X86_ASM_AVAILABLE +# undef CRYPTOPP_X32_ASM_AVAILABLE +# undef CRYPTOPP_X64_ASM_AVAILABLE +# undef CRYPTOPP_SSE2_ASM_AVAILABLE +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) +void Whirlpool_TestInstantiations() +{ + Whirlpool x; +} +#endif + +std::string Whirlpool::AlgorithmProvider() const +{ +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return "SSE2"; +#endif + return "C++"; +} + +void Whirlpool::InitState(HashWordType *state) +{ + memset(state, 0, 8*sizeof(state[0])); +} + +void Whirlpool::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(32); + CorrectEndianess(m_data, m_data, 32); + + m_data[m_data.size()-4] = 0; + m_data[m_data.size()-3] = 0; + m_data[m_data.size()-2] = GetBitCountHi(); + m_data[m_data.size()-1] = GetBitCountLo(); + + Transform(m_state, m_data); + CorrectEndianess(m_state, m_state, DigestSize()); + memcpy(hash, m_state, size); + + Restart(); // reinit for next use +} + +/* + * The number of rounds of the internal dedicated block cipher. + */ +#define R 10 + +/* + * Though Whirlpool is endianness-neutral, the encryption tables are listed + * in BIG-ENDIAN format, which is adopted throughout this implementation + * (but little-endian notation would be equally suitable if consistently + * employed). + */ + +#if CRYPTOPP_SSE2_ASM_AVAILABLE +CRYPTOPP_ALIGN_DATA(16) +CRYPTOPP_TABLE +const word64 Whirlpool_C[4*256+R] = { +#else +const word64 Whirlpool_C[4*256+R] = { +#endif + W64LIT(0x18186018c07830d8), W64LIT(0x23238c2305af4626), W64LIT(0xc6c63fc67ef991b8), W64LIT(0xe8e887e8136fcdfb), + W64LIT(0x878726874ca113cb), W64LIT(0xb8b8dab8a9626d11), W64LIT(0x0101040108050209), W64LIT(0x4f4f214f426e9e0d), + W64LIT(0x3636d836adee6c9b), W64LIT(0xa6a6a2a6590451ff), W64LIT(0xd2d26fd2debdb90c), W64LIT(0xf5f5f3f5fb06f70e), + W64LIT(0x7979f979ef80f296), W64LIT(0x6f6fa16f5fcede30), W64LIT(0x91917e91fcef3f6d), W64LIT(0x52525552aa07a4f8), + W64LIT(0x60609d6027fdc047), W64LIT(0xbcbccabc89766535), W64LIT(0x9b9b569baccd2b37), W64LIT(0x8e8e028e048c018a), + W64LIT(0xa3a3b6a371155bd2), W64LIT(0x0c0c300c603c186c), W64LIT(0x7b7bf17bff8af684), W64LIT(0x3535d435b5e16a80), + W64LIT(0x1d1d741de8693af5), W64LIT(0xe0e0a7e05347ddb3), W64LIT(0xd7d77bd7f6acb321), W64LIT(0xc2c22fc25eed999c), + W64LIT(0x2e2eb82e6d965c43), W64LIT(0x4b4b314b627a9629), W64LIT(0xfefedffea321e15d), W64LIT(0x575741578216aed5), + W64LIT(0x15155415a8412abd), W64LIT(0x7777c1779fb6eee8), W64LIT(0x3737dc37a5eb6e92), W64LIT(0xe5e5b3e57b56d79e), + W64LIT(0x9f9f469f8cd92313), W64LIT(0xf0f0e7f0d317fd23), W64LIT(0x4a4a354a6a7f9420), W64LIT(0xdada4fda9e95a944), + W64LIT(0x58587d58fa25b0a2), W64LIT(0xc9c903c906ca8fcf), W64LIT(0x2929a429558d527c), W64LIT(0x0a0a280a5022145a), + W64LIT(0xb1b1feb1e14f7f50), W64LIT(0xa0a0baa0691a5dc9), W64LIT(0x6b6bb16b7fdad614), W64LIT(0x85852e855cab17d9), + W64LIT(0xbdbdcebd8173673c), W64LIT(0x5d5d695dd234ba8f), W64LIT(0x1010401080502090), W64LIT(0xf4f4f7f4f303f507), + W64LIT(0xcbcb0bcb16c08bdd), W64LIT(0x3e3ef83eedc67cd3), W64LIT(0x0505140528110a2d), W64LIT(0x676781671fe6ce78), + W64LIT(0xe4e4b7e47353d597), W64LIT(0x27279c2725bb4e02), W64LIT(0x4141194132588273), W64LIT(0x8b8b168b2c9d0ba7), + W64LIT(0xa7a7a6a7510153f6), W64LIT(0x7d7de97dcf94fab2), W64LIT(0x95956e95dcfb3749), W64LIT(0xd8d847d88e9fad56), + W64LIT(0xfbfbcbfb8b30eb70), W64LIT(0xeeee9fee2371c1cd), W64LIT(0x7c7ced7cc791f8bb), W64LIT(0x6666856617e3cc71), + W64LIT(0xdddd53dda68ea77b), W64LIT(0x17175c17b84b2eaf), W64LIT(0x4747014702468e45), W64LIT(0x9e9e429e84dc211a), + W64LIT(0xcaca0fca1ec589d4), W64LIT(0x2d2db42d75995a58), W64LIT(0xbfbfc6bf9179632e), W64LIT(0x07071c07381b0e3f), + W64LIT(0xadad8ead012347ac), W64LIT(0x5a5a755aea2fb4b0), W64LIT(0x838336836cb51bef), W64LIT(0x3333cc3385ff66b6), + W64LIT(0x636391633ff2c65c), W64LIT(0x02020802100a0412), W64LIT(0xaaaa92aa39384993), W64LIT(0x7171d971afa8e2de), + W64LIT(0xc8c807c80ecf8dc6), W64LIT(0x19196419c87d32d1), W64LIT(0x494939497270923b), W64LIT(0xd9d943d9869aaf5f), + W64LIT(0xf2f2eff2c31df931), W64LIT(0xe3e3abe34b48dba8), W64LIT(0x5b5b715be22ab6b9), W64LIT(0x88881a8834920dbc), + W64LIT(0x9a9a529aa4c8293e), W64LIT(0x262698262dbe4c0b), W64LIT(0x3232c8328dfa64bf), W64LIT(0xb0b0fab0e94a7d59), + W64LIT(0xe9e983e91b6acff2), W64LIT(0x0f0f3c0f78331e77), W64LIT(0xd5d573d5e6a6b733), W64LIT(0x80803a8074ba1df4), + W64LIT(0xbebec2be997c6127), W64LIT(0xcdcd13cd26de87eb), W64LIT(0x3434d034bde46889), W64LIT(0x48483d487a759032), + W64LIT(0xffffdbffab24e354), W64LIT(0x7a7af57af78ff48d), W64LIT(0x90907a90f4ea3d64), W64LIT(0x5f5f615fc23ebe9d), + W64LIT(0x202080201da0403d), W64LIT(0x6868bd6867d5d00f), W64LIT(0x1a1a681ad07234ca), W64LIT(0xaeae82ae192c41b7), + W64LIT(0xb4b4eab4c95e757d), W64LIT(0x54544d549a19a8ce), W64LIT(0x93937693ece53b7f), W64LIT(0x222288220daa442f), + W64LIT(0x64648d6407e9c863), W64LIT(0xf1f1e3f1db12ff2a), W64LIT(0x7373d173bfa2e6cc), W64LIT(0x12124812905a2482), + W64LIT(0x40401d403a5d807a), W64LIT(0x0808200840281048), W64LIT(0xc3c32bc356e89b95), W64LIT(0xecec97ec337bc5df), + W64LIT(0xdbdb4bdb9690ab4d), W64LIT(0xa1a1bea1611f5fc0), W64LIT(0x8d8d0e8d1c830791), W64LIT(0x3d3df43df5c97ac8), + W64LIT(0x97976697ccf1335b), W64LIT(0x0000000000000000), W64LIT(0xcfcf1bcf36d483f9), W64LIT(0x2b2bac2b4587566e), + W64LIT(0x7676c57697b3ece1), W64LIT(0x8282328264b019e6), W64LIT(0xd6d67fd6fea9b128), W64LIT(0x1b1b6c1bd87736c3), + W64LIT(0xb5b5eeb5c15b7774), W64LIT(0xafaf86af112943be), W64LIT(0x6a6ab56a77dfd41d), W64LIT(0x50505d50ba0da0ea), + W64LIT(0x45450945124c8a57), W64LIT(0xf3f3ebf3cb18fb38), W64LIT(0x3030c0309df060ad), W64LIT(0xefef9bef2b74c3c4), + W64LIT(0x3f3ffc3fe5c37eda), W64LIT(0x55554955921caac7), W64LIT(0xa2a2b2a2791059db), W64LIT(0xeaea8fea0365c9e9), + W64LIT(0x656589650fecca6a), W64LIT(0xbabad2bab9686903), W64LIT(0x2f2fbc2f65935e4a), W64LIT(0xc0c027c04ee79d8e), + W64LIT(0xdede5fdebe81a160), W64LIT(0x1c1c701ce06c38fc), W64LIT(0xfdfdd3fdbb2ee746), W64LIT(0x4d4d294d52649a1f), + W64LIT(0x92927292e4e03976), W64LIT(0x7575c9758fbceafa), W64LIT(0x06061806301e0c36), W64LIT(0x8a8a128a249809ae), + W64LIT(0xb2b2f2b2f940794b), W64LIT(0xe6e6bfe66359d185), W64LIT(0x0e0e380e70361c7e), W64LIT(0x1f1f7c1ff8633ee7), + W64LIT(0x6262956237f7c455), W64LIT(0xd4d477d4eea3b53a), W64LIT(0xa8a89aa829324d81), W64LIT(0x96966296c4f43152), + W64LIT(0xf9f9c3f99b3aef62), W64LIT(0xc5c533c566f697a3), W64LIT(0x2525942535b14a10), W64LIT(0x59597959f220b2ab), + W64LIT(0x84842a8454ae15d0), W64LIT(0x7272d572b7a7e4c5), W64LIT(0x3939e439d5dd72ec), W64LIT(0x4c4c2d4c5a619816), + W64LIT(0x5e5e655eca3bbc94), W64LIT(0x7878fd78e785f09f), W64LIT(0x3838e038ddd870e5), W64LIT(0x8c8c0a8c14860598), + W64LIT(0xd1d163d1c6b2bf17), W64LIT(0xa5a5aea5410b57e4), W64LIT(0xe2e2afe2434dd9a1), W64LIT(0x616199612ff8c24e), + W64LIT(0xb3b3f6b3f1457b42), W64LIT(0x2121842115a54234), W64LIT(0x9c9c4a9c94d62508), W64LIT(0x1e1e781ef0663cee), + W64LIT(0x4343114322528661), W64LIT(0xc7c73bc776fc93b1), W64LIT(0xfcfcd7fcb32be54f), W64LIT(0x0404100420140824), + W64LIT(0x51515951b208a2e3), W64LIT(0x99995e99bcc72f25), W64LIT(0x6d6da96d4fc4da22), W64LIT(0x0d0d340d68391a65), + W64LIT(0xfafacffa8335e979), W64LIT(0xdfdf5bdfb684a369), W64LIT(0x7e7ee57ed79bfca9), W64LIT(0x242490243db44819), + W64LIT(0x3b3bec3bc5d776fe), W64LIT(0xabab96ab313d4b9a), W64LIT(0xcece1fce3ed181f0), W64LIT(0x1111441188552299), + W64LIT(0x8f8f068f0c890383), W64LIT(0x4e4e254e4a6b9c04), W64LIT(0xb7b7e6b7d1517366), W64LIT(0xebeb8beb0b60cbe0), + W64LIT(0x3c3cf03cfdcc78c1), W64LIT(0x81813e817cbf1ffd), W64LIT(0x94946a94d4fe3540), W64LIT(0xf7f7fbf7eb0cf31c), + W64LIT(0xb9b9deb9a1676f18), W64LIT(0x13134c13985f268b), W64LIT(0x2c2cb02c7d9c5851), W64LIT(0xd3d36bd3d6b8bb05), + W64LIT(0xe7e7bbe76b5cd38c), W64LIT(0x6e6ea56e57cbdc39), W64LIT(0xc4c437c46ef395aa), W64LIT(0x03030c03180f061b), + W64LIT(0x565645568a13acdc), W64LIT(0x44440d441a49885e), W64LIT(0x7f7fe17fdf9efea0), W64LIT(0xa9a99ea921374f88), + W64LIT(0x2a2aa82a4d825467), W64LIT(0xbbbbd6bbb16d6b0a), W64LIT(0xc1c123c146e29f87), W64LIT(0x53535153a202a6f1), + W64LIT(0xdcdc57dcae8ba572), W64LIT(0x0b0b2c0b58271653), W64LIT(0x9d9d4e9d9cd32701), W64LIT(0x6c6cad6c47c1d82b), + W64LIT(0x3131c43195f562a4), W64LIT(0x7474cd7487b9e8f3), W64LIT(0xf6f6fff6e309f115), W64LIT(0x464605460a438c4c), + W64LIT(0xacac8aac092645a5), W64LIT(0x89891e893c970fb5), W64LIT(0x14145014a04428b4), W64LIT(0xe1e1a3e15b42dfba), + W64LIT(0x16165816b04e2ca6), W64LIT(0x3a3ae83acdd274f7), W64LIT(0x6969b9696fd0d206), W64LIT(0x09092409482d1241), + W64LIT(0x7070dd70a7ade0d7), W64LIT(0xb6b6e2b6d954716f), W64LIT(0xd0d067d0ceb7bd1e), W64LIT(0xeded93ed3b7ec7d6), + W64LIT(0xcccc17cc2edb85e2), W64LIT(0x424215422a578468), W64LIT(0x98985a98b4c22d2c), W64LIT(0xa4a4aaa4490e55ed), + W64LIT(0x2828a0285d885075), W64LIT(0x5c5c6d5cda31b886), W64LIT(0xf8f8c7f8933fed6b), W64LIT(0x8686228644a411c2), + + W64LIT(0xd818186018c07830), W64LIT(0x2623238c2305af46), W64LIT(0xb8c6c63fc67ef991), W64LIT(0xfbe8e887e8136fcd), + W64LIT(0xcb878726874ca113), W64LIT(0x11b8b8dab8a9626d), W64LIT(0x0901010401080502), W64LIT(0x0d4f4f214f426e9e), + W64LIT(0x9b3636d836adee6c), W64LIT(0xffa6a6a2a6590451), W64LIT(0x0cd2d26fd2debdb9), W64LIT(0x0ef5f5f3f5fb06f7), + W64LIT(0x967979f979ef80f2), W64LIT(0x306f6fa16f5fcede), W64LIT(0x6d91917e91fcef3f), W64LIT(0xf852525552aa07a4), + W64LIT(0x4760609d6027fdc0), W64LIT(0x35bcbccabc897665), W64LIT(0x379b9b569baccd2b), W64LIT(0x8a8e8e028e048c01), + W64LIT(0xd2a3a3b6a371155b), W64LIT(0x6c0c0c300c603c18), W64LIT(0x847b7bf17bff8af6), W64LIT(0x803535d435b5e16a), + W64LIT(0xf51d1d741de8693a), W64LIT(0xb3e0e0a7e05347dd), W64LIT(0x21d7d77bd7f6acb3), W64LIT(0x9cc2c22fc25eed99), + W64LIT(0x432e2eb82e6d965c), W64LIT(0x294b4b314b627a96), W64LIT(0x5dfefedffea321e1), W64LIT(0xd5575741578216ae), + W64LIT(0xbd15155415a8412a), W64LIT(0xe87777c1779fb6ee), W64LIT(0x923737dc37a5eb6e), W64LIT(0x9ee5e5b3e57b56d7), + W64LIT(0x139f9f469f8cd923), W64LIT(0x23f0f0e7f0d317fd), W64LIT(0x204a4a354a6a7f94), W64LIT(0x44dada4fda9e95a9), + W64LIT(0xa258587d58fa25b0), W64LIT(0xcfc9c903c906ca8f), W64LIT(0x7c2929a429558d52), W64LIT(0x5a0a0a280a502214), + W64LIT(0x50b1b1feb1e14f7f), W64LIT(0xc9a0a0baa0691a5d), W64LIT(0x146b6bb16b7fdad6), W64LIT(0xd985852e855cab17), + W64LIT(0x3cbdbdcebd817367), W64LIT(0x8f5d5d695dd234ba), W64LIT(0x9010104010805020), W64LIT(0x07f4f4f7f4f303f5), + W64LIT(0xddcbcb0bcb16c08b), W64LIT(0xd33e3ef83eedc67c), W64LIT(0x2d0505140528110a), W64LIT(0x78676781671fe6ce), + W64LIT(0x97e4e4b7e47353d5), W64LIT(0x0227279c2725bb4e), W64LIT(0x7341411941325882), W64LIT(0xa78b8b168b2c9d0b), + W64LIT(0xf6a7a7a6a7510153), W64LIT(0xb27d7de97dcf94fa), W64LIT(0x4995956e95dcfb37), W64LIT(0x56d8d847d88e9fad), + W64LIT(0x70fbfbcbfb8b30eb), W64LIT(0xcdeeee9fee2371c1), W64LIT(0xbb7c7ced7cc791f8), W64LIT(0x716666856617e3cc), + W64LIT(0x7bdddd53dda68ea7), W64LIT(0xaf17175c17b84b2e), W64LIT(0x454747014702468e), W64LIT(0x1a9e9e429e84dc21), + W64LIT(0xd4caca0fca1ec589), W64LIT(0x582d2db42d75995a), W64LIT(0x2ebfbfc6bf917963), W64LIT(0x3f07071c07381b0e), + W64LIT(0xacadad8ead012347), W64LIT(0xb05a5a755aea2fb4), W64LIT(0xef838336836cb51b), W64LIT(0xb63333cc3385ff66), + W64LIT(0x5c636391633ff2c6), W64LIT(0x1202020802100a04), W64LIT(0x93aaaa92aa393849), W64LIT(0xde7171d971afa8e2), + W64LIT(0xc6c8c807c80ecf8d), W64LIT(0xd119196419c87d32), W64LIT(0x3b49493949727092), W64LIT(0x5fd9d943d9869aaf), + W64LIT(0x31f2f2eff2c31df9), W64LIT(0xa8e3e3abe34b48db), W64LIT(0xb95b5b715be22ab6), W64LIT(0xbc88881a8834920d), + W64LIT(0x3e9a9a529aa4c829), W64LIT(0x0b262698262dbe4c), W64LIT(0xbf3232c8328dfa64), W64LIT(0x59b0b0fab0e94a7d), + W64LIT(0xf2e9e983e91b6acf), W64LIT(0x770f0f3c0f78331e), W64LIT(0x33d5d573d5e6a6b7), W64LIT(0xf480803a8074ba1d), + W64LIT(0x27bebec2be997c61), W64LIT(0xebcdcd13cd26de87), W64LIT(0x893434d034bde468), W64LIT(0x3248483d487a7590), + W64LIT(0x54ffffdbffab24e3), W64LIT(0x8d7a7af57af78ff4), W64LIT(0x6490907a90f4ea3d), W64LIT(0x9d5f5f615fc23ebe), + W64LIT(0x3d202080201da040), W64LIT(0x0f6868bd6867d5d0), W64LIT(0xca1a1a681ad07234), W64LIT(0xb7aeae82ae192c41), + W64LIT(0x7db4b4eab4c95e75), W64LIT(0xce54544d549a19a8), W64LIT(0x7f93937693ece53b), W64LIT(0x2f222288220daa44), + W64LIT(0x6364648d6407e9c8), W64LIT(0x2af1f1e3f1db12ff), W64LIT(0xcc7373d173bfa2e6), W64LIT(0x8212124812905a24), + W64LIT(0x7a40401d403a5d80), W64LIT(0x4808082008402810), W64LIT(0x95c3c32bc356e89b), W64LIT(0xdfecec97ec337bc5), + W64LIT(0x4ddbdb4bdb9690ab), W64LIT(0xc0a1a1bea1611f5f), W64LIT(0x918d8d0e8d1c8307), W64LIT(0xc83d3df43df5c97a), + W64LIT(0x5b97976697ccf133), W64LIT(0x0000000000000000), W64LIT(0xf9cfcf1bcf36d483), W64LIT(0x6e2b2bac2b458756), + W64LIT(0xe17676c57697b3ec), W64LIT(0xe68282328264b019), W64LIT(0x28d6d67fd6fea9b1), W64LIT(0xc31b1b6c1bd87736), + W64LIT(0x74b5b5eeb5c15b77), W64LIT(0xbeafaf86af112943), W64LIT(0x1d6a6ab56a77dfd4), W64LIT(0xea50505d50ba0da0), + W64LIT(0x5745450945124c8a), W64LIT(0x38f3f3ebf3cb18fb), W64LIT(0xad3030c0309df060), W64LIT(0xc4efef9bef2b74c3), + W64LIT(0xda3f3ffc3fe5c37e), W64LIT(0xc755554955921caa), W64LIT(0xdba2a2b2a2791059), W64LIT(0xe9eaea8fea0365c9), + W64LIT(0x6a656589650fecca), W64LIT(0x03babad2bab96869), W64LIT(0x4a2f2fbc2f65935e), W64LIT(0x8ec0c027c04ee79d), + W64LIT(0x60dede5fdebe81a1), W64LIT(0xfc1c1c701ce06c38), W64LIT(0x46fdfdd3fdbb2ee7), W64LIT(0x1f4d4d294d52649a), + W64LIT(0x7692927292e4e039), W64LIT(0xfa7575c9758fbcea), W64LIT(0x3606061806301e0c), W64LIT(0xae8a8a128a249809), + W64LIT(0x4bb2b2f2b2f94079), W64LIT(0x85e6e6bfe66359d1), W64LIT(0x7e0e0e380e70361c), W64LIT(0xe71f1f7c1ff8633e), + W64LIT(0x556262956237f7c4), W64LIT(0x3ad4d477d4eea3b5), W64LIT(0x81a8a89aa829324d), W64LIT(0x5296966296c4f431), + W64LIT(0x62f9f9c3f99b3aef), W64LIT(0xa3c5c533c566f697), W64LIT(0x102525942535b14a), W64LIT(0xab59597959f220b2), + W64LIT(0xd084842a8454ae15), W64LIT(0xc57272d572b7a7e4), W64LIT(0xec3939e439d5dd72), W64LIT(0x164c4c2d4c5a6198), + W64LIT(0x945e5e655eca3bbc), W64LIT(0x9f7878fd78e785f0), W64LIT(0xe53838e038ddd870), W64LIT(0x988c8c0a8c148605), + W64LIT(0x17d1d163d1c6b2bf), W64LIT(0xe4a5a5aea5410b57), W64LIT(0xa1e2e2afe2434dd9), W64LIT(0x4e616199612ff8c2), + W64LIT(0x42b3b3f6b3f1457b), W64LIT(0x342121842115a542), W64LIT(0x089c9c4a9c94d625), W64LIT(0xee1e1e781ef0663c), + W64LIT(0x6143431143225286), W64LIT(0xb1c7c73bc776fc93), W64LIT(0x4ffcfcd7fcb32be5), W64LIT(0x2404041004201408), + W64LIT(0xe351515951b208a2), W64LIT(0x2599995e99bcc72f), W64LIT(0x226d6da96d4fc4da), W64LIT(0x650d0d340d68391a), + W64LIT(0x79fafacffa8335e9), W64LIT(0x69dfdf5bdfb684a3), W64LIT(0xa97e7ee57ed79bfc), W64LIT(0x19242490243db448), + W64LIT(0xfe3b3bec3bc5d776), W64LIT(0x9aabab96ab313d4b), W64LIT(0xf0cece1fce3ed181), W64LIT(0x9911114411885522), + W64LIT(0x838f8f068f0c8903), W64LIT(0x044e4e254e4a6b9c), W64LIT(0x66b7b7e6b7d15173), W64LIT(0xe0ebeb8beb0b60cb), + W64LIT(0xc13c3cf03cfdcc78), W64LIT(0xfd81813e817cbf1f), W64LIT(0x4094946a94d4fe35), W64LIT(0x1cf7f7fbf7eb0cf3), + W64LIT(0x18b9b9deb9a1676f), W64LIT(0x8b13134c13985f26), W64LIT(0x512c2cb02c7d9c58), W64LIT(0x05d3d36bd3d6b8bb), + W64LIT(0x8ce7e7bbe76b5cd3), W64LIT(0x396e6ea56e57cbdc), W64LIT(0xaac4c437c46ef395), W64LIT(0x1b03030c03180f06), + W64LIT(0xdc565645568a13ac), W64LIT(0x5e44440d441a4988), W64LIT(0xa07f7fe17fdf9efe), W64LIT(0x88a9a99ea921374f), + W64LIT(0x672a2aa82a4d8254), W64LIT(0x0abbbbd6bbb16d6b), W64LIT(0x87c1c123c146e29f), W64LIT(0xf153535153a202a6), + W64LIT(0x72dcdc57dcae8ba5), W64LIT(0x530b0b2c0b582716), W64LIT(0x019d9d4e9d9cd327), W64LIT(0x2b6c6cad6c47c1d8), + W64LIT(0xa43131c43195f562), W64LIT(0xf37474cd7487b9e8), W64LIT(0x15f6f6fff6e309f1), W64LIT(0x4c464605460a438c), + W64LIT(0xa5acac8aac092645), W64LIT(0xb589891e893c970f), W64LIT(0xb414145014a04428), W64LIT(0xbae1e1a3e15b42df), + W64LIT(0xa616165816b04e2c), W64LIT(0xf73a3ae83acdd274), W64LIT(0x066969b9696fd0d2), W64LIT(0x4109092409482d12), + W64LIT(0xd77070dd70a7ade0), W64LIT(0x6fb6b6e2b6d95471), W64LIT(0x1ed0d067d0ceb7bd), W64LIT(0xd6eded93ed3b7ec7), + W64LIT(0xe2cccc17cc2edb85), W64LIT(0x68424215422a5784), W64LIT(0x2c98985a98b4c22d), W64LIT(0xeda4a4aaa4490e55), + W64LIT(0x752828a0285d8850), W64LIT(0x865c5c6d5cda31b8), W64LIT(0x6bf8f8c7f8933fed), W64LIT(0xc28686228644a411), + + W64LIT(0x30d818186018c078), W64LIT(0x462623238c2305af), W64LIT(0x91b8c6c63fc67ef9), W64LIT(0xcdfbe8e887e8136f), + W64LIT(0x13cb878726874ca1), W64LIT(0x6d11b8b8dab8a962), W64LIT(0x0209010104010805), W64LIT(0x9e0d4f4f214f426e), + W64LIT(0x6c9b3636d836adee), W64LIT(0x51ffa6a6a2a65904), W64LIT(0xb90cd2d26fd2debd), W64LIT(0xf70ef5f5f3f5fb06), + W64LIT(0xf2967979f979ef80), W64LIT(0xde306f6fa16f5fce), W64LIT(0x3f6d91917e91fcef), W64LIT(0xa4f852525552aa07), + W64LIT(0xc04760609d6027fd), W64LIT(0x6535bcbccabc8976), W64LIT(0x2b379b9b569baccd), W64LIT(0x018a8e8e028e048c), + W64LIT(0x5bd2a3a3b6a37115), W64LIT(0x186c0c0c300c603c), W64LIT(0xf6847b7bf17bff8a), W64LIT(0x6a803535d435b5e1), + W64LIT(0x3af51d1d741de869), W64LIT(0xddb3e0e0a7e05347), W64LIT(0xb321d7d77bd7f6ac), W64LIT(0x999cc2c22fc25eed), + W64LIT(0x5c432e2eb82e6d96), W64LIT(0x96294b4b314b627a), W64LIT(0xe15dfefedffea321), W64LIT(0xaed5575741578216), + W64LIT(0x2abd15155415a841), W64LIT(0xeee87777c1779fb6), W64LIT(0x6e923737dc37a5eb), W64LIT(0xd79ee5e5b3e57b56), + W64LIT(0x23139f9f469f8cd9), W64LIT(0xfd23f0f0e7f0d317), W64LIT(0x94204a4a354a6a7f), W64LIT(0xa944dada4fda9e95), + W64LIT(0xb0a258587d58fa25), W64LIT(0x8fcfc9c903c906ca), W64LIT(0x527c2929a429558d), W64LIT(0x145a0a0a280a5022), + W64LIT(0x7f50b1b1feb1e14f), W64LIT(0x5dc9a0a0baa0691a), W64LIT(0xd6146b6bb16b7fda), W64LIT(0x17d985852e855cab), + W64LIT(0x673cbdbdcebd8173), W64LIT(0xba8f5d5d695dd234), W64LIT(0x2090101040108050), W64LIT(0xf507f4f4f7f4f303), + W64LIT(0x8bddcbcb0bcb16c0), W64LIT(0x7cd33e3ef83eedc6), W64LIT(0x0a2d050514052811), W64LIT(0xce78676781671fe6), + W64LIT(0xd597e4e4b7e47353), W64LIT(0x4e0227279c2725bb), W64LIT(0x8273414119413258), W64LIT(0x0ba78b8b168b2c9d), + W64LIT(0x53f6a7a7a6a75101), W64LIT(0xfab27d7de97dcf94), W64LIT(0x374995956e95dcfb), W64LIT(0xad56d8d847d88e9f), + W64LIT(0xeb70fbfbcbfb8b30), W64LIT(0xc1cdeeee9fee2371), W64LIT(0xf8bb7c7ced7cc791), W64LIT(0xcc716666856617e3), + W64LIT(0xa77bdddd53dda68e), W64LIT(0x2eaf17175c17b84b), W64LIT(0x8e45474701470246), W64LIT(0x211a9e9e429e84dc), + W64LIT(0x89d4caca0fca1ec5), W64LIT(0x5a582d2db42d7599), W64LIT(0x632ebfbfc6bf9179), W64LIT(0x0e3f07071c07381b), + W64LIT(0x47acadad8ead0123), W64LIT(0xb4b05a5a755aea2f), W64LIT(0x1bef838336836cb5), W64LIT(0x66b63333cc3385ff), + W64LIT(0xc65c636391633ff2), W64LIT(0x041202020802100a), W64LIT(0x4993aaaa92aa3938), W64LIT(0xe2de7171d971afa8), + W64LIT(0x8dc6c8c807c80ecf), W64LIT(0x32d119196419c87d), W64LIT(0x923b494939497270), W64LIT(0xaf5fd9d943d9869a), + W64LIT(0xf931f2f2eff2c31d), W64LIT(0xdba8e3e3abe34b48), W64LIT(0xb6b95b5b715be22a), W64LIT(0x0dbc88881a883492), + W64LIT(0x293e9a9a529aa4c8), W64LIT(0x4c0b262698262dbe), W64LIT(0x64bf3232c8328dfa), W64LIT(0x7d59b0b0fab0e94a), + W64LIT(0xcff2e9e983e91b6a), W64LIT(0x1e770f0f3c0f7833), W64LIT(0xb733d5d573d5e6a6), W64LIT(0x1df480803a8074ba), + W64LIT(0x6127bebec2be997c), W64LIT(0x87ebcdcd13cd26de), W64LIT(0x68893434d034bde4), W64LIT(0x903248483d487a75), + W64LIT(0xe354ffffdbffab24), W64LIT(0xf48d7a7af57af78f), W64LIT(0x3d6490907a90f4ea), W64LIT(0xbe9d5f5f615fc23e), + W64LIT(0x403d202080201da0), W64LIT(0xd00f6868bd6867d5), W64LIT(0x34ca1a1a681ad072), W64LIT(0x41b7aeae82ae192c), + W64LIT(0x757db4b4eab4c95e), W64LIT(0xa8ce54544d549a19), W64LIT(0x3b7f93937693ece5), W64LIT(0x442f222288220daa), + W64LIT(0xc86364648d6407e9), W64LIT(0xff2af1f1e3f1db12), W64LIT(0xe6cc7373d173bfa2), W64LIT(0x248212124812905a), + W64LIT(0x807a40401d403a5d), W64LIT(0x1048080820084028), W64LIT(0x9b95c3c32bc356e8), W64LIT(0xc5dfecec97ec337b), + W64LIT(0xab4ddbdb4bdb9690), W64LIT(0x5fc0a1a1bea1611f), W64LIT(0x07918d8d0e8d1c83), W64LIT(0x7ac83d3df43df5c9), + W64LIT(0x335b97976697ccf1), W64LIT(0x0000000000000000), W64LIT(0x83f9cfcf1bcf36d4), W64LIT(0x566e2b2bac2b4587), + W64LIT(0xece17676c57697b3), W64LIT(0x19e68282328264b0), W64LIT(0xb128d6d67fd6fea9), W64LIT(0x36c31b1b6c1bd877), + W64LIT(0x7774b5b5eeb5c15b), W64LIT(0x43beafaf86af1129), W64LIT(0xd41d6a6ab56a77df), W64LIT(0xa0ea50505d50ba0d), + W64LIT(0x8a5745450945124c), W64LIT(0xfb38f3f3ebf3cb18), W64LIT(0x60ad3030c0309df0), W64LIT(0xc3c4efef9bef2b74), + W64LIT(0x7eda3f3ffc3fe5c3), W64LIT(0xaac755554955921c), W64LIT(0x59dba2a2b2a27910), W64LIT(0xc9e9eaea8fea0365), + W64LIT(0xca6a656589650fec), W64LIT(0x6903babad2bab968), W64LIT(0x5e4a2f2fbc2f6593), W64LIT(0x9d8ec0c027c04ee7), + W64LIT(0xa160dede5fdebe81), W64LIT(0x38fc1c1c701ce06c), W64LIT(0xe746fdfdd3fdbb2e), W64LIT(0x9a1f4d4d294d5264), + W64LIT(0x397692927292e4e0), W64LIT(0xeafa7575c9758fbc), W64LIT(0x0c3606061806301e), W64LIT(0x09ae8a8a128a2498), + W64LIT(0x794bb2b2f2b2f940), W64LIT(0xd185e6e6bfe66359), W64LIT(0x1c7e0e0e380e7036), W64LIT(0x3ee71f1f7c1ff863), + W64LIT(0xc4556262956237f7), W64LIT(0xb53ad4d477d4eea3), W64LIT(0x4d81a8a89aa82932), W64LIT(0x315296966296c4f4), + W64LIT(0xef62f9f9c3f99b3a), W64LIT(0x97a3c5c533c566f6), W64LIT(0x4a102525942535b1), W64LIT(0xb2ab59597959f220), + W64LIT(0x15d084842a8454ae), W64LIT(0xe4c57272d572b7a7), W64LIT(0x72ec3939e439d5dd), W64LIT(0x98164c4c2d4c5a61), + W64LIT(0xbc945e5e655eca3b), W64LIT(0xf09f7878fd78e785), W64LIT(0x70e53838e038ddd8), W64LIT(0x05988c8c0a8c1486), + W64LIT(0xbf17d1d163d1c6b2), W64LIT(0x57e4a5a5aea5410b), W64LIT(0xd9a1e2e2afe2434d), W64LIT(0xc24e616199612ff8), + W64LIT(0x7b42b3b3f6b3f145), W64LIT(0x42342121842115a5), W64LIT(0x25089c9c4a9c94d6), W64LIT(0x3cee1e1e781ef066), + W64LIT(0x8661434311432252), W64LIT(0x93b1c7c73bc776fc), W64LIT(0xe54ffcfcd7fcb32b), W64LIT(0x0824040410042014), + W64LIT(0xa2e351515951b208), W64LIT(0x2f2599995e99bcc7), W64LIT(0xda226d6da96d4fc4), W64LIT(0x1a650d0d340d6839), + W64LIT(0xe979fafacffa8335), W64LIT(0xa369dfdf5bdfb684), W64LIT(0xfca97e7ee57ed79b), W64LIT(0x4819242490243db4), + W64LIT(0x76fe3b3bec3bc5d7), W64LIT(0x4b9aabab96ab313d), W64LIT(0x81f0cece1fce3ed1), W64LIT(0x2299111144118855), + W64LIT(0x03838f8f068f0c89), W64LIT(0x9c044e4e254e4a6b), W64LIT(0x7366b7b7e6b7d151), W64LIT(0xcbe0ebeb8beb0b60), + W64LIT(0x78c13c3cf03cfdcc), W64LIT(0x1ffd81813e817cbf), W64LIT(0x354094946a94d4fe), W64LIT(0xf31cf7f7fbf7eb0c), + W64LIT(0x6f18b9b9deb9a167), W64LIT(0x268b13134c13985f), W64LIT(0x58512c2cb02c7d9c), W64LIT(0xbb05d3d36bd3d6b8), + W64LIT(0xd38ce7e7bbe76b5c), W64LIT(0xdc396e6ea56e57cb), W64LIT(0x95aac4c437c46ef3), W64LIT(0x061b03030c03180f), + W64LIT(0xacdc565645568a13), W64LIT(0x885e44440d441a49), W64LIT(0xfea07f7fe17fdf9e), W64LIT(0x4f88a9a99ea92137), + W64LIT(0x54672a2aa82a4d82), W64LIT(0x6b0abbbbd6bbb16d), W64LIT(0x9f87c1c123c146e2), W64LIT(0xa6f153535153a202), + W64LIT(0xa572dcdc57dcae8b), W64LIT(0x16530b0b2c0b5827), W64LIT(0x27019d9d4e9d9cd3), W64LIT(0xd82b6c6cad6c47c1), + W64LIT(0x62a43131c43195f5), W64LIT(0xe8f37474cd7487b9), W64LIT(0xf115f6f6fff6e309), W64LIT(0x8c4c464605460a43), + W64LIT(0x45a5acac8aac0926), W64LIT(0x0fb589891e893c97), W64LIT(0x28b414145014a044), W64LIT(0xdfbae1e1a3e15b42), + W64LIT(0x2ca616165816b04e), W64LIT(0x74f73a3ae83acdd2), W64LIT(0xd2066969b9696fd0), W64LIT(0x124109092409482d), + W64LIT(0xe0d77070dd70a7ad), W64LIT(0x716fb6b6e2b6d954), W64LIT(0xbd1ed0d067d0ceb7), W64LIT(0xc7d6eded93ed3b7e), + W64LIT(0x85e2cccc17cc2edb), W64LIT(0x8468424215422a57), W64LIT(0x2d2c98985a98b4c2), W64LIT(0x55eda4a4aaa4490e), + W64LIT(0x50752828a0285d88), W64LIT(0xb8865c5c6d5cda31), W64LIT(0xed6bf8f8c7f8933f), W64LIT(0x11c28686228644a4), + + W64LIT(0x7830d818186018c0), W64LIT(0xaf462623238c2305), W64LIT(0xf991b8c6c63fc67e), W64LIT(0x6fcdfbe8e887e813), + W64LIT(0xa113cb878726874c), W64LIT(0x626d11b8b8dab8a9), W64LIT(0x0502090101040108), W64LIT(0x6e9e0d4f4f214f42), + W64LIT(0xee6c9b3636d836ad), W64LIT(0x0451ffa6a6a2a659), W64LIT(0xbdb90cd2d26fd2de), W64LIT(0x06f70ef5f5f3f5fb), + W64LIT(0x80f2967979f979ef), W64LIT(0xcede306f6fa16f5f), W64LIT(0xef3f6d91917e91fc), W64LIT(0x07a4f852525552aa), + W64LIT(0xfdc04760609d6027), W64LIT(0x766535bcbccabc89), W64LIT(0xcd2b379b9b569bac), W64LIT(0x8c018a8e8e028e04), + W64LIT(0x155bd2a3a3b6a371), W64LIT(0x3c186c0c0c300c60), W64LIT(0x8af6847b7bf17bff), W64LIT(0xe16a803535d435b5), + W64LIT(0x693af51d1d741de8), W64LIT(0x47ddb3e0e0a7e053), W64LIT(0xacb321d7d77bd7f6), W64LIT(0xed999cc2c22fc25e), + W64LIT(0x965c432e2eb82e6d), W64LIT(0x7a96294b4b314b62), W64LIT(0x21e15dfefedffea3), W64LIT(0x16aed55757415782), + W64LIT(0x412abd15155415a8), W64LIT(0xb6eee87777c1779f), W64LIT(0xeb6e923737dc37a5), W64LIT(0x56d79ee5e5b3e57b), + W64LIT(0xd923139f9f469f8c), W64LIT(0x17fd23f0f0e7f0d3), W64LIT(0x7f94204a4a354a6a), W64LIT(0x95a944dada4fda9e), + W64LIT(0x25b0a258587d58fa), W64LIT(0xca8fcfc9c903c906), W64LIT(0x8d527c2929a42955), W64LIT(0x22145a0a0a280a50), + W64LIT(0x4f7f50b1b1feb1e1), W64LIT(0x1a5dc9a0a0baa069), W64LIT(0xdad6146b6bb16b7f), W64LIT(0xab17d985852e855c), + W64LIT(0x73673cbdbdcebd81), W64LIT(0x34ba8f5d5d695dd2), W64LIT(0x5020901010401080), W64LIT(0x03f507f4f4f7f4f3), + W64LIT(0xc08bddcbcb0bcb16), W64LIT(0xc67cd33e3ef83eed), W64LIT(0x110a2d0505140528), W64LIT(0xe6ce78676781671f), + W64LIT(0x53d597e4e4b7e473), W64LIT(0xbb4e0227279c2725), W64LIT(0x5882734141194132), W64LIT(0x9d0ba78b8b168b2c), + W64LIT(0x0153f6a7a7a6a751), W64LIT(0x94fab27d7de97dcf), W64LIT(0xfb374995956e95dc), W64LIT(0x9fad56d8d847d88e), + W64LIT(0x30eb70fbfbcbfb8b), W64LIT(0x71c1cdeeee9fee23), W64LIT(0x91f8bb7c7ced7cc7), W64LIT(0xe3cc716666856617), + W64LIT(0x8ea77bdddd53dda6), W64LIT(0x4b2eaf17175c17b8), W64LIT(0x468e454747014702), W64LIT(0xdc211a9e9e429e84), + W64LIT(0xc589d4caca0fca1e), W64LIT(0x995a582d2db42d75), W64LIT(0x79632ebfbfc6bf91), W64LIT(0x1b0e3f07071c0738), + W64LIT(0x2347acadad8ead01), W64LIT(0x2fb4b05a5a755aea), W64LIT(0xb51bef838336836c), W64LIT(0xff66b63333cc3385), + W64LIT(0xf2c65c636391633f), W64LIT(0x0a04120202080210), W64LIT(0x384993aaaa92aa39), W64LIT(0xa8e2de7171d971af), + W64LIT(0xcf8dc6c8c807c80e), W64LIT(0x7d32d119196419c8), W64LIT(0x70923b4949394972), W64LIT(0x9aaf5fd9d943d986), + W64LIT(0x1df931f2f2eff2c3), W64LIT(0x48dba8e3e3abe34b), W64LIT(0x2ab6b95b5b715be2), W64LIT(0x920dbc88881a8834), + W64LIT(0xc8293e9a9a529aa4), W64LIT(0xbe4c0b262698262d), W64LIT(0xfa64bf3232c8328d), W64LIT(0x4a7d59b0b0fab0e9), + W64LIT(0x6acff2e9e983e91b), W64LIT(0x331e770f0f3c0f78), W64LIT(0xa6b733d5d573d5e6), W64LIT(0xba1df480803a8074), + W64LIT(0x7c6127bebec2be99), W64LIT(0xde87ebcdcd13cd26), W64LIT(0xe468893434d034bd), W64LIT(0x75903248483d487a), + W64LIT(0x24e354ffffdbffab), W64LIT(0x8ff48d7a7af57af7), W64LIT(0xea3d6490907a90f4), W64LIT(0x3ebe9d5f5f615fc2), + W64LIT(0xa0403d202080201d), W64LIT(0xd5d00f6868bd6867), W64LIT(0x7234ca1a1a681ad0), W64LIT(0x2c41b7aeae82ae19), + W64LIT(0x5e757db4b4eab4c9), W64LIT(0x19a8ce54544d549a), W64LIT(0xe53b7f93937693ec), W64LIT(0xaa442f222288220d), + W64LIT(0xe9c86364648d6407), W64LIT(0x12ff2af1f1e3f1db), W64LIT(0xa2e6cc7373d173bf), W64LIT(0x5a24821212481290), + W64LIT(0x5d807a40401d403a), W64LIT(0x2810480808200840), W64LIT(0xe89b95c3c32bc356), W64LIT(0x7bc5dfecec97ec33), + W64LIT(0x90ab4ddbdb4bdb96), W64LIT(0x1f5fc0a1a1bea161), W64LIT(0x8307918d8d0e8d1c), W64LIT(0xc97ac83d3df43df5), + W64LIT(0xf1335b97976697cc), W64LIT(0x0000000000000000), W64LIT(0xd483f9cfcf1bcf36), W64LIT(0x87566e2b2bac2b45), + W64LIT(0xb3ece17676c57697), W64LIT(0xb019e68282328264), W64LIT(0xa9b128d6d67fd6fe), W64LIT(0x7736c31b1b6c1bd8), + W64LIT(0x5b7774b5b5eeb5c1), W64LIT(0x2943beafaf86af11), W64LIT(0xdfd41d6a6ab56a77), W64LIT(0x0da0ea50505d50ba), + W64LIT(0x4c8a574545094512), W64LIT(0x18fb38f3f3ebf3cb), W64LIT(0xf060ad3030c0309d), W64LIT(0x74c3c4efef9bef2b), + W64LIT(0xc37eda3f3ffc3fe5), W64LIT(0x1caac75555495592), W64LIT(0x1059dba2a2b2a279), W64LIT(0x65c9e9eaea8fea03), + W64LIT(0xecca6a656589650f), W64LIT(0x686903babad2bab9), W64LIT(0x935e4a2f2fbc2f65), W64LIT(0xe79d8ec0c027c04e), + W64LIT(0x81a160dede5fdebe), W64LIT(0x6c38fc1c1c701ce0), W64LIT(0x2ee746fdfdd3fdbb), W64LIT(0x649a1f4d4d294d52), + W64LIT(0xe0397692927292e4), W64LIT(0xbceafa7575c9758f), W64LIT(0x1e0c360606180630), W64LIT(0x9809ae8a8a128a24), + W64LIT(0x40794bb2b2f2b2f9), W64LIT(0x59d185e6e6bfe663), W64LIT(0x361c7e0e0e380e70), W64LIT(0x633ee71f1f7c1ff8), + W64LIT(0xf7c4556262956237), W64LIT(0xa3b53ad4d477d4ee), W64LIT(0x324d81a8a89aa829), W64LIT(0xf4315296966296c4), + W64LIT(0x3aef62f9f9c3f99b), W64LIT(0xf697a3c5c533c566), W64LIT(0xb14a102525942535), W64LIT(0x20b2ab59597959f2), + W64LIT(0xae15d084842a8454), W64LIT(0xa7e4c57272d572b7), W64LIT(0xdd72ec3939e439d5), W64LIT(0x6198164c4c2d4c5a), + W64LIT(0x3bbc945e5e655eca), W64LIT(0x85f09f7878fd78e7), W64LIT(0xd870e53838e038dd), W64LIT(0x8605988c8c0a8c14), + W64LIT(0xb2bf17d1d163d1c6), W64LIT(0x0b57e4a5a5aea541), W64LIT(0x4dd9a1e2e2afe243), W64LIT(0xf8c24e616199612f), + W64LIT(0x457b42b3b3f6b3f1), W64LIT(0xa542342121842115), W64LIT(0xd625089c9c4a9c94), W64LIT(0x663cee1e1e781ef0), + W64LIT(0x5286614343114322), W64LIT(0xfc93b1c7c73bc776), W64LIT(0x2be54ffcfcd7fcb3), W64LIT(0x1408240404100420), + W64LIT(0x08a2e351515951b2), W64LIT(0xc72f2599995e99bc), W64LIT(0xc4da226d6da96d4f), W64LIT(0x391a650d0d340d68), + W64LIT(0x35e979fafacffa83), W64LIT(0x84a369dfdf5bdfb6), W64LIT(0x9bfca97e7ee57ed7), W64LIT(0xb44819242490243d), + W64LIT(0xd776fe3b3bec3bc5), W64LIT(0x3d4b9aabab96ab31), W64LIT(0xd181f0cece1fce3e), W64LIT(0x5522991111441188), + W64LIT(0x8903838f8f068f0c), W64LIT(0x6b9c044e4e254e4a), W64LIT(0x517366b7b7e6b7d1), W64LIT(0x60cbe0ebeb8beb0b), + W64LIT(0xcc78c13c3cf03cfd), W64LIT(0xbf1ffd81813e817c), W64LIT(0xfe354094946a94d4), W64LIT(0x0cf31cf7f7fbf7eb), + W64LIT(0x676f18b9b9deb9a1), W64LIT(0x5f268b13134c1398), W64LIT(0x9c58512c2cb02c7d), W64LIT(0xb8bb05d3d36bd3d6), + W64LIT(0x5cd38ce7e7bbe76b), W64LIT(0xcbdc396e6ea56e57), W64LIT(0xf395aac4c437c46e), W64LIT(0x0f061b03030c0318), + W64LIT(0x13acdc565645568a), W64LIT(0x49885e44440d441a), W64LIT(0x9efea07f7fe17fdf), W64LIT(0x374f88a9a99ea921), + W64LIT(0x8254672a2aa82a4d), W64LIT(0x6d6b0abbbbd6bbb1), W64LIT(0xe29f87c1c123c146), W64LIT(0x02a6f153535153a2), + W64LIT(0x8ba572dcdc57dcae), W64LIT(0x2716530b0b2c0b58), W64LIT(0xd327019d9d4e9d9c), W64LIT(0xc1d82b6c6cad6c47), + W64LIT(0xf562a43131c43195), W64LIT(0xb9e8f37474cd7487), W64LIT(0x09f115f6f6fff6e3), W64LIT(0x438c4c464605460a), + W64LIT(0x2645a5acac8aac09), W64LIT(0x970fb589891e893c), W64LIT(0x4428b414145014a0), W64LIT(0x42dfbae1e1a3e15b), + W64LIT(0x4e2ca616165816b0), W64LIT(0xd274f73a3ae83acd), W64LIT(0xd0d2066969b9696f), W64LIT(0x2d12410909240948), + W64LIT(0xade0d77070dd70a7), W64LIT(0x54716fb6b6e2b6d9), W64LIT(0xb7bd1ed0d067d0ce), W64LIT(0x7ec7d6eded93ed3b), + W64LIT(0xdb85e2cccc17cc2e), W64LIT(0x578468424215422a), W64LIT(0xc22d2c98985a98b4), W64LIT(0x0e55eda4a4aaa449), + W64LIT(0x8850752828a0285d), W64LIT(0x31b8865c5c6d5cda), W64LIT(0x3fed6bf8f8c7f893), W64LIT(0xa411c28686228644), + + W64LIT(0x1823c6e887b8014f), + W64LIT(0x36a6d2f5796f9152), + W64LIT(0x60bc9b8ea30c7b35), + W64LIT(0x1de0d7c22e4bfe57), + W64LIT(0x157737e59ff04ada), + W64LIT(0x58c9290ab1a06b85), + W64LIT(0xbd5d10f4cb3e0567), + W64LIT(0xe427418ba77d95d8), + W64LIT(0xfbee7c66dd17479e), + W64LIT(0xca2dbf07ad5a8333) +}; + +// Whirlpool basic transformation. Transforms state based on block. +void Whirlpool::Transform(word64 *digest, const word64 *block) +{ + CRYPTOPP_ASSERT(digest != NULLPTR); + CRYPTOPP_ASSERT(block != NULLPTR); + +#if CRYPTOPP_SSE2_ASM_AVAILABLE + if (HasSSE2()) + { + // MMX version has the same structure as C version below +#ifdef __GNUC__ + #if CRYPTOPP_BOOL_X64 + word64 workspace[16]; + #endif + __asm__ __volatile__ + ( + INTEL_NOPREFIX + AS_PUSH_IF86( bx) + AS2( mov AS_REG_6, WORD_REG(ax)) +#else + AS2( lea AS_REG_6, [Whirlpool_C]) + AS2( mov WORD_REG(cx), digest) + AS2( mov WORD_REG(dx), block) +#endif +#if CRYPTOPP_BOOL_X86 + AS2( mov eax, esp) + AS2( and esp, -16) + AS2( sub esp, 16*8) + AS_PUSH_IF86( ax) + #if CRYPTOPP_BOOL_X86 + #define SSE2_workspace esp+WORD_SZ + #endif +#else + #define SSE2_workspace %3 +#endif + AS2( xor esi, esi) + ASL(0) + AS2( movq mm0, [WORD_REG(cx)+8*WORD_REG(si)]) + AS2( movq [SSE2_workspace+8*WORD_REG(si)], mm0) // k + AS2( pxor mm0, [WORD_REG(dx)+8*WORD_REG(si)]) + AS2( movq [SSE2_workspace+64+8*WORD_REG(si)], mm0) // s + AS2( movq [WORD_REG(cx)+8*WORD_REG(si)], mm0) + AS1( inc WORD_REG(si)) + AS2( cmp WORD_REG(si), 8) + ASJ( jne, 0, b) + + AS2( xor esi, esi) + ASL(1) + +#define KSL0(a, b) AS2(movq mm##a, b) +#define KSL1(a, b) AS2(pxor mm##a, b) + +#define KSL(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+8*i])\ + AS2(movzx edi, al)\ + KSL##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + KSL##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + KSL##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + KSL##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + +#define KSH0(a, b) \ + ASS(pshufw mm##a, mm##a, 1, 0, 3, 2)\ + AS2(pxor mm##a, b) +#define KSH1(a, b) \ + AS2(pxor mm##a, b) +#define KSH2(a, b) \ + AS2(pxor mm##a, b)\ + AS2(movq [SSE2_workspace+8*a], mm##a) + +#define KSH(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+8*((i+4)-8*((i+4)/8))+4])\ + AS2(movzx edi, al)\ + KSH##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + KSH##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + KSH##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + KSH##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + +#define TSL(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+64+8*i])\ + AS2(movzx edi, al)\ + KSL##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + KSL##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + KSL##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + KSL##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + +#define TSH0(a, b) \ + ASS(pshufw mm##a, mm##a, 1, 0, 3, 2)\ + AS2(pxor mm##a, [SSE2_workspace+8*a])\ + AS2(pxor mm##a, b) +#define TSH1(a, b) \ + AS2(pxor mm##a, b) +#define TSH2(a, b) \ + AS2(pxor mm##a, b)\ + AS2(movq [SSE2_workspace+64+8*a], mm##a) +#define TSH3(a, b) \ + AS2(pxor mm##a, b)\ + AS2(pxor mm##a, [WORD_REG(cx)+8*a])\ + AS2(movq [WORD_REG(cx)+8*a], mm##a) + +#define TSH(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+64+8*((i+4)-8*((i+4)/8))+4])\ + AS2(movzx edi, al)\ + TSH##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + TSH##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + TSH##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + TSH##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + + KSL(0, 4, 3, 2, 1, 0) + KSL(0, 0, 7, 6, 5, 4) + KSL(1, 1, 0, 7, 6, 5) + KSL(1, 2, 1, 0, 7, 6) + KSL(1, 3, 2, 1, 0, 7) + KSL(1, 5, 4, 3, 2, 1) + KSL(1, 6, 5, 4, 3, 2) + KSL(1, 7, 6, 5, 4, 3) + KSH(0, 0, 7, 6, 5, 4) + KSH(0, 4, 3, 2, 1, 0) + KSH(1, 1, 0, 7, 6, 5) + KSH(1, 2, 1, 0, 7, 6) + KSH(1, 5, 4, 3, 2, 1) + KSH(1, 6, 5, 4, 3, 2) + KSH(2, 3, 2, 1, 0, 7) + KSH(2, 7, 6, 5, 4, 3) + + AS2( pxor mm0, [AS_REG_6 + 8*1024 + WORD_REG(si)*8]) + AS2( movq [SSE2_workspace], mm0) + + TSL(0, 4, 3, 2, 1, 0) + TSL(0, 0, 7, 6, 5, 4) + TSL(1, 1, 0, 7, 6, 5) + TSL(1, 2, 1, 0, 7, 6) + TSL(1, 3, 2, 1, 0, 7) + TSL(1, 5, 4, 3, 2, 1) + TSL(1, 6, 5, 4, 3, 2) + TSL(1, 7, 6, 5, 4, 3) + TSH(0, 0, 7, 6, 5, 4) + TSH(0, 4, 3, 2, 1, 0) + TSH(1, 1, 0, 7, 6, 5) + TSH(1, 2, 1, 0, 7, 6) + TSH(1, 5, 4, 3, 2, 1) + TSH(1, 6, 5, 4, 3, 2) + + AS1( inc WORD_REG(si)) + AS2( cmp WORD_REG(si), 10) + ASJ( je, 2, f) + + TSH(2, 3, 2, 1, 0, 7) + TSH(2, 7, 6, 5, 4, 3) + + ASJ( jmp, 1, b) + ASL(2) + + TSH(3, 3, 2, 1, 0, 7) + TSH(3, 7, 6, 5, 4, 3) + +#undef KSL +#undef KSH +#undef TSL +#undef TSH + + AS_POP_IF86( sp) + AS1( emms) + +#if defined(__GNUC__) + AS_POP_IF86( bx) +#endif +#ifdef __GNUC__ + ATT_PREFIX + : + : "a" (Whirlpool_C), "c" (digest), "d" (block) + #if CRYPTOPP_BOOL_X64 + , "r" (workspace) + #endif + : "%esi", "%edi", "memory", "cc" + #if CRYPTOPP_BOOL_X64 + , "%r9" + #endif + ); +#endif + } + else +#endif // #ifdef CRYPTOPP_X86_ASM_AVAILABLE + { + word64 s[8]; // the cipher state + word64 k[8]; // the round key + + // Compute and apply K^0 to the cipher state + // Also apply part of the Miyaguchi-Preneel compression function + for (int i=0; i<8; i++) + digest[i] = s[i] = block[i] ^ (k[i] = digest[i]); + +#define KSL(op, i, a, b, c, d) \ + t = (word32)k[i];\ + w##a = Whirlpool_C[3*256 + (byte)t] ^ (op ? w##a : 0);\ + t >>= 8;\ + w##b = Whirlpool_C[2*256 + (byte)t] ^ (op ? w##b : 0);\ + t >>= 8;\ + w##c = Whirlpool_C[1*256 + (byte)t] ^ (op ? w##c : 0);\ + t >>= 8;\ + w##d = Whirlpool_C[0*256 + t] ^ (op ? w##d : 0); + +#define KSH(op, i, a, b, c, d) \ + t = (word32)(k[(i+4)%8]>>32);\ + w##a = Whirlpool_C[3*256 + (byte)t] ^ (op ? w##a : rotrConstant<32>(w##a));\ + if (op==2) k[a] = w##a;\ + t >>= 8;\ + w##b = Whirlpool_C[2*256 + (byte)t] ^ (op ? w##b : rotrConstant<32>(w##b));\ + if (op==2) k[b] = w##b;\ + t >>= 8;\ + w##c = Whirlpool_C[1*256 + (byte)t] ^ (op ? w##c : rotrConstant<32>(w##c));\ + if (op==2) k[c] = w##c;\ + t >>= 8;\ + w##d = Whirlpool_C[0*256 + t] ^ (op ? w##d : rotrConstant<32>(w##d));\ + if (op==2) k[d] = w##d;\ + +#define TSL(op, i, a, b, c, d) \ + t = (word32)s[i];\ + w##a = Whirlpool_C[3*256 + (byte)t] ^ (op ? w##a : 0);\ + t >>= 8;\ + w##b = Whirlpool_C[2*256 + (byte)t] ^ (op ? w##b : 0);\ + t >>= 8;\ + w##c = Whirlpool_C[1*256 + (byte)t] ^ (op ? w##c : 0);\ + t >>= 8;\ + w##d = Whirlpool_C[0*256 + t] ^ (op ? w##d : 0); + +#define TSH_OP(op, a, b) \ + w##a = Whirlpool_C[b*256 + (byte)t] ^ (op ? w##a : rotrConstant<32>(w##a) ^ k[a]);\ + if (op==2) s[a] = w##a;\ + if (op==3) digest[a] ^= w##a;\ + +#define TSH(op, i, a, b, c, d) \ + t = (word32)(s[(i+4)%8]>>32);\ + TSH_OP(op, a, 3);\ + t >>= 8;\ + TSH_OP(op, b, 2);\ + t >>= 8;\ + TSH_OP(op, c, 1);\ + t >>= 8;\ + TSH_OP(op, d, 0);\ + + // Iterate over all rounds: + int r=0; + while (true) + { + // Added initialization due to Coverity findings. + word64 w0=0, w1=0, w2=0, w3=0, w4=0, w5=0, w6=0, w7=0; + word32 t=0; + + KSL(0, 4, 3, 2, 1, 0) + KSL(0, 0, 7, 6, 5, 4) + KSL(1, 1, 0, 7, 6, 5) + KSL(1, 2, 1, 0, 7, 6) + KSL(1, 3, 2, 1, 0, 7) + KSL(1, 5, 4, 3, 2, 1) + KSL(1, 6, 5, 4, 3, 2) + KSL(1, 7, 6, 5, 4, 3) + KSH(0, 0, 7, 6, 5, 4) + KSH(0, 4, 3, 2, 1, 0) + KSH(1, 1, 0, 7, 6, 5) + KSH(1, 2, 1, 0, 7, 6) + KSH(1, 5, 4, 3, 2, 1) + KSH(1, 6, 5, 4, 3, 2) + KSH(2, 3, 2, 1, 0, 7) + KSH(2, 7, 6, 5, 4, 3) + + k[0] ^= Whirlpool_C[1024+r]; + + TSL(0, 4, 3, 2, 1, 0) + TSL(0, 0, 7, 6, 5, 4) + TSL(1, 1, 0, 7, 6, 5) + TSL(1, 2, 1, 0, 7, 6) + TSL(1, 3, 2, 1, 0, 7) + TSL(1, 5, 4, 3, 2, 1) + TSL(1, 6, 5, 4, 3, 2) + TSL(1, 7, 6, 5, 4, 3) + TSH(0, 0, 7, 6, 5, 4) + TSH(0, 4, 3, 2, 1, 0) + TSH(1, 1, 0, 7, 6, 5) + TSH(1, 2, 1, 0, 7, 6) + TSH(1, 5, 4, 3, 2, 1) + TSH(1, 6, 5, 4, 3, 2) + + if (++r < R) + { + TSH(2, 3, 2, 1, 0, 7) + TSH(2, 7, 6, 5, 4, 3) + } + else + { + TSH(3, 3, 2, 1, 0, 7) + TSH(3, 7, 6, 5, 4, 3) + break; + } + } + } +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/whrlpool.h b/external/ours/library/crypto/src/shared/original/whrlpool.h new file mode 100755 index 000000000..33e4b3020 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/whrlpool.h @@ -0,0 +1,42 @@ +// whrlpool.h - originally modified by Kevin Springle from Paulo Barreto and Vincent Rijmen's +// public domain code, whirlpool.c. Updated to Whirlpool version 3.0, optimized +// and SSE version added by WD. All modifications are placed in the public domain. + +#ifndef CRYPTOPP_WHIRLPOOL_H +#define CRYPTOPP_WHIRLPOOL_H + +/// \file whrlpool.h +/// \brief Classes for the Whirlpool message digest +/// \details Crypto++ provides version 3.0 of the Whirlpool algorithm. +/// This version of the algorithm was submitted for ISO standardization. + +#include "config.h" +#include "iterhash.h" + +// Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler +// error with .intel_syntax, http://llvm.org/bugs/show_bug.cgi?id=24232 +#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) +# define CRYPTOPP_DISABLE_WHIRLPOOL_ASM 1 +#endif + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Whirlpool message digest +/// \details Crypto++ provides version 3.0 of the Whirlpool algorithm. +/// This version of the algorithm was submitted for ISO standardization. +/// \since Crypto++ 5.2 +/// \sa Whirlpool +class Whirlpool : public IteratedHashWithStaticTransform +{ +public: + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Whirlpool";} + std::string AlgorithmProvider() const; + + static void InitState(HashWordType *state); + static void Transform(word64 *digest, const word64 *data); + void TruncatedFinal(byte *hash, size_t size); +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/words.h b/external/ours/library/crypto/src/shared/original/words.h index 8849b6107..86698a3f4 100755 --- a/external/ours/library/crypto/src/shared/original/words.h +++ b/external/ours/library/crypto/src/shared/original/words.h @@ -1,103 +1,225 @@ -#ifndef CRYPTOPP_WORDS_H -#define CRYPTOPP_WORDS_H - -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -inline unsigned int CountWords(const word *X, unsigned int N) -{ - while (N && X[N-1]==0) - N--; - return N; -} - -inline void SetWords(word *r, word a, unsigned int n) -{ - for (unsigned int i=0; i> (WORD_BITS-shiftBits); - } - return carry; -} - -inline word ShiftWordsRightByBits(word *r, unsigned int n, unsigned int shiftBits) -{ - assert (shiftBits=0; i--) - { - u = r[i]; - r[i] = (u >> shiftBits) | carry; - carry = u << (WORD_BITS-shiftBits); - } - return carry; -} - -inline void ShiftWordsLeftByWords(word *r, unsigned int n, unsigned int shiftWords) -{ - shiftWords = STDMIN(shiftWords, n); - if (shiftWords) - { - for (unsigned int i=n-1; i>=shiftWords; i--) - r[i] = r[i-shiftWords]; - SetWords(r, 0, shiftWords); - } -} - -inline void ShiftWordsRightByWords(word *r, unsigned int n, unsigned int shiftWords) -{ - shiftWords = STDMIN(shiftWords, n); - if (shiftWords) - { - for (unsigned int i=0; i+shiftWords> (WORD_BITS-shiftBits); + } + return carry; +} + +/// \brief Right shift word array +/// \param r word array +/// \param n size of the word array, in elements +/// \param shiftBits number of bits to shift +/// \return word shifted out +/// \details ShiftWordsRightByBits shifts the word array shight by +/// shiftBits. ShiftWordsRightByBits shifts bits out on the right. +/// \note shiftBits must be less than WORD_BITS. +/// \since Crypto++ 1.0 +inline word ShiftWordsRightByBits(word *r, size_t n, unsigned int shiftBits) +{ + CRYPTOPP_ASSERT (shiftBits0; i--) + { + u = r[i-1]; + r[i-1] = (u >> shiftBits) | carry; + carry = u << (WORD_BITS-shiftBits); + } + return carry; +} + +/// \brief Left shift word array +/// \param r word array +/// \param n size of the word array, in elements +/// \param shiftWords number of words to shift +/// \details ShiftWordsLeftByWords shifts the word array left by +/// shiftWords. ShiftWordsLeftByWords shifts bits out on the left; +/// it does not extend the array. +/// \since Crypto++ 1.0 +inline void ShiftWordsLeftByWords(word *r, size_t n, size_t shiftWords) +{ + shiftWords = STDMIN(shiftWords, n); + if (shiftWords) + { + for (size_t i=n-1; i>=shiftWords; i--) + r[i] = r[i-shiftWords]; + SetWords(r, 0, shiftWords); + } +} + +/// \brief Right shift word array +/// \param r word array +/// \param n size of the word array, in elements +/// \param shiftWords number of words to shift +/// \details ShiftWordsRightByWords shifts the word array right by +/// shiftWords. ShiftWordsRightByWords shifts bits out on the right. +/// \since Crypto++ 1.0 +inline void ShiftWordsRightByWords(word *r, size_t n, size_t shiftWords) +{ + shiftWords = STDMIN(shiftWords, n); + if (shiftWords) + { + for (size_t i=0; i+shiftWords> 8) & 1); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +// ******************** x25519 Agreement ************************* // + +x25519::x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) +{ + std::memcpy(m_pk, y, PUBLIC_KEYLENGTH); + std::memcpy(m_sk, x, SECRET_KEYLENGTH); + + CRYPTOPP_ASSERT(IsClamped(m_sk) == true); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +x25519::x25519(const byte x[SECRET_KEYLENGTH]) +{ + std::memcpy(m_sk, x, SECRET_KEYLENGTH); + Donna::curve25519_mult(m_pk, m_sk); + + CRYPTOPP_ASSERT(IsClamped(m_sk) == true); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +x25519::x25519(const Integer &y, const Integer &x) +{ + CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH); + CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH); + + y.Encode(m_pk, PUBLIC_KEYLENGTH); std::reverse(m_pk+0, m_pk+PUBLIC_KEYLENGTH); + x.Encode(m_sk, SECRET_KEYLENGTH); std::reverse(m_sk+0, m_sk+SECRET_KEYLENGTH); + + CRYPTOPP_ASSERT(IsClamped(m_sk) == true); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +x25519::x25519(const Integer &x) +{ + CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH); + + x.Encode(m_sk, SECRET_KEYLENGTH); + std::reverse(m_sk+0, m_sk+SECRET_KEYLENGTH); + Donna::curve25519_mult(m_pk, m_sk); + + CRYPTOPP_ASSERT(IsClamped(m_sk) == true); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +x25519::x25519(RandomNumberGenerator &rng) +{ + rng.GenerateBlock(m_sk, SECRET_KEYLENGTH); + ClampKey(m_sk); + SecretToPublicKey(m_pk, m_sk); +} + +x25519::x25519(BufferedTransformation ¶ms) +{ + Load(params); +} + +void x25519::ClampKey(byte x[SECRET_KEYLENGTH]) const +{ + x[0] &= 248; x[31] &= 127; x[31] |= 64; +} + +bool x25519::IsClamped(const byte x[SECRET_KEYLENGTH]) const +{ + return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31]; +} + +bool x25519::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const +{ + return HasSmallOrder(y); +} + +void x25519::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const +{ + Donna::curve25519_mult(y, x); +} + +void x25519::BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt) +{ + // We have not yet determined the OID to use for this object. + // We can't use OID's decoder because it throws BERDecodeError + // if the OIDs do not match. + OID oid(bt); + + // 1.3.6.1.4.1.3029.1.5.1/curvey25519 from Cryptlib used by OpenPGP. + // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-rfc4880bis + if (!m_oid.Empty() && m_oid != oid) + BERDecodeError(); // Only accept user specified OID + else if (oid == ASN1::curve25519() || oid == ASN1::X25519() || + oid == OID(1)+3+6+1+4+1+3029+1+5) + m_oid = oid; // Accept any of the x25519 OIDs + else + BERDecodeError(); +} + +void x25519::BERDecode(BufferedTransformation &bt) +{ + // https://tools.ietf.org/html/rfc8410, section 7 and + // https://www.cryptopp.com/wiki/curve25519_keys + BERSequenceDecoder privateKeyInfo(bt); + word32 version; + BERDecodeUnsigned(privateKeyInfo, version, INTEGER, 0, 1); // check version + + BERSequenceDecoder algorithm(privateKeyInfo); + // GetAlgorithmID().BERDecodeAndCheck(algorithm); + BERDecodeAndCheckAlgorithmID(algorithm); + algorithm.MessageEnd(); + + BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); + BERDecodePrivateKey(octetString, false, (size_t)privateKeyInfo.RemainingLength()); + octetString.MessageEnd(); + + // publicKey [1] IMPLICIT PublicKey OPTIONAL + bool generatePublicKey = true; + if (privateKeyInfo.EndReached() == false /*version == 1?*/) + { + // Should we test this before decoding? In either case we + // just throw a BERDecodeErr() when we can't parse it. + BERGeneralDecoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + SecByteBlock subjectPublicKey; + unsigned int unusedBits; + BERDecodeBitString(publicKey, subjectPublicKey, unusedBits); + CRYPTOPP_ASSERT(unusedBits == 0); + CRYPTOPP_ASSERT(subjectPublicKey.size() == PUBLIC_KEYLENGTH); + if (subjectPublicKey.size() != PUBLIC_KEYLENGTH) + BERDecodeError(); + std::memcpy(m_pk.begin(), subjectPublicKey, PUBLIC_KEYLENGTH); + generatePublicKey = false; + publicKey.MessageEnd(); + } + + privateKeyInfo.MessageEnd(); + + if (generatePublicKey) + Donna::curve25519_mult(m_pk, m_sk); + + CRYPTOPP_ASSERT(IsClamped(m_sk) == true); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +void x25519::DEREncode(BufferedTransformation &bt, int version) const +{ + // https://tools.ietf.org/html/rfc8410, section 7 and + // https://www.cryptopp.com/wiki/curve25519_keys + CRYPTOPP_ASSERT(version == 0 || version == 1); + + DERSequenceEncoder privateKeyInfo(bt); + DEREncodeUnsigned(privateKeyInfo, version); + + DERSequenceEncoder algorithm(privateKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + algorithm.MessageEnd(); + + DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING); + DEREncodePrivateKey(octetString); + octetString.MessageEnd(); + + if (version == 1) + { + DERGeneralEncoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + DEREncodeBitString(publicKey, m_pk, PUBLIC_KEYLENGTH); + publicKey.MessageEnd(); + } + + privateKeyInfo.MessageEnd(); +} + +void x25519::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t /*size*/) +{ + // https://tools.ietf.org/html/rfc8410 and + // https://www.cryptopp.com/wiki/curve25519_keys + + BERGeneralDecoder privateKey(bt, OCTET_STRING); + + if (!privateKey.IsDefiniteLength()) + BERDecodeError(); + + size_t size = privateKey.Get(m_sk, SECRET_KEYLENGTH); + if (size != SECRET_KEYLENGTH) + BERDecodeError(); + + // We don't know how to decode them + if (parametersPresent) + BERDecodeError(); + + privateKey.MessageEnd(); +} + +void x25519::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + // https://tools.ietf.org/html/rfc8410 + DERGeneralEncoder privateKey(bt, OCTET_STRING); + privateKey.Put(m_sk, SECRET_KEYLENGTH); + privateKey.MessageEnd(); +} + +bool x25519::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng); + CRYPTOPP_ASSERT(IsClamped(m_sk) == true); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); + + if (level >= 1 && IsClamped(m_sk) == false) + return false; + if (level >= 2 && IsSmallOrder(m_pk) == true) + return false; + if (level >= 3) + { + // Verify m_pk is pairwise consistent with m_sk + SecByteBlock pk(PUBLIC_KEYLENGTH); + SecretToPublicKey(pk, m_sk); + + if (VerifyBufsEqual(pk, m_pk, PUBLIC_KEYLENGTH) == false) + return false; + } + + return true; +} + +bool x25519::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (std::strcmp(name, Name::PrivateExponent()) == 0 || std::strcmp(name, "SecretKey") == 0) + { + this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType); + reinterpret_cast(pValue)->Assign(m_sk, SECRET_KEYLENGTH, false); + return true; + } + + if (std::strcmp(name, Name::PublicElement()) == 0) + { + this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType); + reinterpret_cast(pValue)->Assign(m_pk, PUBLIC_KEYLENGTH, false); + return true; + } + + if (std::strcmp(name, Name::GroupOID()) == 0) + { + if (m_oid.Empty()) + return false; + + this->ThrowIfTypeMismatch(name, typeid(OID), valueType); + *reinterpret_cast(pValue) = m_oid; + return true; + } + + return false; +} + +void x25519::AssignFrom(const NameValuePairs &source) +{ + ConstByteArrayParameter val; + if (source.GetValue(Name::PrivateExponent(), val) || source.GetValue("SecretKey", val)) + { + std::memcpy(m_sk, val.begin(), SECRET_KEYLENGTH); + } + + if (source.GetValue(Name::PublicElement(), val)) + { + std::memcpy(m_pk, val.begin(), PUBLIC_KEYLENGTH); + } + + OID oid; + if (source.GetValue(Name::GroupOID(), oid)) + { + m_oid = oid; + } + + bool derive = false; + if (source.GetValue("DerivePublicKey", derive) && derive == true) + SecretToPublicKey(m_pk, m_sk); +} + +void x25519::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) +{ + ConstByteArrayParameter seed; + if (params.GetValue(Name::Seed(), seed) && rng.CanIncorporateEntropy()) + rng.IncorporateEntropy(seed.begin(), seed.size()); + + rng.GenerateBlock(m_sk, SECRET_KEYLENGTH); + ClampKey(m_sk); + SecretToPublicKey(m_pk, m_sk); +} + +void x25519::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const +{ + rng.GenerateBlock(privateKey, SECRET_KEYLENGTH); + ClampKey(privateKey); +} + +void x25519::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const +{ + CRYPTOPP_UNUSED(rng); + SecretToPublicKey(publicKey, privateKey); +} + +bool x25519::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const +{ + CRYPTOPP_ASSERT(agreedValue != NULLPTR); + CRYPTOPP_ASSERT(otherPublicKey != NULLPTR); + + if (validateOtherPublicKey && IsSmallOrder(otherPublicKey)) + return false; + + return Donna::curve25519_mult(agreedValue, privateKey, otherPublicKey) == 0; +} + +// ******************** ed25519 Signer ************************* // + +void ed25519PrivateKey::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const +{ + int ret = Donna::ed25519_publickey(y, x); + CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret); +} + +bool ed25519PrivateKey::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const +{ + return HasSmallOrder(y); +} + +bool ed25519PrivateKey::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng); + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); + + if (level >= 1 && IsSmallOrder(m_pk) == true) + return false; + if (level >= 3) + { + // Verify m_pk is pairwise consistent with m_sk + SecByteBlock pk(PUBLIC_KEYLENGTH); + SecretToPublicKey(pk, m_sk); + + if (VerifyBufsEqual(pk, m_pk, PUBLIC_KEYLENGTH) == false) + return false; + } + + return true; +} + +bool ed25519PrivateKey::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (std::strcmp(name, Name::PrivateExponent()) == 0 || std::strcmp(name, "SecretKey") == 0) + { + this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType); + reinterpret_cast(pValue)->Assign(m_sk, SECRET_KEYLENGTH, false); + return true; + } + + if (std::strcmp(name, Name::PublicElement()) == 0) + { + this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType); + reinterpret_cast(pValue)->Assign(m_pk, PUBLIC_KEYLENGTH, false); + return true; + } + + if (std::strcmp(name, Name::GroupOID()) == 0) + { + if (m_oid.Empty()) + return false; + + this->ThrowIfTypeMismatch(name, typeid(OID), valueType); + *reinterpret_cast(pValue) = m_oid; + return true; + } + + return false; +} + +void ed25519PrivateKey::AssignFrom(const NameValuePairs &source) +{ + ConstByteArrayParameter val; + if (source.GetValue(Name::PrivateExponent(), val) || source.GetValue("SecretKey", val)) + { + CRYPTOPP_ASSERT(val.size() == SECRET_KEYLENGTH); + std::memcpy(m_sk, val.begin(), SECRET_KEYLENGTH); + } + if (source.GetValue(Name::PublicElement(), val)) + { + CRYPTOPP_ASSERT(val.size() == PUBLIC_KEYLENGTH); + std::memcpy(m_pk, val.begin(), PUBLIC_KEYLENGTH); + } + + OID oid; + if (source.GetValue(Name::GroupOID(), oid)) + { + m_oid = oid; + } + + bool derive = false; + if (source.GetValue("DerivePublicKey", derive) && derive == true) + SecretToPublicKey(m_pk, m_sk); + + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +void ed25519PrivateKey::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms=g_nullNameValuePairs) +{ + ConstByteArrayParameter seed; + if (params.GetValue(Name::Seed(), seed) && rng.CanIncorporateEntropy()) + rng.IncorporateEntropy(seed.begin(), seed.size()); + + rng.GenerateBlock(m_sk, SECRET_KEYLENGTH); + int ret = Donna::ed25519_publickey(m_pk, m_sk); + CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret); +} + +void ed25519PrivateKey::MakePublicKey (PublicKey &pub) const +{ + pub.AssignFrom(MakeParameters + (Name::PublicElement(), ConstByteArrayParameter(m_pk.begin(), PUBLIC_KEYLENGTH)) + (Name::GroupOID(), GetAlgorithmID())); +} + +void ed25519PrivateKey::BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt) +{ + // We have not yet determined the OID to use for this object. + // We can't use OID's decoder because it throws BERDecodeError + // if the OIDs do not match. + OID oid(bt); + + if (!m_oid.Empty() && m_oid != oid) + BERDecodeError(); // Only accept user specified OID + else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519()) + m_oid = oid; // Accept any of the ed25519PrivateKey OIDs + else + BERDecodeError(); +} + +void ed25519PrivateKey::BERDecode(BufferedTransformation &bt) +{ + // https://tools.ietf.org/html/rfc8410, section 7 and + // https://www.cryptopp.com/wiki/curve25519_keys + BERSequenceDecoder privateKeyInfo(bt); + word32 version; + BERDecodeUnsigned(privateKeyInfo, version, INTEGER, 0, 1); // check version + + BERSequenceDecoder algorithm(privateKeyInfo); + // GetAlgorithmID().BERDecodeAndCheck(algorithm); + BERDecodeAndCheckAlgorithmID(algorithm); + algorithm.MessageEnd(); + + BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); + BERDecodePrivateKey(octetString, false, (size_t)privateKeyInfo.RemainingLength()); + octetString.MessageEnd(); + + // publicKey [1] IMPLICIT PublicKey OPTIONAL + bool generatePublicKey = true; + if (privateKeyInfo.EndReached() == false /*version == 1?*/) + { + // Should we test this before decoding? In either case we + // just throw a BERDecodeErr() when we can't parse it. + BERGeneralDecoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + SecByteBlock subjectPublicKey; + unsigned int unusedBits; + BERDecodeBitString(publicKey, subjectPublicKey, unusedBits); + CRYPTOPP_ASSERT(unusedBits == 0); + CRYPTOPP_ASSERT(subjectPublicKey.size() == PUBLIC_KEYLENGTH); + if (subjectPublicKey.size() != PUBLIC_KEYLENGTH) + BERDecodeError(); + std::memcpy(m_pk.begin(), subjectPublicKey, PUBLIC_KEYLENGTH); + generatePublicKey = false; + publicKey.MessageEnd(); + } + + privateKeyInfo.MessageEnd(); + + if (generatePublicKey) + Donna::ed25519_publickey(m_pk, m_sk); + + CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); +} + +void ed25519PrivateKey::DEREncode(BufferedTransformation &bt, int version) const +{ + // https://tools.ietf.org/html/rfc8410, section 7 and + // https://www.cryptopp.com/wiki/curve25519_keys + CRYPTOPP_ASSERT(version == 0 || version == 1); + + DERSequenceEncoder privateKeyInfo(bt); + DEREncodeUnsigned(privateKeyInfo, version); + + DERSequenceEncoder algorithm(privateKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + algorithm.MessageEnd(); + + DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING); + DEREncodePrivateKey(octetString); + octetString.MessageEnd(); + + if (version == 1) + { + DERGeneralEncoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + DEREncodeBitString(publicKey, m_pk, PUBLIC_KEYLENGTH); + publicKey.MessageEnd(); + } + + privateKeyInfo.MessageEnd(); +} + +void ed25519PrivateKey::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t /*size*/) +{ + // https://tools.ietf.org/html/rfc8410 and + // https://www.cryptopp.com/wiki/curve25519_keys + + BERGeneralDecoder privateKey(bt, OCTET_STRING); + + if (!privateKey.IsDefiniteLength()) + BERDecodeError(); + + size_t size = privateKey.Get(m_sk, SECRET_KEYLENGTH); + if (size != SECRET_KEYLENGTH) + BERDecodeError(); + + // We don't know how to decode them + if (parametersPresent) + BERDecodeError(); + + privateKey.MessageEnd(); +} + +void ed25519PrivateKey::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + // https://tools.ietf.org/html/rfc8410 + DERGeneralEncoder privateKey(bt, OCTET_STRING); + privateKey.Put(m_sk, SECRET_KEYLENGTH); + privateKey.MessageEnd(); +} + +void ed25519PrivateKey::SetPrivateExponent (const byte x[SECRET_KEYLENGTH]) +{ + AssignFrom(MakeParameters + (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH)) + ("DerivePublicKey", true)); +} + +void ed25519PrivateKey::SetPrivateExponent (const Integer &x) +{ + CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH); + + SecByteBlock bx(SECRET_KEYLENGTH); + x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH); + + AssignFrom(MakeParameters + (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false)) + ("DerivePublicKey", true)); +} + +const Integer& ed25519PrivateKey::GetPrivateExponent() const +{ + m_x = Integer(m_sk, SECRET_KEYLENGTH, Integer::UNSIGNED, LITTLE_ENDIAN_ORDER); + return m_x; +} + +//////////////////////// + +ed25519Signer::ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) +{ + AccessPrivateKey().AssignFrom(MakeParameters + (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH, false)) + (Name::PublicElement(), ConstByteArrayParameter(y, PUBLIC_KEYLENGTH, false))); +} + +ed25519Signer::ed25519Signer(const byte x[SECRET_KEYLENGTH]) +{ + AccessPrivateKey().AssignFrom(MakeParameters + (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH, false)) + ("DerivePublicKey", true)); +} + +ed25519Signer::ed25519Signer(const Integer &y, const Integer &x) +{ + CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH); + CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH); + + SecByteBlock by(PUBLIC_KEYLENGTH), bx(SECRET_KEYLENGTH); + y.Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH); + x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH); + + AccessPrivateKey().AssignFrom(MakeParameters + (Name::PublicElement(), ConstByteArrayParameter(by, PUBLIC_KEYLENGTH, false)) + (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false))); +} + +ed25519Signer::ed25519Signer(const Integer &x) +{ + CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH); + + SecByteBlock bx(SECRET_KEYLENGTH); + x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH); + + AccessPrivateKey().AssignFrom(MakeParameters + (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false)) + ("DerivePublicKey", true)); +} + +ed25519Signer::ed25519Signer(const PKCS8PrivateKey &key) +{ + // Load all fields from the other key + ByteQueue queue; + key.Save(queue); + AccessPrivateKey().Load(queue); +} + +ed25519Signer::ed25519Signer(RandomNumberGenerator &rng) +{ + AccessPrivateKey().GenerateRandom(rng); +} + +ed25519Signer::ed25519Signer(BufferedTransformation ¶ms) +{ + AccessPrivateKey().Load(params); +} + +size_t ed25519Signer::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const +{ + CRYPTOPP_ASSERT(signature != NULLPTR); CRYPTOPP_UNUSED(rng); + + ed25519_MessageAccumulator& accum = dynamic_cast(messageAccumulator); + const ed25519PrivateKey& pk = dynamic_cast(GetPrivateKey()); + int ret = Donna::ed25519_sign(accum.data(), accum.size(), pk.GetPrivateKeyBytePtr(), pk.GetPublicKeyBytePtr(), signature); + CRYPTOPP_ASSERT(ret == 0); + + if (restart) + accum.Restart(); + + return ret == 0 ? SIGNATURE_LENGTH : 0; +} + +size_t ed25519Signer::SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const +{ + CRYPTOPP_ASSERT(signature != NULLPTR); CRYPTOPP_UNUSED(rng); + + const ed25519PrivateKey& pk = dynamic_cast(GetPrivateKey()); + int ret = Donna::ed25519_sign(stream, pk.GetPrivateKeyBytePtr(), pk.GetPublicKeyBytePtr(), signature); + CRYPTOPP_ASSERT(ret == 0); + + return ret == 0 ? SIGNATURE_LENGTH : 0; +} + +// ******************** ed25519 Verifier ************************* // + +bool ed25519PublicKey::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (std::strcmp(name, Name::PublicElement()) == 0) + { + this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType); + reinterpret_cast(pValue)->Assign(m_pk, PUBLIC_KEYLENGTH, false); + return true; + } + + if (std::strcmp(name, Name::GroupOID()) == 0) + { + if (m_oid.Empty()) + return false; + + this->ThrowIfTypeMismatch(name, typeid(OID), valueType); + *reinterpret_cast(pValue) = m_oid; + return true; + } + + return false; +} + +void ed25519PublicKey::AssignFrom(const NameValuePairs &source) +{ + ConstByteArrayParameter ba; + if (source.GetValue(Name::PublicElement(), ba)) + { + std::memcpy(m_pk, ba.begin(), PUBLIC_KEYLENGTH); + } + + OID oid; + if (source.GetValue(Name::GroupOID(), oid)) + { + m_oid = oid; + } +} + +void ed25519PublicKey::BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt) +{ + // We have not yet determined the OID to use for this object. + // We can't use OID's decoder because it throws BERDecodeError + // if the OIDs do not match. + OID oid(bt); + + if (!m_oid.Empty() && m_oid != oid) + BERDecodeError(); // Only accept user specified OID + else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519()) + m_oid = oid; // Accept any of the ed25519PublicKey OIDs + else + BERDecodeError(); +} + +void ed25519PublicKey::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder publicKeyInfo(bt); + + BERSequenceDecoder algorithm(publicKeyInfo); + // GetAlgorithmID().BERDecodeAndCheck(algorithm); + BERDecodeAndCheckAlgorithmID(algorithm); + algorithm.MessageEnd(); + + BERDecodePublicKey(publicKeyInfo, false, (size_t)publicKeyInfo.RemainingLength()); + + publicKeyInfo.MessageEnd(); +} + +void ed25519PublicKey::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder publicKeyInfo(bt); + + DERSequenceEncoder algorithm(publicKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + algorithm.MessageEnd(); + + DEREncodePublicKey(publicKeyInfo); + + publicKeyInfo.MessageEnd(); +} + +void ed25519PublicKey::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t /*size*/) +{ + // We don't know how to decode them + if (parametersPresent) + BERDecodeError(); + + SecByteBlock subjectPublicKey; + unsigned int unusedBits; + BERDecodeBitString(bt, subjectPublicKey, unusedBits); + + CRYPTOPP_ASSERT(unusedBits == 0); + CRYPTOPP_ASSERT(subjectPublicKey.size() == PUBLIC_KEYLENGTH); + if (subjectPublicKey.size() != PUBLIC_KEYLENGTH) + BERDecodeError(); + + std::memcpy(m_pk.begin(), subjectPublicKey, PUBLIC_KEYLENGTH); +} + +void ed25519PublicKey::DEREncodePublicKey(BufferedTransformation &bt) const +{ + DEREncodeBitString(bt, m_pk, PUBLIC_KEYLENGTH); +} + +void ed25519PublicKey::SetPublicElement (const byte y[PUBLIC_KEYLENGTH]) +{ + std::memcpy(m_pk, y, PUBLIC_KEYLENGTH); +} + +void ed25519PublicKey::SetPublicElement (const Integer &y) +{ + CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH); + + SecByteBlock by(PUBLIC_KEYLENGTH); + y.Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH); + + std::memcpy(m_pk, by, PUBLIC_KEYLENGTH); +} + +const Integer& ed25519PublicKey::GetPublicElement() const +{ + m_y = Integer(m_pk, PUBLIC_KEYLENGTH, Integer::UNSIGNED, LITTLE_ENDIAN_ORDER); + return m_y; +} + +bool ed25519PublicKey::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level); + return true; +} + +//////////////////////// + +ed25519Verifier::ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]) +{ + AccessPublicKey().AssignFrom(MakeParameters + (Name::PublicElement(), ConstByteArrayParameter(y, PUBLIC_KEYLENGTH))); +} + +ed25519Verifier::ed25519Verifier(const Integer &y) +{ + CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH); + + SecByteBlock by(PUBLIC_KEYLENGTH); + y.Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH); + + AccessPublicKey().AssignFrom(MakeParameters + (Name::PublicElement(), ConstByteArrayParameter(by, PUBLIC_KEYLENGTH, false))); +} + +ed25519Verifier::ed25519Verifier(const X509PublicKey &key) +{ + // Load all fields from the other key + ByteQueue queue; + key.Save(queue); + AccessPublicKey().Load(queue); +} + +ed25519Verifier::ed25519Verifier(BufferedTransformation ¶ms) +{ + AccessPublicKey().Load(params); +} + +ed25519Verifier::ed25519Verifier(const ed25519Signer& signer) +{ + const ed25519PrivateKey& priv = dynamic_cast(signer.GetPrivateKey()); + priv.MakePublicKey(AccessPublicKey()); +} + +bool ed25519Verifier::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const +{ + ed25519_MessageAccumulator& accum = static_cast(messageAccumulator); + const ed25519PublicKey& pk = dynamic_cast(GetPublicKey()); + int ret = Donna::ed25519_sign_open(accum.data(), accum.size(), pk.GetPublicKeyBytePtr(), accum.signature()); + accum.Restart(); + + return ret == 0; +} + +bool ed25519Verifier::VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const +{ + CRYPTOPP_ASSERT(signatureLen == SIGNATURE_LENGTH); + CRYPTOPP_UNUSED(signatureLen); + + const ed25519PublicKey& pk = static_cast(GetPublicKey()); + int ret = Donna::ed25519_sign_open(stream, pk.GetPublicKeyBytePtr(), signature); + + return ret == 0; +} + +NAMESPACE_END // CryptoPP diff --git a/external/ours/library/crypto/src/shared/original/xed25519.h b/external/ours/library/crypto/src/shared/original/xed25519.h new file mode 100755 index 000000000..3dcbd2565 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xed25519.h @@ -0,0 +1,825 @@ +// xed25519.h - written and placed in public domain by Jeffrey Walton +// Crypto++ specific implementation wrapped around Andrew +// Moon's public domain curve25519-donna and ed25519-donna, +// http://github.com/floodyberry/curve25519-donna and +// http://github.com/floodyberry/ed25519-donna. + +// Typically the key agreement classes encapsulate their data more +// than x25519 does below. They are a little more accessible +// due to crypto_box operations. + +/// \file xed25519.h +/// \brief Classes for x25519 and ed25519 operations +/// \details This implementation integrates Andrew Moon's public domain code +/// for curve25519-donna and ed25519-donna. +/// \details Moving keys into and out of the library proceeds as follows. +/// If an Integer class is accepted or returned, then the data is in big +/// endian format. That is, the MSB is at byte position 0, and the LSB +/// is at byte position 31. The Integer will work as expected, just like +/// an int or a long. +/// \details If a byte array is accepted, then the byte array is in little +/// endian format. That is, the LSB is at byte position 0, and the MSB is +/// at byte position 31. This follows the implementation where byte 0 is +/// clamed with 248. That is my_arr[0] &= 248 to mask the lower 3 bits. +/// \details PKCS8 and X509 keys encoded using ASN.1 follow little endian +/// arrays. The format is specified in draft-ietf-curdle-pkix. +/// \details If you have a little endian array and you want to wrap it in +/// an Integer using big endian then you can perform the following: +///

Integer x(my_arr, SECRET_KEYLENGTH, UNSIGNED, LITTLE_ENDIAN_ORDER);
+/// \sa Andrew Moon's x22519 GitHub curve25519-donna, +/// ed22519 GitHub ed25519-donna, and +/// draft-ietf-curdle-pkix +/// \since Crypto++ 8.0 + +#ifndef CRYPTOPP_XED25519_H +#define CRYPTOPP_XED25519_H + +#include "cryptlib.h" +#include "pubkey.h" +#include "oids.h" + +NAMESPACE_BEGIN(CryptoPP) + +class Integer; +struct ed25519Signer; +struct ed25519Verifier; + +// ******************** x25519 Agreement ************************* // + +/// \brief x25519 with key validation +/// \since Crypto++ 8.0 +class x25519 : public SimpleKeyAgreementDomain, public CryptoParameters, public PKCS8PrivateKey +{ +public: + /// \brief Size of the private key + /// \details SECRET_KEYLENGTH is the size of the private key, in bytes. + CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32); + /// \brief Size of the public key + /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes. + CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32); + /// \brief Size of the shared key + /// \details SHARED_KEYLENGTH is the size of the shared key, in bytes. + CRYPTOPP_CONSTANT(SHARED_KEYLENGTH = 32); + + virtual ~x25519() {} + + /// \brief Create a x25519 object + /// \details This constructor creates an empty x25519 object. It is + /// intended for use in loading existing parameters, like CryptoBox + /// parameters. If you are perfoming key agreement you should use a + /// constructor that generates random parameters on construction. + x25519() {} + + /// \brief Create a x25519 object + /// \param y public key + /// \param x private key + /// \details This constructor creates a x25519 object using existing parameters. + /// \note The public key is not validated. + x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]); + + /// \brief Create a x25519 object + /// \param x private key + /// \details This constructor creates a x25519 object using existing parameters. + /// The public key is calculated from the private key. + x25519(const byte x[SECRET_KEYLENGTH]); + + /// \brief Create a x25519 object + /// \param y public key + /// \param x private key + /// \details This constructor creates a x25519 object using existing parameters. + /// \note The public key is not validated. + x25519(const Integer &y, const Integer &x); + + /// \brief Create a x25519 object + /// \param x private key + /// \details This constructor creates a x25519 object using existing parameters. + /// The public key is calculated from the private key. + x25519(const Integer &x); + + /// \brief Create a x25519 object + /// \param rng RandomNumberGenerator derived class + /// \details This constructor creates a new x25519 using the random number generator. + x25519(RandomNumberGenerator &rng); + + /// \brief Create a x25519 object + /// \param params public and private key + /// \details This constructor creates a x25519 object using existing parameters. + /// The params can be created with Save. + /// \note The public key is not validated. + x25519(BufferedTransformation ¶ms); + + /// \brief Create a x25519 object + /// \param oid an object identifier + /// \details This constructor creates a new x25519 using the specified OID. The public + /// and private points are uninitialized. + x25519(const OID &oid); + + /// \brief Clamp a private key + /// \param x private key + /// \details ClampKeys() clamps a private key and then regenerates the + /// public key from the private key. + void ClampKey(byte x[SECRET_KEYLENGTH]) const; + + /// \brief Determine if private key is clamped + /// \param x private key + bool IsClamped(const byte x[SECRET_KEYLENGTH]) const; + + /// \brief Test if a key has small order + /// \param y public key + bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const; + + /// \brief Get the Object Identifier + /// \return the Object Identifier + /// \details The default OID is from RFC 8410 using id-X25519. + /// The default private key format is RFC 5208. + OID GetAlgorithmID() const { + return m_oid.Empty() ? ASN1::X25519() : m_oid; + } + + /// \brief Set the Object Identifier + /// \param oid the new Object Identifier + void SetAlgorithmID(const OID& oid) { + m_oid = oid; + } + + // CryptoParameters + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // CryptoParameters + CryptoParameters & AccessCryptoParameters() {return *this;} + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \details Save() will write the OID associated with algorithm or scheme. + /// In the case of public and private keys, this function writes the + /// subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-X25519. + /// The default private key format is RFC 5208, which is the old format. + /// The old format provides the best interop, and keys will work + /// with OpenSSL. + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Save(BufferedTransformation &bt) const { + DEREncode(bt, 0); + } + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \param v1 flag indicating v1 + /// \details Save() will write the OID associated with algorithm or scheme. + /// In the case of public and private keys, this function writes the + /// subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-X25519. + /// The default private key format is RFC 5208. + /// \details v1 means INTEGER 0 is written. INTEGER 0 means + /// RFC 5208 format, which is the old format. The old format provides + /// the best interop, and keys will work with OpenSSL. The other + /// option uses INTEGER 1. INTEGER 1 means RFC 5958 format, + /// which is the new format. + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Save(BufferedTransformation &bt, bool v1) const { + DEREncode(bt, v1 ? 0 : 1); + } + + /// \brief BER decode ASN.1 object + /// \param bt BufferedTransformation object + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Load(BufferedTransformation &bt) { + BERDecode(bt); + } + + // PKCS8PrivateKey + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); } + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \param version indicates version + /// \details DEREncode() will write the OID associated with algorithm or + /// scheme. In the case of public and private keys, this function writes + /// the subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-X25519. + /// The default private key format is RFC 5208. + /// \details The value of version is written as the INTEGER. INTEGER 0 means + /// RFC 5208 format, which is the old format. The old format provides + /// the best interop, and keys will work with OpenSSL. The INTEGER 1 + /// means RFC 5958 format, which is the new format. + void DEREncode(BufferedTransformation &bt, int version) const; + + /// \brief Determine if OID is valid for this object + /// \details BERDecodeAndCheckAlgorithmID() parses the OID from + /// bt and determines if it valid for this object. The + /// problem in practice is there are multiple OIDs available to + /// denote curve25519 operations. The OIDs include an old GNU + /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves, + /// and OIDs specified in draft-ietf-curdle-pkix. + /// \details By default BERDecodeAndCheckAlgorithmID() accepts an + /// OID set by the user, ASN1::curve25519() and ASN1::X25519(). + /// ASN1::curve25519() is generic and says "this key is valid for + /// curve25519 operations". ASN1::X25519() is specific and says + /// "this key is valid for x25519 key exchange." + void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt); + + // DL_PrivateKey + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms); + + // SimpleKeyAgreementDomain + unsigned int AgreedValueLength() const {return SHARED_KEYLENGTH;} + unsigned int PrivateKeyLength() const {return SECRET_KEYLENGTH;} + unsigned int PublicKeyLength() const {return PUBLIC_KEYLENGTH;} + + // SimpleKeyAgreementDomain + void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const; + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const; + bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const; + +protected: + // Create a public key from a private key + void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const; + +protected: + FixedSizeSecBlock m_sk; + FixedSizeSecBlock m_pk; + OID m_oid; // preferred OID +}; + +// ****************** ed25519 Signer *********************** // + +/// \brief ed25519 message accumulator +/// \details ed25519 buffers the entire message, and does not +/// digest the message incrementally. You should be careful with +/// large messages like files on-disk. The behavior is by design +/// because Bernstein feels small messages should be authenticated; +/// and larger messages will be digested by the application. +/// \details The accumulator is used for signing and verification. +/// The first 64-bytes of storage is reserved for the signature. +/// During signing the signature storage is unused. During +/// verification the first 64 bytes holds the signature. The +/// signature is provided by the PK_Verifier framework and the +/// call to PK_Signer::InputSignature. Member functions data() +/// and size() refer to the accumulated message. Member function +/// signature() refers to the signature with an implicit size of +/// SIGNATURE_LENGTH bytes. +/// \details Applications which digest large messages, like an ISO +/// disk file, should take care because the design effectively +/// disgorges the format operation from the signing operation. +/// Put another way, be careful to ensure what you are signing is +/// is in fact a digest of the intended message, and not a different +/// message digest supplied by an attacker. +struct ed25519_MessageAccumulator : public PK_MessageAccumulator +{ + CRYPTOPP_CONSTANT(RESERVE_SIZE=2048+64); + CRYPTOPP_CONSTANT(SIGNATURE_LENGTH=64); + + /// \brief Create a message accumulator + ed25519_MessageAccumulator() { + Restart(); + } + + /// \brief Create a message accumulator + /// \details ed25519 does not use a RNG. You can safely use + /// NullRNG() because IsProbablistic returns false. + ed25519_MessageAccumulator(RandomNumberGenerator &rng) { + CRYPTOPP_UNUSED(rng); Restart(); + } + + /// \brief Add data to the accumulator + /// \param msg pointer to the data to accumulate + /// \param len the size of the data, in bytes + void Update(const byte* msg, size_t len) { + if (msg && len) + m_msg.insert(m_msg.end(), msg, msg+len); + } + + /// \brief Reset the accumulator + void Restart() { + m_msg.reserve(RESERVE_SIZE); + m_msg.resize(SIGNATURE_LENGTH); + } + + /// \brief Retrieve pointer to signature buffer + /// \return pointer to signature buffer + byte* signature() { + return &m_msg[0]; + } + + /// \brief Retrieve pointer to signature buffer + /// \return pointer to signature buffer + const byte* signature() const { + return &m_msg[0]; + } + + /// \brief Retrieve pointer to data buffer + /// \return pointer to data buffer + const byte* data() const { + return &m_msg[0]+SIGNATURE_LENGTH; + } + + /// \brief Retrieve size of data buffer + /// \return size of the data buffer, in bytes + size_t size() const { + return m_msg.size()-SIGNATURE_LENGTH; + } + +protected: + // TODO: Find an equivalent Crypto++ structure. + std::vector > m_msg; +}; + +/// \brief Ed25519 private key +/// \details ed25519PrivateKey is somewhat of a hack. It needed to +/// provide DL_PrivateKey interface to fit into the existing +/// framework, but it lacks a lot of the internals of a true +/// DL_PrivateKey. The missing pieces include GroupParameters +/// and Point, which provide the low level field operations +/// found in traditional implementations like NIST curves over +/// prime and binary fields. +/// \details ed25519PrivateKey is also unusual because the +/// class members of interest are byte arrays and not Integers. +/// In addition, the byte arrays are little-endian meaning +/// LSB is at element 0 and the MSB is at element 31. +/// If you call GetPrivateExponent() then the little-endian byte +/// array is converted to a big-endian Integer() so it can be +/// returned the way a caller expects. And calling +/// SetPrivateExponent perfoms a similar internal conversion. +/// \since Crypto++ 8.0 +struct ed25519PrivateKey : public PKCS8PrivateKey +{ + /// \brief Size of the private key + /// \details SECRET_KEYLENGTH is the size of the private key, in bytes. + CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32); + /// \brief Size of the public key + /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes. + CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32); + /// \brief Size of the siganture + /// \details SIGNATURE_LENGTH is the size of the signature, in bytes. + /// ed25519 is a DL-based signature scheme. The signature is the + /// concatenation of r || s. + CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64); + + virtual ~ed25519PrivateKey() {} + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // GroupParameters + OID GetAlgorithmID() const { + return m_oid.Empty() ? ASN1::Ed25519() : m_oid; + } + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \details Save() will write the OID associated with algorithm or scheme. + /// In the case of public and private keys, this function writes the + /// subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-Ed25519. + /// The default private key format is RFC 5208, which is the old format. + /// The old format provides the best interop, and keys will work + /// with OpenSSL. + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Save(BufferedTransformation &bt) const { + DEREncode(bt, 0); + } + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \param v1 flag indicating v1 + /// \details Save() will write the OID associated with algorithm or scheme. + /// In the case of public and private keys, this function writes the + /// subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-Ed25519. + /// The default private key format is RFC 5208. + /// \details v1 means INTEGER 0 is written. INTEGER 0 means + /// RFC 5208 format, which is the old format. The old format provides + /// the best interop, and keys will work with OpenSSL. The other + /// option uses INTEGER 1. INTEGER 1 means RFC 5958 format, + /// which is the new format. + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Save(BufferedTransformation &bt, bool v1) const { + DEREncode(bt, v1 ? 0 : 1); + } + + /// \brief BER decode ASN.1 object + /// \param bt BufferedTransformation object + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Load(BufferedTransformation &bt) { + BERDecode(bt); + } + + /// \brief Initializes a public key from this key + /// \param pub reference to a public key + void MakePublicKey(PublicKey &pub) const; + + // PKCS8PrivateKey + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); } + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \param version indicates version + /// \details DEREncode() will write the OID associated with algorithm or + /// scheme. In the case of public and private keys, this function writes + /// the subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-X25519. + /// The default private key format is RFC 5208. + /// \details The value of version is written as the INTEGER. INTEGER 0 means + /// RFC 5208 format, which is the old format. The old format provides + /// the best interop, and keys will work with OpenSSL. The INTEGER 1 + /// means RFC 5958 format, which is the new format. + void DEREncode(BufferedTransformation &bt, int version) const; + + /// \brief Determine if OID is valid for this object + /// \details BERDecodeAndCheckAlgorithmID() parses the OID from + /// bt and determines if it valid for this object. The + /// problem in practice is there are multiple OIDs available to + /// denote curve25519 operations. The OIDs include an old GNU + /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves, + /// and OIDs specified in draft-ietf-curdle-pkix. + /// \details By default BERDecodeAndCheckAlgorithmID() accepts an + /// OID set by the user, ASN1::curve25519() and ASN1::Ed25519(). + /// ASN1::curve25519() is generic and says "this key is valid for + /// curve25519 operations". ASN1::Ed25519() is specific and says + /// "this key is valid for ed25519 signing." + void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt); + + // PKCS8PrivateKey + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms); + void SetPrivateExponent(const byte x[SECRET_KEYLENGTH]); + void SetPrivateExponent(const Integer &x); + const Integer& GetPrivateExponent() const; + + /// \brief Test if a key has small order + /// \param y public key + bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const; + + /// \brief Retrieve private key byte array + /// \return the private key byte array + /// \details GetPrivateKeyBytePtr() is used by signing code to call ed25519_sign. + const byte* GetPrivateKeyBytePtr() const { + return m_sk.begin(); + } + + /// \brief Retrieve public key byte array + /// \return the public key byte array + /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign. + const byte* GetPublicKeyBytePtr() const { + return m_pk.begin(); + } + +protected: + // Create a public key from a private key + void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const; + +protected: + FixedSizeSecBlock m_sk; + FixedSizeSecBlock m_pk; + OID m_oid; // preferred OID + mutable Integer m_x; // for DL_PrivateKey +}; + +/// \brief Ed25519 signature algorithm +/// \since Crypto++ 8.0 +struct ed25519Signer : public PK_Signer +{ + /// \brief Size of the private key + /// \details SECRET_KEYLENGTH is the size of the private key, in bytes. + CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32); + /// \brief Size of the public key + /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes. + CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32); + /// \brief Size of the siganture + /// \details SIGNATURE_LENGTH is the size of the signature, in bytes. + /// ed25519 is a DL-based signature scheme. The signature is the + /// concatenation of r || s. + CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64); + typedef Integer Element; + + virtual ~ed25519Signer() {} + + /// \brief Create an ed25519Signer object + ed25519Signer() {} + + /// \brief Create an ed25519Signer object + /// \param y public key + /// \param x private key + /// \details This constructor creates an ed25519Signer object using existing parameters. + /// \note The public key is not validated. + ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]); + + /// \brief Create an ed25519Signer object + /// \param x private key + /// \details This constructor creates an ed25519Signer object using existing parameters. + /// The public key is calculated from the private key. + ed25519Signer(const byte x[SECRET_KEYLENGTH]); + + /// \brief Create an ed25519Signer object + /// \param y public key + /// \param x private key + /// \details This constructor creates an ed25519Signer object using existing parameters. + /// \note The public key is not validated. + ed25519Signer(const Integer &y, const Integer &x); + + /// \brief Create an ed25519Signer object + /// \param x private key + /// \details This constructor creates an ed25519Signer object using existing parameters. + /// The public key is calculated from the private key. + ed25519Signer(const Integer &x); + + /// \brief Create an ed25519Signer object + /// \param key PKCS8 private key + /// \details This constructor creates an ed25519Signer object using existing private key. + /// \note The keys are not validated. + /// \since Crypto++ 8.6 + ed25519Signer(const PKCS8PrivateKey &key); + + /// \brief Create an ed25519Signer object + /// \param rng RandomNumberGenerator derived class + /// \details This constructor creates a new ed25519Signer using the random number generator. + ed25519Signer(RandomNumberGenerator &rng); + + /// \brief Create an ed25519Signer object + /// \param params public and private key + /// \details This constructor creates an ed25519Signer object using existing parameters. + /// The params can be created with Save. + /// \note The public key is not validated. + ed25519Signer(BufferedTransformation ¶ms); + + // DL_ObjectImplBase + /// \brief Retrieves a reference to a Private Key + /// \details AccessKey() retrieves a non-const reference to a private key. + PrivateKey& AccessKey() { return m_key; } + PrivateKey& AccessPrivateKey() { return m_key; } + + /// \brief Retrieves a reference to a Private Key + /// \details AccessKey() retrieves a const reference to a private key. + const PrivateKey& GetKey() const { return m_key; } + const PrivateKey& GetPrivateKey() const { return m_key; } + + // DL_SignatureSchemeBase + size_t SignatureLength() const { return SIGNATURE_LENGTH; } + size_t MaxRecoverableLength() const { return 0; } + size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const { + CRYPTOPP_UNUSED(signatureLength); return 0; + } + + bool IsProbabilistic() const { return false; } + bool AllowNonrecoverablePart() const { return false; } + bool RecoverablePartFirst() const { return false; } + + PK_MessageAccumulator* NewSignatureAccumulator(RandomNumberGenerator &rng) const { + return new ed25519_MessageAccumulator(rng); + } + + void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const { + CRYPTOPP_UNUSED(messageAccumulator); CRYPTOPP_UNUSED(recoverableMessage); + CRYPTOPP_UNUSED(recoverableMessageLength); + throw NotImplemented("ed25519Signer: this object does not support recoverable messages"); + } + + size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const; + + /// \brief Sign a stream + /// \param rng a RandomNumberGenerator derived class + /// \param stream an std::istream derived class + /// \param signature a block of bytes for the signature + /// \return actual signature length + /// \details SignStream() handles large streams. The Stream functions were added to + /// ed25519 for signing and verifying files that are too large for a memory allocation. + /// The functions are not present in other library signers and verifiers. + /// \details ed25519 is a deterministic signature scheme. IsProbabilistic() + /// returns false and the random number generator can be NullRNG(). + /// \pre COUNTOF(signature) == MaxSignatureLength() + /// \since Crypto++ 8.1 + size_t SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const; + +protected: + ed25519PrivateKey m_key; +}; + +// ****************** ed25519 Verifier *********************** // + +/// \brief Ed25519 public key +/// \details ed25519PublicKey is somewhat of a hack. It needed to +/// provide DL_PublicKey interface to fit into the existing +/// framework, but it lacks a lot of the internals of a true +/// DL_PublicKey. The missing pieces include GroupParameters +/// and Point, which provide the low level field operations +/// found in traditional implementations like NIST curves over +/// prime and binary fields. +/// \details ed25519PublicKey is also unusual because the +/// class members of interest are byte arrays and not Integers. +/// In addition, the byte arrays are little-endian meaning +/// LSB is at element 0 and the MSB is at element 31. +/// If you call GetPublicElement() then the little-endian byte +/// array is converted to a big-endian Integer() so it can be +/// returned the way a caller expects. And calling +/// SetPublicElement() perfoms a similar internal conversion. +/// \since Crypto++ 8.0 +struct ed25519PublicKey : public X509PublicKey +{ + /// \brief Size of the public key + /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes. + CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32); + typedef Integer Element; + + virtual ~ed25519PublicKey() {} + + OID GetAlgorithmID() const { + return m_oid.Empty() ? ASN1::Ed25519() : m_oid; + } + + /// \brief DER encode ASN.1 object + /// \param bt BufferedTransformation object + /// \details Save() will write the OID associated with algorithm or scheme. + /// In the case of public and private keys, this function writes the + /// subjectPublicKeyInfo parts. + /// \details The default OID is from RFC 8410 using id-X25519. + /// The default private key format is RFC 5208, which is the old format. + /// The old format provides the best interop, and keys will work + /// with OpenSSL. + void Save(BufferedTransformation &bt) const { + DEREncode(bt); + } + + /// \brief BER decode ASN.1 object + /// \param bt BufferedTransformation object + /// \sa RFC 5958, Asymmetric + /// Key Packages + void Load(BufferedTransformation &bt) { + BERDecode(bt); + } + + // X509PublicKey + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; + + /// \brief Determine if OID is valid for this object + /// \details BERDecodeAndCheckAlgorithmID() parses the OID from + /// bt and determines if it valid for this object. The + /// problem in practice is there are multiple OIDs available to + /// denote curve25519 operations. The OIDs include an old GNU + /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves, + /// and OIDs specified in draft-ietf-curdle-pkix. + /// \details By default BERDecodeAndCheckAlgorithmID() accepts an + /// OID set by the user, ASN1::curve25519() and ASN1::Ed25519(). + /// ASN1::curve25519() is generic and says "this key is valid for + /// curve25519 operations". ASN1::Ed25519() is specific and says + /// "this key is valid for ed25519 signing." + void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt); + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // DL_PublicKey + void SetPublicElement(const byte y[PUBLIC_KEYLENGTH]); + void SetPublicElement(const Element &y); + const Element& GetPublicElement() const; + + /// \brief Retrieve public key byte array + /// \return the public key byte array + /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign. + const byte* GetPublicKeyBytePtr() const { + return m_pk.begin(); + } + +protected: + FixedSizeSecBlock m_pk; + OID m_oid; // preferred OID + mutable Integer m_y; // for DL_PublicKey +}; + +/// \brief Ed25519 signature verification algorithm +/// \since Crypto++ 8.0 +struct ed25519Verifier : public PK_Verifier +{ + CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32); + CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64); + typedef Integer Element; + + virtual ~ed25519Verifier() {} + + /// \brief Create an ed25519Verifier object + ed25519Verifier() {} + + /// \brief Create an ed25519Verifier object + /// \param y public key + /// \details This constructor creates an ed25519Verifier object using existing parameters. + /// \note The public key is not validated. + ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]); + + /// \brief Create an ed25519Verifier object + /// \param y public key + /// \details This constructor creates an ed25519Verifier object using existing parameters. + /// \note The public key is not validated. + ed25519Verifier(const Integer &y); + + /// \brief Create an ed25519Verifier object + /// \param key X509 public key + /// \details This constructor creates an ed25519Verifier object using an existing public key. + /// \note The public key is not validated. + /// \since Crypto++ 8.6 + ed25519Verifier(const X509PublicKey &key); + + /// \brief Create an ed25519Verifier object + /// \param params public and private key + /// \details This constructor creates an ed25519Verifier object using existing parameters. + /// The params can be created with Save. + /// \note The public key is not validated. + ed25519Verifier(BufferedTransformation ¶ms); + + /// \brief Create an ed25519Verifier object + /// \param signer ed25519 signer object + /// \details This constructor creates an ed25519Verifier object using existing parameters. + /// The params can be created with Save. + /// \note The public key is not validated. + ed25519Verifier(const ed25519Signer& signer); + + // DL_ObjectImplBase + /// \brief Retrieves a reference to a Public Key + /// \details AccessKey() retrieves a non-const reference to a public key. + PublicKey& AccessKey() { return m_key; } + PublicKey& AccessPublicKey() { return m_key; } + + /// \brief Retrieves a reference to a Public Key + /// \details GetKey() retrieves a const reference to a public key. + const PublicKey& GetKey() const { return m_key; } + const PublicKey& GetPublicKey() const { return m_key; } + + // DL_SignatureSchemeBase + size_t SignatureLength() const { return SIGNATURE_LENGTH; } + size_t MaxRecoverableLength() const { return 0; } + size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const { + CRYPTOPP_UNUSED(signatureLength); return 0; + } + + bool IsProbabilistic() const { return false; } + bool AllowNonrecoverablePart() const { return false; } + bool RecoverablePartFirst() const { return false; } + + ed25519_MessageAccumulator* NewVerificationAccumulator() const { + return new ed25519_MessageAccumulator; + } + + void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const { + CRYPTOPP_ASSERT(signature != NULLPTR); + CRYPTOPP_ASSERT(signatureLength == SIGNATURE_LENGTH); + ed25519_MessageAccumulator& accum = static_cast(messageAccumulator); + if (signature && signatureLength) + std::memcpy(accum.signature(), signature, STDMIN((size_t)SIGNATURE_LENGTH, signatureLength)); + } + + bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const; + + /// \brief Check whether input signature is a valid signature for input message + /// \param stream an std::istream derived class + /// \param signature a pointer to the signature over the message + /// \param signatureLen the size of the signature + /// \return true if the signature is valid, false otherwise + /// \details VerifyStream() handles large streams. The Stream functions were added to + /// ed25519 for signing and verifying files that are too large for a memory allocation. + /// The functions are not present in other library signers and verifiers. + /// \since Crypto++ 8.1 + bool VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const; + + DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const { + CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator); + throw NotImplemented("ed25519Verifier: this object does not support recoverable messages"); + } + +protected: + ed25519PublicKey m_key; +}; + +/// \brief Ed25519 signature scheme +/// \sa Ed25519 on the Crypto++ wiki. +/// \since Crypto++ 8.0 +struct ed25519 +{ + /// \brief ed25519 Signer + typedef ed25519Signer Signer; + /// \brief ed25519 Verifier + typedef ed25519Verifier Verifier; +}; + +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_XED25519_H diff --git a/external/ours/library/crypto/src/shared/original/xtr.cpp b/external/ours/library/crypto/src/shared/original/xtr.cpp new file mode 100755 index 000000000..fe49b1eaa --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xtr.cpp @@ -0,0 +1,120 @@ +// xtr.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "xtr.h" +#include "nbtheory.h" +#include "integer.h" +#include "algebra.h" +#include "modarith.h" +#include "algebra.cpp" + +NAMESPACE_BEGIN(CryptoPP) + +const GFP2Element & GFP2Element::Zero() +{ +#if defined(CRYPTOPP_CXX11_STATIC_INIT) + static const GFP2Element s_zero; + return s_zero; +#else + return Singleton().Ref(); +#endif +} + +void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits) +{ + CRYPTOPP_ASSERT(qbits > 9); // no primes exist for pbits = 10, qbits = 9 + CRYPTOPP_ASSERT(pbits > qbits); + + const Integer minQ = Integer::Power2(qbits - 1); + const Integer maxQ = Integer::Power2(qbits) - 1; + const Integer minP = Integer::Power2(pbits - 1); + const Integer maxP = Integer::Power2(pbits) - 1; + +top: + + Integer r1, r2; + do + { + (void)q.Randomize(rng, minQ, maxQ, Integer::PRIME, 7, 12); + // Solution always exists because q === 7 mod 12. + (void)SolveModularQuadraticEquation(r1, r2, 1, -1, 1, q); + // I believe k_i, r1 and r2 are being used slightly different than the + // paper's algorithm. I believe it is leading to the failed asserts. + // Just make the assert part of the condition. + if(!p.Randomize(rng, minP, maxP, Integer::PRIME, CRT(rng.GenerateBit() ? + r1 : r2, q, 2, 3, EuclideanMultiplicativeInverse(p, 3)), 3 * q)) { continue; } + } while (((p % 3U) != 2) || (((p.Squared() - p + 1) % q).NotZero())); + + // CRYPTOPP_ASSERT((p % 3U) == 2); + // CRYPTOPP_ASSERT(((p.Squared() - p + 1) % q).IsZero()); + + GFP2_ONB gfp2(p); + GFP2Element three = gfp2.ConvertIn(3), t; + + while (true) + { + g.c1.Randomize(rng, Integer::Zero(), p-1); + g.c2.Randomize(rng, Integer::Zero(), p-1); + t = XTR_Exponentiate(g, p+1, p); + if (t.c1 == t.c2) + continue; + g = XTR_Exponentiate(g, (p.Squared()-p+1)/q, p); + if (g != three) + break; + } + + if (XTR_Exponentiate(g, q, p) != three) + goto top; + + // CRYPTOPP_ASSERT(XTR_Exponentiate(g, q, p) == three); +} + +GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p) +{ + unsigned int bitCount = e.BitCount(); + if (bitCount == 0) + return GFP2Element(-3, -3); + + // find the lowest bit of e that is 1 + unsigned int lowest1bit; + for (lowest1bit=0; e.GetBit(lowest1bit) == 0; lowest1bit++) {} + + GFP2_ONB gfp2(p); + GFP2Element c = gfp2.ConvertIn(b); + GFP2Element cp = gfp2.PthPower(c); + GFP2Element S[5] = {gfp2.ConvertIn(3), c, gfp2.SpecialOperation1(c)}; + + // do all exponents bits except the lowest zeros starting from the top + unsigned int i; + for (i = e.BitCount() - 1; i>lowest1bit; i--) + { + if (e.GetBit(i)) + { + gfp2.RaiseToPthPower(S[0]); + gfp2.Accumulate(S[0], gfp2.SpecialOperation2(S[2], c, S[1])); + S[1] = gfp2.SpecialOperation1(S[1]); + S[2] = gfp2.SpecialOperation1(S[2]); + S[0].swap(S[1]); + } + else + { + gfp2.RaiseToPthPower(S[2]); + gfp2.Accumulate(S[2], gfp2.SpecialOperation2(S[0], cp, S[1])); + S[1] = gfp2.SpecialOperation1(S[1]); + S[0] = gfp2.SpecialOperation1(S[0]); + S[2].swap(S[1]); + } + } + + // now do the lowest zeros + while (i--) + S[1] = gfp2.SpecialOperation1(S[1]); + + return gfp2.ConvertOut(S[1]); +} + +template class AbstractRing; +template class AbstractGroup; + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/xtr.h b/external/ours/library/crypto/src/shared/original/xtr.h new file mode 100755 index 000000000..29479d8ca --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xtr.h @@ -0,0 +1,219 @@ +#ifndef CRYPTOPP_XTR_H +#define CRYPTOPP_XTR_H + +/// \file xtr.h +/// \brief The XTR public key system +/// \details The XTR public key system by Arjen K. Lenstra and Eric R. Verheul + +#include "cryptlib.h" +#include "modarith.h" +#include "integer.h" +#include "algebra.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief an element of GF(p^2) +class GFP2Element +{ +public: + GFP2Element() {} + GFP2Element(const Integer &c1, const Integer &c2) : c1(c1), c2(c2) {} + GFP2Element(const byte *encodedElement, unsigned int size) + : c1(encodedElement, size/2), c2(encodedElement+size/2, size/2) {} + + void Encode(byte *encodedElement, unsigned int size) + { + c1.Encode(encodedElement, size/2); + c2.Encode(encodedElement+size/2, size/2); + } + + bool operator==(const GFP2Element &rhs) const {return c1 == rhs.c1 && c2 == rhs.c2;} + bool operator!=(const GFP2Element &rhs) const {return !operator==(rhs);} + + void swap(GFP2Element &a) + { + c1.swap(a.c1); + c2.swap(a.c2); + } + + static const GFP2Element & Zero(); + + Integer c1, c2; +}; + +/// \brief GF(p^2), optimal normal basis +template +class GFP2_ONB : public AbstractRing +{ +public: + typedef F BaseField; + + GFP2_ONB(const Integer &p) : modp(p) + { + if (p%3 != 2) + throw InvalidArgument("GFP2_ONB: modulus must be equivalent to 2 mod 3"); + } + + const Integer& GetModulus() const {return modp.GetModulus();} + + GFP2Element ConvertIn(const Integer &a) const + { + t = modp.Inverse(modp.ConvertIn(a)); + return GFP2Element(t, t); + } + + GFP2Element ConvertIn(const GFP2Element &a) const + {return GFP2Element(modp.ConvertIn(a.c1), modp.ConvertIn(a.c2));} + + GFP2Element ConvertOut(const GFP2Element &a) const + {return GFP2Element(modp.ConvertOut(a.c1), modp.ConvertOut(a.c2));} + + bool Equal(const GFP2Element &a, const GFP2Element &b) const + { + return modp.Equal(a.c1, b.c1) && modp.Equal(a.c2, b.c2); + } + + const Element& Identity() const + { + return GFP2Element::Zero(); + } + + const Element& Add(const Element &a, const Element &b) const + { + result.c1 = modp.Add(a.c1, b.c1); + result.c2 = modp.Add(a.c2, b.c2); + return result; + } + + const Element& Inverse(const Element &a) const + { + result.c1 = modp.Inverse(a.c1); + result.c2 = modp.Inverse(a.c2); + return result; + } + + const Element& Double(const Element &a) const + { + result.c1 = modp.Double(a.c1); + result.c2 = modp.Double(a.c2); + return result; + } + + const Element& Subtract(const Element &a, const Element &b) const + { + result.c1 = modp.Subtract(a.c1, b.c1); + result.c2 = modp.Subtract(a.c2, b.c2); + return result; + } + + Element& Accumulate(Element &a, const Element &b) const + { + modp.Accumulate(a.c1, b.c1); + modp.Accumulate(a.c2, b.c2); + return a; + } + + Element& Reduce(Element &a, const Element &b) const + { + modp.Reduce(a.c1, b.c1); + modp.Reduce(a.c2, b.c2); + return a; + } + + bool IsUnit(const Element &a) const + { + return a.c1.NotZero() || a.c2.NotZero(); + } + + const Element& MultiplicativeIdentity() const + { + result.c1 = result.c2 = modp.Inverse(modp.MultiplicativeIdentity()); + return result; + } + + const Element& Multiply(const Element &a, const Element &b) const + { + t = modp.Add(a.c1, a.c2); + t = modp.Multiply(t, modp.Add(b.c1, b.c2)); + result.c1 = modp.Multiply(a.c1, b.c1); + result.c2 = modp.Multiply(a.c2, b.c2); + result.c1.swap(result.c2); + modp.Reduce(t, result.c1); + modp.Reduce(t, result.c2); + modp.Reduce(result.c1, t); + modp.Reduce(result.c2, t); + return result; + } + + const Element& MultiplicativeInverse(const Element &a) const + { + return result = Exponentiate(a, modp.GetModulus()-2); + } + + const Element& Square(const Element &a) const + { + const Integer &ac1 = (&a == &result) ? (t = a.c1) : a.c1; + result.c1 = modp.Multiply(modp.Subtract(modp.Subtract(a.c2, a.c1), a.c1), a.c2); + result.c2 = modp.Multiply(modp.Subtract(modp.Subtract(ac1, a.c2), a.c2), ac1); + return result; + } + + Element Exponentiate(const Element &a, const Integer &e) const + { + Integer edivp, emodp; + Integer::Divide(emodp, edivp, e, modp.GetModulus()); + Element b = PthPower(a); + return AbstractRing::CascadeExponentiate(a, emodp, b, edivp); + } + + const Element & PthPower(const Element &a) const + { + result = a; + result.c1.swap(result.c2); + return result; + } + + void RaiseToPthPower(Element &a) const + { + a.c1.swap(a.c2); + } + + // a^2 - 2a^p + const Element & SpecialOperation1(const Element &a) const + { + CRYPTOPP_ASSERT(&a != &result); + result = Square(a); + modp.Reduce(result.c1, a.c2); + modp.Reduce(result.c1, a.c2); + modp.Reduce(result.c2, a.c1); + modp.Reduce(result.c2, a.c1); + return result; + } + + // x * z - y * z^p + const Element & SpecialOperation2(const Element &x, const Element &y, const Element &z) const + { + CRYPTOPP_ASSERT(&x != &result && &y != &result && &z != &result); + t = modp.Add(x.c2, y.c2); + result.c1 = modp.Multiply(z.c1, modp.Subtract(y.c1, t)); + modp.Accumulate(result.c1, modp.Multiply(z.c2, modp.Subtract(t, x.c1))); + t = modp.Add(x.c1, y.c1); + result.c2 = modp.Multiply(z.c2, modp.Subtract(y.c2, t)); + modp.Accumulate(result.c2, modp.Multiply(z.c1, modp.Subtract(t, x.c2))); + return result; + } + +protected: + BaseField modp; + mutable GFP2Element result; + mutable Integer t; +}; + +/// \brief Creates primes p,q and generator g for XTR +void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits); + +GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p); + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/xtrcrypt.cpp b/external/ours/library/crypto/src/shared/original/xtrcrypt.cpp new file mode 100755 index 000000000..aa106aa44 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xtrcrypt.cpp @@ -0,0 +1,122 @@ +// xtrcrypt.cpp - originally written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "asn.h" +#include "integer.h" +#include "xtrcrypt.h" +#include "nbtheory.h" +#include "modarith.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +XTR_DH::XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g) + : m_p(p), m_q(q), m_g(g) +{ +} + +XTR_DH::XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) +{ + XTR_FindPrimesAndGenerator(rng, m_p, m_q, m_g, pbits, qbits); +} + +XTR_DH::XTR_DH(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_g.c1.BERDecode(seq); + m_g.c2.BERDecode(seq); + seq.MessageEnd(); +} + +void XTR_DH::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_g.c1.DEREncode(seq); + m_g.c2.DEREncode(seq); + seq.MessageEnd(); +} + +bool XTR_DH::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_p > Integer::One() && m_p.IsOdd(); + CRYPTOPP_ASSERT(pass); + pass = pass && m_q > Integer::One() && m_q.IsOdd(); + CRYPTOPP_ASSERT(pass); + GFP2Element three = GFP2_ONB(m_p).ConvertIn(3); + CRYPTOPP_ASSERT(pass); + pass = pass && !(m_g.c1.IsNegative() || m_g.c2.IsNegative() || m_g.c1 >= m_p || m_g.c2 >= m_p || m_g == three); + CRYPTOPP_ASSERT(pass); + if (level >= 1) + { + pass = pass && ((m_p.Squared()-m_p+1)%m_q).IsZero(); + CRYPTOPP_ASSERT(pass); + } + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + CRYPTOPP_ASSERT(pass); + pass = pass && XTR_Exponentiate(m_g, (m_p.Squared()-m_p+1)/m_q, m_p) != three; + CRYPTOPP_ASSERT(pass); + pass = pass && XTR_Exponentiate(m_g, m_q, m_p) == three; + CRYPTOPP_ASSERT(pass); + } + return pass; +} + +bool XTR_DH::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) + ; +} + +void XTR_DH::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupGenerator) + ; +} + +void XTR_DH::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const +{ + Integer x(rng, Integer::Zero(), m_q-1); + x.Encode(privateKey, PrivateKeyLength()); +} + +void XTR_DH::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const +{ + CRYPTOPP_UNUSED(rng); + Integer x(privateKey, PrivateKeyLength()); + GFP2Element y = XTR_Exponentiate(m_g, x, m_p); + y.Encode(publicKey, PublicKeyLength()); +} + +bool XTR_DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const +{ + GFP2Element w(otherPublicKey, PublicKeyLength()); + if (validateOtherPublicKey) + { + GFP2_ONB gfp2(m_p); + GFP2Element three = gfp2.ConvertIn(3); + if (w.c1.IsNegative() || w.c2.IsNegative() || w.c1 >= m_p || w.c2 >= m_p || w == three) + return false; + if (XTR_Exponentiate(w, m_q, m_p) != three) + return false; + } + Integer s(privateKey, PrivateKeyLength()); + GFP2Element z = XTR_Exponentiate(w, s, m_p); + z.Encode(agreedValue, AgreedValueLength()); + return true; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/xtrcrypt.h b/external/ours/library/crypto/src/shared/original/xtrcrypt.h new file mode 100755 index 000000000..64c9430ba --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xtrcrypt.h @@ -0,0 +1,55 @@ +#ifndef CRYPTOPP_XTRCRYPT_H +#define CRYPTOPP_XTRCRYPT_H + +/// \file +/// \brief XTR public key system +/// \sa "The XTR public key system" by Arjen K. Lenstra and Eric R. Verheul + +#include "cryptlib.h" +#include "xtr.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief XTR-DH with key validation +class XTR_DH : public SimpleKeyAgreementDomain, public CryptoParameters +{ + typedef XTR_DH ThisClass; + +public: + XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g); + XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits); + XTR_DH(BufferedTransformation &domainParams); + + void DEREncode(BufferedTransformation &domainParams) const; + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + CryptoParameters & AccessCryptoParameters() {return *this;} + unsigned int AgreedValueLength() const {return 2*m_p.ByteCount();} + unsigned int PrivateKeyLength() const {return m_q.ByteCount();} + unsigned int PublicKeyLength() const {return 2*m_p.ByteCount();} + + void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const; + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const; + bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const; + + const Integer &GetModulus() const {return m_p;} + const Integer &GetSubgroupOrder() const {return m_q;} + const GFP2Element &GetSubgroupGenerator() const {return m_g;} + + void SetModulus(const Integer &p) {m_p = p;} + void SetSubgroupOrder(const Integer &q) {m_q = q;} + void SetSubgroupGenerator(const GFP2Element &g) {m_g = g;} + +private: + unsigned int ExponentBitLength() const; + + Integer m_p, m_q; + GFP2Element m_g; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/xts.cpp b/external/ours/library/crypto/src/shared/original/xts.cpp new file mode 100755 index 000000000..27fbf76cd --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xts.cpp @@ -0,0 +1,512 @@ +// xts.cpp - written and placed in the public domain by Jeffrey Walton + +// Aarch32, Aarch64, Altivec and X86_64 include SIMD as part of the +// base architecture. We can use the SIMD code below without an +// architecture option. No runtime tests are required. Unfortunately, +// we can't use it on Altivec because an architecture switch is required. +// The updated XorBuffer gains 0.3 to 1.5 cpb on the architectures for +// 16-byte block sizes. + +#include "pch.h" + +#include "xts.h" +#include "misc.h" +#include "modes.h" +#include "cpu.h" + +#if defined(CRYPTOPP_DEBUG) +# include "aes.h" +# include "threefish.h" +#endif + +// 0.3 to 0.4 cpb profit +#if defined(__SSE2__) || defined(_M_X64) +# include +#endif + +#if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if (CRYPTOPP_ARM_NEON_HEADER) +# include +# endif +#endif + +#if defined(__ALTIVEC__) +# include "ppc_simd.h" +#endif + +ANONYMOUS_NAMESPACE_BEGIN + +using namespace CryptoPP; + +#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) + +using CryptoPP::AES; +using CryptoPP::XTS_Mode; +using CryptoPP::Threefish512; + +void Modes_TestInstantiations() +{ + XTS_Mode::Encryption m0; + XTS_Mode::Decryption m1; + XTS_Mode::Encryption m2; + XTS_Mode::Decryption m3; + +#if CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS + XTS_Mode::Encryption m4; + XTS_Mode::Decryption m5; +#endif +} +#endif // CRYPTOPP_DEBUG + +inline void XorBuffer(byte *output, const byte *input, const byte *mask, size_t count) +{ + CRYPTOPP_ASSERT(count >= 16 && (count % 16 == 0)); + +#if defined(CRYPTOPP_DISABLE_ASM) + xorbuf(output, input, mask, count); + +#elif defined(__SSE2__) || defined(_M_X64) + for (size_t i=0; i(false, LITTLE_ENDIAN_ORDER, in+idx); + word64 y = (x >> 63); x = (x << 1) + carry; + PutWord(false, LITTLE_ENDIAN_ORDER, out+idx, x); + carry = y; + } +#else + word32 carry = 0, x; + for (size_t i=0, idx=0; i(false, LITTLE_ENDIAN_ORDER, in+idx); + word32 y = (x >> 31); x = (x << 1) + carry; + PutWord(false, LITTLE_ENDIAN_ORDER, out+idx, x); + carry = y; + } +#endif + +#if CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS + + CRYPTOPP_ASSERT(IsPowerOf2(len)); + CRYPTOPP_ASSERT(len >= 16); + CRYPTOPP_ASSERT(len <= 128); + + byte* k = out; + if (carry) + { + switch (len) + { + case 16: + { + const size_t LEIDX = 16-1; + k[LEIDX-15] ^= 0x87; + break; + } + case 32: + { + // https://crypto.stackexchange.com/q/9815/10496 + // Polynomial x^256 + x^10 + x^5 + x^2 + 1 + const size_t LEIDX = 32-1; + k[LEIDX-30] ^= 4; + k[LEIDX-31] ^= 0x25; + break; + } + case 64: + { + // https://crypto.stackexchange.com/q/9815/10496 + // Polynomial x^512 + x^8 + x^5 + x^2 + 1 + const size_t LEIDX = 64-1; + k[LEIDX-62] ^= 1; + k[LEIDX-63] ^= 0x25; + break; + } + case 128: + { + // https://crypto.stackexchange.com/q/9815/10496 + // Polynomial x^1024 + x^19 + x^6 + x + 1 + const size_t LEIDX = 128-1; + k[LEIDX-125] ^= 8; + k[LEIDX-126] ^= 0x00; + k[LEIDX-127] ^= 0x43; + break; + } + default: + CRYPTOPP_ASSERT(0); + } + } +#else + CRYPTOPP_ASSERT(len == 16); + + byte* k = out; + if (carry) + { + k[0] ^= 0x87; + return; + } +#endif // CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS +} + +inline void GF_Double(byte *inout, unsigned int len) +{ + GF_Double(inout, inout, len); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void XTS_ModeBase::ThrowIfInvalidBlockSize(size_t length) +{ +#if CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS + CRYPTOPP_ASSERT(length >= 16 && length <= 128 && IsPowerOf2(length)); + if (length < 16 || length > 128 || !IsPowerOf2(length)) + throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not valid"); +#else + CRYPTOPP_ASSERT(length == 16); + if (length != 16) + throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16"); +#endif +} + +void XTS_ModeBase::ThrowIfInvalidKeyLength(size_t length) +{ + CRYPTOPP_ASSERT(length % 2 == 0); + if (!GetBlockCipher().IsValidKeyLength((length+1)/2)) + throw InvalidKeyLength(AlgorithmName(), length); +} + +void XTS_ModeBase::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms) +{ + ThrowIfInvalidKeyLength(length); + ThrowIfInvalidBlockSize(BlockSize()); + + const size_t klen = length/2; + AccessBlockCipher().SetKey(key+0, klen, params); + AccessTweakCipher().SetKey(key+klen, klen, params); + + ResizeBuffers(); + + size_t ivLength; + const byte *iv = GetIVAndThrowIfInvalid(params, ivLength); + Resynchronize(iv, (int)ivLength); +} + +void XTS_ModeBase::Resynchronize(const byte *iv, int ivLength) +{ + BlockOrientedCipherModeBase::Resynchronize(iv, ivLength); + std::memcpy(m_xregister, m_register, ivLength); + GetTweakCipher().ProcessBlock(m_xregister); +} + +void XTS_ModeBase::Resynchronize(word64 sector, ByteOrder order) +{ + SecByteBlock iv(GetTweakCipher().BlockSize()); + PutWord(false, order, iv, sector); + std::memset(iv+8, 0x00, iv.size()-8); + + BlockOrientedCipherModeBase::Resynchronize(iv, (int)iv.size()); + std::memcpy(m_xregister, iv, iv.size()); + GetTweakCipher().ProcessBlock(m_xregister); +} + +void XTS_ModeBase::ResizeBuffers() +{ + BlockOrientedCipherModeBase::ResizeBuffers(); + m_xworkspace.New(GetBlockCipher().BlockSize()*ParallelBlocks); + m_xregister.New(GetBlockCipher().BlockSize()*ParallelBlocks); +} + +// ProcessData runs either 12-4-1 blocks, 8-2-1 or 4-1 blocks. Which is +// selected depends on ParallelBlocks in the header file. 12-4-1 or 8-2-1 +// can be used on Aarch64 and PowerPC. Intel should use 4-1 due to lack +// of registers. The unneeded code paths should be removed by optimizer. +// The extra gyrations save us 1.8 cpb on Aarch64 and 2.1 cpb on PowerPC. +void XTS_ModeBase::ProcessData(byte *outString, const byte *inString, size_t length) +{ + // data unit is multiple of 16 bytes + CRYPTOPP_ASSERT(length % BlockSize() == 0); + + enum { lastParallelBlock = ParallelBlocks-1 }; + const unsigned int blockSize = GetBlockCipher().BlockSize(); + const size_t parallelSize = blockSize*ParallelBlocks; + + // encrypt the data unit, optimal size at a time + while (length >= parallelSize) + { + // m_xregister[0] always points to the next tweak. + GF_Double(m_xregister+1*blockSize, m_xregister+0*blockSize, blockSize); + GF_Double(m_xregister+2*blockSize, m_xregister+1*blockSize, blockSize); + GF_Double(m_xregister+3*blockSize, m_xregister+2*blockSize, blockSize); + + if (ParallelBlocks > 4) + { + GF_Double(m_xregister+4*blockSize, m_xregister+3*blockSize, blockSize); + GF_Double(m_xregister+5*blockSize, m_xregister+4*blockSize, blockSize); + GF_Double(m_xregister+6*blockSize, m_xregister+5*blockSize, blockSize); + GF_Double(m_xregister+7*blockSize, m_xregister+6*blockSize, blockSize); + } + if (ParallelBlocks > 8) + { + GF_Double(m_xregister+8*blockSize, m_xregister+7*blockSize, blockSize); + GF_Double(m_xregister+9*blockSize, m_xregister+8*blockSize, blockSize); + GF_Double(m_xregister+10*blockSize, m_xregister+9*blockSize, blockSize); + GF_Double(m_xregister+11*blockSize, m_xregister+10*blockSize, blockSize); + } + + // merge the tweak into the input block + XorBuffer(m_xworkspace, inString, m_xregister, parallelSize); + + // encrypt one block, merge the tweak into the output block + GetBlockCipher().AdvancedProcessBlocks(m_xworkspace, m_xregister, + outString, parallelSize, BlockTransformation::BT_AllowParallel); + + // m_xregister[0] always points to the next tweak. + GF_Double(m_xregister+0, m_xregister+lastParallelBlock*blockSize, blockSize); + + inString += parallelSize; + outString += parallelSize; + length -= parallelSize; + } + + // encrypt the data unit, 4 blocks at a time + while (ParallelBlocks == 12 && length >= blockSize*4) + { + // m_xregister[0] always points to the next tweak. + GF_Double(m_xregister+1*blockSize, m_xregister+0*blockSize, blockSize); + GF_Double(m_xregister+2*blockSize, m_xregister+1*blockSize, blockSize); + GF_Double(m_xregister+3*blockSize, m_xregister+2*blockSize, blockSize); + + // merge the tweak into the input block + XorBuffer(m_xworkspace, inString, m_xregister, blockSize*4); + + // encrypt one block, merge the tweak into the output block + GetBlockCipher().AdvancedProcessBlocks(m_xworkspace, m_xregister, + outString, blockSize*4, BlockTransformation::BT_AllowParallel); + + // m_xregister[0] always points to the next tweak. + GF_Double(m_xregister+0, m_xregister+3*blockSize, blockSize); + + inString += blockSize*4; + outString += blockSize*4; + length -= blockSize*4; + } + + // encrypt the data unit, 2 blocks at a time + while (ParallelBlocks == 8 && length >= blockSize*2) + { + // m_xregister[0] always points to the next tweak. + GF_Double(m_xregister+1*blockSize, m_xregister+0*blockSize, blockSize); + + // merge the tweak into the input block + XorBuffer(m_xworkspace, inString, m_xregister, blockSize*2); + + // encrypt one block, merge the tweak into the output block + GetBlockCipher().AdvancedProcessBlocks(m_xworkspace, m_xregister, + outString, blockSize*2, BlockTransformation::BT_AllowParallel); + + // m_xregister[0] always points to the next tweak. + GF_Double(m_xregister+0, m_xregister+1*blockSize, blockSize); + + inString += blockSize*2; + outString += blockSize*2; + length -= blockSize*2; + } + + // encrypt the data unit, blocksize at a time + while (length) + { + // merge the tweak into the input block + XorBuffer(m_xworkspace, inString, m_xregister, blockSize); + + // encrypt one block + GetBlockCipher().ProcessBlock(m_xworkspace); + + // merge the tweak into the output block + XorBuffer(outString, m_xworkspace, m_xregister, blockSize); + + // Multiply T by alpha + GF_Double(m_xregister, blockSize); + + inString += blockSize; + outString += blockSize; + length -= blockSize; + } +} + +size_t XTS_ModeBase::ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) +{ + // need at least a full AES block + CRYPTOPP_ASSERT(inLength >= BlockSize()); + + if (inLength < BlockSize()) + throw InvalidArgument("XTS: message is too short for ciphertext stealing"); + + if (IsForwardTransformation()) + return ProcessLastPlainBlock(outString, outLength, inString, inLength); + else + return ProcessLastCipherBlock(outString, outLength, inString, inLength); +} + +size_t XTS_ModeBase::ProcessLastPlainBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) +{ + // ensure output buffer is large enough + CRYPTOPP_ASSERT(outLength >= inLength); + + const unsigned int blockSize = GetBlockCipher().BlockSize(); + const size_t blocks = inLength / blockSize; + const size_t tail = inLength % blockSize; + outLength = inLength; + + if (tail == 0) + { + // Allow ProcessData to handle all the full blocks + ProcessData(outString, inString, inLength); + return inLength; + } + else if (blocks > 1) + { + // Allow ProcessData to handle full blocks except one + const size_t head = (blocks-1)*blockSize; + ProcessData(outString, inString, inLength-head); + + outString += head; + inString += head; inLength -= head; + } + + ///// handle the full block ///// + + // merge the tweak into the input block + XorBuffer(m_xworkspace, inString, m_xregister, blockSize); + + // encrypt one block + GetBlockCipher().ProcessBlock(m_xworkspace); + + // merge the tweak into the output block + XorBuffer(outString, m_xworkspace, m_xregister, blockSize); + + // Multiply T by alpha + GF_Double(m_xregister, blockSize); + + ///// handle final partial block ///// + + inString += blockSize; + outString += blockSize; + const size_t len = inLength-blockSize; + + // copy in the final plaintext bytes + std::memcpy(m_xworkspace, inString, len); + // and copy out the final ciphertext bytes + std::memcpy(outString, outString-blockSize, len); + // "steal" ciphertext to complete the block + std::memcpy(m_xworkspace+len, outString-blockSize+len, blockSize-len); + + // merge the tweak into the input block + XorBuffer(m_xworkspace, m_xregister, blockSize); + + // encrypt one block + GetBlockCipher().ProcessBlock(m_xworkspace); + + // merge the tweak into the previous output block + XorBuffer(outString-blockSize, m_xworkspace, m_xregister, blockSize); + + return outLength; +} + +size_t XTS_ModeBase::ProcessLastCipherBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength) +{ + // ensure output buffer is large enough + CRYPTOPP_ASSERT(outLength >= inLength); + + const unsigned int blockSize = GetBlockCipher().BlockSize(); + const size_t blocks = inLength / blockSize; + const size_t tail = inLength % blockSize; + outLength = inLength; + + if (tail == 0) + { + // Allow ProcessData to handle all the full blocks + ProcessData(outString, inString, inLength); + return inLength; + } + else if (blocks > 1) + { + // Allow ProcessData to handle full blocks except one + const size_t head = (blocks-1)*blockSize; + ProcessData(outString, inString, inLength-head); + + outString += head; + inString += head; inLength -= head; + } + + #define poly1 (m_xregister+0*blockSize) + #define poly2 (m_xregister+1*blockSize) + GF_Double(poly2, poly1, blockSize); + + ///// handle final partial block ///// + + inString += blockSize; + outString += blockSize; + const size_t len = inLength-blockSize; + + // merge the tweak into the input block + XorBuffer(m_xworkspace, inString-blockSize, poly2, blockSize); + + // encrypt one block + GetBlockCipher().ProcessBlock(m_xworkspace); + + // merge the tweak into the output block + XorBuffer(m_xworkspace, poly2, blockSize); + + // copy in the final plaintext bytes + std::memcpy(outString-blockSize, inString, len); + // and copy out the final ciphertext bytes + std::memcpy(outString, m_xworkspace, len); + // "steal" ciphertext to complete the block + std::memcpy(outString-blockSize+len, m_xworkspace+len, blockSize-len); + + ///// handle the full previous block ///// + + inString -= blockSize; + outString -= blockSize; + + // merge the tweak into the input block + XorBuffer(m_xworkspace, outString, poly1, blockSize); + + // encrypt one block + GetBlockCipher().ProcessBlock(m_xworkspace); + + // merge the tweak into the output block + XorBuffer(outString, m_xworkspace, poly1, blockSize); + + return outLength; +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/xts.h b/external/ours/library/crypto/src/shared/original/xts.h new file mode 100755 index 000000000..4ac70e3ed --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/xts.h @@ -0,0 +1,224 @@ +// xts.h - written and placed in the public domain by Jeffrey Walton + +/// \file xts.h +/// \brief Classes for XTS block cipher mode of operation +/// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST +/// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007. +/// IEEE 1619-2007 provides both a reference implementation and test vectors. +/// The IEEE reference implementation fails to arrive at the expected result +/// for some test vectors. +/// \sa Modes of +/// Operation on the Crypto++ wiki, Evaluation of Some +/// Blockcipher Modes of Operation, Recommendation +/// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on +/// Storage Devices, IEEE P1619-2007 +/// and IEEE P1619/XTS, +/// inconsistent reference implementation and test vectors. +/// \since Crypto++ 8.3 + +#ifndef CRYPTOPP_XTS_MODE_H +#define CRYPTOPP_XTS_MODE_H + +#include "cryptlib.h" +#include "secblock.h" +#include "modes.h" +#include "misc.h" + +/// \brief Enable XTS for wide block ciphers +/// \details XTS is only defined for AES. The library can support wide +/// block ciphers like Kaylna and Threefish since we know the polynomials. +/// To enable wide block ciphers define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS +/// to non-zero. Note this is a library compile time define. +/// \details There is risk involved with using XTS with wider block ciphers. +/// According to Phillip Rogaway, "The narrow width of the underlying PRP and +/// the poor treatment of fractional final blocks are problems." +/// \sa Evaluation +/// of Some Blockcipher Modes of Operation +/// \since Crypto++ 8.3 +#ifndef CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS +# define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS 0 +#endif // CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief XTS block cipher mode of operation default implementation +/// \since Crypto++ 8.3 +class CRYPTOPP_NO_VTABLE XTS_ModeBase : public BlockOrientedCipherModeBase +{ +public: + /// \brief The algorithm name + /// \return the algorithm name + /// \details StaticAlgorithmName returns the algorithm's name as a static + /// member function. + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() + {return "XTS";} + + virtual ~XTS_ModeBase() {} + + std::string AlgorithmName() const + {return GetBlockCipher().AlgorithmName() + "/XTS";} + std::string AlgorithmProvider() const + {return GetBlockCipher().AlgorithmProvider();} + + size_t MinKeyLength() const + {return GetBlockCipher().MinKeyLength()*2;} + size_t MaxKeyLength() const + {return GetBlockCipher().MaxKeyLength()*2;} + size_t DefaultKeyLength() const + {return GetBlockCipher().DefaultKeyLength()*2;} + size_t GetValidKeyLength(size_t n) const + {return 2*GetBlockCipher().GetValidKeyLength((n+1)/2);} + bool IsValidKeyLength(size_t keylength) const + {return keylength == GetValidKeyLength(keylength);} + + /// \brief Validates the key length + /// \param length the size of the keying material, in bytes + /// \throw InvalidKeyLength if the key length is invalid + void ThrowIfInvalidKeyLength(size_t length); + + /// Provides the block size of the cipher + /// \return the block size of the cipher, in bytes + unsigned int BlockSize() const + {return GetBlockCipher().BlockSize();} + + /// \brief Provides the input block size most efficient for this cipher + /// \return The input block size that is most efficient for the cipher + /// \details The base class implementation returns MandatoryBlockSize(). + /// \note Optimal input length is + /// n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for + /// any n \> 0. + unsigned int GetOptimalBlockSize() const + {return GetBlockCipher().BlockSize()*ParallelBlocks;} + unsigned int MinLastBlockSize() const + {return GetBlockCipher().BlockSize()+1;} + unsigned int OptimalDataAlignment() const + {return GetBlockCipher().OptimalDataAlignment();} + + /// \brief Validates the block size + /// \param length the block size of the cipher, in bytes + /// \throw InvalidArgument if the block size is invalid + /// \details If CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS is 0, + /// then CIPHER must be a 16-byte block cipher. If + /// CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS is non-zero then + /// CIPHER can be 16, 32, 64, or 128-byte block cipher. + void ThrowIfInvalidBlockSize(size_t length); + + void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); + IV_Requirement IVRequirement() const {return UNIQUE_IV;} + void Resynchronize(const byte *iv, int ivLength=-1); + void ProcessData(byte *outString, const byte *inString, size_t length); + size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); + + /// \brief Resynchronize the cipher + /// \param sector a 64-bit sector number + /// \param order the endian order the word should be written + /// \details The Resynchronize() overload was provided for API + /// compatibility with the IEEE P1619 paper. + void Resynchronize(word64 sector, ByteOrder order=BIG_ENDIAN_ORDER); + +protected: + virtual void ResizeBuffers(); + + inline size_t ProcessLastPlainBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); + inline size_t ProcessLastCipherBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); + + virtual BlockCipher& AccessBlockCipher() = 0; + virtual BlockCipher& AccessTweakCipher() = 0; + + const BlockCipher& GetBlockCipher() const + {return const_cast(this)->AccessBlockCipher();} + const BlockCipher& GetTweakCipher() const + {return const_cast(this)->AccessTweakCipher();} + + // Buffers are sized based on ParallelBlocks + AlignedSecByteBlock m_xregister; + AlignedSecByteBlock m_xworkspace; + + // Intel lacks the SSE registers to run 8 or 12 parallel blocks. + // Do not change this value after compiling. It has no effect. +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 + enum {ParallelBlocks = 4}; +#else + enum {ParallelBlocks = 12}; +#endif +}; + +/// \brief XTS block cipher mode of operation implementation +/// \tparam CIPHER BlockCipher derived class or type +/// \details XTS_Final() provides access to CIPHER in base class XTS_ModeBase() +/// through an interface. AccessBlockCipher() and AccessTweakCipher() allow +/// the XTS_ModeBase() base class to access the user's block cipher without +/// recompiling the library. +/// \details If CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS is 0, then CIPHER must +/// be a 16-byte block cipher. If CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS is +/// non-zero then CIPHER can be 16, 32, 64, or 128-byte block cipher. +/// There is risk involved with using XTS with wider block ciphers. +/// According to Phillip Rogaway, "The narrow width of the underlying PRP and +/// the poor treatment of fractional final blocks are problems." To enable +/// wide block cipher support define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS to +/// non-zero. +/// \sa Modes of +/// Operation on the Crypto++ wiki, Evaluation of Some +/// Blockcipher Modes of Operation, Recommendation +/// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on +/// Storage Devices, IEEE P1619-2007 +/// and IEEE P1619/XTS, +/// inconsistent reference implementation and test vectors. +/// \since Crypto++ 8.3 +template +class CRYPTOPP_NO_VTABLE XTS_Final : public XTS_ModeBase +{ +protected: + BlockCipher& AccessBlockCipher() + {return *m_cipher;} + BlockCipher& AccessTweakCipher() + {return m_tweaker;} + +protected: + typename CIPHER::Encryption m_tweaker; +}; + +/// \brief XTS block cipher mode of operation +/// \tparam CIPHER BlockCipher derived class or type +/// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST +/// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007. +/// IEEE 1619-2007 provides both a reference implementation and test vectors. +/// The IEEE reference implementation fails to arrive at the expected result +/// for some test vectors. +/// \details XTS is only defined for AES. The library can support wide +/// block ciphers like Kaylna and Threefish since we know the polynomials. +/// There is risk involved with using XTS with wider block ciphers. +/// According to Phillip Rogaway, "The narrow width of the underlying PRP and +/// the poor treatment of fractional final blocks are problems." To enable +/// wide block cipher support define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS to +/// non-zero. +/// \sa Modes of +/// Operation on the Crypto++ wiki, Evaluation of Some +/// Blockcipher Modes of Operation, Recommendation +/// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on +/// Storage Devices, IEEE P1619-2007 +/// and IEEE P1619/XTS, +/// inconsistent reference implementation and test vectors. +/// \since Crypto++ 8.3 +template +struct XTS : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > Encryption; + typedef CipherModeFinalTemplate_CipherHolder > Decryption; +}; + +// C++03 lacks the mechanics to typedef a template +#define XTS_Mode XTS + +NAMESPACE_END + +#endif // CRYPTOPP_XTS_MODE_H diff --git a/external/ours/library/crypto/src/shared/original/zdeflate.cpp b/external/ours/library/crypto/src/shared/original/zdeflate.cpp new file mode 100755 index 000000000..44413ab5e --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/zdeflate.cpp @@ -0,0 +1,821 @@ +// zdeflate.cpp - originally written and placed in the public domain by Wei Dai + +// Many of the algorithms and tables used here came from the deflate implementation +// by Jean-loup Gailly, which was included in Crypto++ 4.0 and earlier. I completely +// rewrote it in order to fix a bug that I could not figure out. This code +// is less clever, but hopefully more understandable and maintainable. + +#include "pch.h" +#include "zdeflate.h" +#include "stdcpp.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if (defined(_MSC_VER) && (_MSC_VER < 1400)) && !defined(__MWERKS__) + // VC60 and VC7 workaround: built-in std::reverse_iterator has two template parameters, Dinkumware only has one + typedef std::reverse_bidirectional_iterator RevIt; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator RevIt; +#else + typedef std::reverse_iterator RevIt; +#endif + +LowFirstBitWriter::LowFirstBitWriter(BufferedTransformation *attachment) + : Filter(attachment), m_counting(false), m_bitCount(0), m_buffer(0) + , m_bitsBuffered(0), m_bytesBuffered(0) +{ +} + +void LowFirstBitWriter::StartCounting() +{ + CRYPTOPP_ASSERT(!m_counting); + m_counting = true; + m_bitCount = 0; +} + +unsigned long LowFirstBitWriter::FinishCounting() +{ + CRYPTOPP_ASSERT(m_counting); + m_counting = false; + return m_bitCount; +} + +void LowFirstBitWriter::PutBits(unsigned long value, unsigned int length) +{ + if (m_counting) + m_bitCount += length; + else + { + m_buffer |= value << m_bitsBuffered; + m_bitsBuffered += length; + CRYPTOPP_ASSERT(m_bitsBuffered <= sizeof(unsigned long)*8); + while (m_bitsBuffered >= 8) + { + m_outputBuffer[m_bytesBuffered++] = (byte)m_buffer; + if (m_bytesBuffered == m_outputBuffer.size()) + { + AttachedTransformation()->PutModifiable(m_outputBuffer, m_bytesBuffered); + m_bytesBuffered = 0; + } + m_buffer >>= 8; + m_bitsBuffered -= 8; + } + } +} + +void LowFirstBitWriter::FlushBitBuffer() +{ + if (m_counting) + m_bitCount += 8*(m_bitsBuffered > 0); + else + { + if (m_bytesBuffered > 0) + { + AttachedTransformation()->PutModifiable(m_outputBuffer, m_bytesBuffered); + m_bytesBuffered = 0; + } + if (m_bitsBuffered > 0) + { + AttachedTransformation()->Put((byte)m_buffer); + m_buffer = 0; + m_bitsBuffered = 0; + } + } +} + +void LowFirstBitWriter::ClearBitBuffer() +{ + m_buffer = 0; + m_bytesBuffered = 0; + m_bitsBuffered = 0; +} + +HuffmanEncoder::HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes) +{ + Initialize(codeBits, nCodes); +} + +struct HuffmanNode +{ + HuffmanNode() + : symbol(0), parent(0) {} + HuffmanNode(const HuffmanNode& rhs) + : symbol(rhs.symbol), parent(rhs.parent) {} + HuffmanNode& operator=(const HuffmanNode& rhs) + { + // No this guard + symbol = rhs.symbol; + parent = rhs.parent; + return *this; + } + + size_t symbol; + union {size_t parent; unsigned depth, freq;}; +}; + +struct FreqLessThan +{ + inline bool operator()(unsigned int lhs, const HuffmanNode &rhs) {return lhs < rhs.freq;} + inline bool operator()(const HuffmanNode &lhs, const HuffmanNode &rhs) const {return lhs.freq < rhs.freq;} + // needed for MSVC .NET 2005 + inline bool operator()(const HuffmanNode &lhs, unsigned int rhs) {return lhs.freq < rhs;} +}; + +void HuffmanEncoder::GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes) +{ + CRYPTOPP_ASSERT(nCodes > 0); + CRYPTOPP_ASSERT(nCodes <= ((size_t)1 << maxCodeBits)); + + size_t i; + SecBlockWithHint tree(nCodes); + for (i=0; i= 2) + for (i=tree.size()-2; i>=nCodes; i--) + tree[i].depth = tree[tree[i].parent].depth + 1; + unsigned int sum = 0; + SecBlockWithHint blCount(maxCodeBits+1); + std::fill(blCount.begin(), blCount.end(), 0); + for (i=treeBegin; i (unsigned int)(1 << maxCodeBits) ? sum - (1 << maxCodeBits) : 0; + + while (overflow--) + { + unsigned int bits = maxCodeBits-1; + while (blCount[bits] == 0) + bits--; + blCount[bits]--; + blCount[bits+1] += 2; + CRYPTOPP_ASSERT(blCount[maxCodeBits] > 0); + blCount[maxCodeBits]--; + } + + for (i=0; i 0); + unsigned int maxCodeBits = *std::max_element(codeBits, codeBits+nCodes); + if (maxCodeBits == 0) + return; // assume this object won't be used + + SecBlockWithHint blCount(maxCodeBits+1); + std::fill(blCount.begin(), blCount.end(), 0); + unsigned int i; + for (i=0; i nextCode(maxCodeBits+1); + nextCode[1] = 0; + for (i=2; i<=maxCodeBits; i++) + { + code = (code + blCount[i-1]) << 1; + nextCode[i] = code; + } + CRYPTOPP_ASSERT(maxCodeBits == 1 || code == (1 << maxCodeBits) - blCount[maxCodeBits]); + + m_valueToCode.resize(nCodes); + for (i=0; i> (8*sizeof(code_t)-len); + } +} + +inline void HuffmanEncoder::Encode(LowFirstBitWriter &writer, value_t value) const +{ + CRYPTOPP_ASSERT(m_valueToCode[value].len > 0); + writer.PutBits(m_valueToCode[value].code, m_valueToCode[value].len); +} + +Deflator::Deflator(BufferedTransformation *attachment, int deflateLevel, int log2WindowSize, bool detectUncompressible) + : LowFirstBitWriter(attachment) + , m_deflateLevel(-1) +{ + InitializeStaticEncoders(); + Deflator::IsolatedInitialize(MakeParameters("DeflateLevel", deflateLevel)("Log2WindowSize", log2WindowSize)("DetectUncompressible", detectUncompressible)); +} + +Deflator::Deflator(const NameValuePairs ¶meters, BufferedTransformation *attachment) + : LowFirstBitWriter(attachment) + , m_deflateLevel(-1) +{ + InitializeStaticEncoders(); + Deflator::IsolatedInitialize(parameters); +} + +void Deflator::InitializeStaticEncoders() +{ + unsigned int codeLengths[288]; + std::fill(codeLengths + 0, codeLengths + 144, 8); + std::fill(codeLengths + 144, codeLengths + 256, 9); + std::fill(codeLengths + 256, codeLengths + 280, 7); + std::fill(codeLengths + 280, codeLengths + 288, 8); + m_staticLiteralEncoder.Initialize(codeLengths, 288); + std::fill(codeLengths + 0, codeLengths + 32, 5); + m_staticDistanceEncoder.Initialize(codeLengths, 32); +} + +void Deflator::IsolatedInitialize(const NameValuePairs ¶meters) +{ + int log2WindowSize = parameters.GetIntValueWithDefault("Log2WindowSize", DEFAULT_LOG2_WINDOW_SIZE); + if (!(MIN_LOG2_WINDOW_SIZE <= log2WindowSize && log2WindowSize <= MAX_LOG2_WINDOW_SIZE)) + throw InvalidArgument("Deflator: " + IntToString(log2WindowSize) + " is an invalid window size"); + + m_log2WindowSize = log2WindowSize; + DSIZE = 1 << m_log2WindowSize; + DMASK = DSIZE - 1; + HSIZE = 1 << m_log2WindowSize; + HMASK = HSIZE - 1; + m_byteBuffer.New(2*DSIZE); + m_head.New(HSIZE); + m_prev.New(DSIZE); + m_matchBuffer.New(DSIZE/2); + Reset(true); + + const int deflateLevel = parameters.GetIntValueWithDefault("DeflateLevel", DEFAULT_DEFLATE_LEVEL); + CRYPTOPP_ASSERT(deflateLevel >= MIN_DEFLATE_LEVEL /*0*/ && deflateLevel <= MAX_DEFLATE_LEVEL /*9*/); + SetDeflateLevel(deflateLevel); + bool detectUncompressible = parameters.GetValueWithDefault("DetectUncompressible", true); + m_compressibleDeflateLevel = detectUncompressible ? m_deflateLevel : 0; +} + +void Deflator::Reset(bool forceReset) +{ + if (forceReset) + ClearBitBuffer(); + else + CRYPTOPP_ASSERT(m_bitsBuffered == 0); + + m_headerWritten = false; + m_matchAvailable = false; + m_dictionaryEnd = 0; + m_stringStart = 0; + m_lookahead = 0; + m_minLookahead = MAX_MATCH; + m_matchBufferEnd = 0; + m_blockStart = 0; + m_blockLength = 0; + + m_detectCount = 1; + m_detectSkip = 0; + + // m_prev will be initialized automatically in InsertString + std::fill(m_head.begin(), m_head.end(), byte(0)); + + std::fill(m_literalCounts.begin(), m_literalCounts.end(), byte(0)); + std::fill(m_distanceCounts.begin(), m_distanceCounts.end(), byte(0)); +} + +void Deflator::SetDeflateLevel(int deflateLevel) +{ + if (!(MIN_DEFLATE_LEVEL <= deflateLevel && deflateLevel <= MAX_DEFLATE_LEVEL)) + throw InvalidArgument("Deflator: " + IntToString(deflateLevel) + " is an invalid deflate level"); + + if (deflateLevel == m_deflateLevel) + return; + + EndBlock(false); + + static const unsigned int configurationTable[10][4] = { + /* good lazy nice chain */ + /* 0 */ {0, 0, 0, 0}, /* store only */ + /* 1 */ {4, 3, 8, 4}, /* maximum speed, no lazy matches */ + /* 2 */ {4, 3, 16, 8}, + /* 3 */ {4, 3, 32, 32}, + /* 4 */ {4, 4, 16, 16}, /* lazy matches */ + /* 5 */ {8, 16, 32, 32}, + /* 6 */ {8, 16, 128, 128}, + /* 7 */ {8, 32, 128, 256}, + /* 8 */ {32, 128, 258, 1024}, + /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ + + GOOD_MATCH = configurationTable[deflateLevel][0]; + MAX_LAZYLENGTH = configurationTable[deflateLevel][1]; + MAX_CHAIN_LENGTH = configurationTable[deflateLevel][3]; + + m_deflateLevel = deflateLevel; +} + +unsigned int Deflator::FillWindow(const byte *str, size_t length) +{ + unsigned int maxBlockSize = (unsigned int)STDMIN(2UL*DSIZE, 0xffffUL); + + if (m_stringStart >= maxBlockSize - MAX_MATCH) + { + if (m_blockStart < DSIZE) + EndBlock(false); + + memcpy(m_byteBuffer, m_byteBuffer + DSIZE, DSIZE); + + m_dictionaryEnd = m_dictionaryEnd < DSIZE ? 0 : m_dictionaryEnd-DSIZE; + CRYPTOPP_ASSERT(m_stringStart >= DSIZE); + m_stringStart -= DSIZE; + CRYPTOPP_ASSERT(!m_matchAvailable || m_previousMatch >= DSIZE); + m_previousMatch -= DSIZE; + CRYPTOPP_ASSERT(m_blockStart >= DSIZE); + m_blockStart -= DSIZE; + + // These are set to the same value in IsolatedInitialize(). If they + // are the same, then we can clear a Coverity false alarm. + CRYPTOPP_ASSERT(DSIZE == HSIZE); + + unsigned int i; + for (i=0; i m_stringStart+m_lookahead); + unsigned int accepted = UnsignedMin(maxBlockSize-(m_stringStart+m_lookahead), length); + CRYPTOPP_ASSERT(accepted > 0); + memcpy(m_byteBuffer + m_stringStart + m_lookahead, str, accepted); + m_lookahead += accepted; + return accepted; +} + +inline unsigned int Deflator::ComputeHash(const byte *str) const +{ + CRYPTOPP_ASSERT(str+3 <= m_byteBuffer + m_stringStart + m_lookahead); + return ((str[0] << 10) ^ (str[1] << 5) ^ str[2]) & HMASK; +} + +unsigned int Deflator::LongestMatch(unsigned int &bestMatch) const +{ + CRYPTOPP_ASSERT(m_previousLength < MAX_MATCH); + + bestMatch = 0; + unsigned int bestLength = STDMAX(m_previousLength, (unsigned int)MIN_MATCH-1); + if (m_lookahead <= bestLength) + return 0; + + const byte *scan = m_byteBuffer + m_stringStart, *scanEnd = scan + STDMIN((unsigned int)MAX_MATCH, m_lookahead); + unsigned int limit = m_stringStart > (DSIZE-MAX_MATCH) ? m_stringStart - (DSIZE-MAX_MATCH) : 0; + unsigned int current = m_head[ComputeHash(scan)]; + + unsigned int chainLength = MAX_CHAIN_LENGTH; + if (m_previousLength >= GOOD_MATCH) + chainLength >>= 2; + + while (current > limit && --chainLength > 0) + { + const byte *match = m_byteBuffer + current; + CRYPTOPP_ASSERT(scan + bestLength < m_byteBuffer + m_stringStart + m_lookahead); + if (scan[bestLength-1] == match[bestLength-1] && scan[bestLength] == match[bestLength] && scan[0] == match[0] && scan[1] == match[1]) + { + CRYPTOPP_ASSERT(scan[2] == match[2]); + unsigned int len = (unsigned int)( +#if defined(_STDEXT_BEGIN) && !(defined(_MSC_VER) && (_MSC_VER < 1400 || _MSC_VER >= 1600)) && !defined(_STLPORT_VERSION) + stdext::unchecked_mismatch +#else + std::mismatch +#endif +#if _MSC_VER >= 1600 + (stdext::make_unchecked_array_iterator(scan)+3, stdext::make_unchecked_array_iterator(scanEnd), stdext::make_unchecked_array_iterator(match)+3).first - stdext::make_unchecked_array_iterator(scan)); +#else + (scan+3, scanEnd, match+3).first - scan); +#endif + CRYPTOPP_ASSERT(len != bestLength); + if (len > bestLength) + { + bestLength = len; + bestMatch = current; + + CRYPTOPP_ASSERT(scanEnd >= scan); + if (len == (unsigned int)(scanEnd - scan)) + break; + } + } + current = m_prev[current & DMASK]; + } + return (bestMatch > 0) ? bestLength : 0; +} + +inline void Deflator::InsertString(unsigned int start) +{ + CRYPTOPP_ASSERT(start <= 0xffff); + unsigned int hash = ComputeHash(m_byteBuffer + start); + m_prev[start & DMASK] = m_head[hash]; + m_head[hash] = word16(start); +} + +void Deflator::ProcessBuffer() +{ + if (!m_headerWritten) + { + WritePrestreamHeader(); + m_headerWritten = true; + } + + if (m_deflateLevel == 0) + { + m_stringStart += m_lookahead; + m_lookahead = 0; + m_blockLength = m_stringStart - m_blockStart; + m_matchAvailable = false; + return; + } + + while (m_lookahead > m_minLookahead) + { + while (m_dictionaryEnd < m_stringStart && m_dictionaryEnd+3 <= m_stringStart+m_lookahead) + InsertString(m_dictionaryEnd++); + + if (m_matchAvailable) + { + unsigned int matchPosition = 0, matchLength = 0; + bool usePreviousMatch; + if (m_previousLength >= MAX_LAZYLENGTH) + usePreviousMatch = true; + else + { + matchLength = LongestMatch(matchPosition); + usePreviousMatch = (matchLength == 0); + } + if (usePreviousMatch) + { + MatchFound(m_stringStart-1-m_previousMatch, m_previousLength); + m_stringStart += m_previousLength-1; + m_lookahead -= m_previousLength-1; + m_matchAvailable = false; + } + else + { + m_previousLength = matchLength; + m_previousMatch = matchPosition; + LiteralByte(m_byteBuffer[m_stringStart-1]); + m_stringStart++; + m_lookahead--; + } + } + else + { + m_previousLength = 0; + m_previousLength = LongestMatch(m_previousMatch); + if (m_previousLength) + m_matchAvailable = true; + else + LiteralByte(m_byteBuffer[m_stringStart]); + m_stringStart++; + m_lookahead--; + } + + CRYPTOPP_ASSERT(m_stringStart - (m_blockStart+m_blockLength) == (unsigned int)m_matchAvailable); + } + + if (m_minLookahead == 0 && m_matchAvailable) + { + LiteralByte(m_byteBuffer[m_stringStart-1]); + m_matchAvailable = false; + } +} + +size_t Deflator::Put2(const byte *str, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Deflator"); + + size_t accepted = 0; + while (accepted < length) + { + unsigned int newAccepted = FillWindow(str+accepted, length-accepted); + ProcessBuffer(); + // call ProcessUncompressedData() after WritePrestreamHeader() + ProcessUncompressedData(str+accepted, newAccepted); + accepted += newAccepted; + } + CRYPTOPP_ASSERT(accepted == length); + + if (messageEnd) + { + m_minLookahead = 0; + ProcessBuffer(); + EndBlock(true); + FlushBitBuffer(); + WritePoststreamTail(); + Reset(); + } + + Output(0, NULLPTR, 0, messageEnd, blocking); + return 0; +} + +bool Deflator::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Deflator"); + + m_minLookahead = 0; + ProcessBuffer(); + m_minLookahead = MAX_MATCH; + EndBlock(false); + if (hardFlush) + EncodeBlock(false, STORED); + return false; +} + +void Deflator::LiteralByte(byte b) +{ + if (m_matchBufferEnd == m_matchBuffer.size()) + EndBlock(false); + + m_matchBuffer[m_matchBufferEnd++].literalCode = b; + m_literalCounts[b]++; + m_blockLength++; +} + +void Deflator::MatchFound(unsigned int distance, unsigned int length) +{ + if (m_matchBufferEnd == m_matchBuffer.size()) + EndBlock(false); + + static const unsigned int lengthCodes[] = { + 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, + 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, + 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, + 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285}; + static const unsigned int lengthBases[] = + {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195, + 227,258}; + static const unsigned int distanceBases[30] = + {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073, + 4097,6145,8193,12289,16385,24577}; + + CRYPTOPP_ASSERT(m_matchBufferEnd < m_matchBuffer.size()); + EncodedMatch &m = m_matchBuffer[m_matchBufferEnd++]; + CRYPTOPP_ASSERT((length >= 3) && (length-3 < COUNTOF(lengthCodes))); + unsigned int lengthCode = lengthCodes[length-3]; + m.literalCode = lengthCode; + m.literalExtra = length - lengthBases[lengthCode-257]; + unsigned int distanceCode = (unsigned int)(std::upper_bound(distanceBases, distanceBases+30, distance) - distanceBases - 1); + m.distanceCode = distanceCode; + m.distanceExtra = distance - distanceBases[distanceCode]; + + m_literalCounts[lengthCode]++; + m_distanceCounts[distanceCode]++; + m_blockLength += length; +} + +inline unsigned int CodeLengthEncode(const unsigned int *begin, + const unsigned int *end, + const unsigned int *& p, + unsigned int &extraBits, + unsigned int &extraBitsLength) +{ + unsigned int v = *p; + if ((end-p) >= 3) + { + const unsigned int *oldp = p; + if (v==0 && p[1]==0 && p[2]==0) + { + for (p=p+3; p!=end && *p==0 && p!=oldp+138; p++) {} + unsigned int repeat = (unsigned int)(p - oldp); + if (repeat <= 10) + { + extraBits = repeat-3; + extraBitsLength = 3; + return 17; + } + else + { + extraBits = repeat-11; + extraBitsLength = 7; + return 18; + } + } + else if (p!=begin && v==p[-1] && v==p[1] && v==p[2]) + { + for (p=p+3; p!=end && *p==v && p!=oldp+6; p++) {} + unsigned int repeat = (unsigned int)(p - oldp); + extraBits = repeat-3; + extraBitsLength = 2; + return 16; + } + } + p++; + extraBits = 0; + extraBitsLength = 0; + return v; +} + +void Deflator::EncodeBlock(bool eof, unsigned int blockType) +{ + PutBits(eof, 1); + PutBits(blockType, 2); + + if (blockType == STORED) + { + CRYPTOPP_ASSERT(m_blockStart + m_blockLength <= m_byteBuffer.size()); + CRYPTOPP_ASSERT(m_blockLength <= 0xffff); + FlushBitBuffer(); + AttachedTransformation()->PutWord16(word16(m_blockLength), LITTLE_ENDIAN_ORDER); + AttachedTransformation()->PutWord16(word16(~m_blockLength), LITTLE_ENDIAN_ORDER); + AttachedTransformation()->Put(m_byteBuffer + m_blockStart, m_blockLength); + } + else + { + if (blockType == DYNAMIC) + { + FixedSizeSecBlock literalCodeLengths; + FixedSizeSecBlock distanceCodeLengths; + + m_literalCounts[256] = 1; + HuffmanEncoder::GenerateCodeLengths(literalCodeLengths, 15, m_literalCounts, 286); + m_dynamicLiteralEncoder.Initialize(literalCodeLengths, 286); + unsigned int hlit = (unsigned int)(FindIfNot(RevIt(literalCodeLengths.end()), RevIt(literalCodeLengths.begin()+257), 0).base() - (literalCodeLengths.begin()+257)); + + HuffmanEncoder::GenerateCodeLengths(distanceCodeLengths, 15, m_distanceCounts, 30); + m_dynamicDistanceEncoder.Initialize(distanceCodeLengths, 30); + unsigned int hdist = (unsigned int)(FindIfNot(RevIt(distanceCodeLengths.end()), RevIt(distanceCodeLengths.begin()+1), 0).base() - (distanceCodeLengths.begin()+1)); + + SecBlockWithHint combinedLengths(hlit+257+hdist+1); + memcpy(combinedLengths, literalCodeLengths, (hlit+257)*sizeof(unsigned int)); + memcpy(combinedLengths+hlit+257, distanceCodeLengths, (hdist+1)*sizeof(unsigned int)); + + FixedSizeSecBlock codeLengthCodeCounts, codeLengthCodeLengths; + std::fill(codeLengthCodeCounts.begin(), codeLengthCodeCounts.end(), 0); + const unsigned int *p = combinedLengths.begin(), *begin = combinedLengths.begin(), *end = combinedLengths.end(); + while (p != end) + { + unsigned int code=0, extraBits=0, extraBitsLength=0; + code = CodeLengthEncode(begin, end, p, extraBits, extraBitsLength); + codeLengthCodeCounts[code]++; + } + HuffmanEncoder::GenerateCodeLengths(codeLengthCodeLengths, 7, codeLengthCodeCounts, 19); + HuffmanEncoder codeLengthEncoder(codeLengthCodeLengths, 19); + static const unsigned int border[] = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + unsigned int hclen = 19; + while (hclen > 4 && codeLengthCodeLengths[border[hclen-1]] == 0) + hclen--; + hclen -= 4; + + PutBits(hlit, 5); + PutBits(hdist, 5); + PutBits(hclen, 4); + + for (unsigned int i=0; i= 257) + { + CRYPTOPP_ASSERT(literalCode <= 285); + PutBits(m_matchBuffer[i].literalExtra, lengthExtraBits[literalCode-257]); + unsigned int distanceCode = m_matchBuffer[i].distanceCode; + distanceEncoder.Encode(*this, distanceCode); + PutBits(m_matchBuffer[i].distanceExtra, distanceExtraBits[distanceCode]); + } + } + literalEncoder.Encode(*this, 256); // end of block + } +} + +void Deflator::EndBlock(bool eof) +{ + if (m_blockLength == 0 && !eof) + return; + + if (m_deflateLevel == 0) + { + EncodeBlock(eof, STORED); + + if (m_compressibleDeflateLevel > 0 && ++m_detectCount == m_detectSkip) + { + m_deflateLevel = m_compressibleDeflateLevel; + m_detectCount = 1; + } + } + else + { + unsigned long storedLen = 8*((unsigned long)m_blockLength+4) + RoundUpToMultipleOf(m_bitsBuffered+3, 8U)-m_bitsBuffered; + + StartCounting(); + EncodeBlock(eof, STATIC); + unsigned long staticLen = FinishCounting(); + + unsigned long dynamicLen; + if (m_blockLength < 128 && m_deflateLevel < 8) + dynamicLen = ULONG_MAX; + else + { + StartCounting(); + EncodeBlock(eof, DYNAMIC); + dynamicLen = FinishCounting(); + } + + if (storedLen <= staticLen && storedLen <= dynamicLen) + { + EncodeBlock(eof, STORED); + + if (m_compressibleDeflateLevel > 0) + { + if (m_detectSkip) + m_deflateLevel = 0; + m_detectSkip = m_detectSkip ? STDMIN(2*m_detectSkip, 128U) : 1; + } + } + else + { + if (staticLen <= dynamicLen) + EncodeBlock(eof, STATIC); + else + EncodeBlock(eof, DYNAMIC); + + if (m_compressibleDeflateLevel > 0) + m_detectSkip = 0; + } + } + + m_matchBufferEnd = 0; + m_blockStart += m_blockLength; + m_blockLength = 0; + std::fill(m_literalCounts.begin(), m_literalCounts.end(), 0); + std::fill(m_distanceCounts.begin(), m_distanceCounts.end(), 0); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/zdeflate.h b/external/ours/library/crypto/src/shared/original/zdeflate.h new file mode 100755 index 000000000..b72f5416d --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/zdeflate.h @@ -0,0 +1,174 @@ +// zdeflate.h - originally written and placed in the public domain by Wei Dai + +/// \file zdeflate.h +/// \brief DEFLATE compression and decompression (RFC 1951) + +#ifndef CRYPTOPP_ZDEFLATE_H +#define CRYPTOPP_ZDEFLATE_H + +#include "cryptlib.h" +#include "filters.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief Encoding table writer +/// \since Crypto++ 1.0 +class LowFirstBitWriter : public Filter +{ +public: + /// \brief Construct a LowFirstBitWriter + /// \param attachment an attached transformation + LowFirstBitWriter(BufferedTransformation *attachment); + + void PutBits(unsigned long value, unsigned int length); + void FlushBitBuffer(); + void ClearBitBuffer(); + + void StartCounting(); + unsigned long FinishCounting(); + +protected: + bool m_counting; + unsigned long m_bitCount; + unsigned long m_buffer; + unsigned int m_bitsBuffered, m_bytesBuffered; + FixedSizeSecBlock m_outputBuffer; +}; + +/// \brief Huffman Encoder +/// \since Crypto++ 1.0 +class HuffmanEncoder +{ +public: + typedef unsigned int code_t; + typedef unsigned int value_t; + + /// \brief Construct a HuffmanEncoder + HuffmanEncoder() {} + + /// \brief Construct a HuffmanEncoder + /// \param codeBits a table of code bits + /// \param nCodes the number of codes in the table + HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes); + + /// \brief Initialize or reinitialize this object + /// \param codeBits a table of code bits + /// \param nCodes the number of codes in the table + void Initialize(const unsigned int *codeBits, unsigned int nCodes); + + static void GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes); + + void Encode(LowFirstBitWriter &writer, value_t value) const; + + struct Code + { + unsigned int code; + unsigned int len; + }; + + SecBlock m_valueToCode; +}; + +/// \brief DEFLATE compressor (RFC 1951) +/// \since Crypto++ 1.0 +class Deflator : public LowFirstBitWriter +{ +public: + /// \brief Deflate level as enumerated values. + enum { + /// \brief Minimum deflation level, fastest speed (0) + MIN_DEFLATE_LEVEL = 0, + /// \brief Default deflation level, compromise between speed (6) + DEFAULT_DEFLATE_LEVEL = 6, + /// \brief Minimum deflation level, slowest speed (9) + MAX_DEFLATE_LEVEL = 9}; + + /// \brief Windows size as enumerated values. + enum { + /// \brief Minimum window size, smallest table (9) + MIN_LOG2_WINDOW_SIZE = 9, + /// \brief Default window size (15) + DEFAULT_LOG2_WINDOW_SIZE = 15, + /// \brief Maximum window size, largest table (15) + MAX_LOG2_WINDOW_SIZE = 15}; + + /// \brief Construct a Deflator compressor + /// \param attachment an attached transformation + /// \param deflateLevel the deflate level + /// \param log2WindowSize the window size + /// \param detectUncompressible flag to detect if data is compressible + /// \details detectUncompressible makes it faster to process uncompressible files, but + /// if a file has both compressible and uncompressible parts, it may fail to compress + /// some of the compressible parts. + Deflator(BufferedTransformation *attachment=NULLPTR, int deflateLevel=DEFAULT_DEFLATE_LEVEL, int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true); + /// \brief Construct a Deflator compressor + /// \param parameters a set of NameValuePairs to initialize this object + /// \param attachment an attached transformation + /// \details Possible parameter names: Log2WindowSize, DeflateLevel, DetectUncompressible + Deflator(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULLPTR); + + /// \brief Sets the deflation level + /// \param deflateLevel the level of deflation + /// \details SetDeflateLevel can be used to set the deflate level in the middle of compression + void SetDeflateLevel(int deflateLevel); + + /// \brief Retrieves the deflation level + /// \return the level of deflation + int GetDeflateLevel() const {return m_deflateLevel;} + + /// \brief Retrieves the window size + /// \return the windows size + int GetLog2WindowSize() const {return m_log2WindowSize;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + +protected: + virtual void WritePrestreamHeader() {} + virtual void ProcessUncompressedData(const byte *string, size_t length) + {CRYPTOPP_UNUSED(string), CRYPTOPP_UNUSED(length);} + virtual void WritePoststreamTail() {} + + enum {STORED = 0, STATIC = 1, DYNAMIC = 2}; + enum {MIN_MATCH = 3, MAX_MATCH = 258}; + + void InitializeStaticEncoders(); + void Reset(bool forceReset = false); + unsigned int FillWindow(const byte *str, size_t length); + unsigned int ComputeHash(const byte *str) const; + unsigned int LongestMatch(unsigned int &bestMatch) const; + void InsertString(unsigned int start); + void ProcessBuffer(); + + void LiteralByte(byte b); + void MatchFound(unsigned int distance, unsigned int length); + void EncodeBlock(bool eof, unsigned int blockType); + void EndBlock(bool eof); + + struct EncodedMatch + { + unsigned literalCode : 9; + unsigned literalExtra : 5; + unsigned distanceCode : 5; + unsigned distanceExtra : 13; + }; + + int m_deflateLevel, m_log2WindowSize, m_compressibleDeflateLevel; + unsigned int m_detectSkip, m_detectCount; + unsigned int DSIZE, DMASK, HSIZE, HMASK, GOOD_MATCH, MAX_LAZYLENGTH, MAX_CHAIN_LENGTH; + bool m_headerWritten, m_matchAvailable; + unsigned int m_dictionaryEnd, m_stringStart, m_lookahead, m_minLookahead, m_previousMatch, m_previousLength; + HuffmanEncoder m_staticLiteralEncoder, m_staticDistanceEncoder, m_dynamicLiteralEncoder, m_dynamicDistanceEncoder; + SecByteBlock m_byteBuffer; + SecBlock m_head, m_prev; + FixedSizeSecBlock m_literalCounts; + FixedSizeSecBlock m_distanceCounts; + SecBlock m_matchBuffer; + unsigned int m_matchBufferEnd, m_blockStart, m_blockLength; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/zinflate.cpp b/external/ours/library/crypto/src/shared/original/zinflate.cpp new file mode 100755 index 000000000..859912647 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/zinflate.cpp @@ -0,0 +1,662 @@ +// zinflate.cpp - originally written and placed in the public domain by Wei Dai + +// This is a complete reimplementation of the DEFLATE decompression algorithm. +// It should not be affected by any security vulnerabilities in the zlib +// compression library. In particular it is not affected by the double free bug +// (http://www.kb.cert.org/vuls/id/368819). + +#include "pch.h" + +#include "zinflate.h" +#include "secblock.h" +#include "smartptr.h" + +NAMESPACE_BEGIN(CryptoPP) + +struct CodeLessThan +{ + inline bool operator()(CryptoPP::HuffmanDecoder::code_t lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) + {return lhs < rhs.code;} + // needed for MSVC .NET 2005 + inline bool operator()(const CryptoPP::HuffmanDecoder::CodeInfo &lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) + {return lhs.code < rhs.code;} +}; + +inline bool LowFirstBitReader::FillBuffer(unsigned int length) +{ + while (m_bitsBuffered < length) + { + byte b; + if (!m_store.Get(b)) + return false; + m_buffer |= (unsigned long)b << m_bitsBuffered; + m_bitsBuffered += 8; + } + CRYPTOPP_ASSERT(m_bitsBuffered <= sizeof(unsigned long)*8); + return true; +} + +inline unsigned long LowFirstBitReader::PeekBits(unsigned int length) +{ + bool result = FillBuffer(length); + CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result); + return m_buffer & (((unsigned long)1 << length) - 1); +} + +inline void LowFirstBitReader::SkipBits(unsigned int length) +{ + CRYPTOPP_ASSERT(m_bitsBuffered >= length); + m_buffer >>= length; + m_bitsBuffered -= length; +} + +inline unsigned long LowFirstBitReader::GetBits(unsigned int length) +{ + unsigned long result = PeekBits(length); + SkipBits(length); + return result; +} + +inline HuffmanDecoder::code_t HuffmanDecoder::NormalizeCode(HuffmanDecoder::code_t code, unsigned int codeBits) +{ + return code << (MAX_CODE_BITS - codeBits); +} + +void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes) +{ + // the Huffman codes are represented in 3 ways in this code: + // + // 1. most significant code bit (i.e. top of code tree) in the least significant bit position + // 2. most significant code bit (i.e. top of code tree) in the most significant bit position + // 3. most significant code bit (i.e. top of code tree) in n-th least significant bit position, + // where n is the maximum code length for this code tree + // + // (1) is the way the codes come in from the deflate stream + // (2) is used to sort codes so they can be binary searched + // (3) is used in this function to compute codes from code lengths + // + // a code in representation (2) is called "normalized" here + // The BitReverse() function is used to convert between (1) and (2) + // The NormalizeCode() function is used to convert from (3) to (2) + + if (nCodes == 0) + throw Err("null code"); + + m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes); + + if (m_maxCodeBits > MAX_CODE_BITS) + throw Err("code length exceeds maximum"); + + if (m_maxCodeBits == 0) + throw Err("null code"); + + // count number of codes of each length + SecBlockWithHint blCount(m_maxCodeBits+1); + std::fill(blCount.begin(), blCount.end(), 0); + unsigned int i; + for (i=0; i nextCode(m_maxCodeBits+1); + nextCode[1] = 0; + for (i=2; i<=m_maxCodeBits; i++) + { + // compute this while checking for overflow: code = (code + blCount[i-1]) << 1 + if (code > code + blCount[i-1]) + throw Err("codes oversubscribed"); + code += blCount[i-1]; + if (code > (code << 1)) + throw Err("codes oversubscribed"); + code <<= 1; + nextCode[i] = code; + } + + // MAX_CODE_BITS is 32, m_maxCodeBits may be smaller. + const word64 shiftedMaxCode = ((word64)1 << m_maxCodeBits); + if (code > shiftedMaxCode - blCount[m_maxCodeBits]) + throw Err("codes oversubscribed"); + else if (m_maxCodeBits != 1 && code < shiftedMaxCode - blCount[m_maxCodeBits]) + throw Err("codes incomplete"); + + // compute a vector of triples sorted by code + m_codeToValue.resize(nCodes - blCount[0]); + unsigned int j=0; + for (i=0; ilen) + { + entry.type = 2; + entry.len = codeInfo.len; + } + else + { + entry.type = 3; + entry.end = last+1; + } + } +} + +inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value) const +{ + CRYPTOPP_ASSERT(((int)(code & m_cacheMask)) < (int)m_cache.size()); + LookupEntry &entry = m_cache[code & m_cacheMask]; + + code_t normalizedCode = 0; + if (entry.type != 1) + normalizedCode = BitReverse(code); + + if (entry.type == 0) + FillCacheEntry(entry, normalizedCode); + + if (entry.type == 1) + { + value = entry.value; + return entry.len; + } + else + { + const CodeInfo &codeInfo = (entry.type == 2) + ? entry.begin[(normalizedCode << m_cacheBits) >> (MAX_CODE_BITS - (entry.len - m_cacheBits))] + : *(std::upper_bound(entry.begin, entry.end, normalizedCode, CodeLessThan())-1); + value = codeInfo.value; + return codeInfo.len; + } +} + +bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const +{ + bool result = reader.FillBuffer(m_maxCodeBits); + CRYPTOPP_UNUSED(result); // CRYPTOPP_ASSERT(result); + + unsigned int codeBits = Decode(reader.PeekBuffer(), value); + if (codeBits > reader.BitsBuffered()) + return false; + reader.SkipBits(codeBits); + return true; +} + +// ************************************************************* + +Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation) + : AutoSignaling(propagation) + , m_state(PRE_STREAM), m_repeat(repeat), m_eof(0), m_wrappedAround(0) + , m_blockType(0xff), m_storedLen(0xffff), m_nextDecode(), m_literal(0) + , m_distance(0), m_reader(m_inQueue), m_current(0), m_lastFlush(0) +{ + Detach(attachment); +} + +void Inflator::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_state = PRE_STREAM; + parameters.GetValue("Repeat", m_repeat); + m_inQueue.Clear(); + m_reader.SkipBits(m_reader.BitsBuffered()); +} + +void Inflator::OutputByte(byte b) +{ + m_window[m_current++] = b; + if (m_current == m_window.size()) + { + ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush); + m_lastFlush = 0; + m_current = 0; + m_wrappedAround = true; + } +} + +void Inflator::OutputString(const byte *string, size_t length) +{ + while (length) + { + size_t len = UnsignedMin(length, m_window.size() - m_current); + memcpy(m_window + m_current, string, len); + m_current += len; + if (m_current == m_window.size()) + { + ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush); + m_lastFlush = 0; + m_current = 0; + m_wrappedAround = true; + } + string += len; + length -= len; + } +} + +void Inflator::OutputPast(unsigned int length, unsigned int distance) +{ + size_t start; + if (distance <= m_current) + start = m_current - distance; + else if (m_wrappedAround && distance <= m_window.size()) + start = m_current + m_window.size() - distance; + else + throw BadBlockErr(); + + if (start + length > m_window.size()) + { + for (; start < m_window.size(); start++, length--) + OutputByte(m_window[start]); + start = 0; + } + + if (start + length > m_current || m_current + length >= m_window.size()) + { + while (length--) + OutputByte(m_window[start++]); + } + else + { + memcpy(m_window + m_current, m_window + start, length); + m_current += length; + } +} + +size_t Inflator::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Inflator"); + + LazyPutter lp(m_inQueue, inString, length); + ProcessInput(messageEnd != 0); + + if (messageEnd) + if (!(m_state == PRE_STREAM || m_state == AFTER_END)) + throw UnexpectedEndErr(); + + Output(0, NULLPTR, 0, messageEnd, blocking); + return 0; +} + +bool Inflator::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Inflator"); + + if (hardFlush) + ProcessInput(true); + FlushOutput(); + + return false; +} + +void Inflator::ProcessInput(bool flush) +{ + while (true) + { + switch (m_state) + { + case PRE_STREAM: + if (!flush && m_inQueue.CurrentSize() < MaxPrestreamHeaderSize()) + return; + ProcessPrestreamHeader(); + m_state = WAIT_HEADER; + m_wrappedAround = false; + m_current = 0; + m_lastFlush = 0; + m_window.New(((size_t) 1) << GetLog2WindowSize()); + break; + case WAIT_HEADER: + { + // maximum number of bytes before actual compressed data starts + const size_t MAX_HEADER_SIZE = BitsToBytes(3+5+5+4+19*7+286*15+19*15); + if (m_inQueue.CurrentSize() < (flush ? 1 : MAX_HEADER_SIZE)) + return; + DecodeHeader(); + break; + } + case DECODING_BODY: + if (!DecodeBody()) + return; + break; + case POST_STREAM: + if (!flush && m_inQueue.CurrentSize() < MaxPoststreamTailSize()) + return; + ProcessPoststreamTail(); + m_state = m_repeat ? PRE_STREAM : AFTER_END; + Output(0, NULLPTR, 0, GetAutoSignalPropagation(), true); // TODO: non-blocking + if (m_inQueue.IsEmpty()) + return; + break; + case AFTER_END: + m_inQueue.TransferTo(*AttachedTransformation()); + return; + } + } +} + +void Inflator::DecodeHeader() +{ + if (!m_reader.FillBuffer(3)) + throw UnexpectedEndErr(); + m_eof = m_reader.GetBits(1) != 0; + m_blockType = (byte)m_reader.GetBits(2); + + switch (m_blockType) + { + case 0: // stored + { + m_reader.SkipBits(m_reader.BitsBuffered() % 8); + if (!m_reader.FillBuffer(32)) + throw UnexpectedEndErr(); + m_storedLen = (word16)m_reader.GetBits(16); + word16 nlen = (word16)m_reader.GetBits(16); + if (nlen != (word16)~m_storedLen) + throw BadBlockErr(); + break; + } + case 1: // fixed codes + m_nextDecode = LITERAL; + break; + case 2: // dynamic codes + { + if (!m_reader.FillBuffer(5+5+4)) + throw UnexpectedEndErr(); + unsigned int hlit = m_reader.GetBits(5); + unsigned int hdist = m_reader.GetBits(5); + unsigned int hclen = m_reader.GetBits(4); + unsigned int i = 0; + + FixedSizeSecBlock codeLengths; + static const unsigned int border[] = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + std::fill(codeLengths.begin(), codeLengths+19, 0); + for (i=0; i hlit+257+hdist+1) + throw BadBlockErr(); + std::fill(codeLengths + i, codeLengths + i + count, repeater); + i += count; + } + m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257); + if (hdist == 0 && codeLengths[hlit+257] == 0) + { + if (hlit != 0) // a single zero distance code length means all literals + throw BadBlockErr(); + } + else + m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1); + m_nextDecode = LITERAL; + } + catch (HuffmanDecoder::Err &) + { + throw BadBlockErr(); + } + break; + } + default: + throw BadBlockErr(); // reserved block type + } + m_state = DECODING_BODY; +} + +bool Inflator::DecodeBody() +{ + bool blockEnd = false; + switch (m_blockType) + { + case 0: // stored + CRYPTOPP_ASSERT(m_reader.BitsBuffered() == 0); + while (!m_inQueue.IsEmpty() && !blockEnd) + { + size_t size; + const byte *block = m_inQueue.Spy(size); + size = UnsignedMin(m_storedLen, size); + CRYPTOPP_ASSERT(size <= 0xffff); + + OutputString(block, size); + m_inQueue.Skip(size); + m_storedLen = m_storedLen - (word16)size; + if (m_storedLen == 0) + blockEnd = true; + } + break; + case 1: // fixed codes + case 2: // dynamic codes + static const unsigned int lengthStarts[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; + static const unsigned int lengthExtraBits[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; + static const unsigned int distanceStarts[] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; + static const unsigned int distanceExtraBits[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + const HuffmanDecoder& literalDecoder = GetLiteralDecoder(); + const HuffmanDecoder& distanceDecoder = GetDistanceDecoder(); + + switch (m_nextDecode) + { + case LITERAL: + while (true) + { + if (!literalDecoder.Decode(m_reader, m_literal)) + { + m_nextDecode = LITERAL; + break; + } + if (m_literal < 256) + OutputByte((byte)m_literal); + else if (m_literal == 256) // end of block + { + blockEnd = true; + break; + } + else + { + if (m_literal > 285) + throw BadBlockErr(); + unsigned int bits; + case LENGTH_BITS: + CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthExtraBits)); + bits = lengthExtraBits[m_literal-257]; + if (!m_reader.FillBuffer(bits)) + { + m_nextDecode = LENGTH_BITS; + break; + } + CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthStarts)); + m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257]; + case DISTANCE: + if (!distanceDecoder.Decode(m_reader, m_distance)) + { + m_nextDecode = DISTANCE; + break; + } + case DISTANCE_BITS: + CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits)); + if (m_distance >= COUNTOF(distanceExtraBits)) + throw BadDistanceErr(); + bits = distanceExtraBits[m_distance]; + if (!m_reader.FillBuffer(bits)) + { + m_nextDecode = DISTANCE_BITS; + break; + } + CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceStarts)); + if (m_distance >= COUNTOF(distanceStarts)) + throw BadDistanceErr(); + m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance]; + OutputPast(m_literal, m_distance); + } + } + break; + default: + CRYPTOPP_ASSERT(0); + } + } + if (blockEnd) + { + if (m_eof) + { + FlushOutput(); + m_reader.SkipBits(m_reader.BitsBuffered()%8); + if (m_reader.BitsBuffered()) + { + // undo too much lookahead + SecBlockWithHint buffer(m_reader.BitsBuffered() / 8); + for (unsigned int i=0; i= m_lastFlush); + ProcessDecompressedData(m_window + m_lastFlush, m_current - m_lastFlush); + m_lastFlush = m_current; + } +} + +void Inflator::CreateFixedLiteralDecoder() +{ + unsigned int codeLengths[288]; + std::fill(codeLengths + 0, codeLengths + 144, 8); + std::fill(codeLengths + 144, codeLengths + 256, 9); + std::fill(codeLengths + 256, codeLengths + 280, 7); + std::fill(codeLengths + 280, codeLengths + 288, 8); + m_fixedLiteralDecoder.reset(new HuffmanDecoder); + m_fixedLiteralDecoder->Initialize(codeLengths, 288); +} + +void Inflator::CreateFixedDistanceDecoder() +{ + unsigned int codeLengths[32]; + std::fill(codeLengths + 0, codeLengths + 32, 5); + m_fixedDistanceDecoder.reset(new HuffmanDecoder); + m_fixedDistanceDecoder->Initialize(codeLengths, 32); +} + +const HuffmanDecoder& Inflator::GetLiteralDecoder() +{ + if (m_blockType == 1) + { + if (m_fixedLiteralDecoder.get() == NULLPTR) + CreateFixedLiteralDecoder(); + return *m_fixedLiteralDecoder; + } + else + { + return m_dynamicLiteralDecoder; + } +} + +const HuffmanDecoder& Inflator::GetDistanceDecoder() +{ + if (m_blockType == 1) + { + if (m_fixedDistanceDecoder.get() == NULLPTR) + CreateFixedDistanceDecoder(); + return *m_fixedDistanceDecoder; + } + else + { + return m_dynamicDistanceDecoder; + } +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/zinflate.h b/external/ours/library/crypto/src/shared/original/zinflate.h new file mode 100755 index 000000000..bebc0fdf6 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/zinflate.h @@ -0,0 +1,164 @@ +// zinflate.h - originally written and placed in the public domain by Wei Dai + +/// \file zinflate.h +/// \brief DEFLATE compression and decompression (RFC 1951) + +#ifndef CRYPTOPP_ZINFLATE_H +#define CRYPTOPP_ZINFLATE_H + +#include "cryptlib.h" +#include "secblock.h" +#include "filters.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \since Crypto++ 1.0 +class LowFirstBitReader +{ +public: + LowFirstBitReader(BufferedTransformation &store) + : m_store(store), m_buffer(0), m_bitsBuffered(0) {} + unsigned int BitsBuffered() const {return m_bitsBuffered;} + unsigned long PeekBuffer() const {return m_buffer;} + bool FillBuffer(unsigned int length); + unsigned long PeekBits(unsigned int length); + void SkipBits(unsigned int length); + unsigned long GetBits(unsigned int length); + +private: + BufferedTransformation &m_store; + unsigned long m_buffer; + unsigned int m_bitsBuffered; +}; + +struct CodeLessThan; + +/// \brief Huffman Decoder +/// \since Crypto++ 1.0 +class HuffmanDecoder +{ +public: + typedef unsigned int code_t; + typedef unsigned int value_t; + enum {MAX_CODE_BITS = sizeof(code_t)*8}; + + class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}}; + + HuffmanDecoder() : m_maxCodeBits(0), m_cacheBits(0), m_cacheMask(0), m_normalizedCacheMask(0) {} + HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes) + : m_maxCodeBits(0), m_cacheBits(0), m_cacheMask(0), m_normalizedCacheMask(0) + {Initialize(codeBitLengths, nCodes);} + + void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes); + unsigned int Decode(code_t code, /* out */ value_t &value) const; + bool Decode(LowFirstBitReader &reader, value_t &value) const; + +private: + friend struct CodeLessThan; + + struct CodeInfo + { + CodeInfo(code_t code=0, unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {} + inline bool operator<(const CodeInfo &rhs) const {return code < rhs.code;} + code_t code; + unsigned int len; + value_t value; + }; + + struct LookupEntry + { + unsigned int type; + union + { + value_t value; + const CodeInfo *begin; + }; + union + { + unsigned int len; + const CodeInfo *end; + }; + }; + + static code_t NormalizeCode(code_t code, unsigned int codeBits); + void FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const; + + unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask; + std::vector > m_codeToValue; + mutable std::vector > m_cache; +}; + +/// \brief DEFLATE decompressor (RFC 1951) +/// \since Crypto++ 1.0 +class Inflator : public AutoSignaling +{ +public: + class Err : public Exception + { + public: + Err(ErrorType e, const std::string &s) + : Exception(e, s) {} + }; + /// \brief Exception thrown when a truncated stream is encountered + class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}}; + /// \brief Exception thrown when a bad block is encountered + class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}}; + /// \brief Exception thrown when an invalid distance is encountered + class BadDistanceErr : public Err {public: BadDistanceErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in bit distance") {}}; + + /// \brief RFC 1951 Decompressor + /// \param attachment the filter's attached transformation + /// \param repeat decompress multiple compressed streams in series + /// \param autoSignalPropagation 0 to turn off MessageEnd signal + Inflator(BufferedTransformation *attachment = NULLPTR, bool repeat = false, int autoSignalPropagation = -1); + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + + virtual unsigned int GetLog2WindowSize() const {return 15;} + +protected: + ByteQueue m_inQueue; + +private: + virtual unsigned int MaxPrestreamHeaderSize() const {return 0;} + virtual void ProcessPrestreamHeader() {} + virtual void ProcessDecompressedData(const byte *string, size_t length) + {AttachedTransformation()->Put(string, length);} + virtual unsigned int MaxPoststreamTailSize() const {return 0;} + virtual void ProcessPoststreamTail() {} + + void ProcessInput(bool flush); + void DecodeHeader(); + bool DecodeBody(); + void FlushOutput(); + void OutputByte(byte b); + void OutputString(const byte *string, size_t length); + void OutputPast(unsigned int length, unsigned int distance); + + void CreateFixedDistanceDecoder(); + void CreateFixedLiteralDecoder(); + + const HuffmanDecoder& GetLiteralDecoder(); + const HuffmanDecoder& GetDistanceDecoder(); + + enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END}; + State m_state; + bool m_repeat, m_eof, m_wrappedAround; + byte m_blockType; + word16 m_storedLen; + enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS}; + NextDecode m_nextDecode; + unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS + HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder; + member_ptr m_fixedLiteralDecoder, m_fixedDistanceDecoder; + LowFirstBitReader m_reader; + SecByteBlock m_window; + size_t m_current, m_lastFlush; +}; + +NAMESPACE_END + +#endif diff --git a/external/ours/library/crypto/src/shared/original/zlib.cpp b/external/ours/library/crypto/src/shared/original/zlib.cpp new file mode 100755 index 000000000..58dd8bc2b --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/zlib.cpp @@ -0,0 +1,93 @@ +// zlib.cpp - originally written and placed in the public domain by Wei Dai + +// "zlib" is the name of a well known C language compression library +// (http://www.zlib.org) and also the name of a compression format +// (RFC 1950) that the library implements. This file is part of a +// complete reimplementation of the zlib compression format. + +#include "pch.h" +#include "zlib.h" +#include "zdeflate.h" +#include "zinflate.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const byte DEFLATE_METHOD = 8; +static const byte FDICT_FLAG = (1 << 5); + +// ************************************************************* + +void ZlibCompressor::WritePrestreamHeader() +{ + m_adler32.Restart(); + CRYPTOPP_ASSERT(((GetLog2WindowSize()-8) << 4) <= 255); + byte cmf = byte(DEFLATE_METHOD | ((GetLog2WindowSize()-8) << 4)); + CRYPTOPP_ASSERT((GetCompressionLevel() << 6) <= 255); + byte flags = byte(GetCompressionLevel() << 6); + AttachedTransformation()->PutWord16(RoundUpToMultipleOf(word16(cmf*256+flags), word16(31))); +} + +void ZlibCompressor::ProcessUncompressedData(const byte *inString, size_t length) +{ + m_adler32.Update(inString, length); +} + +void ZlibCompressor::WritePoststreamTail() +{ + FixedSizeSecBlock adler32; + m_adler32.Final(adler32); + AttachedTransformation()->Put(adler32, 4); +} + +unsigned int ZlibCompressor::GetCompressionLevel() const +{ + static const unsigned int deflateToCompressionLevel[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3}; + return deflateToCompressionLevel[GetDeflateLevel()]; +} + +// ************************************************************* + +ZlibDecompressor::ZlibDecompressor(BufferedTransformation *attachment, bool repeat, int propagation) + : Inflator(attachment, repeat, propagation), m_log2WindowSize(0) +{ +} + +void ZlibDecompressor::ProcessPrestreamHeader() +{ + m_adler32.Restart(); + + byte cmf; + byte flags; + + if (!m_inQueue.Get(cmf) || !m_inQueue.Get(flags)) + throw HeaderErr(); + + if ((cmf*256+flags) % 31 != 0) + throw HeaderErr(); // if you hit this exception, you're probably trying to decompress invalid data + + if ((cmf & 0xf) != DEFLATE_METHOD) + throw UnsupportedAlgorithm(); + + if (flags & FDICT_FLAG) + throw UnsupportedPresetDictionary(); + + m_log2WindowSize = 8 + (cmf >> 4); +} + +void ZlibDecompressor::ProcessDecompressedData(const byte *inString, size_t length) +{ + AttachedTransformation()->Put(inString, length); + m_adler32.Update(inString, length); +} + +void ZlibDecompressor::ProcessPoststreamTail() +{ + FixedSizeSecBlock adler32; + if (m_inQueue.Get(adler32, 4) != 4) + throw Adler32Err(); + if (!m_adler32.Verify(adler32)) + throw Adler32Err(); +} + +NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original/zlib.h b/external/ours/library/crypto/src/shared/original/zlib.h new file mode 100755 index 000000000..a330eeb88 --- /dev/null +++ b/external/ours/library/crypto/src/shared/original/zlib.h @@ -0,0 +1,65 @@ +// zlib.h - originally written and placed in the public domain by Wei Dai + +/// \file zlib.h +/// \brief ZLIB compression and decompression (RFC 1950) + +#ifndef CRYPTOPP_ZLIB_H +#define CRYPTOPP_ZLIB_H + +#include "cryptlib.h" +#include "adler32.h" +#include "zdeflate.h" +#include "zinflate.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// ZLIB Compressor (RFC 1950) +class ZlibCompressor : public Deflator +{ +public: + ZlibCompressor(BufferedTransformation *attachment=NULLPTR, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true) + : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible) {} + ZlibCompressor(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULLPTR) + : Deflator(parameters, attachment) {} + + unsigned int GetCompressionLevel() const; + +protected: + void WritePrestreamHeader(); + void ProcessUncompressedData(const byte *string, size_t length); + void WritePoststreamTail(); + + Adler32 m_adler32; +}; + +/// ZLIB Decompressor (RFC 1950) +class ZlibDecompressor : public Inflator +{ +public: + typedef Inflator::Err Err; + class HeaderErr : public Err {public: HeaderErr() : Err(INVALID_DATA_FORMAT, "ZlibDecompressor: header decoding error") {}}; + class Adler32Err : public Err {public: Adler32Err() : Err(DATA_INTEGRITY_CHECK_FAILED, "ZlibDecompressor: ADLER32 check error") {}}; + class UnsupportedAlgorithm : public Err {public: UnsupportedAlgorithm() : Err(INVALID_DATA_FORMAT, "ZlibDecompressor: unsupported algorithm") {}}; + class UnsupportedPresetDictionary : public Err {public: UnsupportedPresetDictionary() : Err(INVALID_DATA_FORMAT, "ZlibDecompressor: unsupported preset dictionary") {}}; + + /// \brief Construct a ZlibDecompressor + /// \param attachment a \ BufferedTransformation to attach to this object + /// \param repeat decompress multiple compressed streams in series + /// \param autoSignalPropagation 0 to turn off MessageEnd signal + ZlibDecompressor(BufferedTransformation *attachment = NULLPTR, bool repeat = false, int autoSignalPropagation = -1); + unsigned int GetLog2WindowSize() const {return m_log2WindowSize;} + +private: + unsigned int MaxPrestreamHeaderSize() const {return 2;} + void ProcessPrestreamHeader(); + void ProcessDecompressedData(const byte *string, size_t length); + unsigned int MaxPoststreamTailSize() const {return 4;} + void ProcessPoststreamTail(); + + unsigned int m_log2WindowSize; + Adler32 m_adler32; +}; + +NAMESPACE_END + +#endif From e172d412161a9cfef5cb199fd91ecc7d01267e39 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 30 Oct 2021 14:56:30 -0400 Subject: [PATCH 03/46] Progress on updating Crypto++ --- .../ours/library/crypto/src/CMakeLists.txt | 1 - .../crypto/src/shared/wrapper/MD5Hash.h | 6 +- .../src/shared/wrapper/TwofishCrypt.cpp | 93 ------------------- .../crypto/src/shared/wrapper/TwofishCrypt.h | 51 ++++++++-- .../src/shared/wrapper/TwofishDecryptor.h | 3 +- .../src/shared/wrapper/TwofishEncryptor.h | 8 +- 6 files changed, 50 insertions(+), 112 deletions(-) delete mode 100755 external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.cpp diff --git a/external/ours/library/crypto/src/CMakeLists.txt b/external/ours/library/crypto/src/CMakeLists.txt index 215b59675..b0c01c6fa 100644 --- a/external/ours/library/crypto/src/CMakeLists.txt +++ b/external/ours/library/crypto/src/CMakeLists.txt @@ -29,7 +29,6 @@ set(SHARED_SOURCES shared/wrapper/Hash.h shared/wrapper/MD5Hash.cpp shared/wrapper/MD5Hash.h - shared/wrapper/TwofishCrypt.cpp shared/wrapper/TwofishCrypt.h shared/wrapper/TwofishDecryptor.cpp shared/wrapper/TwofishDecryptor.h diff --git a/external/ours/library/crypto/src/shared/wrapper/MD5Hash.h b/external/ours/library/crypto/src/shared/wrapper/MD5Hash.h index 97595d653..14abc12ac 100755 --- a/external/ours/library/crypto/src/shared/wrapper/MD5Hash.h +++ b/external/ours/library/crypto/src/shared/wrapper/MD5Hash.h @@ -11,7 +11,9 @@ namespace CryptoPP { - class MD5; + namespace Weak1 { + class MD5; + } } namespace Crypto { @@ -35,7 +37,7 @@ class MD5Hash MD5Hash(const MD5Hash & source); private: - CryptoPP::MD5 * md5; + CryptoPP::Weak1::MD5 * md5; }; //----------------------------------------------------------------------- diff --git a/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.cpp b/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.cpp deleted file mode 100755 index 9a272ae38..000000000 --- a/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// TwofishCrypt.cpp -// copyright 2001 Verant Interactive -// Author: Justin Randall - -//----------------------------------------------------------------------- - -#include "FirstCrypto.h" -#include "twofish.h" -#include "TwofishCrypt.h" - -namespace Crypto { - -//----------------------------------------------------------------------- -/** - @brief default ctor -*/ -TwofishCrypt::TwofishCrypt() : -cipher(0) -{ -} - -//----------------------------------------------------------------------- - -TwofishCrypt::TwofishCrypt(const TwofishCrypt &) -{ -} - -//----------------------------------------------------------------------- -/** - @brief dtor - - Deletes the instance of the Twofish cipher -*/ -TwofishCrypt::~TwofishCrypt() -{ - delete cipher; -} - -//----------------------------------------------------------------------- -/** - @brief disabled assignment operator -*/ -TwofishCrypt & TwofishCrypt::operator = (const TwofishCrypt &) -{ - return *this; -} - -//----------------------------------------------------------------------- -/** - @brief return the blocksize of the cipher -*/ -const unsigned int TwofishCrypt::getBlockSize() const -{ - return BLOCKSIZE; -} - -//----------------------------------------------------------------------- -/** - @brief perform a cipher operation - - The cipher operation is determined by the instance of the - TwofishCrypt object (which is actually either a TwofishEncryptor or - TwofishDecryptor) - - The input block size must be greater than or equal to the cipher block - size. -*/ -void TwofishCrypt::process(const unsigned char * const inputBuffer, unsigned char * outputBuffer, const unsigned int size) -{ - static unsigned char block[BLOCKSIZE]; - - if(cipher && size >= BLOCKSIZE) - { - const unsigned int r = size & 3; // optimization -- safe is % BLOCKSIZE - if(r == 0) - { - unsigned int i; - for(i = 0; i < size; i += BLOCKSIZE) - { - memcpy(block, &inputBuffer[i], BLOCKSIZE); - cipher->ProcessBlock(block); - memcpy(&outputBuffer[i], block, BLOCKSIZE); - } - } - assert( r == 0 ); // size must be a 16 byte block for Twofish to do it's job! - } - assert(cipher != nullptr); // can't process data without a twofish encryptor or decryptor! -} - -//----------------------------------------------------------------------- - -}//namespace Crypto - diff --git a/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h b/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h index bcec162b2..c16124f36 100755 --- a/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h +++ b/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h @@ -7,6 +7,7 @@ //----------------------------------------------------------------------- +#include "assert.h" #include "CryptoBufferTransform.h" namespace CryptoPP @@ -20,23 +21,55 @@ namespace Crypto { /** @brief abstract base class for Twofish ciphers */ +template class TwofishCrypt { public: - TwofishCrypt(); - virtual ~TwofishCrypt() = 0; + TwofishCrypt() : cipher(0) + { + } - enum { BLOCKSIZE=16 }; - const unsigned int getBlockSize() const; - void process(const unsigned char * const inputBuffer, unsigned char * outputBuffer, const unsigned int size); + virtual ~TwofishCrypt() = 0; + + enum + { + BLOCKSIZE = 16 + }; + + const unsigned int getBlockSize() const + { + return BLOCKSIZE; + } + + void process(const unsigned char *const inputBuffer, unsigned char *outputBuffer, const unsigned int size) + { + static unsigned char block[BLOCKSIZE]; + + if (cipher && size >= BLOCKSIZE) + { + const unsigned int r = size & 3; // optimization -- safe is % BLOCKSIZE + if (r == 0) + { + unsigned int i; + for (i = 0; i < size; i += BLOCKSIZE) + { + memcpy(block, &inputBuffer[i], BLOCKSIZE); + cipher->ProcessAndXorBlock(block, NULLPTR, block); + memcpy(&outputBuffer[i], block, BLOCKSIZE); + } + } + assert(r == 0); // size must be a 16 byte block for Twofish to do it's job! + } + assert(cipher != nullptr); // can't process data without a twofish encryptor or decryptor! + } private: - TwofishCrypt & operator = (const TwofishCrypt & rhs); - TwofishCrypt(const TwofishCrypt & source); + TwofishCrypt &operator=(const TwofishCrypt &rhs); + TwofishCrypt(const TwofishCrypt &source); protected: - /** @brief assigned by a TwofishEncryptor or TwofishDecryptor */ - CryptoPP::Twofish * cipher; + /** @brief assigned by a TwofishEncryptor or TwofishDecryptor */ + T *cipher; }; //----------------------------------------------------------------------- diff --git a/external/ours/library/crypto/src/shared/wrapper/TwofishDecryptor.h b/external/ours/library/crypto/src/shared/wrapper/TwofishDecryptor.h index 9c5f7576e..eb2099d20 100755 --- a/external/ours/library/crypto/src/shared/wrapper/TwofishDecryptor.h +++ b/external/ours/library/crypto/src/shared/wrapper/TwofishDecryptor.h @@ -7,13 +7,14 @@ //----------------------------------------------------------------------- +#include "twofish.h" #include "TwofishCrypt.h" namespace Crypto { //----------------------------------------------------------------------- - class TwofishDecryptor : public TwofishCrypt + class TwofishDecryptor : public TwofishCrypt { public: TwofishDecryptor(); diff --git a/external/ours/library/crypto/src/shared/wrapper/TwofishEncryptor.h b/external/ours/library/crypto/src/shared/wrapper/TwofishEncryptor.h index 437cb07c2..70aea9e58 100755 --- a/external/ours/library/crypto/src/shared/wrapper/TwofishEncryptor.h +++ b/external/ours/library/crypto/src/shared/wrapper/TwofishEncryptor.h @@ -7,18 +7,14 @@ //----------------------------------------------------------------------- +#include "twofish.h" #include "TwofishCrypt.h" -namespace CryptoPP -{ - class TwofishEncryption; -} - namespace Crypto { //----------------------------------------------------------------------- -class TwofishEncryptor : public TwofishCrypt +class TwofishEncryptor : public TwofishCrypt { public: TwofishEncryptor(); From 7700a7c7ea1b94ce815c5cd5f693484d818fec09 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sun, 31 Oct 2021 13:52:33 -0400 Subject: [PATCH 04/46] Adjusting CMake files --- external/ours/library/crypto/CMakeLists.txt | 2 ++ external/ours/library/crypto/src/CMakeLists.txt | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/external/ours/library/crypto/CMakeLists.txt b/external/ours/library/crypto/CMakeLists.txt index 26724306d..58533e032 100644 --- a/external/ours/library/crypto/CMakeLists.txt +++ b/external/ours/library/crypto/CMakeLists.txt @@ -6,6 +6,8 @@ if(WIN32) add_definitions(/D_CRT_SECURE_NO_WARNINGS) endif() +add_definitions(-DCRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) add_subdirectory(src) diff --git a/external/ours/library/crypto/src/CMakeLists.txt b/external/ours/library/crypto/src/CMakeLists.txt index b0c01c6fa..c9789cf51 100644 --- a/external/ours/library/crypto/src/CMakeLists.txt +++ b/external/ours/library/crypto/src/CMakeLists.txt @@ -3,11 +3,23 @@ set(SHARED_SOURCES shared/core/FirstCrypto.h + shared/original/algebra.cpp + shared/original/algebra.h + shared/original/algparam.cpp + shared/original/algparam.h + shared/original/allocate.cpp + shared/original/allocate.h + shared/original/asn.cpp + shared/original/asn.h shared/original/config.h shared/original/cryptlib.cpp shared/original/cryptlib.h shared/original/filters.cpp shared/original/filters.h + shared/original/fips140.cpp + shared/original/fips140.h + shared/original/integer.cpp + shared/original/integer.h shared/original/iterhash.cpp shared/original/iterhash.h shared/original/md5.cpp From 88bdd17f06fbd902316894303f40a6aa526608c2 Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 1 Nov 2021 00:30:09 -0400 Subject: [PATCH 05/46] Compiling 100% - Execution still broken - DataTable tool may need adjustment --- external/ours/library/crypto/CMakeLists.txt | 1 + .../ours/library/crypto/src/CMakeLists.txt | 29 +++++++++++++++++++ .../crypto/src/shared/wrapper/TwofishCrypt.h | 5 +++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/external/ours/library/crypto/CMakeLists.txt b/external/ours/library/crypto/CMakeLists.txt index 58533e032..13ad4e447 100644 --- a/external/ours/library/crypto/CMakeLists.txt +++ b/external/ours/library/crypto/CMakeLists.txt @@ -7,6 +7,7 @@ if(WIN32) endif() add_definitions(-DCRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) +add_definitions(-DCRYPTOPP_DISABLE_SHANI) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/external/ours/library/crypto/src/CMakeLists.txt b/external/ours/library/crypto/src/CMakeLists.txt index c9789cf51..b8a4bde24 100644 --- a/external/ours/library/crypto/src/CMakeLists.txt +++ b/external/ours/library/crypto/src/CMakeLists.txt @@ -12,12 +12,16 @@ set(SHARED_SOURCES shared/original/asn.cpp shared/original/asn.h shared/original/config.h + shared/original/cpu.cpp + shared/original/cpu.h shared/original/cryptlib.cpp shared/original/cryptlib.h shared/original/filters.cpp shared/original/filters.h shared/original/fips140.cpp shared/original/fips140.h + shared/original/hmac.cpp + shared/original/hmac.h shared/original/integer.cpp shared/original/integer.h shared/original/iterhash.cpp @@ -28,9 +32,34 @@ set(SHARED_SOURCES shared/original/misc.h shared/original/mqueue.cpp shared/original/mqueue.h + shared/original/nbtheory.cpp + shared/original/nbtheory.h + shared/original/osrng.cpp + shared/original/osrng.h + shared/original/pch.cpp + shared/original/pch.h + shared/original/pubkey.cpp + shared/original/pubkey.h shared/original/queue.cpp shared/original/queue.h + shared/original/rc2.cpp + shared/original/rc2.h + shared/original/rdtables.cpp + shared/original/rijndael.cpp + shared/original/rijndael.h + shared/original/rijndael_simd.cpp + shared/original/rng.cpp + shared/original/rng.h + shared/original/seckey.h + shared/original/sha.cpp + shared/original/sha.h + shared/original/sha3.cpp + shared/original/sha3.h + shared/original/shacal2.cpp + shared/original/shacal2.h + shared/original/sha_simd.cpp shared/original/smartptr.h + shared/original/sse_simd.cpp shared/original/tftables.cpp shared/original/twofish.cpp shared/original/twofish.h diff --git a/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h b/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h index c16124f36..9ecd1f22f 100755 --- a/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h +++ b/external/ours/library/crypto/src/shared/wrapper/TwofishCrypt.h @@ -29,7 +29,10 @@ class TwofishCrypt { } - virtual ~TwofishCrypt() = 0; + virtual ~TwofishCrypt() + { + delete cipher; + } enum { From ac1f374b0b9d519b6d1c72cac59161622f13ba60 Mon Sep 17 00:00:00 2001 From: Cekis Date: Tue, 2 Nov 2021 00:44:59 -0400 Subject: [PATCH 06/46] Datatables now compiling correctly --- engine/client/application/Miff/src/lex_yy.c | 8 +++--- .../application/Miff/src/linux/parser.yac | 25 ++++++++++--------- engine/client/application/Miff/src/parser.c | 24 +++++++++--------- .../AuctionTransferGameAPI/Base/linux/Types.h | 4 +-- .../library/sharedFile/src/shared/Iff.cpp | 4 +-- .../src/shared/CrcStringTable.cpp | 21 ++++++++++++++++ .../src/shared/object/ObjectTemplateList.cpp | 3 ++- .../sharedUtility/src/shared/DataTable.cpp | 10 ++++---- .../sharedUtility/src/shared/DataTable.h | 10 ++++---- .../src/shared/DataTableCell.cpp | 2 +- .../sharedUtility/src/shared/DataTableCell.h | 16 ++++++------ .../src/shared/DataTableWriter.cpp | 8 +++--- .../library/platform/utils/Base/linux/Types.h | 4 +-- .../library/platform/utils/Base/win32/Types.h | 4 +-- .../CSAssist/utils/Base/linux/Types.h | 4 +-- .../CSAssist/utils/Base/win32/Types.h | 4 +-- .../CTServiceGameAPI/Base/linux/Types.h | 4 +-- .../CTServiceGameAPI/Base/win32/Types.h | 4 +-- .../ChatAPI/utils/Base/linux/Types.h | 4 +-- .../ChatAPI/utils/Base/win32/Types.h | 4 +-- .../VChatAPI/utils2.0/utils/Base/types.h | 4 +-- .../cleanup/TaskObjectTemplateListUpdater.cpp | 2 +- 22 files changed, 98 insertions(+), 75 deletions(-) diff --git a/engine/client/application/Miff/src/lex_yy.c b/engine/client/application/Miff/src/lex_yy.c index df6de76d9..bdf2e3fa8 100644 --- a/engine/client/application/Miff/src/lex_yy.c +++ b/engine/client/application/Miff/src/lex_yy.c @@ -49,11 +49,11 @@ typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; +typedef short short int flex_int16_t; +typedef short int flex_int32_t; typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; +typedef unsigned short short int flex_uint16_t; +typedef unsigned short int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN diff --git a/engine/client/application/Miff/src/linux/parser.yac b/engine/client/application/Miff/src/linux/parser.yac index 25feaf7e8..647b4e766 100644 --- a/engine/client/application/Miff/src/linux/parser.yac +++ b/engine/client/application/Miff/src/linux/parser.yac @@ -29,6 +29,7 @@ #include /* for wide character (16bit) strings */ #include /* for strtoupper and strtolower */ #include +#include /* for standard types - i.e. uint32_t */ /*----------------------------------------------------------------** ** debug options, turn these on to TEST ONLY! don't leave these ** @@ -66,11 +67,11 @@ void checkPragmas(void); void includeBinary(char *fname); -void write32(long i32); -void write16(short i16); +void write32(int32_t i32); +void write16(int16_t i16); void write8(char i8); -void writeU32(unsigned long ui32); -void writeU16(unsigned short ui16); +void writeU32(uint32_t ui32); +void writeU16(uint16_t ui16); void writeU8(unsigned char u8); void writeDouble(double d); void writeFloat(float f); @@ -627,14 +628,14 @@ void checkArgs(void) /*----------------------------** ** Write to FILE functions... ** **----------------------------*/ -void write32(long i32) +void write32(int32_t i32) { - MIFFinsertChunkData(&i32, sizeof(long)); + MIFFinsertChunkData(&i32, sizeof(int32_t)); } -void write16(short i16) +void write16(int16_t i16) { - MIFFinsertChunkData(&i16, sizeof(short)); + MIFFinsertChunkData(&i16, sizeof(int16_t)); } void write8(char i8) @@ -642,14 +643,14 @@ void write8(char i8) MIFFinsertChunkData(&i8, sizeof(char)); } -void writeU32(unsigned long ui32) +void writeU32(uint32_t ui32) { - MIFFinsertChunkData(&ui32, sizeof(long)); + MIFFinsertChunkData(&ui32, sizeof(uint32_t)); } -void writeU16(unsigned short ui16) +void writeU16(uint16_t ui16) { - MIFFinsertChunkData(&ui16, sizeof(short)); + MIFFinsertChunkData(&ui16, sizeof(uint16_t)); } void writeU8(unsigned char ui8) diff --git a/engine/client/application/Miff/src/parser.c b/engine/client/application/Miff/src/parser.c index 22fdd21e4..90a23d7c2 100644 --- a/engine/client/application/Miff/src/parser.c +++ b/engine/client/application/Miff/src/parser.c @@ -134,11 +134,11 @@ void checkPragmas(void); void includeBinary(char *fname); -void write32(long i32); -void write16(short i16); +void write32(int32_t i32); +void write16(int16_t i16); void write8(char i8); -void writeU32(unsigned long ui32); -void writeU16(unsigned short ui16); +void writeU32(uint32_t ui32); +void writeU16(uint16_t ui16); void writeU8(unsigned char u8); void writeDouble(double d); void writeFloat(float f); @@ -2829,14 +2829,14 @@ void checkArgs(void) /*----------------------------** ** Write to FILE functions... ** **----------------------------*/ -void write32(long i32) +void write32(int32_t i32) { - MIFFinsertChunkData(&i32, sizeof(long)); + MIFFinsertChunkData(&i32, sizeof(int32_t)); } -void write16(short i16) +void write16(int16_t i16) { - MIFFinsertChunkData(&i16, sizeof(short)); + MIFFinsertChunkData(&i16, sizeof(int16_t)); } void write8(char i8) @@ -2844,14 +2844,14 @@ void write8(char i8) MIFFinsertChunkData(&i8, sizeof(char)); } -void writeU32(unsigned long ui32) +void writeU32(uint32_t ui32) { - MIFFinsertChunkData(&ui32, sizeof(long)); + MIFFinsertChunkData(&ui32, sizeof(uint32_t)); } -void writeU16(unsigned short ui16) +void writeU16(uint16_t ui16) { - MIFFinsertChunkData(&ui16, sizeof(short)); + MIFFinsertChunkData(&ui16, sizeof(uint16_t)); } void writeU8(unsigned char ui8) diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h index a5eb04133..ea2b96257 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/linux/Types.h @@ -31,8 +31,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef signed short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/engine/shared/library/sharedFile/src/shared/Iff.cpp b/engine/shared/library/sharedFile/src/shared/Iff.cpp index 48eaeed12..5eb06ec76 100755 --- a/engine/shared/library/sharedFile/src/shared/Iff.cpp +++ b/engine/shared/library/sharedFile/src/shared/Iff.cpp @@ -744,10 +744,10 @@ void Iff::insertForm(Tag name, bool shouldEnterForm) void Iff::insertChunk(Tag name, bool shouldEnterChunk) { - const int CHUNK_OVERHEAD = sizeof(Tag) + sizeof(uint32); + const int32 CHUNK_OVERHEAD = sizeof(Tag) + sizeof(uint32); Tag t; - int offset; + int32 offset; NOT_NULL(data); IFF_DEBUG_FATAL(inChunk, "inside chunk"); diff --git a/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp b/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp index ab00efba8..d9855c03b 100755 --- a/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp +++ b/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp @@ -14,6 +14,7 @@ #include "sharedFoundation/ConstCharCrcString.h" #include +#include // ====================================================================== @@ -164,6 +165,26 @@ ConstCharCrcString const CrcStringTable::lookUp(uint32 crc) const high = mid - 1; } + WARNING(true,("\n=========== Could not find entry 0x%08x with %d entries!!\n", crc, m_numberOfEntries)); + + low = 0; + high = m_numberOfEntries - 1; + + while (low <= high) + { + int const mid = (low + high) / 2; + uint32 const entry = m_crcTable[mid]; + + WARNING(true, ("Checking 0x%08x against entry value 0x%08x at index %d", crc, entry, mid)); + if (crc == entry) + return ConstCharCrcString(m_strings + m_stringsOffsetTable[mid], crc); + else + if (crc > entry) + low = mid + 1; + else + high = mid - 1; + } + return ConstCharCrcString("", 0); } diff --git a/engine/shared/library/sharedObject/src/shared/object/ObjectTemplateList.cpp b/engine/shared/library/sharedObject/src/shared/object/ObjectTemplateList.cpp index 823629063..2b6484a8b 100755 --- a/engine/shared/library/sharedObject/src/shared/object/ObjectTemplateList.cpp +++ b/engine/shared/library/sharedObject/src/shared/object/ObjectTemplateList.cpp @@ -16,6 +16,7 @@ #include "sharedObject/Object.h" #include "sharedFoundation/ConstCharCrcString.h" #include "sharedFoundation/CrcStringTable.h" +#include "sharedFoundation/Crc.h" #include "sharedFoundation/DataResourceList.h" #include @@ -174,7 +175,7 @@ void ObjectTemplateList::loadCrcStringTable(const char *fileName) ConstCharCrcString const ObjectTemplateList::lookUp(const char * string) { ConstCharCrcString result = ms_crcStringTable.lookUp(string); - WARNING(result.isEmpty(), ("ObjectTemplateList::lookUp objectTemplate %s not found in table", string)); + WARNING(result.isEmpty(), ("ObjectTemplateList::lookUp objectTemplate %s (CRC 0x%08x) not found in table", string, Crc::calculate(string))); return result; } diff --git a/engine/shared/library/sharedUtility/src/shared/DataTable.cpp b/engine/shared/library/sharedUtility/src/shared/DataTable.cpp index 2a0974c73..4cdd7f032 100755 --- a/engine/shared/library/sharedUtility/src/shared/DataTable.cpp +++ b/engine/shared/library/sharedUtility/src/shared/DataTable.cpp @@ -185,7 +185,7 @@ int DataTable::getIntValue(const std::string & column, int row) const //---------------------------------------------------------------------------- -int DataTable::getIntValue(int column, int row) const +int32 DataTable::getIntValue(int column, int row) const { DEBUG_FATAL(row < 0 || row >= getNumRows(), ("DataTable [%s] getIntValue(): Invalid row number [%d]. Rows=[%d]\n", m_name.c_str(), row, getNumRows())); DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getIntValue(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns())); @@ -210,7 +210,7 @@ int DataTable::getIntValue(int column, int row) const //---------------------------------------------------------------------------- -int DataTable::getIntDefaultForColumn(const std::string & column) const +int32 DataTable::getIntDefaultForColumn(const std::string & column) const { int const columnIndex = findColumnNumber(column); DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable [%s] getIntDefaultForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), columnIndex, getNumColumns())); @@ -219,7 +219,7 @@ int DataTable::getIntDefaultForColumn(const std::string & column) const //---------------------------------------------------------------------------- -int DataTable::getIntDefaultForColumn(int column) const +int32 DataTable::getIntDefaultForColumn(int column) const { DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getIntDefaultForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns())); DEBUG_FATAL(m_types[static_cast(column)]->getBasicType() != DataTableColumnType::DT_Int, ("Wrong data type for column %d.", column)); @@ -405,7 +405,7 @@ void DataTable::_readCell(Iff & iff, int column, int row) { case DataTableColumnType::DT_Int: { - int tmp = iff.read_int32(); + int32 tmp = iff.read_int32(); new (cell) DataTableCell(tmp); break; @@ -677,7 +677,7 @@ int DataTable::searchColumnFloat( int column, float searchValue ) const // ---------- -int DataTable::searchColumnInt( int column, int searchValue ) const +int DataTable::searchColumnInt( int column, int32 searchValue ) const { DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] searchColumnInt(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns())); diff --git a/engine/shared/library/sharedUtility/src/shared/DataTable.h b/engine/shared/library/sharedUtility/src/shared/DataTable.h index ef9c3fe3b..13b3988d1 100755 --- a/engine/shared/library/sharedUtility/src/shared/DataTable.h +++ b/engine/shared/library/sharedUtility/src/shared/DataTable.h @@ -31,10 +31,10 @@ class DataTable DataTableColumnType const &getDataTypeForColumn(const std::string& column) const; DataTableColumnType const &getDataTypeForColumn(int column) const; - int getIntValue(const std::string & column, int row) const; - int getIntValue(int column, int row) const; - int getIntDefaultForColumn(const std::string & column) const; - int getIntDefaultForColumn(int column) const; + int32 getIntValue(const std::string & column, int row) const; + int32 getIntValue(int column, int row) const; + int32 getIntDefaultForColumn(const std::string & column) const; + int32 getIntDefaultForColumn(int column) const; float getFloatValue(const std::string & column, int row) const; float getFloatValue(int column, int row) const; float getFloatDefaultForColumn(const std::string & column) const; @@ -63,7 +63,7 @@ class DataTable int searchColumnString(int column, const std::string & searchValue) const; int searchColumnFloat(int column, float searchValue) const; - int searchColumnInt(int column, int searchValue) const; + int searchColumnInt(int column, int32 searchValue) const; std::string const & getName() const; diff --git a/engine/shared/library/sharedUtility/src/shared/DataTableCell.cpp b/engine/shared/library/sharedUtility/src/shared/DataTableCell.cpp index 625730695..c0b9f8fa1 100755 --- a/engine/shared/library/sharedUtility/src/shared/DataTableCell.cpp +++ b/engine/shared/library/sharedUtility/src/shared/DataTableCell.cpp @@ -55,7 +55,7 @@ void DataTableCell::operator delete(void *pointer) // ---------------------------------------------------------------------- -DataTableCell::DataTableCell(int value) +DataTableCell::DataTableCell(int32 value) : m_type(CT_int) { m_value.m_i=value; diff --git a/engine/shared/library/sharedUtility/src/shared/DataTableCell.h b/engine/shared/library/sharedUtility/src/shared/DataTableCell.h index 5021b5f86..1cd4b616f 100755 --- a/engine/shared/library/sharedUtility/src/shared/DataTableCell.h +++ b/engine/shared/library/sharedUtility/src/shared/DataTableCell.h @@ -31,16 +31,16 @@ class DataTableCell ,CT_float }; - explicit DataTableCell(int value); + explicit DataTableCell(int32 value); explicit DataTableCell(float value); explicit DataTableCell(const char *value); ~DataTableCell(); - CellType getType() const { return m_type; } - int getIntValue() const { return m_value.m_i; } - float getFloatValue() const { return m_value.m_f; } - const char *getStringValue() const; - int getStringValueCrc() const { return m_value.m_s.m_crc; } + CellType getType() const { return m_type; } + int32 getIntValue() const { return m_value.m_i; } + float getFloatValue() const { return m_value.m_f; } + const char *getStringValue() const; + int32 getStringValueCrc() const { return m_value.m_s.m_crc; } private: const CellType m_type; @@ -48,12 +48,12 @@ class DataTableCell { union { - int m_i; + int32 m_i; float m_f; struct { const char *m_sz; - int m_crc; + int32 m_crc; } m_s; }; } m_value; diff --git a/engine/shared/library/sharedUtility/src/shared/DataTableWriter.cpp b/engine/shared/library/sharedUtility/src/shared/DataTableWriter.cpp index 795c86964..5d3d6e6d6 100755 --- a/engine/shared/library/sharedUtility/src/shared/DataTableWriter.cpp +++ b/engine/shared/library/sharedUtility/src/shared/DataTableWriter.cpp @@ -728,7 +728,7 @@ DataTableCell *DataTableWriter::_getNewCell(DataTableColumnType const &columnTyp switch (columnType.getBasicType()) { case DataTableColumnType::DT_Int: - return new DataTableCell(static_cast(strtol(value.c_str(), nullptr, 0))); + return new DataTableCell(static_cast(strtol(value.c_str(), nullptr, 0))); break; case DataTableColumnType::DT_Float: return new DataTableCell(static_cast(atof(value.c_str()))); @@ -859,7 +859,7 @@ void DataTableWriter::_saveRows(NamedDataTable * ndt, Iff& iff) const iff.insertChunk(TAG(R,O,W,S)); int numRows = static_cast(ndt->m_rows.size()); - iff.insertChunkData(&numRows, sizeof(int)); + iff.insertChunkData(&numRows, sizeof(int32)); std::vector::iterator i = ndt->m_rows.begin(); for (; i!= ndt->m_rows.end(); ++i) { @@ -873,8 +873,8 @@ void DataTableWriter::_saveRows(NamedDataTable * ndt, Iff& iff) const { const DataTableCell * cell = *j; NOT_NULL(cell); - int tmp = cell->getIntValue(); - iff.insertChunkData(&tmp, sizeof(int)); + int32 tmp = cell->getIntValue(); + iff.insertChunkData(&tmp, sizeof(int32)); break; } case DataTableColumnType::DT_Float: diff --git a/external/3rd/library/platform/utils/Base/linux/Types.h b/external/3rd/library/platform/utils/Base/linux/Types.h index a685807d6..574ee5caa 100755 --- a/external/3rd/library/platform/utils/Base/linux/Types.h +++ b/external/3rd/library/platform/utils/Base/linux/Types.h @@ -28,8 +28,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef signed short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/platform/utils/Base/win32/Types.h b/external/3rd/library/platform/utils/Base/win32/Types.h index aa9ba015f..10905cc1a 100755 --- a/external/3rd/library/platform/utils/Base/win32/Types.h +++ b/external/3rd/library/platform/utils/Base/win32/Types.h @@ -25,8 +25,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h b/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h index a5eb04133..ea2b96257 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/linux/Types.h @@ -31,8 +31,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef signed short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h b/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h index aa9ba015f..10905cc1a 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/win32/Types.h @@ -25,8 +25,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h index a5eb04133..ea2b96257 100755 --- a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h @@ -31,8 +31,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef signed short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h index aa9ba015f..10905cc1a 100755 --- a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h @@ -25,8 +25,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h b/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h index a685807d6..574ee5caa 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/linux/Types.h @@ -28,8 +28,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef signed short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h b/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h index aa9ba015f..10905cc1a 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/win32/Types.h @@ -25,8 +25,8 @@ namespace Base typedef signed char int8; typedef unsigned char uint8; -typedef short int16; -typedef unsigned short uint16; +typedef int16_t int16; +typedef uint16_t uint16; typedef int32_t int32; typedef uint32_t uint32; diff --git a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h index 389d8a490..19d20d139 100755 --- a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h +++ b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/types.h @@ -35,8 +35,8 @@ namespace soe { typedef char int8; typedef unsigned char uint8; - typedef short int16; - typedef unsigned short uint16; + typedef int16_t int16; + typedef uint16_t uint16; #ifdef WIN32 typedef int32_t int32; diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp index f4653cd98..54b181fe2 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp @@ -32,7 +32,7 @@ bool TaskObjectTemplateListUpdater::process(DB::Session *session) int i_lines = 0; while(1) { - int i_id; + uint32 i_id; char s_name[4096]; int i_retval = 0; From f059a84c8c29f23f1931842f91cb2f137ae34209 Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 3 Nov 2021 14:39:09 -0400 Subject: [PATCH 07/46] Fixed issues loading string tables. --- .../ours/library/localization/src/shared/LocalizedString.h | 4 ++-- .../library/localization/src/shared/LocalizedStringTable.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/external/ours/library/localization/src/shared/LocalizedString.h b/external/ours/library/localization/src/shared/LocalizedString.h index bd3b8cb32..c897cd107 100755 --- a/external/ours/library/localization/src/shared/LocalizedString.h +++ b/external/ours/library/localization/src/shared/LocalizedString.h @@ -38,8 +38,8 @@ class LocalizedString // TODO: make these typedefs platform dependent - typedef unsigned long id_type; - typedef unsigned long crc_type; + typedef uint32_t id_type; + typedef uint32_t crc_type; LocalizedString(id_type id, crc_type sourceCrc, Unicode::String const & str); LocalizedString(id_type id, Unicode::String const & str); // GENERATE Crc FROM UNICODE. diff --git a/external/ours/library/localization/src/shared/LocalizedStringTable.h b/external/ours/library/localization/src/shared/LocalizedStringTable.h index cea6635e4..dfcc3d2b8 100755 --- a/external/ours/library/localization/src/shared/LocalizedStringTable.h +++ b/external/ours/library/localization/src/shared/LocalizedStringTable.h @@ -46,7 +46,7 @@ class LocalizedStringTable typedef std::map NameMap_t; // TODO: make this typedef platform dependent - typedef long magic_type; + typedef uint32_t magic_type; static const magic_type ms_MAGIC; explicit LocalizedStringTable (const std::string & filename); From 5889d7e75321baefac406b2e29065dd4060987ea Mon Sep 17 00:00:00 2001 From: Cekis Date: Thu, 4 Nov 2021 17:04:49 -0400 Subject: [PATCH 08/46] Fixed issue with profanity filter --- .../src/shared/core/TextManager.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp b/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp index 741f494e2..599ee57c0 100755 --- a/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp +++ b/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp @@ -120,7 +120,7 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) // Sub-string search time for words that are listed for sub-string searches Unicode::String lowerText(Unicode::toLower(text)); - unsigned int findStartPosition = 0; + size_t findStartPosition = 0; for (;;) { @@ -137,7 +137,7 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) continue; } - unsigned int index = lowerText.find(cussWord, findStartPosition); + size_t index = lowerText.find(cussWord, findStartPosition); if (index != Unicode::String::npos) { @@ -297,8 +297,8 @@ Unicode::String TextManager::filterText(Unicode::String const &text) { Unicode::String result(text); Unicode::String::const_iterator iterText = text.begin(); - int startIndex = Unicode::String::npos; - int currentIndex = 0; + size_t startIndex = Unicode::String::npos; + size_t currentIndex = 0; { // Walk through the text finding sections of alpha characters. @@ -309,12 +309,12 @@ Unicode::String TextManager::filterText(Unicode::String const &text) { Unicode::unicode_char_t const character = (*iterText); - if ( (static_cast(startIndex) == Unicode::String::npos) + if ( (startIndex == Unicode::String::npos) && isAlpha(character)) { startIndex = currentIndex; } - else if ( (static_cast(startIndex) != Unicode::String::npos) + else if ( (startIndex != Unicode::String::npos) && !isAlpha(character)) { checkText(result, startIndex, currentIndex); @@ -327,7 +327,7 @@ Unicode::String TextManager::filterText(Unicode::String const &text) // Possibly check the last word - if (static_cast(startIndex) != Unicode::String::npos) + if (startIndex != Unicode::String::npos) { checkText(result, startIndex, currentIndex); } @@ -346,12 +346,12 @@ Unicode::String TextManager::filterText(Unicode::String const &text) { Unicode::unicode_char_t const character = (*iterText); - if ( (static_cast(startIndex) == Unicode::String::npos) + if ( (startIndex == Unicode::String::npos) && character != static_cast(' ')) { startIndex = currentIndex; } - else if ( (static_cast(startIndex) != Unicode::String::npos) + else if ( (startIndex != Unicode::String::npos) && character == static_cast(' ')) { checkText(result, startIndex, currentIndex); @@ -364,7 +364,7 @@ Unicode::String TextManager::filterText(Unicode::String const &text) // Possibly check the last word - if (static_cast(startIndex) != Unicode::String::npos) + if (startIndex != Unicode::String::npos) { checkText(result, startIndex, currentIndex); } From 45e474ecbe1cfcf873fa959b4c7bda478582102a Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 6 Nov 2021 00:26:45 -0400 Subject: [PATCH 09/46] Fixed timeout issue with server startup. --- engine/server/library/serverGame/src/shared/core/GameServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/server/library/serverGame/src/shared/core/GameServer.h b/engine/server/library/serverGame/src/shared/core/GameServer.h index 594f98791..e5b7944ac 100755 --- a/engine/server/library/serverGame/src/shared/core/GameServer.h +++ b/engine/server/library/serverGame/src/shared/core/GameServer.h @@ -230,7 +230,7 @@ public MessageDispatch::Receiver bool m_gameServerReadyObjectIds; bool m_gameServerReadyDatabaseConnected; bool m_gameServerReadyPlanetConnected; - uint32 m_connectionTimeout; + uint64_t m_connectionTimeout; ChatServerConnection * m_chatServerConnection; }; From 05e9202dbf1a06e70d03d28750c726969981b118 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 6 Nov 2021 16:08:49 -0400 Subject: [PATCH 10/46] Removed native methods that no longer exist. --- engine/server/library/serverScript/src/shared/JavaLibrary.cpp | 1 + .../library/serverScript/src/shared/ScriptMethodsCollection.cpp | 2 +- .../serverScript/src/shared/ScriptMethodsPermissions.cpp | 2 +- .../serverScript/src/shared/ScriptMethodsPlayerAccount.cpp | 2 +- .../library/serverScript/src/shared/ScriptMethodsSystem.cpp | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp index b1df5f350..c373980a2 100755 --- a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp +++ b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp @@ -1955,6 +1955,7 @@ bool JavaLibrary::registerNatives(const JNINativeMethod natives[], int count) { ms_env->ExceptionClear(); DEBUG_REPORT_LOG(true, ("RegisterNatives failed: %s: %s\n", natives[i].name, natives[i].signature)); + WARNING(true, ("RegisterNatives failed: could not register Java method: %s: with signature %s (does it exist in the codebase?)\n", natives[i].name, natives[i].signature)); result = lresult; } } diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp index 080d7994c..396e6d900 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp @@ -90,7 +90,7 @@ bool ScriptMethodsCollectionNamespace::install() JF("getCollectionSlotCategoryInfo", "(Ljava/lang/String;)[Ljava/lang/String;", getCollectionSlotCategoryInfo), JF("getCollectionSlotPrereqInfo", "(Ljava/lang/String;)[Ljava/lang/String;", getCollectionSlotPrereqInfo), JF("getCollectionSlotName", "(I)Ljava/lang/String;", getCollectionSlotName), - JF("getCollectionSlotMaxValue", "(Ljava/lang/String;)J", getCollectionSlotMaxValue), + //JF("getCollectionSlotMaxValue", "(Ljava/lang/String;)J", getCollectionSlotMaxValue), JF("getAllCollectionSlotsInCollection", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInCollection), JF("getAllCollectionSlotsInPage", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionSlotsInPage), JF("getAllCollectionsInPage", "(Ljava/lang/String;)[Ljava/lang/String;", getAllCollectionsInPage), diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp index 45e0981e5..3d2c7d2fb 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPermissions.cpp @@ -66,7 +66,7 @@ const JNINativeMethod NATIVES[] = { JF("_permissionsMakePublic", "(J)V", permissionsMakePublic), JF("_permissionsMakePrivate", "(J)V", permissionsMakePrivate), JF("_expelFromBuilding", "(J)V", expelFromBuilding), - JF("_sendDirtyCellPermissionsUpdateToClient", "(JJZ)V", sendDirtyCellPermissionsUpdateToClient), + //JF("_sendDirtyCellPermissionsUpdateToClient", "(JJZ)V", sendDirtyCellPermissionsUpdateToClient), }; return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp index 48fa7ad19..e38ecdd3c 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp @@ -112,7 +112,7 @@ const JNINativeMethod NATIVES[] = { JF("_renameCharacterReleaseNameReservation", "(J)V", renameCharacterReleaseNameReservation), JF("_renameCharacter", "(JLjava/lang/String;)V", renameCharacter), JF("_getPlayerStationId", "(J)I", getPlayerStationId), - JF("_getPlayerUsernameDoNotUse", "(J)Ljava/lang/String;", getPlayerUsername), + //JF("_getPlayerUsernameDoNotUse", "(J)Ljava/lang/String;", getPlayerUsername), }; return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp index 47c662cf1..d3395b849 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsSystem.cpp @@ -50,7 +50,7 @@ const JNINativeMethod NATIVES[] = { JF("_saveBytesOnClient", "(JLjava/lang/String;[B)V", saveBytesOnClient), JF("_launchClientWebBrowser", "(JLjava/lang/String;)V", launchClientWebBrowser), JF("_playCutScene", "(JLjava/lang/String;)V", playCutScene), - JF("_triggerServerWarning", "(Ljava/lang/String;)V", triggerServerWarning), + // JF("_triggerServerWarning", "(Ljava/lang/String;)V", triggerServerWarning), }; return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); From 6725ce76966e8585920790e84279ae84d1e37723 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sun, 7 Nov 2021 21:53:51 -0500 Subject: [PATCH 11/46] Fixed some incorrect sizing on network messages. --- .../src/shared/TaskConnectionIdMessage.h | 2 +- .../library/serverScript/src/shared/ScriptMethodsCombat.cpp | 2 +- .../serverUtility/src/shared/SystemAssignedProcessId.h | 2 +- .../src/shared/clientGameServer/GalaxyLoopTimesResponse.h | 4 ++-- .../src/shared/clientGameServer/SlowDownEffectMessage.h | 2 +- .../sharedNetworkMessages/src/shared/common/FrameEndMessage.h | 2 +- .../src/shared/common/GameNetworkMessage.h | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h b/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h index ce5e57353..75bc92955 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h +++ b/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h @@ -42,7 +42,7 @@ class TaskConnectionIdMessage : public GameNetworkMessage Archive::AutoVariable serverType; Archive::AutoVariable commandLine; Archive::AutoVariable clusterName; - Archive::AutoVariable currentEpochTime; + Archive::AutoVariable currentEpochTime; }; //----------------------------------------------------------------------- diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp index fdb842bc5..f8700fc5c 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCombat.cpp @@ -1680,7 +1680,7 @@ jboolean JNICALL ScriptMethodsCombatNamespace::doCombatResults(JNIEnv *env, jobj if (!ClientCombatManagerSupport::doesCombatActionNameExist(TemporaryCrcString(animationString.c_str(), true))) { - WARNING(true, ("doCombatResults(): caller passed in unsupported combat action name [%s]! Continuing to send combat action. Call stack follows in stdout.", animationString.c_str())); + DEBUG_WARNING(true, ("doCombatResults(): caller passed in unsupported combat action name [%s]! Continuing to send combat action. Call stack follows in stdout.", animationString.c_str())); // @todo make this go to the log rather than stdout; otherwise, we're going to have to do a lot more work to see this info. JavaLibrary::printJavaStack(); } diff --git a/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h b/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h index 2ecbf8b05..630471243 100755 --- a/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h +++ b/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h @@ -24,7 +24,7 @@ class SystemAssignedProcessId : public GameNetworkMessage SystemAssignedProcessId & operator = (const SystemAssignedProcessId & rhs); SystemAssignedProcessId(const SystemAssignedProcessId & source); - Archive::AutoVariable m_id; + Archive::AutoVariable m_id; }; //----------------------------------------------------------------------- diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/GalaxyLoopTimesResponse.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/GalaxyLoopTimesResponse.h index 56d447c54..b1c47ddf2 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/GalaxyLoopTimesResponse.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/GalaxyLoopTimesResponse.h @@ -25,8 +25,8 @@ class GalaxyLoopTimesResponse : public GameNetworkMessage GalaxyLoopTimesResponse & operator = (const GalaxyLoopTimesResponse & rhs); GalaxyLoopTimesResponse(const GalaxyLoopTimesResponse & source); - Archive::AutoVariable currentFrameMilliseconds; - Archive::AutoVariable lastFrameMilliseconds; + Archive::AutoVariable currentFrameMilliseconds; + Archive::AutoVariable lastFrameMilliseconds; }; //----------------------------------------------------------------------- diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SlowDownEffectMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SlowDownEffectMessage.h index effac2e71..035e081ec 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SlowDownEffectMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SlowDownEffectMessage.h @@ -45,7 +45,7 @@ class SlowDownEffectMessage : public GameNetworkMessage Archive::AutoVariable m_coneLength; Archive::AutoVariable m_coneAngle; Archive::AutoVariable m_slopeAngle; - Archive::AutoVariable m_expireTime; + Archive::AutoVariable m_expireTime; }; //----------------------------------------------------------------------- diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/common/FrameEndMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/common/FrameEndMessage.h index d65192e61..7fb4a4bcb 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/common/FrameEndMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/common/FrameEndMessage.h @@ -28,7 +28,7 @@ class FrameEndMessage: public GameNetworkMessage private: Archive::AutoVariable m_processId; - Archive::AutoVariable m_frameTime; + Archive::AutoVariable m_frameTime; Archive::AutoVariable m_profilerData; FrameEndMessage(); diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h index 3e8f93b40..cac844662 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h @@ -43,7 +43,7 @@ class GameNetworkMessage: public Archive::AutoByteStream, public MessageDispatch private: GameNetworkMessage(); - Archive::AutoVariable cmd; + Archive::AutoVariable cmd; }; // ====================================================================== From 26b6f8365f91de4fb2c55232415955c8b6b4bae7 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 13 Nov 2021 02:22:37 -0500 Subject: [PATCH 12/46] Reworked Archive package for standard data types and fixed issue with Server package overrun --- CMakeLists.txt | 4 +- .../TaskManager/src/shared/GameConnection.cpp | 2 +- .../src/shared/ManagerConnection.cpp | 8 +-- .../TaskManager/src/shared/TaskManager.cpp | 2 +- .../src/shared/PopulationList.cpp | 6 +- .../src/shared/common/GameNetworkMessage.cpp | 2 +- .../src/shared/common/GameNetworkMessage.h | 2 +- .../ours/library/archive/src/shared/Archive.h | 60 +++++-------------- .../archive/src/shared/AutoDeltaByteStream.h | 2 +- .../library/archive/src/shared/AutoDeltaMap.h | 32 +++++----- .../archive/src/shared/AutoDeltaPackedMap.h | 45 ++++---------- .../archive/src/shared/AutoDeltaQueue.h | 18 +++--- .../library/archive/src/shared/AutoDeltaSet.h | 30 +++++----- .../archive/src/shared/AutoDeltaVector.h | 40 ++++++------- .../library/archive/src/shared/ByteStream.cpp | 35 +++++++++++ .../localization/src/shared/StringId.cpp | 4 +- .../localization/src/shared/StringId.h | 10 ++-- .../src/shared/StringIdArchive.cpp | 2 +- .../src/shared/core/SwgSnapshot.cpp | 40 ++++++------- 19 files changed, 164 insertions(+), 180 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3594347c..7a066532d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,13 +77,13 @@ elseif (UNIX) endif () # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS - set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -g3") + set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -ggdb") # release specific cflags - optimizations beyond the default for both types is mostly just -O flags set(CMAKE_CXX_FLAGS_RELEASE "-DDEBUG_LEVEL=0 -DPRODUCTION=1") # we use fewer, if any, crazy optimizations for profile generation, and likewise release flags for the minsizerel - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}") # Ofast doesn't work with gcc builds diff --git a/engine/server/application/TaskManager/src/shared/GameConnection.cpp b/engine/server/application/TaskManager/src/shared/GameConnection.cpp index baa6adfb1..afbbc6cce 100755 --- a/engine/server/application/TaskManager/src/shared/GameConnection.cpp +++ b/engine/server/application/TaskManager/src/shared/GameConnection.cpp @@ -79,7 +79,7 @@ void GameConnection::receive(const Archive::ByteStream & message) { if(! m_pid) { - GenericValueTypeMessage msg(r); + GenericValueTypeMessage msg(r); m_pid = msg.getValue(); #ifndef _WIN32 diff --git a/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp b/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp index 42db20990..d131eff9e 100755 --- a/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp +++ b/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp @@ -103,8 +103,8 @@ void ManagerConnection::onReceive(const Archive::ByteStream & message) switch(messageType) { case constcrc("SystemTimeCheck") : { - long const currentTime = static_cast(::time(nullptr)); - GenericValueTypeMessage > msg(r); + int32_t const currentTime = static_cast(::time(nullptr)); + GenericValueTypeMessage > msg(r); if (TaskManager::getNodeLabel() == "node0") { @@ -150,7 +150,7 @@ void ManagerConnection::onReceive(const Archive::ByteStream & message) { LOG("CustomerService", ("system_clock_mismatch:System clock mismatch (%d seconds) by more than %d seconds: master TaskManager epoch (%ld), remote TaskManager %s (%s) epoch (%ld). Telling remote TaskManager to terminate.", (std::max(currentTime, t.getCurrentEpochTime()) - std::min(currentTime, t.getCurrentEpochTime())), ConfigTaskManager::getMaximumClockDriftToleranceSeconds(), currentTime, t.getCommandLine().c_str(), getRemoteAddress().c_str(), t.getCurrentEpochTime())); - GenericValueTypeMessage > > systemTimeMismatchMessage("SystemTimeMismatchMessage", std::make_pair(TaskManager::getNodeLabel(), std::make_pair(static_cast(currentTime), t.getCurrentEpochTime()))); + GenericValueTypeMessage > > systemTimeMismatchMessage("SystemTimeMismatchMessage", std::make_pair(TaskManager::getNodeLabel(), std::make_pair(static_cast(currentTime), static_cast (t.getCurrentEpochTime())))); send(systemTimeMismatchMessage); } } @@ -166,7 +166,7 @@ void ManagerConnection::onReceive(const Archive::ByteStream & message) } case constcrc("SystemTimeMismatchMessage") : { - GenericValueTypeMessage > > msg(r); + GenericValueTypeMessage > > msg(r); FATAL((msg.getValue().first == "node0"), ("System clock mismatch (%d seconds) by more than %d seconds: master TaskManager epoch (%ld), self epoch (%ld)", (std::max(msg.getValue().second.first, msg.getValue().second.second) - std::min(msg.getValue().second.first, msg.getValue().second.second)), ConfigTaskManager::getMaximumClockDriftToleranceSeconds(), msg.getValue().second.first, msg.getValue().second.second)); break; } diff --git a/engine/server/application/TaskManager/src/shared/TaskManager.cpp b/engine/server/application/TaskManager/src/shared/TaskManager.cpp index f4a9ec31d..356271dbc 100755 --- a/engine/server/application/TaskManager/src/shared/TaskManager.cpp +++ b/engine/server/application/TaskManager/src/shared/TaskManager.cpp @@ -970,7 +970,7 @@ void TaskManager::update() ManagerConnection * master = Locator::getServer("node0"); if (master) { - GenericValueTypeMessage > msg("SystemTimeCheck", std::make_pair(getNodeLabel(), static_cast(timeNow))); + GenericValueTypeMessage > msg("SystemTimeCheck", std::make_pair(getNodeLabel(), static_cast(timeNow))); master->send(msg); } } diff --git a/engine/server/library/serverUtility/src/shared/PopulationList.cpp b/engine/server/library/serverUtility/src/shared/PopulationList.cpp index 80db4b1eb..1209b786f 100755 --- a/engine/server/library/serverUtility/src/shared/PopulationList.cpp +++ b/engine/server/library/serverUtility/src/shared/PopulationList.cpp @@ -115,9 +115,9 @@ namespace Archive { void get(ReadIterator & source, PopulationList & target) { - size_t numEntries; + int32_t numEntries; get(source,numEntries); - for (size_t count=0; count < numEntries; ++count) + for (int32_t count=0; count < numEntries; ++count) { std::string scene; int x; @@ -133,7 +133,7 @@ namespace Archive void put(ByteStream & target, const PopulationList & source) { - put(target,source.m_populationMap.size()); + put(target, static_cast (source.m_populationMap.size())); for (PopulationList::PopulationMapType::const_iterator i=source.m_populationMap.begin(); i!=source.m_populationMap.end(); ++i) { put(target,i->first.getScene()); diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.cpp b/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.cpp index bd1a5db36..651c01ae9 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.cpp +++ b/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.cpp @@ -122,7 +122,7 @@ std::string const &GameNetworkMessage::getCmdName() const // ---------------------------------------------------------------------- -std::string const &GameNetworkMessage::getCmdName(unsigned long cmdCrc) // static +std::string const &GameNetworkMessage::getCmdName(uint32_t cmdCrc) // static { std::string &val = s_messageTypes[cmdCrc]; if (val.empty()) diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h index cac844662..2ee7de9b9 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/common/GameNetworkMessage.h @@ -39,7 +39,7 @@ class GameNetworkMessage: public Archive::AutoByteStream, public MessageDispatch std::string const &getCmdName() const; static std::vector > const getMessageCount(); - static std::string const &getCmdName(unsigned long cmdCrc); + static std::string const &getCmdName(uint32_t cmdCrc); private: GameNetworkMessage(); diff --git a/external/ours/library/archive/src/shared/Archive.h b/external/ours/library/archive/src/shared/Archive.h index 2921d66f7..b47190c19 100755 --- a/external/ours/library/archive/src/shared/Archive.h +++ b/external/ours/library/archive/src/shared/Archive.h @@ -30,42 +30,28 @@ inline void get(ReadIterator & source, float & target) //--------------------------------------------------------------------- -inline void get(ReadIterator & source, unsigned long int & target) +inline void get(ReadIterator & source, uint32_t & target) { source.get(&target, 4); } //--------------------------------------------------------------------- -inline void get(ReadIterator & source, signed long int & target) +inline void get(ReadIterator & source, int32_t & target) { source.get(&target, 4); } //--------------------------------------------------------------------- -inline void get(ReadIterator & source, unsigned int & target) -{ - source.get(&target, 4); -} - -//--------------------------------------------------------------------- - -inline void get(ReadIterator & source, signed int & target) -{ - source.get(&target, 4); -} - -//--------------------------------------------------------------------- - -inline void get(ReadIterator & source, unsigned short int & target) +inline void get(ReadIterator & source, uint16_t & target) { source.get(&target, 2); } //--------------------------------------------------------------------- -inline void get(ReadIterator & source, signed short int & target) +inline void get(ReadIterator & source, int16_t & target) { source.get(&target, 2); } @@ -190,9 +176,9 @@ template inline void get_ptr(ReadIterator & source, std::vector inline void get(ReadIterator & source, std::map & target) { - size_t numKeys; + int32_t numKeys; get(source, numKeys); - size_t i; + int32_t i; for(i = 0; i < numKeys; ++i) { Key k; @@ -229,42 +215,28 @@ inline void put(ByteStream & target, const float & source) //--------------------------------------------------------------------- -inline void put(ByteStream & target, const unsigned long int & source) -{ - target.put(&source, 4); -} - -//--------------------------------------------------------------------- - -inline void put(ByteStream & target, const signed long int & source) -{ - target.put(&source, 4); -} - -//--------------------------------------------------------------------- - -inline void put(ByteStream & target, const unsigned int & source) +inline void put(ByteStream & target, const uint32_t & source) { target.put(&source, 4); } //--------------------------------------------------------------------- -inline void put(ByteStream & target, const signed int & source) +inline void put(ByteStream & target, const int32_t & source) { target.put(&source, 4); } //--------------------------------------------------------------------- -inline void put(ByteStream & target, const unsigned short int & source) +inline void put(ByteStream & target, const uint16_t & source) { target.put(&source, 2); } //--------------------------------------------------------------------- -inline void put(ByteStream & target, const signed short int & source) +inline void put(ByteStream & target, const int16_t & source) { target.put(&source, 2); } @@ -296,12 +268,12 @@ inline void put(ByteStream & target, const std::string & source) { if (source.size() < 65535) { - unsigned short len = static_cast(source.size()); + unsigned short len = static_cast(source.size()); put(target, len); } else { - unsigned short len = static_cast(65535); + unsigned short len = static_cast(65535); put(target, len); unsigned int size = source.size(); put(target, size); @@ -345,7 +317,7 @@ template inline void put(ByteStream & target, const std: template inline void put(ByteStream & target, const std::vector & source) { - signed int length = source.size(); + int32_t length = source.size(); target.put(&length, 4); for(int i = 0; i < length; ++i) { @@ -357,7 +329,7 @@ template inline void put(ByteStream & target, const std::vector & template inline void put(ByteStream & target, const std::set & source) { - signed int length = source.size(); + int32_t length = source.size(); target.put(&length, 4); for (typename std::set::const_iterator i = source.begin(); i != source.end(); ++i) put(target, *i); @@ -367,7 +339,7 @@ template inline void put(ByteStream & target, const std::set & so template inline void put(ByteStream & target, const std::deque & source) { - signed int length = source.size(); + int32_t length = source.size(); target.put(&length, 4); for(int i = 0; i < length; ++i) { @@ -379,7 +351,7 @@ template inline void put(ByteStream & target, const std::deque & template inline void put(ByteStream & target, const std::map & source) { - size_t numKeys = source.size(); + int32_t numKeys = source.size(); put(target, numKeys); for (typename std::map::const_iterator i = source.begin(); i != source.end(); ++i) { diff --git a/external/ours/library/archive/src/shared/AutoDeltaByteStream.h b/external/ours/library/archive/src/shared/AutoDeltaByteStream.h index 53b4d07d0..64519aa06 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaByteStream.h +++ b/external/ours/library/archive/src/shared/AutoDeltaByteStream.h @@ -726,7 +726,7 @@ class AutoDeltaContainer : public AutoDeltaVariableBase /** pure virtual */ virtual ~AutoDeltaContainer() = 0; /** pure virtual */ - virtual const size_t size() const = 0; + virtual const int32_t size() const = 0; }; //----------------------------------------------------------------------- diff --git a/external/ours/library/archive/src/shared/AutoDeltaMap.h b/external/ours/library/archive/src/shared/AutoDeltaMap.h index 9256495cf..ca223a0f8 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaMap.h +++ b/external/ours/library/archive/src/shared/AutoDeltaMap.h @@ -65,7 +65,7 @@ class AutoDeltaMap : public AutoDeltaContainer void pack(ByteStream & target) const; void packDelta(ByteStream & target) const; void set(const KeyType & key, const ValueType & value); - const size_t size() const; + const int32_t size() const; void unpack(ReadIterator & source); void unpackDelta(ReadIterator & source); static void pack(ByteStream & target, const std::vector & data); @@ -88,7 +88,7 @@ class AutoDeltaMap : public AutoDeltaContainer void onSet(const KeyType &, const ValueType &, const ValueType &); MapType container; - size_t baselineCommandCount; + int32_t baselineCommandCount; mutable std::vector changes; std::pair *onEraseCallback; std::pair *onInsertCallback; @@ -349,7 +349,7 @@ template inline void AutoDeltaMap::pack(ByteStream & target) const { typename std::map::const_iterator i; - Archive::put(target, container.size()); + Archive::put(target, static_cast(container.size())); Archive::put(target, baselineCommandCount); unsigned char cmd; for(i = container.begin(); i != container.end(); ++i) @@ -374,8 +374,8 @@ inline void AutoDeltaMap::pack(ByteStream & targ template inline void AutoDeltaMap::pack(ByteStream & target, const std::vector &data) { - Archive::put(target, data.size()); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(data.size())); + Archive::put(target, static_cast(0)); // baselineCommandCount for(typename std::vector::const_iterator c(data.begin()); c != data.end(); ++c) { assert(c->cmd == Command::ADD); // only add is valid in packing the whole container @@ -403,7 +403,7 @@ inline void AutoDeltaMap::pack(ByteStream & targ template inline void AutoDeltaMap::packDelta(ByteStream & target) const { - Archive::put(target, changes.size()); + Archive::put(target, static_cast(changes.size())); Archive::put(target, baselineCommandCount); for (typename std::vector::iterator i = changes.begin(); i != changes.end(); ++i) { @@ -435,7 +435,7 @@ inline void AutoDeltaMap::packDelta(ByteStream & @return the number of elements in the map */ template -inline const size_t AutoDeltaMap::size() const +inline const int32_t AutoDeltaMap::size() const { return container.size(); } @@ -514,12 +514,12 @@ inline void AutoDeltaMap::unpack(ReadIterator & clearDelta(); Command c; - size_t commandCount; + int32_t commandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); assert(c.cmd == Command::ADD); // only add is valid in unpack @@ -548,13 +548,13 @@ inline void AutoDeltaMap::unpack(ReadIterator & // unpacking baseline data Command c; - size_t commandCount; - size_t baselineCommandCount; + int32_t commandCount; + int32_t baselineCommandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); assert(c.cmd == Command::ADD); // only add is valid in unpack @@ -572,7 +572,7 @@ template inline void AutoDeltaMap::unpackDelta(ReadIterator & source) { Command c; - size_t skipCount, commandCount, targetBaselineCommandCount; + int32_t skipCount, commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); @@ -593,7 +593,7 @@ inline void AutoDeltaMap::unpackDelta(ReadIterat if (skipCount > commandCount) skipCount = commandCount; - size_t i; + int32_t i; for (i = 0; i < skipCount; ++i) { Archive::get(source, c.cmd); @@ -647,12 +647,12 @@ template inline void AutoDeltaMap::unpackDelta(ReadIterator & source, std::vector & data) { Command c; - size_t commandCount, targetBaselineCommandCount; + int32_t commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); - for (size_t i=0 ; i < commandCount; ++i) + for (int32_t i=0 ; i < commandCount; ++i) { Archive::get(source, c.cmd); switch(c.cmd) diff --git a/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h index 466bbde35..f6b0539f6 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h +++ b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h @@ -23,8 +23,8 @@ namespace Archive void get(ReadIterator & source, unsigned __int64 & target); void put(ByteStream & target, const unsigned __int64 & source); #else - void get(ReadIterator & source, unsigned long long int & target); - void put(ByteStream & target, const unsigned long long int & source); + void get(ReadIterator & source, uint64_t & target); + void put(ByteStream & target, const uint64_t & source); #endif /** * An AutoDeltaPackedMap is an AutoDeltaMap that will be packed into @@ -100,7 +100,7 @@ namespace Archive typename AutoDeltaMap::Command c; Archive::put(target, countCharacter(buffer,':')); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(0)); // baselineCommandCount int tempPos = 0; for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i) @@ -127,8 +127,8 @@ namespace Archive char temp[200]; typename AutoDeltaMap::Command c; - size_t commandCount; - size_t baselineCommandCount; + int32_t commandCount; + int32_t baselineCommandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); @@ -139,7 +139,7 @@ namespace Archive } else { - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); Archive::get(source, c.key); @@ -193,37 +193,25 @@ namespace Archive } template<> - inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) { internal_pack(target, buffer, "%i %i"); } template<> - inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) { internal_unpack(source, buffer, "%i %i:"); } template<> inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) - { - internal_pack(target, buffer, "%i %i"); - } - - template<> - inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) - { - internal_unpack(source, buffer, "%i %i:"); - } - - template<> - inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) { internal_pack(target, buffer, "%i %u"); } template<> - inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) { internal_unpack(source, buffer, "%i %u:"); } @@ -254,24 +242,13 @@ namespace Archive #else template<> - inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) - { - internal_pack(target, buffer, "%lu %llu"); - } - - template<> - inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) - { - internal_unpack(source, buffer, "%lu %llu:"); - } - template<> - inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) { internal_pack(target, buffer, "%lu %llu"); } template<> - inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) { internal_unpack(source, buffer, "%lu %llu:"); } diff --git a/external/ours/library/archive/src/shared/AutoDeltaQueue.h b/external/ours/library/archive/src/shared/AutoDeltaQueue.h index 5b29aacf3..d0305e8ca 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaQueue.h +++ b/external/ours/library/archive/src/shared/AutoDeltaQueue.h @@ -46,7 +46,7 @@ class AutoDeltaQueue: public AutoDeltaContainer const bool isDirty() const; void pack(ByteStream &target) const; void packDelta(ByteStream &target) const; - const size_t size() const; + const int32_t size() const; void unpack(ReadIterator &source); void unpackDelta(ReadIterator &source); @@ -72,7 +72,7 @@ class AutoDeltaQueue: public AutoDeltaContainer }; QueueType container; - size_t baselineCommandCount; + uint32_t baselineCommandCount; mutable std::vector changes; AutoDeltaQueue &operator=(AutoDeltaQueue const &); @@ -251,7 +251,7 @@ template inline void AutoDeltaQueue::pack(ByteStream &target) const { const_iterator i; - Archive::put(target, container.size()); + Archive::put(target, static_cast (container.size())); Archive::put(target, baselineCommandCount); unsigned char cmd; for (i = container.begin(); i != container.end(); ++i) @@ -267,7 +267,7 @@ inline void AutoDeltaQueue::pack(ByteStream &target) const template inline void AutoDeltaQueue::packDelta(ByteStream &target) const { - Archive::put(target, changes.size()); + Archive::put(target, static_cast (changes.size())); Archive::put(target, baselineCommandCount); for (typename std::vector::iterator i = changes.begin(); i != changes.end(); ++i) { @@ -293,7 +293,7 @@ inline void AutoDeltaQueue::packDelta(ByteStream &target) const //----------------------------------------------------------------------- template -inline const size_t AutoDeltaQueue::size() const +inline const int32_t AutoDeltaQueue::size() const { return container.size(); } @@ -324,12 +324,12 @@ inline void AutoDeltaQueue::unpack(ReadIterator &source) clearDelta(); ModifyCommand c; - size_t commandCount; + int32_t commandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); assert(c.cmd == ModifyCommand::PUSH); // only push valid for pack/unpack @@ -345,7 +345,7 @@ inline void AutoDeltaQueue::unpackDelta(ReadIterator &source) { using Archive::get; ModifyCommand c; - size_t skipCount, commandCount, targetBaselineCommandCount; + int32_t skipCount, commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); @@ -359,7 +359,7 @@ inline void AutoDeltaQueue::unpackDelta(ReadIterator &source) if (skipCount > commandCount) skipCount = commandCount; - size_t i; + int32_t i; for (i = 0; i < skipCount; ++i) { Archive::get(source, c.cmd); diff --git a/external/ours/library/archive/src/shared/AutoDeltaSet.h b/external/ours/library/archive/src/shared/AutoDeltaSet.h index e413c21e7..14cf1e2df 100644 --- a/external/ours/library/archive/src/shared/AutoDeltaSet.h +++ b/external/ours/library/archive/src/shared/AutoDeltaSet.h @@ -57,7 +57,7 @@ class AutoDeltaSet: public AutoDeltaContainer void packDelta(ByteStream &target) const; SetType const & get() const; - const size_t size() const; + const int32_t size() const; bool empty() const; bool contains(ValueType const &t) const; const_iterator find(ValueType const &t) const; @@ -84,7 +84,7 @@ class AutoDeltaSet: public AutoDeltaContainer private: SetType m_set; - size_t m_baselineCommandCount; + uint32_t m_baselineCommandCount; mutable std::vector m_commands; std::pair *m_onChangedCallback; std::pair *m_onEraseCallback; @@ -301,7 +301,7 @@ inline void AutoDeltaSet::onInsert(ValueType const &value template inline void AutoDeltaSet::pack(ByteStream &target) const { - Archive::put(target, m_set.size()); + Archive::put(target, static_cast (m_set.size())); Archive::put(target, m_baselineCommandCount); for (typename SetType::const_iterator i = m_set.begin(); i != m_set.end(); ++i) put(target, *i); @@ -312,8 +312,8 @@ inline void AutoDeltaSet::pack(ByteStream &target) const template inline void AutoDeltaSet::pack(ByteStream &target, std::set const &data) { - Archive::put(target, data.size()); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast (data.size())); + Archive::put(target, static_cast (0)); // baselineCommandCount for (typename std::set::const_iterator i = data.begin(); i != data.end(); ++i) put(target, *i); } @@ -323,7 +323,7 @@ inline void AutoDeltaSet::pack(ByteStream &target, std::s template inline void AutoDeltaSet::packDelta(ByteStream &target) const { - Archive::put(target, m_commands.size()); + Archive::put(target, static_cast (m_commands.size())); Archive::put(target, m_baselineCommandCount); for (typename std::vector::iterator i = m_commands.begin(); i != m_commands.end(); ++i) { @@ -402,7 +402,7 @@ inline bool AutoDeltaSet::empty() const //----------------------------------------------------------------------- template -inline const size_t AutoDeltaSet::size() const +inline const int32_t AutoDeltaSet::size() const { return m_set.size(); } @@ -415,13 +415,13 @@ inline void AutoDeltaSet::unpack(ReadIterator &source) m_set.clear(); clearDelta(); - size_t commandCount; + int32_t commandCount; ValueType value; Archive::get(source, commandCount); Archive::get(source, m_baselineCommandCount); using Archive::get; - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { get(source, value); m_set.insert(value); @@ -436,13 +436,13 @@ template inline void AutoDeltaSet::unpack(ReadIterator &source, std::vector &data) { Command c; - size_t commandCount, targetBaselineCommandCount; + int32_t commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); c.cmd = Command::INSERT; - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source,c.value); data.push_back(c); @@ -455,12 +455,12 @@ template inline void AutoDeltaSet::unpackDelta(ReadIterator &source, std::vector &data) { Command c; - size_t commandCount, targetBaselineCommandCount; + int32_t commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); - for (size_t i = 0 ; i < commandCount; ++i) + for (int32_t i = 0 ; i < commandCount; ++i) { Archive::get(source, c.cmd); switch (c.cmd) @@ -486,7 +486,7 @@ inline void AutoDeltaSet::unpackDelta(ReadIterator &sourc { using Archive::get; Command c; - size_t skipCount, commandCount, targetBaselineCommandCount; + int32_t skipCount, commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); @@ -503,7 +503,7 @@ inline void AutoDeltaSet::unpackDelta(ReadIterator &sourc if (skipCount > commandCount) skipCount = commandCount; - size_t i = 0; + int32_t i = 0; for ( ; i < skipCount; ++i) { Archive::get(source, c.cmd); diff --git a/external/ours/library/archive/src/shared/AutoDeltaVector.h b/external/ours/library/archive/src/shared/AutoDeltaVector.h index 5d2d37bf8..e7979a41c 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaVector.h +++ b/external/ours/library/archive/src/shared/AutoDeltaVector.h @@ -39,7 +39,7 @@ class AutoDeltaVector : public AutoDeltaContainer public: AutoDeltaVector(); - explicit AutoDeltaVector(size_t initialSize); + explicit AutoDeltaVector(int32_t initialSize); ~AutoDeltaVector(); const ValueType & back () const; @@ -74,7 +74,7 @@ class AutoDeltaVector : public AutoDeltaContainer void setOnInsert (ObjectType * owner, void (ObjectType::*onInsert)(const unsigned int, const ValueType &)); void setOnSet (ObjectType * owner, void (ObjectType::*onSet)(const unsigned int, const ValueType &, const ValueType &)); - const size_t size () const; + const int32_t size () const; bool empty () const; const ValueType & operator[] (const unsigned int element) const; @@ -91,7 +91,7 @@ class AutoDeltaVector : public AutoDeltaContainer private: std::vector v; - size_t baselineCommandCount; + int32_t baselineCommandCount; mutable std::vector commands; std::pair * onChangedCallback; std::pair * onEraseCallback; @@ -120,7 +120,7 @@ onSetCallback(0) //----------------------------------------------------------------------- template -inline AutoDeltaVector::AutoDeltaVector(size_t initialSize) : +inline AutoDeltaVector::AutoDeltaVector(int32_t initialSize) : AutoDeltaContainer(), v(initialSize), baselineCommandCount(0), @@ -366,7 +366,7 @@ inline void AutoDeltaVector::onSet(const unsigned int ele template inline void AutoDeltaVector::pack(ByteStream & target) const { - Archive::put(target, v.size()); + Archive::put(target, static_cast (v.size())); Archive::put(target, baselineCommandCount); typename std::vector::const_iterator i; for (i = v.begin(); i != v.end(); ++i) @@ -380,8 +380,8 @@ inline void AutoDeltaVector::pack(ByteStream & target) co template inline void AutoDeltaVector::pack(ByteStream & target, const std::vector & data) { - Archive::put(target, data.size()); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(data.size())); + Archive::put(target, static_cast(0)); // baselineCommandCount typename std::vector::const_iterator i; for (i = data.begin(); i != data.end(); ++i) { @@ -394,7 +394,7 @@ inline void AutoDeltaVector::pack(ByteStream & target, co template inline void AutoDeltaVector::packDelta(ByteStream & target) const { - Archive::put(target, commands.size()); + Archive::put(target, static_cast(commands.size())); Archive::put(target, baselineCommandCount); typename std::vector::iterator i; @@ -483,13 +483,13 @@ inline void AutoDeltaVector::resize(size_type n, ValueTyp { // expand the vector v.resize(n); - for (size_t i = size; i < n; ++i) + for (int32_t i = size; i < n; ++i) set(i, x); } else if (size > n) { // contract the vector - for (size_t i = size - 1; i >= n; --i) + for (int32_t i = size - 1; i >= n; --i) { erase(i); @@ -607,7 +607,7 @@ inline bool AutoDeltaVector::empty() const //----------------------------------------------------------------------- template -inline const size_t AutoDeltaVector::size() const +inline const int32_t AutoDeltaVector::size() const { return v.size(); } @@ -622,13 +622,13 @@ inline void AutoDeltaVector::unpack(ReadIterator & source v.clear(); clearDelta(); - size_t commandCount; + int32_t commandCount; ValueType value; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { get(source, value); v.push_back(value); @@ -644,14 +644,14 @@ inline void AutoDeltaVector::unpack(ReadIterator & source { using Archive::get; // unpacking the whole kazaba - size_t commandCount; - size_t bcc; + int32_t commandCount; + int32_t bcc; Command c; Archive::get(source, commandCount); Archive::get(source, bcc); - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { get(source,c.value); c.index = static_cast(i); @@ -668,12 +668,12 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s { using Archive::get; Command c; - size_t commandCount, targetBaselineCommandCount; + int32_t commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); - for (size_t i=0 ; i < commandCount; ++i) + for (int32_t i=0 ; i < commandCount; ++i) { Archive::get(source, c.cmd); switch (c.cmd) @@ -708,7 +708,7 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s { using Archive::get; Command c; - size_t skipCount, commandCount, targetBaselineCommandCount; + int32_t skipCount, commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); @@ -719,7 +719,7 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s if (skipCount > commandCount) skipCount = commandCount; - size_t i; + int32_t i; for (i = 0; i < skipCount; ++i) { Archive::get(source, c.cmd); diff --git a/external/ours/library/archive/src/shared/ByteStream.cpp b/external/ours/library/archive/src/shared/ByteStream.cpp index 4965bc8cf..13aab2c1a 100755 --- a/external/ours/library/archive/src/shared/ByteStream.cpp +++ b/external/ours/library/archive/src/shared/ByteStream.cpp @@ -5,6 +5,16 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + // ====================================================================== //static volatile int s_dataFreeListLocked; @@ -233,6 +243,31 @@ void ByteStream::get(void *target, ReadIterator &readIterator, const unsigned lo else { static const char * const desc = "Archive::ByteStream - read beyond end of buffer"; + std::cout << "read position: " << readIterator.getReadPosition() << " target size: " << targetSize << " allocated size: " << allocatedSize << std::endl; + std::cout << "I'm being called from: " << program_invocation_name; + std::cout << "======> BUFFER: " << std::endl; + + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (int i = 0; i < allocatedSize; ++i) + { + ss << std::setw(2) << static_cast(data->buffer[i]); + } + std::cout << ss.str() << std::endl; + + char pid_buf[30]; + sprintf(pid_buf, "%d", getpid()); + char name_buf[512]; + name_buf[readlink("/proc/self/exe", name_buf, 511)]=0; + prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); + int child_pid = fork(); + if (!child_pid) { + dup2(2,1); // redirect output to stderr - edit: unnecessary? + execl("/usr/bin/gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL); + abort(); /* If gdb failed to start */ + } else { + waitpid(child_pid,NULL,0); + } ReadException ex(desc); throw (ex); } diff --git a/external/ours/library/localization/src/shared/StringId.cpp b/external/ours/library/localization/src/shared/StringId.cpp index cb1492e41..3e8c28ba0 100755 --- a/external/ours/library/localization/src/shared/StringId.cpp +++ b/external/ours/library/localization/src/shared/StringId.cpp @@ -39,7 +39,7 @@ m_textIndex (0) //---------------------------------------------------------------------- -StringId::StringId (const std::string & table, unsigned long textIndex) : +StringId::StringId (const std::string & table, uint32_t textIndex) : m_table (table), m_text (), m_textIndex (textIndex) @@ -238,7 +238,7 @@ void StringId::setText (const std::string & text) //---------------------------------------------------------------------- -void StringId::setTextIndex (unsigned long textIndex) const +void StringId::setTextIndex (uint32_t textIndex) const { m_textIndex = textIndex; } diff --git a/external/ours/library/localization/src/shared/StringId.h b/external/ours/library/localization/src/shared/StringId.h index 4b4572df1..752a2cebe 100755 --- a/external/ours/library/localization/src/shared/StringId.h +++ b/external/ours/library/localization/src/shared/StringId.h @@ -39,12 +39,12 @@ class StringId StringId (); StringId (const std::string & table, const std::string & text); - StringId (const std::string & table, unsigned long textIndex); + StringId (const std::string & table, uint32_t textIndex); explicit StringId (const std::string & canonicalRepresentation); const std::string & getTable () const; const std::string & getText () const; - unsigned long getTextIndex () const; + uint32_t getTextIndex () const; bool isInvalid () const; bool isValid () const; @@ -60,7 +60,7 @@ class StringId //-- text index is a mutable property of the StringId //-- it is set the first time a StringId is localized, to speed up future lookups - void setTextIndex (unsigned long textIndex) const; + void setTextIndex (uint32_t textIndex) const; bool localize (LocUnicodeString & result, bool forceEnglish = false) const; LocUnicodeString localize (bool forceEnglish = false) const; @@ -79,7 +79,7 @@ class StringId std::string m_table; std::string m_text; - mutable unsigned long m_textIndex; //if this number is nonzero, assume it is valid + mutable uint32_t m_textIndex; //if this number is nonzero, assume it is valid }; //---------------------------------------------------------------------- @@ -98,7 +98,7 @@ inline const std::string & StringId::getText() const //---------------------------------------------------------------------- -inline unsigned long StringId::getTextIndex() const +inline uint32_t StringId::getTextIndex() const { return m_textIndex; } diff --git a/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp b/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp index b4054a253..028bbfdaf 100755 --- a/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp +++ b/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp @@ -23,7 +23,7 @@ namespace Archive */ void get(ReadIterator & source, StringId & target) { - unsigned long index = 0; + int32_t index = 0; std::string table; std::string name; diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp index a111e70ca..dc9f96fac 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp @@ -331,21 +331,21 @@ void SwgSnapshot::encodeScriptObject(const NetworkId &objectId, Archive::ByteStr void SwgSnapshot::decodeAttributes(const NetworkId &objectId, Archive::ReadIterator &data, bool isBaseline, int offset) { if (isBaseline) { - size_t size, baselineCommandCount; + int32_t size, baselineCommandCount; Archive::get(data, size); Archive::get(data, baselineCommandCount); Attributes::Value temp; - for (size_t i = 0; i < size; ++i) { + for (int32_t i = 0; i < size; ++i) { Archive::get(data, temp); m_creatureObjectBuffer.setAttribute(objectId, i + offset, temp); } } else { typedef Archive::AutoDeltaVector VectorType; - size_t numCommands, baselineCommandCount; + int32_t numCommands, baselineCommandCount; Archive::get(data, numCommands); Archive::get(data, baselineCommandCount); - for (size_t count = 0; count < numCommands; ++count) { + for (int32_t count = 0; count < numCommands; ++count) { unsigned char cmd;// datatype? uint16 index; @@ -386,8 +386,8 @@ void SwgSnapshot::encodeAttributes(const NetworkId &objectId, Archive::ByteStrea std::vector values; m_creatureObjectBuffer.getAttributesForObject(objectId, values, offset, Attributes::NumberOfAttributes); - Archive::put(data, Attributes::NumberOfAttributes); - Archive::put(data, static_cast(0)); // baselineCommandCount + Archive::put(data, static_cast (Attributes::NumberOfAttributes)); + Archive::put(data, static_cast(0)); // baselineCommandCount if (values.size() < static_cast(Attributes::NumberOfAttributes)) { DEBUG_REPORT_LOG(true, ("Object %s did not have valid attribute data in the database. Missing attributes will be set to 100.\n", objectId.getValueString().c_str())); values.resize(Attributes::NumberOfAttributes, 100); @@ -754,21 +754,21 @@ void SwgSnapshot::ignorePersistedFlag(const NetworkId &objectId, Archive::ReadIt void SwgSnapshot::decodeLocationDataList(const NetworkId &objectId, size_t listId, Archive::ReadIterator &data, bool isBaseline) { if (isBaseline) { - size_t size, baselineCommandCount; + int32_t size, baselineCommandCount; Archive::get(data, size); Archive::get(data, baselineCommandCount); LocationData temp; - for (size_t i = 0; i < size; ++i) { + for (int32_t i = 0; i < size; ++i) { Archive::get(data, temp); m_locationBuffer.set(objectId, listId, i, temp); } } else { typedef Archive::AutoDeltaVector VectorType; - size_t numCommands, baselineCommandCount; + int32_t numCommands, baselineCommandCount; Archive::get(data, numCommands); Archive::get(data, baselineCommandCount); - for (size_t count = 0; count < numCommands; ++count) { + for (int32_t count = 0; count < numCommands; ++count) { unsigned char cmd; uint16 index; @@ -813,8 +813,8 @@ void SwgSnapshot::encodeLocationDataList(const NetworkId &objectId, size_t listI std::vector values; m_locationBuffer.getLocationList(objectId, listId, values); - Archive::put(data, values.size()); - Archive::put(data, static_cast(0)); + Archive::put(data, static_cast (values.size())); + Archive::put(data, static_cast(0)); for (std::vector::iterator i = values.begin(); i != values.end(); ++i) { Archive::put(data, *i); } @@ -855,8 +855,8 @@ void SwgSnapshot::encodeExperience(const NetworkId &objectId, Archive::ByteStrea ValuesType values; m_experienceBuffer.getExperienceForObject(objectId, values); - Archive::put(data, values.size()); - Archive::put(data, static_cast(0)); // baselineCommandCount + Archive::put(data, static_cast (values.size())); + Archive::put(data, static_cast (0)); // baselineCommandCount for (ValuesType::const_iterator i = values.begin(); i != values.end(); ++i) { const unsigned char command = 0; //ADD Archive::put(data, command); @@ -901,8 +901,8 @@ void SwgSnapshot::encodeBattlefieldParticipants(const NetworkId &objectId, Archi ValuesType values; m_battlefieldParticipantBuffer.getParticipantsForRegion(objectId, values); - Archive::put(data, values.size()); - Archive::put(data, static_cast(0)); // baselineCommandCount + Archive::put(data, static_cast (values.size())); + Archive::put(data, static_cast (0)); // baselineCommandCount for (ValuesType::const_iterator i = values.begin(); i != values.end(); ++i) { const unsigned char command = 0; //ADD Archive::put(data, command); @@ -945,8 +945,8 @@ void SwgSnapshot::encodeManufactureSchematicAttributes(const NetworkId &objectId ValuesType values; m_manufactureSchematicAttributeBuffer.getDataForObject(objectId, values); - Archive::put(data, values.size()); - Archive::put(data, static_cast(0)); // baselineCommandCount + Archive::put(data, static_cast (values.size())); + Archive::put(data, static_cast (0)); // baselineCommandCount for (ValuesType::const_iterator i = values.begin(); i != values.end(); ++i) { const unsigned char command = 0; //ADD Archive::put(data, command); @@ -1087,8 +1087,8 @@ void SwgSnapshot::encodeWaypoints(const NetworkId &objectId, Archive::ByteStream ValuesType values; m_waypointBuffer.getWaypointsForObject(objectId, values); - Archive::put(data, values.size()); - Archive::put(data, static_cast(0)); // baselineCommandCount + Archive::put(data, static_cast (values.size())); + Archive::put(data, static_cast (0)); // baselineCommandCount for (ValuesType::const_iterator i = values.begin(); i != values.end(); ++i) { const unsigned char command = 0; //ADD Archive::put(data, command); From a4367ad879d92c4bac58efa9a3b8565ca7456681 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 13 Nov 2021 03:12:15 -0500 Subject: [PATCH 13/46] Fixed issue with PlayerQuestData parsing - server is RUNNING --- .../sharedGame/src/shared/quest/PlayerQuestData.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/shared/library/sharedGame/src/shared/quest/PlayerQuestData.cpp b/engine/shared/library/sharedGame/src/shared/quest/PlayerQuestData.cpp index 841f584b4..29f20d491 100755 --- a/engine/shared/library/sharedGame/src/shared/quest/PlayerQuestData.cpp +++ b/engine/shared/library/sharedGame/src/shared/quest/PlayerQuestData.cpp @@ -259,8 +259,8 @@ namespace Archive char temp[200]; Command c; - size_t commandCount; - size_t baselineCommandCount; //lint !e578 hides a symbol elsewhere + int32_t commandCount; + int32_t baselineCommandCount; //lint !e578 hides a symbol elsewhere Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); @@ -274,7 +274,7 @@ namespace Archive // We need to sort the quests by age SortableQuestList sortedQuests; - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); Archive::get(source, c.key); @@ -314,8 +314,8 @@ namespace Archive char temp[200]; AutoDeltaMap::Command c; - Archive::put(target, countCharacter(buffer,':')); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast (countCharacter(buffer,':'))); + Archive::put(target, static_cast (0)); // baselineCommandCount int tempPos = 0; for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i) From 62db74b999829f5d596020324731265de1c7b903 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 13 Nov 2021 00:40:01 -0800 Subject: [PATCH 14/46] Updated readme and added recognition to Apathy Mega thanks to Apathy for his help in making the 64 bit version happen. Without his knowledge and super-special ability to act as a mega sounding board. Thanks for letting me ramble and lose my mind! --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ad7cb7b7..cec8d0139 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is the main server code for SWGSource 1.2 as originally forked from the https://bitbucket.org/stellabellumswg/ repository. Please see that repository for original publication and alteration credit. # Works in progress -* testing-64 - fully 64 bit version thatbuilds but doesn't run, some typedefs and things are wrong +* 64-bit-types - fully 64 bit version (presently in testing - 11/12/2021) (Special thanks to Apathy for his help in making a 64 bit version happen!) # Building @@ -37,4 +37,4 @@ See http://clang.llvm.org/docs/UsersManual.html#profiling-with-instrumentation f See http://www.swgsource.com/ for more information on the SWG Source project. -Join the SWGSource Discord if you would like to contribute: https://discord.gg/j53cMj9 \ No newline at end of file +Join the SWGSource Discord if you would like to contribute: https://discord.gg/j53cMj9 From ebe78d309b52e2e85beeb5ae99f273cd01f9fe7b Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 13 Nov 2021 00:42:08 -0800 Subject: [PATCH 15/46] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cec8d0139..6030460e6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ This is the main server code for SWGSource 1.2 as originally forked from the htt **Important**: For versions of clang <= 4 you'll probably have to remove/omit a deprecated CFLAG or two from the CMakelists.txt file -Only use the Debug and Release targets unless you want to work on 64 bit. For local testing, and non-live builds set MODE=Release or MODE=debug in build_linux.sh. +Only use the Debug and Release targets unless you want to work on 64 bit (MODE=RELWITHDEBINFO). For local testing, and non-live builds set MODE=Release or MODE=debug in build_linux.sh. For production, user facing builds, set MODE=MINSIZEREL for profile built, heavily optimized versions of the binaries. From 094525218e716b79414eb9fb23614742faec330f Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 17 Nov 2021 02:06:36 -0500 Subject: [PATCH 16/46] Adjusted a few more data types to fix communication issues. --- .../src/shared/core/CharacterMatchManager.cpp | 10 ++--- .../src/shared/core/CharacterMatchManager.h | 10 ++--- .../serverGame/src/shared/core/GameServer.cpp | 43 ++++++++++--------- .../serverGame/src/shared/core/GameServer.h | 4 +- .../GameConnectionServerMessages.cpp | 2 +- .../GameConnectionServerMessages.h | 8 ++-- .../src/shared/ScriptMethodsPlayerAccount.cpp | 2 +- .../src/shared/Message.cpp | 6 +-- .../src/shared/Message.h | 22 +++++----- .../sharedUtility/src/shared/DataTable.cpp | 4 +- 10 files changed, 56 insertions(+), 55 deletions(-) diff --git a/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.cpp b/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.cpp index 89668966b..cb3d32c4f 100755 --- a/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.cpp +++ b/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.cpp @@ -40,9 +40,9 @@ // ============================================================================ -unsigned long CharacterMatchManager::ms_numberOfCharacterMatchRequests = 0; -unsigned long CharacterMatchManager::ms_numberOfCharacterMatchResults = 0; -unsigned long CharacterMatchManager::ms_timeSpentOnCharacterMatchRequestsMs = 0; +uint32_t CharacterMatchManager::ms_numberOfCharacterMatchRequests = 0; +uint32_t CharacterMatchManager::ms_numberOfCharacterMatchResults = 0; +uint32_t CharacterMatchManager::ms_timeSpentOnCharacterMatchRequestsMs = 0; // ============================================================================ // @@ -639,14 +639,14 @@ void CharacterMatchManager::requestMatch(NetworkId const &networkId, MatchMaking requestCreatureObject->onCharacterMatchRetrieved(mmcr); } - const unsigned long endTimeMs = Clock::timeMs(); + const uint32_t endTimeMs = Clock::timeMs(); if (endTimeMs >= startTimeMs) { ms_timeSpentOnCharacterMatchRequestsMs += (endTimeMs - startTimeMs); } else // time wrapped { - static const unsigned long max = std::numeric_limits::max(); + static const uint32_t max = std::numeric_limits::max(); ms_timeSpentOnCharacterMatchRequestsMs += (max - startTimeMs + endTimeMs); } } diff --git a/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.h b/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.h index 7fe8ed0ae..900b5e888 100755 --- a/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.h +++ b/engine/server/library/serverGame/src/shared/core/CharacterMatchManager.h @@ -17,14 +17,14 @@ class CharacterMatchManager public: static void requestMatch(NetworkId const &networkId, MatchMakingCharacterPreferenceId const &matchMakingCharacterPreferenceId); - static void getMatchStatistics(unsigned long &numberOfCharacterMatchRequests, unsigned long &numberOfCharacterMatchResults, unsigned long &timeSpentOnCharacterMatchRequestsMs); + static void getMatchStatistics(uint32_t &numberOfCharacterMatchRequests, uint32_t &numberOfCharacterMatchResults, uint32_t &timeSpentOnCharacterMatchRequestsMs); static void clearMatchStatistics(); private: - static unsigned long ms_numberOfCharacterMatchRequests; - static unsigned long ms_numberOfCharacterMatchResults; - static unsigned long ms_timeSpentOnCharacterMatchRequestsMs; + static uint32_t ms_numberOfCharacterMatchRequests; + static uint32_t ms_numberOfCharacterMatchResults; + static uint32_t ms_timeSpentOnCharacterMatchRequestsMs; // Disable @@ -36,7 +36,7 @@ class CharacterMatchManager //----------------------------------------------------------------------- -inline void CharacterMatchManager::getMatchStatistics(unsigned long &numberOfCharacterMatchRequests, unsigned long &numberOfCharacterMatchResults, unsigned long &timeSpentOnCharacterMatchRequestsMs) +inline void CharacterMatchManager::getMatchStatistics(uint32_t &numberOfCharacterMatchRequests, uint32_t &numberOfCharacterMatchResults, uint32_t &timeSpentOnCharacterMatchRequestsMs) { numberOfCharacterMatchRequests = ms_numberOfCharacterMatchRequests; numberOfCharacterMatchResults = ms_numberOfCharacterMatchResults; diff --git a/engine/server/library/serverGame/src/shared/core/GameServer.cpp b/engine/server/library/serverGame/src/shared/core/GameServer.cpp index 80009486b..e1e7b75a0 100755 --- a/engine/server/library/serverGame/src/shared/core/GameServer.cpp +++ b/engine/server/library/serverGame/src/shared/core/GameServer.cpp @@ -233,6 +233,7 @@ #include "sharedFoundation/CrcConstexpr.hpp" #include +#include //----------------------------------------------------------------------- @@ -253,11 +254,11 @@ namespace GameServerNamespace const float IDLE_CLIENTS_CHECK_TIME_SEC = 30.0f; ServerCommandPermissionManager * s_permissionManager = 0; - unsigned long s_frameTime; - uint64 s_totalObjectCreateMessagesReceived; - uint64 s_totalObjectCreateMessagesSent; - bool s_metricsManagerInstalled = false; - uint32 s_lastTaskKeepaliveTime = 0; + uint32_t s_frameTime; + uint64 s_totalObjectCreateMessagesReceived; + uint64 s_totalObjectCreateMessagesSent; + bool s_metricsManagerInstalled = false; + uint32 s_lastTaskKeepaliveTime = 0; #ifdef _DEBUG int s_extraDelayPerFrameMs = 0; // to emulate long loop time @@ -266,11 +267,11 @@ namespace GameServerNamespace std::set s_clusterStartupResidenceStructureListResponse; std::map > s_clusterStartupResidenceStructureListByStructure; - unsigned long getFrameRateLimit(); + uint32_t getFrameRateLimit(); void broadCastHyperspaceOnWarp(ServerObject const * owner); ShipObject *getAttachedShip(CreatureObject *creature); - std::map s_pendingLoadRequests; + std::map s_pendingLoadRequests; struct CtsSourceCharacterInfo { @@ -745,7 +746,7 @@ void GameServer::dropClient(const NetworkId& oid, const bool immediate) //----------------------------------------------------------------------- -unsigned long GameServer::getFrameTime() const +uint32_t GameServer::getFrameTime() const { return s_frameTime; } @@ -895,7 +896,7 @@ void GameServer::receiveMessage(const MessageDispatch::Emitter & source, const M if(Clock::timeMs() - s_lastTaskKeepaliveTime > 60000) { DEBUG_WARNING(true, ("Sending keepalive message to taskmanager for process %i", Os::getProcessId())); - static const GenericValueTypeMessage gameServerTaskManagerKeepAlive("GameServerTaskManagerKeepAlive", Os::getProcessId()); + static const GenericValueTypeMessage gameServerTaskManagerKeepAlive("GameServerTaskManagerKeepAlive", Os::getProcessId()); getInstance().m_taskManagerConnection->send(gameServerTaskManagerKeepAlive, true); s_lastTaskKeepaliveTime = Clock::timeMs(); } @@ -3583,14 +3584,14 @@ void GameServer::receiveMessage2(const MessageDispatch::Emitter & source, const GenericValueTypeMessage const characterMatchStatisticsRequest(ri); UNREF(characterMatchStatisticsRequest); - unsigned long numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs; + uint32_t numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs; CharacterMatchManager::getMatchStatistics(numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs); if (numberOfCharacterMatchRequests || numberOfCharacterMatchResults || timeSpentOnCharacterMatchRequestsMs) { CharacterMatchManager::clearMatchStatistics(); - const GenericValueTypeMessage >> characterMatchStatisticsResponse("LfgStatRsp", std::make_pair(numberOfCharacterMatchRequests, std::make_pair(numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs))); + const GenericValueTypeMessage >> characterMatchStatisticsResponse("LfgStatRsp", std::make_pair(numberOfCharacterMatchRequests, std::make_pair(numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs))); sendToCentralServer(characterMatchStatisticsResponse); } @@ -4048,7 +4049,7 @@ bool GameServer::requestSceneWarpDelayed(const CachedNetworkId &objectId, const // ---------------------------------------------------------------------- -unsigned long GameServerNamespace::getFrameRateLimit() +uint32_t GameServerNamespace::getFrameRateLimit() { return ServerWorld::isSpaceScene() ? ConfigServerGame::getSpaceFrameRateLimit() : ConfigServerGame::getGroundFrameRateLimit(); } @@ -4059,17 +4060,17 @@ void GameServer::run(void) { getInstance().initialize(); - unsigned long lastFrameTime = 0; + uint32_t lastFrameTime = 0; int oldFilesOpened = TreeFile::getNumberOfFilesOpenedTotal(); int oldSizeOpened = TreeFile::getSizeOfFilesOpenedTotal(); int newFilesOpened = 0; int newSizeOpened = 0; - unsigned long startTime = Clock::timeMs(); - unsigned long lastFrameProcessStartTime = startTime; + uint32_t startTime = Clock::timeMs(); + uint32_t lastFrameProcessStartTime = startTime; - const unsigned long targetFrameTime = static_cast(1000.0f/getFrameRateLimit()); + const uint32_t targetFrameTime = static_cast(1000.0f/getFrameRateLimit()); - const GenericValueTypeMessage gameServerTaskManagerKeepAlive("GameServerTaskManagerKeepAlive", Os::getProcessId()); + const GenericValueTypeMessage gameServerTaskManagerKeepAlive("GameServerTaskManagerKeepAlive", Os::getProcessId()); PROFILER_BLOCK_DEFINE(profileBlockMainLoop, "main loop"); PROFILER_BLOCK_ENTER(profileBlockMainLoop); @@ -4186,7 +4187,7 @@ void GameServer::run(void) alreadyReported=false; } - unsigned long curTime = Clock::timeMs(); + uint32_t curTime = Clock::timeMs(); lastFrameTime = curTime-startTime; if (!getInstance().getDone()) ServerClock::getInstance().incrementServerFrame(); @@ -5193,11 +5194,11 @@ int GameServer::getNumberOfPendingLoadRequests() // ---------------------------------------------------------------------- -unsigned long GameServer::getOldestPendingLoadRequestTime(NetworkId & id) +uint32_t GameServer::getOldestPendingLoadRequestTime(NetworkId & id) { - unsigned long oldestTime = std::numeric_limits::max(); + uint32_t oldestTime = std::numeric_limits::max(); - std::map::const_iterator i = s_pendingLoadRequests.begin(); + std::map::const_iterator i = s_pendingLoadRequests.begin(); for (; i != s_pendingLoadRequests.end(); ++i) if (i->second < oldestTime) { diff --git a/engine/server/library/serverGame/src/shared/core/GameServer.h b/engine/server/library/serverGame/src/shared/core/GameServer.h index e5b7944ac..0e229b3b6 100755 --- a/engine/server/library/serverGame/src/shared/core/GameServer.h +++ b/engine/server/library/serverGame/src/shared/core/GameServer.h @@ -87,7 +87,7 @@ public MessageDispatch::Receiver bool isGameServerConnected (uint32 processId) const; ConnectionServerConnection * getConnectionServerConnection (const std::string & connectionServerIp, const uint16 connectionServerPort); uint32 getFirstGameServerForPlanet (); - unsigned long getFrameTime () const; + uint32_t getFrameTime () const; int getNumClients() const; uint32 getProcessId () const; uint32 getPreloadAreaId () const; @@ -138,7 +138,7 @@ public MessageDispatch::Receiver static bool isAtPendingLoadRequestLimit(); static int getPendingLoadRequestLimit(); static int getNumberOfPendingLoadRequests(); - static unsigned long getOldestPendingLoadRequestTime(NetworkId & id); + static uint32_t getOldestPendingLoadRequestTime(NetworkId & id); static std::string getRetroactiveCtsHistory(std::string const & clusterName, NetworkId const & characterId); static std::vector > const *> const & getRetroactiveCtsHistoryObjvars(NetworkId const & characterId); diff --git a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp index 6b8d1f5ad..e274f15af 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp +++ b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp @@ -86,7 +86,7 @@ TransferControlMessage::~TransferControlMessage() //----------------------------------------------------------------------- ControlAssumed::ControlAssumed(NetworkId oid, const std::string & newSceneName, const bool skipLoadScreen, const Vector &startPos, const float startYaw, const std::string & templateName, - const int64 t) : + const int32_t t) : GameNetworkMessage("ControlAssumed"), m_oid(oid), m_sceneName(newSceneName), diff --git a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h index c81e6ae82..a80edad45 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h +++ b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h @@ -118,7 +118,7 @@ class ControlAssumed : public GameNetworkMessage public: explicit ControlAssumed(NetworkId oid, const std::string & newSceneName, const bool skipLoadScreen, const Vector &startPos, const float startYaw, const std::string & templateName, - const int64 timeSeconds); + const int32_t timeSeconds); ControlAssumed(Archive::ReadIterator & source); virtual ~ControlAssumed(); @@ -128,7 +128,7 @@ class ControlAssumed : public GameNetworkMessage const Vector & getStartPosition () const; const float getStartYaw () const; const std::string & getTemplateName () const; - const int64 getTimeSeconds () const; + const int32_t getTimeSeconds () const; private: Archive::AutoVariable m_oid; @@ -137,7 +137,7 @@ class ControlAssumed : public GameNetworkMessage Archive::AutoVariable m_startPosition; Archive::AutoVariable m_startYaw; Archive::AutoVariable m_templateName; - Archive::AutoVariable m_timeSeconds; + Archive::AutoVariable m_timeSeconds; ControlAssumed(); @@ -188,7 +188,7 @@ inline const std::string & ControlAssumed::getTemplateName() const //----------------------------------------------------------------------- -inline const int64 ControlAssumed::getTimeSeconds() const +inline const int32_t ControlAssumed::getTimeSeconds() const { return m_timeSeconds.get(); } diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp index e38ecdd3c..48fa7ad19 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp @@ -112,7 +112,7 @@ const JNINativeMethod NATIVES[] = { JF("_renameCharacterReleaseNameReservation", "(J)V", renameCharacterReleaseNameReservation), JF("_renameCharacter", "(JLjava/lang/String;)V", renameCharacter), JF("_getPlayerStationId", "(J)I", getPlayerStationId), - //JF("_getPlayerUsernameDoNotUse", "(J)Ljava/lang/String;", getPlayerUsername), + JF("_getPlayerUsernameDoNotUse", "(J)Ljava/lang/String;", getPlayerUsername), }; return JavaLibrary::registerNatives(NATIVES, sizeof(NATIVES)/sizeof(NATIVES[0])); diff --git a/engine/shared/library/sharedMessageDispatch/src/shared/Message.cpp b/engine/shared/library/sharedMessageDispatch/src/shared/Message.cpp index f3d6f4b5e..5cca2bafb 100755 --- a/engine/shared/library/sharedMessageDispatch/src/shared/Message.cpp +++ b/engine/shared/library/sharedMessageDispatch/src/shared/Message.cpp @@ -24,9 +24,9 @@ namespace MessageDispatch Returns an STL hash of the type name. */ -const unsigned long int MessageBase::makeMessageTypeFromString(const char * const idString) +const uint32_t MessageBase::makeMessageTypeFromString(const char * const idString) { - unsigned long int result = 0; + uint32_t result = 0; #if PRODUCTION == 0 result = LabelHash::hashLabel("MessageDispatch", idString); #else @@ -59,7 +59,7 @@ type(0) @author Justin Randall */ -MessageBase::MessageBase(const unsigned long int newType) : +MessageBase::MessageBase(const uint32_t newType) : type(newType) { } diff --git a/engine/shared/library/sharedMessageDispatch/src/shared/Message.h b/engine/shared/library/sharedMessageDispatch/src/shared/Message.h index 0a355f1f9..50dfcfdc9 100755 --- a/engine/shared/library/sharedMessageDispatch/src/shared/Message.h +++ b/engine/shared/library/sharedMessageDispatch/src/shared/Message.h @@ -26,16 +26,16 @@ namespace MessageDispatch { public: explicit MessageBase(const char * const typeName); - explicit MessageBase(const unsigned long int type); + explicit MessageBase(const uint32_t type); virtual ~MessageBase(); - static const unsigned long int makeMessageTypeFromString(const char * const id); - const unsigned long int getType() const; + static const uint32_t makeMessageTypeFromString(const char * const id); + const uint32_t getType() const; const bool isType(const char * const typeName) const; - void setType(const unsigned long int newType); + void setType(const uint32_t newType); void setType(const char * const typeName); private: MessageBase(); - unsigned long int type; + uint32_t type; }; /** @@ -50,9 +50,9 @@ namespace MessageDispatch { public: explicit Message(const char * const typeName=""); - explicit Message(const unsigned long int type); + explicit Message(const uint32_t type); Message(const char * const typeName, const ValueType & value); - Message(const unsigned long int type, const ValueType & value); + Message(const uint32_t type, const ValueType & value); explicit Message(const Message & source); virtual ~Message(); Message & operator = (const Message & rhs); @@ -69,7 +69,7 @@ namespace MessageDispatch @return the type of the Message. The type is an STL hash of the type name. */ - inline const unsigned long int MessageBase::getType() const + inline const uint32_t MessageBase::getType() const { return type; } @@ -85,7 +85,7 @@ namespace MessageDispatch /** @brief set or reset the type identifier */ - inline void MessageBase::setType(const unsigned long newType) + inline void MessageBase::setType(const uint32_t newType) { type = newType; } @@ -116,7 +116,7 @@ namespace MessageDispatch } template - inline Message::Message(const unsigned long int type) : + inline Message::Message(const uint32_t type) : MessageBase(type), value() { @@ -142,7 +142,7 @@ namespace MessageDispatch } template - inline Message::Message(const unsigned long int type, const ValueType & newValue) : + inline Message::Message(const uint32_t type, const ValueType & newValue) : MessageBase(type), value(newValue) { diff --git a/engine/shared/library/sharedUtility/src/shared/DataTable.cpp b/engine/shared/library/sharedUtility/src/shared/DataTable.cpp index 4cdd7f032..2f2e65cd2 100755 --- a/engine/shared/library/sharedUtility/src/shared/DataTable.cpp +++ b/engine/shared/library/sharedUtility/src/shared/DataTable.cpp @@ -626,7 +626,7 @@ int DataTable::searchColumnString( int column, const std::string & searchValue ) int valueCrc = getIntValue(column,i); IGNORE_RETURN ( indexPair->second.insert(std::pair(valueCrc, i)) ); if (retval == -1 && valueString == searchValue) - retval = i; + retval = i; // don't return here because we're adding indexes for everything in this table as we've not indexed it before. } } else @@ -634,7 +634,7 @@ int DataTable::searchColumnString( int column, const std::string & searchValue ) std::pair, std::multimap > * indexPair = static_cast, std::multimap > *>(voidIndex); std::multimap::iterator iter = indexPair->first.find(searchValue); if (iter != indexPair->first.end()) - retval = iter->second; + return iter->second; // if we find our value, return here instead of iterating through the rest of the table. } return retval; From 7e13b9546a4536e38a768f07ff228c54cc1b99e9 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 20 Nov 2021 19:08:23 -0500 Subject: [PATCH 17/46] Fixed size issue with ByteStream and removed some debug output --- CMakeLists.txt | 26 +++++++------ .../src/shared/CrcStringTable.cpp | 3 -- .../src/shared/object/AlterScheduler.cpp | 6 +-- .../library/platform/utils/Base/Archive.cpp | 2 +- .../3rd/library/platform/utils/Base/Archive.h | 8 ++-- .../library/archive/src/shared/ByteStream.cpp | 39 +------------------ .../library/archive/src/shared/ByteStream.h | 9 +++-- 7 files changed, 29 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a066532d..16eb9f2ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,15 +77,21 @@ elseif (UNIX) endif () # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS - set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -ggdb") + set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -ggdb -pg -no-pie") # release specific cflags - optimizations beyond the default for both types is mostly just -O flags set(CMAKE_CXX_FLAGS_RELEASE "-DDEBUG_LEVEL=0 -DPRODUCTION=1") # we use fewer, if any, crazy optimizations for profile generation, and likewise release flags for the minsizerel - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb -pg -no-pie") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}") + # our "always on" flags - build by default for the system we're on but include all instruction sets + set(CMAKE_CXX_FLAGS "-pipe -march=native -mtune=native \ + -Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \ + -Wno-write-strings -Wno-unknown-pragmas \ + -Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare -Wno-address-of-packed-member") + # Ofast doesn't work with gcc builds if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast \ @@ -94,12 +100,12 @@ elseif (UNIX) -fno-coverage-mapping -fno-spell-checking \ -mno-retpoline") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -fprofile-instr-generate -fcoverage-mapping") # RELWITHDEBINFO is used for building bins that produce profdata files - # we only need the basics of our heavy optimizations here, i think - that and one of these flags - # breaks JNI when we profile - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Ofast -finline-hint-functions -fprofile-instr-generate") + # we only need the basics of our heavy optimizations here, i think - that and one of these flags + # breaks JNI when we profile + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Ofast -finline-hint-functions -fprofile-instr-generate -g -fcoverage-mapping") # MINSIZEREL is used for profiled, flto builds set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} -flto -fwhole-program-vtables") @@ -109,14 +115,10 @@ elseif (UNIX) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "g++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") endif () - # our "always on" flags - build by default for the system we're on but include all instruction sets - set(CMAKE_CXX_FLAGS "-pipe -march=native -mtune=native \ - -Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \ - -Wno-write-strings -Wno-unknown-pragmas \ - -Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare -Wno-stringop-overflow -Wno-address-of-packed-member") - add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE) # this is so some profile specific stuff is turned on in the code diff --git a/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp b/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp index d9855c03b..6c962b3f0 100755 --- a/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp +++ b/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp @@ -165,8 +165,6 @@ ConstCharCrcString const CrcStringTable::lookUp(uint32 crc) const high = mid - 1; } - WARNING(true,("\n=========== Could not find entry 0x%08x with %d entries!!\n", crc, m_numberOfEntries)); - low = 0; high = m_numberOfEntries - 1; @@ -175,7 +173,6 @@ ConstCharCrcString const CrcStringTable::lookUp(uint32 crc) const int const mid = (low + high) / 2; uint32 const entry = m_crcTable[mid]; - WARNING(true, ("Checking 0x%08x against entry value 0x%08x at index %d", crc, entry, mid)); if (crc == entry) return ConstCharCrcString(m_strings + m_stringsOffsetTable[mid], crc); else diff --git a/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp b/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp index 2ae617993..24e46165e 100755 --- a/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp +++ b/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp @@ -114,7 +114,7 @@ namespace AlterSchedulerNamespace float const cs_schedulerTicksPerSecond = 1000.0f; // # schedule ticks per second. Frame rates will not be able to exceed this. float const cs_secondsPerSchedulerTick = 1.0f / cs_schedulerTicksPerSecond; - uint32 const cs_freeFillPattern = 0xEFEFEFEF; // this should match MemoryManager's free fill pattern. + uint64_t const cs_freeFillPattern = 0xEFEFEFEFEFEFEFEF; // this should match MemoryManager's free fill pattern. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -291,7 +291,7 @@ void AlterSchedulerNamespace::validateObject(Object const *object) #ifdef _DEBUG //-- Check if object memory is deleted. - if (*reinterpret_cast(object) == cs_freeFillPattern) //lint !e740 // unusual pointer cast // Yes. + if (*reinterpret_cast(object) == cs_freeFillPattern) //lint !e740 // unusual pointer cast // Yes. { DEBUG_WARNING(true, ("validateObject(): alter scheduler found deleted object (object memory starts with 4 bytes of free-fill pattern).")); //lint !e740 // unusual pointer cast from incompatible indirect types // okay, I'm doing something unusual. isInvalid = true; @@ -313,7 +313,7 @@ void AlterSchedulerNamespace::validateObject(Object const *object) } catch (...) { //lint !e1775 // catch block does not declare any exception // that's right: I want to catch it all. - WARNING(true, ("validateObject(): Object-derived class with address [%x] failed to return valid C++ type info; likely a deleted Object.", reinterpret_cast(object))); + WARNING(true, ("validateObject(): Object-derived class with address [%x] failed to return valid C++ type info; likely a deleted Object.", reinterpret_cast(object))); isInvalid = true; } } diff --git a/external/3rd/library/platform/utils/Base/Archive.cpp b/external/3rd/library/platform/utils/Base/Archive.cpp index fa1ec78ea..11e235b91 100755 --- a/external/3rd/library/platform/utils/Base/Archive.cpp +++ b/external/3rd/library/platform/utils/Base/Archive.cpp @@ -152,7 +152,7 @@ namespace Base return *this; } - void ByteStream::get(void * target, ReadIterator & readIterator, const unsigned long int targetSize) const + void ByteStream::get(void * target, ReadIterator & readIterator, const uint32_t targetSize) const { assert(readIterator.getReadPosition() + targetSize <= allocatedSize); memcpy(target, &data->buffer[readIterator.getReadPosition()], targetSize); diff --git a/external/3rd/library/platform/utils/Base/Archive.h b/external/3rd/library/platform/utils/Base/Archive.h index c461f4d74..f8f5ef394 100755 --- a/external/3rd/library/platform/utils/Base/Archive.h +++ b/external/3rd/library/platform/utils/Base/Archive.h @@ -63,7 +63,7 @@ const unsigned MAX_ARRAY_SIZE = 1024; ReadIterator & operator = (const ReadIterator & source); void advance (const unsigned int distance); - void get (void * target, const unsigned long int readSize); + void get (void * target, const uint32_t readSize); const unsigned int getSize () const; const unsigned char * const getBuffer () const; const unsigned int getReadPosition () const; @@ -92,7 +92,7 @@ const unsigned MAX_ARRAY_SIZE = 1024; void ref (); protected: unsigned char * buffer; - unsigned long size; + uint32_t size; private: struct DataFreeList { @@ -132,7 +132,7 @@ const unsigned MAX_ARRAY_SIZE = 1024; void put(const void * const source, const unsigned int sourceSize); private: - void get(void * target, ReadIterator & readIterator, const unsigned long int readSize) const; + void get(void * target, ReadIterator & readIterator, const uint32_t readSize) const; void growToAtLeast(const unsigned int targetSize); void reAllocate(const unsigned int newSize); @@ -255,7 +255,7 @@ const unsigned MAX_ARRAY_SIZE = 1024; return *this; } - inline void ByteStream::ReadIterator::get(void * target, const unsigned long int readSize) + inline void ByteStream::ReadIterator::get(void * target, const uint32_t readSize) { assert(stream); stream->get(target, *this, readSize); diff --git a/external/ours/library/archive/src/shared/ByteStream.cpp b/external/ours/library/archive/src/shared/ByteStream.cpp index 13aab2c1a..6b16bf293 100755 --- a/external/ours/library/archive/src/shared/ByteStream.cpp +++ b/external/ours/library/archive/src/shared/ByteStream.cpp @@ -5,16 +5,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - // ====================================================================== //static volatile int s_dataFreeListLocked; @@ -234,7 +224,7 @@ ByteStream &ByteStream::operator=(ByteStream const &rhs) @author Justin Randall */ -void ByteStream::get(void *target, ReadIterator &readIterator, const unsigned long int targetSize) const +void ByteStream::get(void *target, ReadIterator &readIterator, const uint32_t targetSize) const { if (data && readIterator.getReadPosition() + targetSize <= allocatedSize) { @@ -243,31 +233,6 @@ void ByteStream::get(void *target, ReadIterator &readIterator, const unsigned lo else { static const char * const desc = "Archive::ByteStream - read beyond end of buffer"; - std::cout << "read position: " << readIterator.getReadPosition() << " target size: " << targetSize << " allocated size: " << allocatedSize << std::endl; - std::cout << "I'm being called from: " << program_invocation_name; - std::cout << "======> BUFFER: " << std::endl; - - std::stringstream ss; - ss << std::hex << std::setfill('0'); - for (int i = 0; i < allocatedSize; ++i) - { - ss << std::setw(2) << static_cast(data->buffer[i]); - } - std::cout << ss.str() << std::endl; - - char pid_buf[30]; - sprintf(pid_buf, "%d", getpid()); - char name_buf[512]; - name_buf[readlink("/proc/self/exe", name_buf, 511)]=0; - prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); - int child_pid = fork(); - if (!child_pid) { - dup2(2,1); // redirect output to stderr - edit: unnecessary? - execl("/usr/bin/gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL); - abort(); /* If gdb failed to start */ - } else { - waitpid(child_pid,NULL,0); - } ReadException ex(desc); throw (ex); } @@ -380,7 +345,7 @@ ByteStream::Data *ByteStream::Data::getNewData() void ByteStream::Data::releaseOldData(ByteStream::Data *oldData) { - assert((unsigned) reinterpret_cast(oldData) != 0xefefefefu); + assert(reinterpret_cast(oldData) != 0xefefefefefefefefu); if (oldData->size > 4096) delete oldData; diff --git a/external/ours/library/archive/src/shared/ByteStream.h b/external/ours/library/archive/src/shared/ByteStream.h index a94aeb36a..d40bb0902 100755 --- a/external/ours/library/archive/src/shared/ByteStream.h +++ b/external/ours/library/archive/src/shared/ByteStream.h @@ -9,6 +9,7 @@ #include #include +#include //--------------------------------------------------------------------- @@ -82,7 +83,7 @@ class ReadIterator bool operator == (const ReadIterator & other) const; bool operator != (const ReadIterator & other) const; void advance (const unsigned int distance); - void get (void * target, const unsigned long int readSize); + void get (void * target, const uint32_t readSize); const unsigned int getSize () const; const unsigned char * const getBuffer () const; const unsigned int getReadPosition () const; @@ -136,7 +137,7 @@ class ByteStream void setAllocatedSizeLimit(unsigned int limit); private: - void get(void * target, ReadIterator & readIterator, const unsigned long int readSize) const; + void get(void * target, ReadIterator & readIterator, const uint32_t readSize) const; void growToAtLeast(const unsigned int targetSize); void reAllocate(const unsigned int newSize); @@ -155,7 +156,7 @@ class ByteStream friend class ByteStream; friend class Archive::ReadIterator; unsigned char * buffer; - unsigned long size; + uint32_t size; private: struct DataFreeList { @@ -252,7 +253,7 @@ inline ReadIterator & ReadIterator::operator = (const ReadIterator & rhs) //--------------------------------------------------------------------- -inline void ReadIterator::get(void * target, const unsigned long int readSize) +inline void ReadIterator::get(void * target, const uint32_t readSize) { if(stream) { From 3fad5178971293daea31531617015b9fbf9e9126 Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 22 Nov 2021 00:28:35 -0500 Subject: [PATCH 18/46] Back port to 32 bit to take advantage of 64 bit adjustments --- CMakeLists.txt | 2 +- cmake/linux/FindOracle.cmake | 29 +----- .../src/shared/CentralServer.cpp | 2 +- .../ChatServer/src/shared/ChatInterface.cpp | 16 ++-- .../ChatServer/src/shared/ChatInterface.h | 2 +- .../src/shared/ClientConnection.cpp | 7 +- .../src/shared/UniverseLocator.cpp | 2 +- .../serverGame/src/shared/ai/HateList.cpp | 4 +- .../serverGame/src/shared/ai/HateList.h | 4 +- .../src/shared/command/CommandCppFuncs.cpp | 4 +- .../shared/console/ConsoleCommandParserAi.cpp | 8 +- .../ConsoleCommandParserCollection.cpp | 16 ++-- .../controller/AiCreatureController.cpp | 2 +- .../shared/controller/AiCreatureController.h | 4 +- .../serverGame/src/shared/core/Client.cpp | 3 +- .../src/shared/core/ReportManager.cpp | 14 +-- .../src/shared/object/CreatureObject.cpp | 20 ++--- .../src/shared/object/CreatureObject.h | 20 ++--- .../src/shared/object/PlayerObject.cpp | 74 +++++++-------- .../src/shared/object/PlayerObject.h | 32 +++---- .../src/shared/object/ServerObject.cpp | 42 ++++----- .../src/shared/object/ServerObject.h | 10 +-- .../src/shared/object/TangibleObject.cpp | 8 +- .../src/shared/object/TangibleObject.h | 8 +- .../ServerIntangibleObjectTemplate.h | 2 +- .../library/serverGame/src/shared/pvp/Pvp.cpp | 4 +- .../centralGameServer/MessageToPayloadImpl.h | 2 +- .../core/SetupServerNetworkMessages.cpp | 16 ++-- .../GameConnectionServerMessages.cpp | 4 +- .../src/shared/ScriptMethodsCollection.cpp | 2 +- .../src/shared/ChatLogManager.cpp | 28 +++--- .../serverUtility/src/shared/ChatLogManager.h | 8 +- .../src/shared/core/DbBindableLong.cpp | 8 +- .../src/shared/core/DbBindableLong.h | 47 +++++----- .../src_oci/DbBindableVarray.cpp | 90 +++++++++---------- .../src_oci/DbBindableVarray.h | 12 +-- .../src/shared/chat/ChatOnRequestLog.h | 2 +- .../src/shared/clientGameServer/AuctionData.h | 4 +- .../BuffBuilderChangeMessage.cpp | 2 +- .../BuffBuilderChangeMessage.h | 6 +- .../ImageDesignChangeMessage.cpp | 2 +- .../ImageDesignChangeMessage.h | 6 +- .../MessageQueueSlowDownEffect.cpp | 2 +- .../MessageQueueSlowDownEffect.h | 6 +- .../src/shared/planetWatch/ServerInfo.h | 4 +- .../core/SetupSwgServerNetworkMessages.cpp | 20 ++--- .../core/SetupSwgSharedNetworkMessages.cpp | 6 +- 47 files changed, 296 insertions(+), 320 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16eb9f2ff..f99dadfd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ elseif (UNIX) set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}") # our "always on" flags - build by default for the system we're on but include all instruction sets - set(CMAKE_CXX_FLAGS "-pipe -march=native -mtune=native \ + set(CMAKE_CXX_FLAGS "-m32 -pipe -march=native -mtune=native \ -Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \ -Wno-write-strings -Wno-unknown-pragmas \ -Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare -Wno-address-of-packed-member") diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index 0cd0e9446..20abfc388 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -22,34 +22,23 @@ # ############################################################################### - # If ORACLE_HOME not defined, assume Oracle libraries not available if(DEFINED ENV{ORACLE_HOME}) - set(ORACLE_HOME $ENV{ORACLE_HOME}) - message("ORACLE_HOME=${ORACLE_HOME}") - find_path(ORACLE_INCLUDE_DIR NAMES oci.h PATHS - /usr/include/oracle/19.12/client64 - /usr/include/oracle/19.12/client - /usr/lib/oracle/19.12/client64 - /usr/share/oracle/19.12/client64 - /usr/lib/oracle/19.12/client - /usr/share/oracle/19.12/client + /usr/include/oracle/21/client ${ORACLE_HOME}/rdbms/public ${ORACLE_HOME}/include ${ORACLE_HOME}/sdk/include # Oracle SDK ${ORACLE_HOME}/OCI/include) # Oracle XE on Windows - set(ORACLE_OCI_NAMES clntsh libclntsh oci) - set(ORACLE_NNZ_NAMES nnz10 libnnz10 nnz11 libnnz11 nnz12 libnnz12 nnz18 libnnz18 nnz19 libnnz19 ociw32) - set(ORACLE_OCCI_NAMES libocci occi oraocci10 oraocci11 oraocci12 libocci.so.19.1 oraocci19) - + set(ORACLE_NNZ_NAMES libnnz21 nnz21 ociw32) + set(ORACLE_OCCI_NAMES libocci occi oraocci10 oraocci11) set(ORACLE_LIB_DIR ${ORACLE_HOME}/lib @@ -57,24 +46,19 @@ if(DEFINED ENV{ORACLE_HOME}) ${ORACLE_HOME}/sdk/lib/msvc ${ORACLE_HOME}/OCI/lib/msvc) # Oracle XE on Windows - find_library(ORACLE_OCI_LIBRARY NAMES ${ORACLE_OCI_NAMES} PATHS ${ORACLE_LIB_DIR}) find_library(ORACLE_OCCI_LIBRARY NAMES ${ORACLE_OCCI_NAMES} PATHS ${ORACLE_LIB_DIR}) find_library(ORACLE_NNZ_LIBRARY NAMES ${ORACLE_NNZ_NAMES} PATHS ${ORACLE_LIB_DIR}) - set(ORACLE_LIBRARY ${ORACLE_OCI_LIBRARY} ${ORACLE_OCCI_LIBRARY} ${ORACLE_NNZ_LIBRARY}) - if(APPLE) set(ORACLE_OCIEI_NAMES libociei ociei) - find_library(ORACLE_OCIEI_LIBRARY NAMES libociei ociei PATHS ${ORACLE_LIB_DIR}) - if(ORACLE_OCIEI_LIBRARY) set(ORACLE_LIBRARY ${ORACLE_LIBRARY} ${ORACLE_OCIEI_LIBRARY}) else(ORACLE_OCIEI_LIBRARY) @@ -83,18 +67,13 @@ if(DEFINED ENV{ORACLE_HOME}) endif() endif() - set(ORACLE_LIBRARIES ${ORACLE_LIBRARY}) - endif(DEFINED ENV{ORACLE_HOME}) - # Handle the QUIETLY and REQUIRED arguments and set ORACLE_FOUND to TRUE # if all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ORACLE DEFAULT_MSG ORACLE_LIBRARY ORACLE_INCLUDE_DIR) - -mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY) - +mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY) \ No newline at end of file diff --git a/engine/server/application/CentralServer/src/shared/CentralServer.cpp b/engine/server/application/CentralServer/src/shared/CentralServer.cpp index 1cdb83bb0..0ae86526a 100755 --- a/engine/server/application/CentralServer/src/shared/CentralServer.cpp +++ b/engine/server/application/CentralServer/src/shared/CentralServer.cpp @@ -2324,7 +2324,7 @@ void CentralServer::receiveMessage(const MessageDispatch::Emitter & source, cons } case constcrc("LfgStatRsp") : { Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage >> const msg(ri); + GenericValueTypeMessage >> const msg(ri); m_numberOfCharacterMatchRequests += msg.getValue().first; m_numberOfCharacterMatchResults += msg.getValue().second.first; diff --git a/engine/server/application/ChatServer/src/shared/ChatInterface.cpp b/engine/server/application/ChatServer/src/shared/ChatInterface.cpp index afc1b2f4d..b75a79139 100755 --- a/engine/server/application/ChatServer/src/shared/ChatInterface.cpp +++ b/engine/server/application/ChatServer/src/shared/ChatInterface.cpp @@ -355,7 +355,7 @@ void ChatInterface::OnGetRoom(unsigned track, unsigned result, const ChatRoom *r ChatServer::putSystemAvatarInRoom(roomName); } std::string lowerRoomName = toLower(roomName); - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; std::unordered_map::iterator f = roomList.find(lowerRoomName); if (f != roomList.end() && room) { @@ -416,7 +416,7 @@ void ChatInterface::OnGetRoom(unsigned track, unsigned result, const ChatRoom *r //----------------------------------------------------------------------- -void ChatInterface::queryRoom(const NetworkId & id, ConnectionServerConnection * connection, const uint64_t sequence, const std::string & roomName) +void ChatInterface::queryRoom(const NetworkId & id, ConnectionServerConnection * connection, const uintptr_t sequence, const std::string & roomName) { UNREF(connection); ChatServer::fileLog(s_enableChatRoomLogs, "ChatInterface", "queryRoom() id(%s) connection(%s) sequence(%u) roomName(%s)", id.getValueString().c_str(), ChatServer::getConnectionAddress(connection).c_str(), sequence, roomName.c_str()); @@ -1579,7 +1579,7 @@ void ChatInterface::OnCreateRoom(unsigned track,unsigned result, const ChatRoom PROFILER_AUTO_BLOCK_DEFINE("ChatInterface - OnCreateRoom"); UNREF(user); - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; static Unicode::String wideSWG = Unicode::narrowToWide("SOE+SWG"); static Unicode::String wideFilter = Unicode::narrowToWide(""); static ChatUnicodeString swgNode(wideSWG.data(), wideSWG.size()); @@ -1882,7 +1882,7 @@ void ChatInterface::OnEnterRoom(unsigned track, unsigned result, const ChatAvata return; } - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; ChatAvatarId srcId; if (srcAvatar) @@ -2559,7 +2559,7 @@ void ChatInterface::OnLeaveRoom(unsigned track, unsigned result, const ChatAvata return; } - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; ChatAvatarId id; if (srcAvatar) @@ -2913,7 +2913,7 @@ void ChatInterface::OnSendRoomMessage(unsigned track, unsigned result, const Cha } UNREF(srcAvatar); UNREF(destRoom); - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; ChatOnSendRoomMessage chat(sequence, result); IGNORE_RETURN(ChatServer::sendResponseForTrackId(track, chat)); } @@ -2998,7 +2998,7 @@ void ChatInterface::OnSendInstantMessage(unsigned track, unsigned result, const } UNREF(srcAvatar); - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; ChatOnSendInstantMessage chat(sequence, result); IGNORE_RETURN(ChatServer::sendResponseForTrackId(track, chat)); @@ -3053,7 +3053,7 @@ void ChatInterface::OnSendPersistentMessage(unsigned track, unsigned result, con DEBUG_WARNING(true, ("We received an OnSendPersistentMessage with a success result code but nullptr data. This is an error that the API should never give.")); return; } - uint64_t sequence = (uint64_t)user; + uintptr_t sequence = (uintptr_t)user; UNREF(srcAvatar); ChatOnSendPersistentMessage chat(sequence, result); IGNORE_RETURN(ChatServer::sendResponseForTrackId(track, chat)); diff --git a/engine/server/application/ChatServer/src/shared/ChatInterface.h b/engine/server/application/ChatServer/src/shared/ChatInterface.h index 3fc0f225d..b92212078 100755 --- a/engine/server/application/ChatServer/src/shared/ChatInterface.h +++ b/engine/server/application/ChatServer/src/shared/ChatInterface.h @@ -68,7 +68,7 @@ class ChatInterface : public ChatAPI std::string getChatName(const NetworkId &id); - void queryRoom (const NetworkId & id, ConnectionServerConnection * connection, const uint64_t sequenceId, const std::string & roomName); + void queryRoom (const NetworkId & id, ConnectionServerConnection * connection, const uintptr_t sequenceId, const std::string & roomName); void updateRoomForThisChatAPI(const ChatRoom *room, const ChatAvatar *additionalAvatar); void updateRooms(); diff --git a/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp b/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp index 187997edd..9f0bdee51 100755 --- a/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp +++ b/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp @@ -198,8 +198,7 @@ std::string ClientConnection::getCurrentActivePlayTimeDuration() const { void ClientConnection::sendPlayTimeInfoToGameServer() const { if (m_client && m_client->getGameConnection()) { // update the game server with play time info - GenericValueTypeMessage < std::pair < int32, std::pair < int32, unsigned - long > > > + GenericValueTypeMessage < std::pair < int32, std::pair < int32, uint32_t > > > const msgPlayTimeInfo( "UpdateSessionPlayTimeInfo", std::make_pair(static_cast(m_startPlayTime), std::make_pair(static_cast(m_lastActiveTime), m_activePlayTimeDuration))); @@ -1369,9 +1368,7 @@ ClientConnection::onValidateClient(StationId suid, const std::string &username, } // tell client the server-side game and subscription feature bits and which ConnectionServer we are and the current server Epoch time - GenericValueTypeMessage < std::pair < std::pair < unsigned - long, unsigned - long > , std::pair < int, int32 > > > + GenericValueTypeMessage < std::pair < std::pair < uint32_t, uint32_t > , std::pair < int, int32 > > > const msgFeatureBits( "AccountFeatureBits", std::make_pair(std::make_pair(gameFeatures, subscriptionFeatures), std::make_pair(ConfigConnectionServer::getConnectionServerNumber(), static_cast(::time(nullptr))))); send(msgFeatureBits, true); diff --git a/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp b/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp index bad7a18cc..0ee906b93 100755 --- a/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp +++ b/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp @@ -37,7 +37,7 @@ bool UniverseLocator::locateObjects(DB::Session *session, const std::string &sch void UniverseLocator::sendPostBaselinesCustomData(GameServerConnection &conn) const { DEBUG_REPORT_LOG(true,("Sending UniverseComplete.\n")); - GenericValueTypeMessage const universeCompleteMessage("UniverseCompleteMessage", DatabaseProcess::getInstance().getProcessId()); + GenericValueTypeMessage const universeCompleteMessage("UniverseCompleteMessage", DatabaseProcess::getInstance().getProcessId()); conn.send(universeCompleteMessage, true); SetUniverseAuthoritativeMessage const setUniverseAuthoritativeMessage(conn.getProcessId()); diff --git a/engine/server/library/serverGame/src/shared/ai/HateList.cpp b/engine/server/library/serverGame/src/shared/ai/HateList.cpp index 496fb2b9a..2419100ca 100755 --- a/engine/server/library/serverGame/src/shared/ai/HateList.cpp +++ b/engine/server/library/serverGame/src/shared/ai/HateList.cpp @@ -535,8 +535,8 @@ void HateList::addServerNpAutoDeltaVariables(Archive::AutoDeltaByteStream & stre // ---------------------------------------------------------------------- int HateList::getTimeSinceLastUpdate() const { - time_t const currentTime = Os::getRealSystemTime(); - time_t const timeSinceActivitiy = (currentTime - m_lastUpdateTime.get()); + uint32_t const currentTime = Os::getRealSystemTime(); + uint32_t const timeSinceActivitiy = (currentTime - m_lastUpdateTime.get()); return clamp(0, static_cast(timeSinceActivitiy), 1024); } diff --git a/engine/server/library/serverGame/src/shared/ai/HateList.h b/engine/server/library/serverGame/src/shared/ai/HateList.h index e63690416..ec9c0fa1c 100755 --- a/engine/server/library/serverGame/src/shared/ai/HateList.h +++ b/engine/server/library/serverGame/src/shared/ai/HateList.h @@ -90,8 +90,8 @@ class HateList Archive::AutoDeltaMap m_hateList; Archive::AutoDeltaVariable m_target; Archive::AutoDeltaVariable m_maxHate; - Archive::AutoDeltaVariable m_lastUpdateTime; - Archive::AutoDeltaVariable m_autoExpireTargetDuration; + Archive::AutoDeltaVariable m_lastUpdateTime; + Archive::AutoDeltaVariable m_autoExpireTargetDuration; std::set m_recentHateList; // This is used for assist logic }; diff --git a/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp b/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp index c0e08287e..7fc71ebde 100755 --- a/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp +++ b/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp @@ -8277,7 +8277,7 @@ static void commandFuncSpammer(Command const &, NetworkId const &actor, NetworkI { // check warden permission first or if god const PlayerObject * gmPlayerObject = PlayerCreatureController::getPlayerObject(gm); - if (!gmPlayerObject || (!gmPlayerObject->isWarden()) && !gmClient->isGod()) + if (!gmPlayerObject || (!gmPlayerObject->isWarden() && !gmClient->isGod())) { Chat::sendSystemMessage(*gm, StringId("warden", "not_authorized"), Unicode::emptyString); return; @@ -8428,7 +8428,7 @@ static void commandFuncUnspammer(Command const &, NetworkId const &actor, Networ { // check warden permission first or if god const PlayerObject * gmPlayerObject = PlayerCreatureController::getPlayerObject(gm); - if (!gmPlayerObject || (!gmPlayerObject->isWarden()) && !gmClient->isGod()) + if (!gmPlayerObject || (!gmPlayerObject->isWarden() && !gmClient->isGod())) { Chat::sendSystemMessage(*gm, StringId("warden", "not_authorized"), Unicode::emptyString); return; diff --git a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserAi.cpp b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserAi.cpp index ade32b450..fadec301d 100755 --- a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserAi.cpp +++ b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserAi.cpp @@ -272,12 +272,12 @@ bool ConsoleCommandParserAi::performParsing(const NetworkId & userId, const Stri // Hate Over Time List { - std::map > > const & hateOverTime = aiCreatureController->getCreature()->getHateOverTime(); + std::map > > const & hateOverTime = aiCreatureController->getCreature()->getHateOverTime(); if (!hateOverTime.empty()) { result += Unicode::narrowToWide(fs.sprintf("* HATE OVER TIME LIST currentGameTime=(%lu)*\n", ServerClock::getInstance().getGameTimeSeconds())); - for (std::map > >::const_iterator iter = hateOverTime.begin(); iter != hateOverTime.end(); ++iter) + for (std::map > >::const_iterator iter = hateOverTime.begin(); iter != hateOverTime.end(); ++iter) { CachedNetworkId const hateTarget(iter->first); TangibleObject const * const hateTargetTangibleObject = TangibleObject::asTangibleObject(hateTarget.getObject()); @@ -369,12 +369,12 @@ bool ConsoleCommandParserAi::performParsing(const NetworkId & userId, const Stri // Hate Over Time List { - std::map > > const & hateOverTime = to->getHateOverTime(); + std::map > > const & hateOverTime = to->getHateOverTime(); if (!hateOverTime.empty()) { result += Unicode::narrowToWide(fs.sprintf("* HATE OVER TIME LIST currentGameTime=(%lu)*\n", ServerClock::getInstance().getGameTimeSeconds())); - for (std::map > >::const_iterator iter = hateOverTime.begin(); iter != hateOverTime.end(); ++iter) + for (std::map > >::const_iterator iter = hateOverTime.begin(); iter != hateOverTime.end(); ++iter) { CachedNetworkId const hateTarget(iter->first); TangibleObject const * const hateTargetTangibleObject = TangibleObject::asTangibleObject(hateTarget.getObject()); diff --git a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserCollection.cpp b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserCollection.cpp index a8ef94a9a..55c98d6d4 100755 --- a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserCollection.cpp +++ b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserCollection.cpp @@ -167,7 +167,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c } } - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(*slot, currentValue)); result += Unicode::narrowToWide(FormattedString<512>().sprintf("modifying collection slot %s/%s/%s/%s value of %lu by %s for character object %s (%s)\n", slot->collection.page.book.name.c_str(), slot->collection.page.name.c_str(), slot->collection.name.c_str(), Unicode::wideToNarrow(argv[2]).c_str(), currentValue, adjustment.getValueString().c_str(), oid.getValueString().c_str(), Unicode::wideToNarrow(o->getAssignedObjectName()).c_str())); @@ -239,7 +239,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c else { // grant counter-type slot - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(**iter, currentValue)); // quickie way to convert to an int64 @@ -316,7 +316,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c else { // grant counter-type slot - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(**iter, currentValue)); // quickie way to convert to an int64 @@ -393,7 +393,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c else { // grant counter-type slot - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(**iter, currentValue)); // quickie way to convert to an int64 @@ -456,7 +456,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c else { // revoke counter-type slot - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(**iter, currentValue)); // quickie way to convert to an int64 @@ -519,7 +519,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c else { // revoke counter-type slot - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(**iter, currentValue)); // quickie way to convert to an int64 @@ -582,7 +582,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c else { // revoke counter-type slot - unsigned long currentValue; + uint32_t currentValue; IGNORE_RETURN(p->getCollectionSlotValue(**iter, currentValue)); // quickie way to convert to an int64 @@ -651,7 +651,7 @@ bool ConsoleCommandParserCollection::performParsing (const NetworkId & userId, c } else { - unsigned long value; + uint32_t value; IGNORE_RETURN(p->getCollectionSlotValue(**iterSlot, value)); if (value == 0) continue; diff --git a/engine/server/library/serverGame/src/shared/controller/AiCreatureController.cpp b/engine/server/library/serverGame/src/shared/controller/AiCreatureController.cpp index 121e63833..4486f242a 100755 --- a/engine/server/library/serverGame/src/shared/controller/AiCreatureController.cpp +++ b/engine/server/library/serverGame/src/shared/controller/AiCreatureController.cpp @@ -2960,7 +2960,7 @@ PersistentCrcString const & AICreatureController::getCombatAction() } //----------------------------------------------------------------------- -time_t AICreatureController::getKnockDownRecoveryTime() const +uint32_t AICreatureController::getKnockDownRecoveryTime() const { AiCreatureCombatProfile const * const combatProfile = AiCreatureCombatProfile::getCombatProfile(m_aiCreatureData->m_primarySpecials); diff --git a/engine/server/library/serverGame/src/shared/controller/AiCreatureController.h b/engine/server/library/serverGame/src/shared/controller/AiCreatureController.h index 83aa7a070..5b0dc038b 100755 --- a/engine/server/library/serverGame/src/shared/controller/AiCreatureController.h +++ b/engine/server/library/serverGame/src/shared/controller/AiCreatureController.h @@ -186,7 +186,7 @@ class AICreatureController : public CreatureController AiMovementType getPendingMovementType() const; PersistentCrcString const & getCombatAction(); - time_t getKnockDownRecoveryTime() const; + uint32_t getKnockDownRecoveryTime() const; std::string const getCombatActionsString(); @@ -245,7 +245,7 @@ class AICreatureController : public CreatureController Archive::AutoDeltaVariable m_frozen; Archive::AutoDeltaVariable m_combatStartLocation; Archive::AutoDeltaVariable m_retreating; - Archive::AutoDeltaVariable m_retreatingStartTime; + Archive::AutoDeltaVariable m_retreatingStartTime; Archive::AutoDeltaVariable m_logging; Archive::AutoDeltaVariableCallback m_creatureName; Archive::AutoDeltaVariable m_hibernationDelay; diff --git a/engine/server/library/serverGame/src/shared/core/Client.cpp b/engine/server/library/serverGame/src/shared/core/Client.cpp index 78f2c8cac..23dd89bdf 100755 --- a/engine/server/library/serverGame/src/shared/core/Client.cpp +++ b/engine/server/library/serverGame/src/shared/core/Client.cpp @@ -1613,8 +1613,7 @@ void Client::receiveClientMessage(const GameNetworkMessage &message) { } case constcrc("UpdateSessionPlayTimeInfo") : { Archive::ReadIterator readIterator = static_cast (message).getByteStream().begin(); - GenericValueTypeMessage < std::pair < int32, std::pair < int32, unsigned - long > > > + GenericValueTypeMessage < std::pair < int32, std::pair < int32, uint32_t > > > const msgPlayTimeInfo(readIterator); PlayerObject *playerObject = PlayerCreatureController::getPlayerObject(safe_cast(getCharacterObject())); diff --git a/engine/server/library/serverGame/src/shared/core/ReportManager.cpp b/engine/server/library/serverGame/src/shared/core/ReportManager.cpp index 843373c7d..074fb4834 100755 --- a/engine/server/library/serverGame/src/shared/core/ReportManager.cpp +++ b/engine/server/library/serverGame/src/shared/core/ReportManager.cpp @@ -54,12 +54,12 @@ namespace ReportManagerNamespace typedef std::map ReportList; ReportList s_reportList; - typedef std::map ReportThrottle; + typedef std::map ReportThrottle; ReportThrottle s_reportThrottle; - time_t const s_throttleTime = 10; // seconds - time_t const s_throttleCleanupTime = 60; // seconds - time_t s_throttleCleanupTimer = 0; // seconds + uint32_t const s_throttleTime = 10; // seconds + uint32_t const s_throttleCleanupTime = 60; // seconds + uint32_t s_throttleCleanupTimer = 0; // seconds } using namespace ReportManagerNamespace; @@ -114,7 +114,7 @@ void ReportManager::addReport(Unicode::String const &reportingName, NetworkId co { // Remove any expired throttling - time_t const systemTime = Os::getRealSystemTime(); + uint32_t const systemTime = Os::getRealSystemTime(); if ((systemTime - s_throttleCleanupTimer) > s_throttleCleanupTime) { @@ -223,7 +223,7 @@ void ReportManager::handleMessage(ChatOnRequestLog const &chatOnRequestLog) report.append(header); - typedef std::multimap SortedChatLog; + typedef std::multimap SortedChatLog; typedef std::set SortedFromPlayers; SortedChatLog sortedChatLog; SortedFromPlayers sortedFromPlayers; @@ -266,7 +266,7 @@ void ReportManager::handleMessage(ChatOnRequestLog const &chatOnRequestLog) Unicode::String toPlayer; Unicode::String text; Unicode::String channel; - time_t time; + uint32_t time; for (; iterChatLog != chatLog.end(); ++iterChatLog) { diff --git a/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp b/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp index aaf8affd2..151130db5 100755 --- a/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp @@ -6231,7 +6231,7 @@ void CreatureObject::setMood(uint32 mood) } else { - sendControllerMessageToAuthServer(CM_setMood, new MessageQueueGenericValueType(mood)); + sendControllerMessageToAuthServer(CM_setMood, new MessageQueueGenericValueType(mood)); } } @@ -6656,7 +6656,7 @@ void CreatureObject::setSayMode(uint32 sayMode) } else { - sendControllerMessageToAuthServer(CM_setSayMode, new MessageQueueGenericValueType(sayMode)); + sendControllerMessageToAuthServer(CM_setSayMode, new MessageQueueGenericValueType(sayMode)); } } @@ -8723,7 +8723,7 @@ void CreatureObject::setGuildId(int guildId) //----------------------------------------------------------------------- -void CreatureObject::setTimeToUpdateGuildWarPvpStatus(unsigned long timeToUpdateGuildWarPvpStatus) +void CreatureObject::setTimeToUpdateGuildWarPvpStatus(uint32_t timeToUpdateGuildWarPvpStatus) { FATAL(!isAuthoritative(), ("setTimeToUpdateGuildWarPvpStatus called on nonauthoritative object")); m_timeToUpdateGuildWarPvpStatus = timeToUpdateGuildWarPvpStatus; @@ -13511,7 +13511,7 @@ void CreatureObject::pushedMe(const NetworkId & attackerId, * @param slopeAngle the angle of the "hill", in radians * @param expireTime the game time when the effect expires */ -void CreatureObject::addSlowDownEffect(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, unsigned long expireTime) +void CreatureObject::addSlowDownEffect(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, uint32_t expireTime) { if (isAuthoritative()) { @@ -13554,7 +13554,7 @@ void CreatureObject::addSlowDownEffect(const TangibleObject & defender, float co * * @return true if the effect was added, false if the creature already had a slow down effect */ -bool CreatureObject::addSlowDownEffectProxy(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, unsigned long expireTime) +bool CreatureObject::addSlowDownEffectProxy(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, uint32_t expireTime) { // if we already are doing a slowdown, don't do another Property * property = getProperty(SlowDownProperty::getClassPropertyId()); @@ -14236,7 +14236,7 @@ void CreatureObject::setRegenRate(Attributes::Enumerator poolAttrib, float value // ---------------------------------------------------------------------- -void CreatureObject::setLastWaterDamageTime(unsigned long newTime) +void CreatureObject::setLastWaterDamageTime(uint32_t newTime) { m_lastWaterDamageTime = newTime; } @@ -15346,7 +15346,7 @@ void CreatureObject::addPackedAppearanceWearable(std::string const &appearanceDa void CreatureObject::saveDecorationLayout(ServerObject const & pobSourceObject, int saveSlotNumber, std::string const & description) { int debugNumItems = 0; - const unsigned long debugStartTimeMs = Clock::timeMs(); + const uint32_t debugStartTimeMs = Clock::timeMs(); if (!isAuthoritative()) return; @@ -15540,7 +15540,7 @@ void CreatureObject::saveDecorationLayout(ServerObject const & pobSourceObject, if ((debugNumItems > 0) && getClient()->isGod()) { - const unsigned long debugEndTimeMs = Clock::timeMs(); + const uint32_t debugEndTimeMs = Clock::timeMs(); Chat::sendSystemMessage(*this, Unicode::narrowToWide(FormattedString<256>().sprintf("!!!GOD MODE STATISTICS!!! %d items saved in %lums", debugNumItems, (debugEndTimeMs - debugStartTimeMs))), Unicode::emptyString); } } @@ -15549,7 +15549,7 @@ void CreatureObject::saveDecorationLayout(ServerObject const & pobSourceObject, void CreatureObject::restoreDecorationLayout(ServerObject const & pobTargetObject, int saveSlotNumber) { - const unsigned long debugStartTimeMs = Clock::timeMs(); + const uint32_t debugStartTimeMs = Clock::timeMs(); if (!isAuthoritative()) return; @@ -15885,7 +15885,7 @@ void CreatureObject::restoreDecorationLayout(ServerObject const & pobTargetObjec if ((debugNumItems > 0) && getClient()->isGod()) { - const unsigned long debugEndTimeMs = Clock::timeMs(); + const uint32_t debugEndTimeMs = Clock::timeMs(); Chat::sendSystemMessage(*this, Unicode::narrowToWide(FormattedString<256>().sprintf("!!!GOD MODE STATISTICS!!! %d items read (%d will be moved) in %lums", debugNumItems, numItemsToBeMoved, (debugEndTimeMs - debugStartTimeMs))), Unicode::emptyString); } } diff --git a/engine/server/library/serverGame/src/shared/object/CreatureObject.h b/engine/server/library/serverGame/src/shared/object/CreatureObject.h index c1161c70e..0716c1192 100755 --- a/engine/server/library/serverGame/src/shared/object/CreatureObject.h +++ b/engine/server/library/serverGame/src/shared/object/CreatureObject.h @@ -385,8 +385,8 @@ class CreatureObject : public TangibleObject void setPerformanceWatchTarget(NetworkId const &who); int getGuildId() const; void setGuildId(int guildId); - unsigned long getTimeToUpdateGuildWarPvpStatus() const; - void setTimeToUpdateGuildWarPvpStatus(unsigned long timeToUpdateGuildWarPvpStatus); + uint32_t getTimeToUpdateGuildWarPvpStatus() const; + void setTimeToUpdateGuildWarPvpStatus(uint32_t timeToUpdateGuildWarPvpStatus); bool getGuildWarEnabled() const; void setGuildWarEnabled(bool guildWarEnabled); int getMilitiaOfCityId() const; @@ -546,8 +546,8 @@ class CreatureObject : public TangibleObject int loadPackedHouses(); void setClientUsesAnimationLocomotion(bool const enabled); - void addSlowDownEffect(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, unsigned long expireTime); - bool addSlowDownEffectProxy(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, unsigned long expireTime); + void addSlowDownEffect(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, uint32_t expireTime); + bool addSlowDownEffectProxy(const TangibleObject & defender, float coneLength, float coneAngle, float slopeAngle, uint32_t expireTime); void removeSlowDownEffect(); void removeSlowDownEffectProxy(); void addTerrainSlopeEffect(const Vector & normal); @@ -645,8 +645,8 @@ class CreatureObject : public TangibleObject void setRegenRate(Attributes::Enumerator poolAttrib, float value); float getLavaResistance() const; - unsigned long getLastWaterDamageTime() const; - void setLastWaterDamageTime(unsigned long newTime); + uint32_t getLastWaterDamageTime() const; + void setLastWaterDamageTime(uint32_t newTime); std::map const & getCommandList() const; void clearCommands(); @@ -862,7 +862,7 @@ class CreatureObject : public TangibleObject // when switching guild war pvp status using the guild war exemption/exclusive list, // add a delay to when the actually switch takes place, to prevent exploit of quickly // switching in and out guiild war pvp using the guild war exemption/exclusive list - Archive::AutoDeltaVariable m_timeToUpdateGuildWarPvpStatus; + Archive::AutoDeltaVariable m_timeToUpdateGuildWarPvpStatus; Archive::AutoDeltaVariableObserver m_guildWarEnabled; Archive::AutoDeltaVariableObserver m_militiaOfCityId; @@ -1000,7 +1000,7 @@ class CreatureObject : public TangibleObject bool m_fixedupPersistentBuffsAfterLoading; bool m_fixedupLevelXpAfterLoading; float m_lavaResistance; - unsigned long m_lastWaterDamageTime; // used for timing last damage taken by lava (and other future harmful water types) + uint32_t m_lastWaterDamageTime; // used for timing last damage taken by lava (and other future harmful water types) float m_attribRegenMultipliers[AR_count]; Archive::AutoDeltaMap m_commands; // game commands a creature may execute @@ -1347,7 +1347,7 @@ inline float CreatureObject::getLavaResistance() const //----------------------------------------------------------------------- -inline unsigned long CreatureObject::getLastWaterDamageTime() const +inline uint32_t CreatureObject::getLastWaterDamageTime() const { return m_lastWaterDamageTime; } @@ -1409,7 +1409,7 @@ inline int CreatureObject::getGuildId() const //----------------------------------------------------------------------- -inline unsigned long CreatureObject::getTimeToUpdateGuildWarPvpStatus() const +inline uint32_t CreatureObject::getTimeToUpdateGuildWarPvpStatus() const { return m_timeToUpdateGuildWarPvpStatus.get(); } diff --git a/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp b/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp index 2c1df6ae9..8a098bf00 100755 --- a/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp @@ -511,11 +511,11 @@ int PlayerObject::getCurrentBornDate() baseTimeData.tm_wday = 0; baseTimeData.tm_yday = 0; baseTimeData.tm_year = 101; - time_t baseTime = mktime(&baseTimeData); + uint32_t baseTime = mktime(&baseTimeData); // get the current time and compute the birth date - time_t currentTime = time(nullptr); - time_t delta = (currentTime - baseTime) / (60 * 60 * 24); + uint32_t currentTime = time(nullptr); + uint32_t delta = (currentTime - baseTime) / (60 * 60 * 24); delta += ((currentTime - baseTime) % (60 * 60 * 24) != 0 ? 1 : 0); return int(delta); } // PlayerObject::getCurrentBornDate @@ -859,7 +859,7 @@ int PlayerObject::grantExperiencePoints(const std::string & experienceType, int if (ConfigServerScript::getLogBalance() && (total != current)) { // log the grant - unsigned long time = ServerClock::getInstance().getGameTimeSeconds(); + uint32_t time = ServerClock::getInstance().getGameTimeSeconds(); LOG("GameBalance", ("balancelog:%d:XP;%lu;%s;%s;%d;%d;%d;%d", static_cast(GameServer::getInstance().getProcessId()), time, owner->getNetworkId().getValueString().c_str(), experienceType.c_str(), @@ -4231,7 +4231,7 @@ void PlayerObject::handleCMessageTo(const MessageToPayload &message) { // see if guild war pvp status has changed, and if yes, start countdown timer to change the status if (GuildInterface::getGuildMemberGuildWarEnabled(owner->getGuildId(), owner->getNetworkId()) != owner->getGuildWarEnabled()) - owner->setTimeToUpdateGuildWarPvpStatus(ServerClock::getInstance().getGameTimeSeconds() + static_cast(ConfigServerGame::getPvpGuildWarExemptionExclusiveDelaySeconds())); + owner->setTimeToUpdateGuildWarPvpStatus(ServerClock::getInstance().getGameTimeSeconds() + static_cast(ConfigServerGame::getPvpGuildWarExemptionExclusiveDelaySeconds())); } else if (owner->getGuildWarEnabled()) { @@ -4770,7 +4770,7 @@ void PlayerObject::logChat(int const logIndex) { if (m_chatLog != nullptr) { - time_t const logTime = Os::getRealSystemTime(); + uint32_t const logTime = Os::getRealSystemTime(); ChatLogEntry chatLogEntry; @@ -4834,13 +4834,13 @@ void PlayerObject::cleanChatLog() // See if anything needs to be purged from the front of the logs - time_t const chatLogTime = ConfigServerUtility::getChatLogMinutes() * 60; + uint32_t const chatLogTime = ConfigServerUtility::getChatLogMinutes() * 60; int chatLogCount = static_cast(m_chatLog->size()); ChatLog::iterator iterChatLog = m_chatLog->begin(); while (!m_chatLog->empty()) { - const time_t messageTime = iterChatLog->m_time; + const uint32_t messageTime = iterChatLog->m_time; if (messageTime < (currentTime - chatLogTime) || (chatLogCount > ConfigServerUtility::getPlayerMaxChatLogLines())) { @@ -6337,14 +6337,14 @@ void PlayerObject::setPlayedTimeAccumOnly(float playedTimeAccum) // ---------------------------------------------------------------------- -unsigned long PlayerObject::getSessionPlayTimeDuration() const +uint32_t PlayerObject::getSessionPlayTimeDuration() const { - time_t const sessionStartPlayTime = static_cast(m_sessionStartPlayTime.get()); + uint32_t const sessionStartPlayTime = static_cast(m_sessionStartPlayTime.get()); if (sessionStartPlayTime > 0) { - time_t const now = ::time(nullptr); + uint32_t const now = ::time(nullptr); if (now > sessionStartPlayTime) - return static_cast(now - sessionStartPlayTime); + return static_cast(now - sessionStartPlayTime); } return 0; @@ -6352,16 +6352,16 @@ unsigned long PlayerObject::getSessionPlayTimeDuration() const // ---------------------------------------------------------------------- -unsigned long PlayerObject::getSessionActivePlayTimeDuration() const +uint32_t PlayerObject::getSessionActivePlayTimeDuration() const { - unsigned long activePlayTimeDuration = m_sessionActivePlayTimeDuration.get(); + uint32_t activePlayTimeDuration = m_sessionActivePlayTimeDuration.get(); - time_t const sessionLastActiveTime = static_cast(m_sessionLastActiveTime.get()); + uint32_t const sessionLastActiveTime = static_cast(m_sessionLastActiveTime.get()); if (sessionLastActiveTime > 0) { - time_t const now = ::time(nullptr); + uint32_t const now = ::time(nullptr); if (now > sessionLastActiveTime) - activePlayTimeDuration += static_cast(now - sessionLastActiveTime); + activePlayTimeDuration += static_cast(now - sessionLastActiveTime); } return activePlayTimeDuration; @@ -6369,7 +6369,7 @@ unsigned long PlayerObject::getSessionActivePlayTimeDuration() const // ---------------------------------------------------------------------- -void PlayerObject::setSessionPlayTimeInfo(int32 sessionStartPlayTime, int32 sessionLastActiveTime, unsigned long sessionActivePlayTimeDuration) +void PlayerObject::setSessionPlayTimeInfo(int32 sessionStartPlayTime, int32 sessionLastActiveTime, uint32_t sessionActivePlayTimeDuration) { // shouldn't be calling this on a non-auth object if (!isAuthoritative()) @@ -6447,7 +6447,7 @@ int PlayerObject::getRoleIconChoice() const void PlayerObject::setAggroImmuneDuration(int const time) { - m_aggroImmuneDuration = static_cast(time); + m_aggroImmuneDuration = static_cast(time); m_aggroImmuneStartTime = Os::getRealSystemTime(); } @@ -6455,7 +6455,7 @@ void PlayerObject::setAggroImmuneDuration(int const time) bool PlayerObject::isAggroImmune() const { - time_t const elapsedTime = Os::getRealSystemTime() - m_aggroImmuneStartTime.get(); + uint32_t const elapsedTime = Os::getRealSystemTime() - m_aggroImmuneStartTime.get(); return (elapsedTime < m_aggroImmuneDuration.get()); } @@ -7185,7 +7185,7 @@ void PlayerObject::setNextGcwRatingCalcTime(bool const alwaysSendMessageToForRec { if (m_nextGcwRatingCalcTime.get() <= 0) { - time_t const nextCalcTime = CalendarTime::getNextGMTTimeOcurrence(static_cast(now), ConfigServerGame::getGcwRecalcTimeDayOfWeek(), ConfigServerGame::getGcwRecalcTimeHour(), ConfigServerGame::getGcwRecalcTimeMinute(), ConfigServerGame::getGcwRecalcTimeSecond()); + uint32_t const nextCalcTime = CalendarTime::getNextGMTTimeOcurrence(static_cast(now), ConfigServerGame::getGcwRecalcTimeDayOfWeek(), ConfigServerGame::getGcwRecalcTimeHour(), ConfigServerGame::getGcwRecalcTimeMinute(), ConfigServerGame::getGcwRecalcTimeSecond()); if (nextCalcTime > 0) { m_nextGcwRatingCalcTime = static_cast(nextCalcTime); @@ -7250,14 +7250,14 @@ void PlayerObject::handleRecalculateGcwRating() totalRatingAdjustment = Pvp::calculateRatingAdjustment(static_cast(points), static_cast(currentRating), totalEarnedRating, totalEarnedRatingAfterDecay, cappedRatingAdjustment); // don't apply rating loss if we are in a "rating loss exclusion interval" - if ((totalRatingAdjustment < 0) && (Pvp::isInGcwRankDecayExclusionInterval(static_cast(nextCalcInterval)))) + if ((totalRatingAdjustment < 0) && (Pvp::isInGcwRankDecayExclusionInterval(static_cast(nextCalcInterval)))) { // CS log LOG("CustomerService", ("PvP_Ranking:%s|NOT APPLYING RATING LOSS|interval %ld (%s) (%s)|current rating=%ld|points=%ld|total earned rating=%ld|total earned rating after decay=%ld|capped rating adjustment=%ld|final rating adjustment=%ld", getAccountDescription().c_str(), nextCalcInterval, - CalendarTime::convertEpochToTimeStringGMT(static_cast(nextCalcInterval)).c_str(), - CalendarTime::convertEpochToTimeStringLocal(static_cast(nextCalcInterval)).c_str(), + CalendarTime::convertEpochToTimeStringGMT(static_cast(nextCalcInterval)).c_str(), + CalendarTime::convertEpochToTimeStringLocal(static_cast(nextCalcInterval)).c_str(), currentRating, points, totalEarnedRating, @@ -7279,8 +7279,8 @@ void PlayerObject::handleRecalculateGcwRating() LOG("CustomerService", ("PvP_Ranking:%s|interval %ld (%s) (%s)|current rating=%ld|new rating=%ld|points=%ld|total earned rating=%ld|total earned rating after decay=%ld|capped rating adjustment=%ld|final rating adjustment=%ld", getAccountDescription().c_str(), nextCalcInterval, - CalendarTime::convertEpochToTimeStringGMT(static_cast(nextCalcInterval)).c_str(), - CalendarTime::convertEpochToTimeStringLocal(static_cast(nextCalcInterval)).c_str(), + CalendarTime::convertEpochToTimeStringGMT(static_cast(nextCalcInterval)).c_str(), + CalendarTime::convertEpochToTimeStringLocal(static_cast(nextCalcInterval)).c_str(), previousRating, currentRating, points, @@ -7294,7 +7294,7 @@ void PlayerObject::handleRecalculateGcwRating() points = 0; // check to see if we need to do another calculation for the next interval - nextCalcInterval = static_cast(CalendarTime::getNextGMTTimeOcurrence(static_cast(nextCalcInterval)+1, ConfigServerGame::getGcwRecalcTimeDayOfWeek(), ConfigServerGame::getGcwRecalcTimeHour(), ConfigServerGame::getGcwRecalcTimeMinute(), ConfigServerGame::getGcwRecalcTimeSecond())); + nextCalcInterval = static_cast(CalendarTime::getNextGMTTimeOcurrence(static_cast(nextCalcInterval)+1, ConfigServerGame::getGcwRecalcTimeDayOfWeek(), ConfigServerGame::getGcwRecalcTimeHour(), ConfigServerGame::getGcwRecalcTimeMinute(), ConfigServerGame::getGcwRecalcTimeSecond())); if (nextCalcInterval <= 0) break; @@ -7406,7 +7406,7 @@ void PlayerObject::addSessionActivity(uint32 activity) { CreatureObject * const owner = getCreatureObject(); if (owner) - owner->sendControllerMessageToAuthServer(CM_addSessionActivity, new MessageQueueGenericValueType(static_cast(activity))); + owner->sendControllerMessageToAuthServer(CM_addSessionActivity, new MessageQueueGenericValueType(static_cast(activity))); } } @@ -7618,7 +7618,7 @@ bool PlayerObject::modifyCollectionSlotValue(std::string const & slotName, int64 if (currentSlotValue != newSlotValue) { BitArray b = collections->get(); - b.setValue(slotInfo->beginSlotId, slotInfo->endSlotId, static_cast(newSlotValue)); + b.setValue(slotInfo->beginSlotId, slotInfo->endSlotId, static_cast(newSlotValue)); collections->set(b); LOG("CustomerService", ("Collection:%s modified collection %d-%d (%s/%s/%s/%s) from %lu to %lu", @@ -7629,10 +7629,10 @@ bool PlayerObject::modifyCollectionSlotValue(std::string const & slotName, int64 slotInfo->collection.page.name.c_str(), slotInfo->collection.name.c_str(), slotInfo->name.c_str(), - static_cast(currentSlotValue), - static_cast(newSlotValue))); + static_cast(currentSlotValue), + static_cast(newSlotValue))); - bool const completedCollectionSlot = hasCompletedCollectionSlot(*slotInfo, static_cast(newSlotValue)); + bool const completedCollectionSlot = hasCompletedCollectionSlot(*slotInfo, static_cast(newSlotValue)); // for "server first" tracking, we need to check if the collection // is completed *BEFORE* triggering script, because script may clear @@ -7692,7 +7692,7 @@ bool PlayerObject::modifyCollectionSlotValue(std::string const & slotName, int64 // ---------------------------------------------------------------------- -bool PlayerObject::getCollectionSlotValue(std::string const & slotName, unsigned long & value) const +bool PlayerObject::getCollectionSlotValue(std::string const & slotName, uint32_t & value) const { value = 0; @@ -7708,7 +7708,7 @@ bool PlayerObject::getCollectionSlotValue(std::string const & slotName, unsigned // ---------------------------------------------------------------------- -bool PlayerObject::getCollectionSlotValue(CollectionsDataTable::CollectionInfoSlot const & slotInfo, unsigned long & value) const +bool PlayerObject::getCollectionSlotValue(CollectionsDataTable::CollectionInfoSlot const & slotInfo, uint32_t & value) const { // bit-type slot if (!slotInfo.counterTypeSlot) @@ -7795,7 +7795,7 @@ bool PlayerObject::hasCompletedCollectionSlot(CollectionsDataTable::CollectionIn // ---------------------------------------------------------------------- -bool PlayerObject::hasCompletedCollectionSlot(CollectionsDataTable::CollectionInfoSlot const & slotInfo, unsigned long slotValue) +bool PlayerObject::hasCompletedCollectionSlot(CollectionsDataTable::CollectionInfoSlot const & slotInfo, uint32_t slotValue) { // bit-type slot if (!slotInfo.counterTypeSlot) @@ -8123,7 +8123,7 @@ void PlayerObject::updateChatSpamSpatialNumCharacters(NetworkId const & characte // sync chat character count with chat server if ((syncChatServer) || (timeNow > m_chatSpamNextTimeToSyncWithChatServer.get())) { - time_t timeUnsquelch = static_cast(getSecondsUntilUnsquelched()); + uint32_t timeUnsquelch = static_cast(getSecondsUntilUnsquelched()); if (timeUnsquelch > 0) timeUnsquelch += ::time(nullptr); @@ -8166,7 +8166,7 @@ void PlayerObject::handleChatStatisticsFromChatServer(NetworkId const & characte // sync chat character count with chat server if (syncChatServer || ((spatialNumCharacters != m_chatSpamSpatialNumCharacters.get()) && (timeNow > m_chatSpamNextTimeToSyncWithChatServer.get()))) { - time_t timeUnsquelch = static_cast(getSecondsUntilUnsquelched()); + uint32_t timeUnsquelch = static_cast(getSecondsUntilUnsquelched()); if (timeUnsquelch > 0) timeUnsquelch += ::time(nullptr); diff --git a/engine/server/library/serverGame/src/shared/object/PlayerObject.h b/engine/server/library/serverGame/src/shared/object/PlayerObject.h index eab82de30..b2f308084 100755 --- a/engine/server/library/serverGame/src/shared/object/PlayerObject.h +++ b/engine/server/library/serverGame/src/shared/object/PlayerObject.h @@ -60,7 +60,7 @@ class PlayerObject : public IntangibleObject ChatLogEntry(); int m_index; - time_t m_time; + uint32_t m_time; }; typedef std::list ChatLog; @@ -105,11 +105,11 @@ class PlayerObject : public IntangibleObject float getPlayedTimeAccumOnly() const; void setPlayedTimeAccumOnly(float playedTimeAccum); - unsigned long getSessionPlayTimeDuration() const; - unsigned long getSessionActivePlayTimeDuration() const; + uint32_t getSessionPlayTimeDuration() const; + uint32_t getSessionActivePlayTimeDuration() const; int32 getSessionStartPlayTime() const; int32 getSessionLastActiveTime() const; - void setSessionPlayTimeInfo(int32 sessionStartPlayTime, int32 sessionLastActiveTime, unsigned long sessionActivePlayTimeDuration); + void setSessionPlayTimeInfo(int32 sessionStartPlayTime, int32 sessionLastActiveTime, uint32_t sessionActivePlayTimeDuration); void setStationId(StationId account); void setCheaterLevel(float level); @@ -358,15 +358,15 @@ class PlayerObject : public IntangibleObject bool modifyCollectionSlotValue(std::string const & slotName, int64 delta); - bool getCollectionSlotValue(std::string const & slotName, unsigned long & value) const; - bool getCollectionSlotValue(CollectionsDataTable::CollectionInfoSlot const & slotInfo, unsigned long & value) const; + bool getCollectionSlotValue(std::string const & slotName, uint32_t & value) const; + bool getCollectionSlotValue(CollectionsDataTable::CollectionInfoSlot const & slotInfo, uint32_t & value) const; bool hasCompletedCollectionSlotPrereq(std::string const & slotName, std::vector * collectionInfo = nullptr) const; bool hasCompletedCollectionSlotPrereq(CollectionsDataTable::CollectionInfoSlot const & slotInfo, std::vector * collectionInfo = nullptr) const; bool hasCompletedCollectionSlot(std::string const & slotName) const; bool hasCompletedCollectionSlot(CollectionsDataTable::CollectionInfoSlot const & slotInfo) const; - static bool hasCompletedCollectionSlot(CollectionsDataTable::CollectionInfoSlot const & slotInfo, unsigned long slotValue); + static bool hasCompletedCollectionSlot(CollectionsDataTable::CollectionInfoSlot const & slotInfo, uint32_t slotValue); bool hasCompletedCollection(std::string const & collectionName) const; @@ -395,8 +395,8 @@ class PlayerObject : public IntangibleObject int getChatSpamTimeEndInterval() const; - time_t getChatSpamNextTimeToNotifyPlayerWhenLimited() const; - void setChatSpamNextTimeToNotifyPlayerWhenLimited(time_t chatSpamNextTimeToNotifyPlayerWhenLimited); + uint32_t getChatSpamNextTimeToNotifyPlayerWhenLimited() const; + void setChatSpamNextTimeToNotifyPlayerWhenLimited(uint32_t chatSpamNextTimeToNotifyPlayerWhenLimited); // citizenship info void updateCitizenshipInfo(); @@ -554,7 +554,7 @@ class PlayerObject : public IntangibleObject // cached here for use by the game server Archive::AutoDeltaVariable m_sessionStartPlayTime; // time when the player started playing the character Archive::AutoDeltaVariable m_sessionLastActiveTime; // the client will detect when the player is "active" or "inactive"; this keeps track of the last time that the client said the player was "active"; if 0, it means the client is currently "inactive" - Archive::AutoDeltaVariable m_sessionActivePlayTimeDuration; // total amount of play time player was active (i.e. at the mouse/keyboard/joystick) + Archive::AutoDeltaVariable m_sessionActivePlayTimeDuration; // total amount of play time player was active (i.e. at the mouse/keyboard/joystick) Archive::AutoDeltaVariable m_food; Archive::AutoDeltaVariable m_maxFood; @@ -581,11 +581,11 @@ class PlayerObject : public IntangibleObject Archive::AutoDeltaVariable m_theaterId; Archive::AutoDeltaVariable m_theaterLocationType; Archive::AutoDeltaVariable m_roleIconChoice; - Archive::AutoDeltaVariable m_aggroImmuneDuration; - Archive::AutoDeltaVariable m_aggroImmuneStartTime; + Archive::AutoDeltaVariable m_aggroImmuneDuration; + Archive::AutoDeltaVariable m_aggroImmuneStartTime; ChatLog * const m_chatLog; - time_t m_chatLogPurgeTime; + uint32_t m_chatLogPurgeTime; bool m_isUnsticking; //when asking a player to accept or complete a quest, remember the quest that we asked them about @@ -641,7 +641,7 @@ class PlayerObject : public IntangibleObject Archive::AutoDeltaVariable m_chatSpamNonSpatialNumCharacters; Archive::AutoDeltaVariable m_chatSpamTimeEndInterval; Archive::AutoDeltaVariable m_chatSpamNextTimeToSyncWithChatServer; - time_t m_chatSpamNextTimeToNotifyPlayerWhenLimited; + uint32_t m_chatSpamNextTimeToNotifyPlayerWhenLimited; // citizenship info Archive::AutoDeltaVariable m_citizenshipCity; @@ -1053,14 +1053,14 @@ inline int PlayerObject::getChatSpamTimeEndInterval() const // ---------------------------------------------------------------------- -inline time_t PlayerObject::getChatSpamNextTimeToNotifyPlayerWhenLimited() const +inline uint32_t PlayerObject::getChatSpamNextTimeToNotifyPlayerWhenLimited() const { return m_chatSpamNextTimeToNotifyPlayerWhenLimited; } // ---------------------------------------------------------------------- -inline void PlayerObject::setChatSpamNextTimeToNotifyPlayerWhenLimited(time_t chatSpamNextTimeToNotifyPlayerWhenLimited) +inline void PlayerObject::setChatSpamNextTimeToNotifyPlayerWhenLimited(uint32_t chatSpamNextTimeToNotifyPlayerWhenLimited) { m_chatSpamNextTimeToNotifyPlayerWhenLimited = chatSpamNextTimeToNotifyPlayerWhenLimited; } diff --git a/engine/server/library/serverGame/src/shared/object/ServerObject.cpp b/engine/server/library/serverGame/src/shared/object/ServerObject.cpp index 585cd19fc..3625e9dc2 100755 --- a/engine/server/library/serverGame/src/shared/object/ServerObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/ServerObject.cpp @@ -241,7 +241,7 @@ namespace ServerObjectNamespace const std::string OBJVAR_OPEN_BANK_TERMINAL_ID("open_bank_location"); - unsigned long gs_objectCount = 0; + uint32_t gs_objectCount = 0; const char * const portalPropertyCrcObjectVariableName = "portalProperty.crc"; @@ -262,7 +262,7 @@ namespace ServerObjectNamespace // sentinel to keep the messageTo current being // handled from getting removed from m_messageTos - std::pair, MessageToId> s_currentMessageToBeingHandled = std::make_pair(std::make_pair(0, 0), MessageToId::cms_invalid); + std::pair, MessageToId> s_currentMessageToBeingHandled = std::make_pair(std::make_pair(0, 0), MessageToId::cms_invalid); // ---------------------------------------------------------------------- @@ -1295,7 +1295,7 @@ static const ConstCharCrcLowerString templateName("object/object/base/shared_obj //----------------------------------------------------------------------- -const unsigned long ServerObject::getObjectCount() +const uint32_t ServerObject::getObjectCount() { return gs_objectCount; } @@ -2320,9 +2320,9 @@ bool ServerObject::handleContentsSetup() //----------------------------------------------------------------------- -unsigned long ServerObject::getAndIncrementMoveSequenceNumber() +uint32_t ServerObject::getAndIncrementMoveSequenceNumber() { - unsigned long newValue = m_transformSequence.get(); + uint32_t newValue = m_transformSequence.get(); newValue++; m_transformSequence = newValue; return newValue; @@ -3401,7 +3401,7 @@ void ServerObject::sendToClientsInUpdateRange(const GameNetworkMessage & message Vector combatSpamAttackerPosition_w, combatSpamDefenderPosition_w; if (!clients.empty()) { - static unsigned long int const controllerMessageCrc = MessageDispatch::MessageBase::makeMessageTypeFromString("ObjControllerMessage"); + static uint32_t const controllerMessageCrc = MessageDispatch::MessageBase::makeMessageTypeFromString("ObjControllerMessage"); if (controllerMessageCrc == message.getType()) { ObjControllerMessage const & ocm = static_cast(message); @@ -5083,10 +5083,10 @@ bool ServerObject::setPackedObjVars(std::string const &packedVarString) std::string ServerObject::debugGetMessageToList() const { - unsigned long const now = ServerClock::getInstance().getGameTimeSeconds(); + uint32_t const now = ServerClock::getInstance().getGameTimeSeconds(); std::string result; - time_t const timeNow = ::time(nullptr); - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) + uint32_t const timeNow = ::time(nullptr); + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) { char temp[256]; @@ -5114,14 +5114,14 @@ std::string ServerObject::debugGetMessageToList() const * @return The delivery time of the next message, or 0 if there are no more messages */ -unsigned long ServerObject::processQueuedMessageTos(unsigned long effectiveMessageToTime) +uint32_t ServerObject::processQueuedMessageTos(uint32_t effectiveMessageToTime) { PROFILER_AUTO_BLOCK_DEFINE("ServerObject::processQueuedMessageTos"); if (isAuthoritative()) { int handledMessageCount = 0; - unsigned long startTime = Clock::timeMs(); + uint32_t startTime = Clock::timeMs(); while (!m_messageTos.empty() && m_messageTos.begin()->second.getCallTime() <= effectiveMessageToTime) { ++handledMessageCount; @@ -5131,7 +5131,7 @@ unsigned long ServerObject::processQueuedMessageTos(unsigned long effectiveMessa std::string nextTenMessages; { int count = 1; - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator iter = m_messageTos.begin(); ((iter != m_messageTos.end()) && (count <= 10)); ++iter, ++count) + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator iter = m_messageTos.begin(); ((iter != m_messageTos.end()) && (count <= 10)); ++iter, ++count) { nextTenMessages += iter->second.getMethod(); nextTenMessages += ", "; @@ -5150,7 +5150,7 @@ unsigned long ServerObject::processQueuedMessageTos(unsigned long effectiveMessa break; } - Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator message = m_messageTos.begin(); + Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator message = m_messageTos.begin(); // if the message is going to be recurring, create a // new messageTo to reschedule the recurring message @@ -5162,7 +5162,7 @@ unsigned long ServerObject::processQueuedMessageTos(unsigned long effectiveMessa message->second.getMessageId(), message->second.getMethod(), message->second.getPackedDataVector(), - ServerClock::getInstance().getGameTimeSeconds() + static_cast(message->second.getRecurringTime()), + ServerClock::getInstance().getGameTimeSeconds() + static_cast(message->second.getRecurringTime()), false, message->second.getDeliveryType(), NetworkId::cms_invalid, @@ -5378,7 +5378,7 @@ void ServerObject::handleCMessageTo(const MessageToPayload &message) else if (message.getMethod() == "CancelRecurringMessageTo") { std::string const & methodName = message.getDataAsString(); - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) { if ((i->second.getRecurringTime() != 0) && (i->second.getMethod() == methodName) && (i->first != s_currentMessageToBeingHandled)) { @@ -7718,7 +7718,7 @@ void ServerObject::deliverMessageTo(MessageToPayload & message) { // Recurring messages can have only one instance each. Ignore // this message if there is already a recurring one with the same method name. - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) { if ((i->second.getRecurringTime() != 0) && (i->second.getMethod() == message.getMethod())) return; @@ -7778,7 +7778,7 @@ int ServerObject::cancelMessageTo(std::string const & messageName) { removeCount = 0; - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end();) + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end();) { if ((i->second.getMethod() == messageName) && (i->first != s_currentMessageToBeingHandled)) { @@ -7812,7 +7812,7 @@ int ServerObject::cancelMessageToByMessageId(NetworkId const & messageId) { removeCount = 0; - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end();) + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end();) { if ((i->second.getMessageId() == messageId) && (i->first != s_currentMessageToBeingHandled)) { @@ -7842,14 +7842,14 @@ int ServerObject::cancelMessageToByMessageId(NetworkId const & messageId) // returns -1 if object doesn't have the messageTo int ServerObject::timeUntilMessageTo(std::string const & messageName) const { - for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) + for (Archive::AutoDeltaMap, MessageToId>, MessageToPayload>::const_iterator i=m_messageTos.begin(); i!=m_messageTos.end(); ++i) { if (i->second.getMethod() == messageName) { if ((i->first != s_currentMessageToBeingHandled) || (i->second.getRecurringTime() > 0)) { - unsigned long const now = ServerClock::getInstance().getGameTimeSeconds(); - unsigned long const callTime = i->second.getCallTime(); + uint32_t const now = ServerClock::getInstance().getGameTimeSeconds(); + uint32_t const callTime = i->second.getCallTime(); if (callTime > now) return static_cast(callTime - now); diff --git a/engine/server/library/serverGame/src/shared/object/ServerObject.h b/engine/server/library/serverGame/src/shared/object/ServerObject.h index 90437a5ce..7f8f9fa6b 100755 --- a/engine/server/library/serverGame/src/shared/object/ServerObject.h +++ b/engine/server/library/serverGame/src/shared/object/ServerObject.h @@ -260,7 +260,7 @@ class ServerObject : public Object int getConversionId () const; void setConversionId (int newConversionId); - static const unsigned long getObjectCount (); + static const uint32_t getObjectCount (); const bool getPositionChanged () const; const Sphere getLocalSphere () const; const Sphere & getSphereExtent () const; @@ -485,7 +485,7 @@ class ServerObject : public Object void attachStartupScripts (); void customize (const std::string & customName, int value); void serverObjectEndBaselines (bool fromDatabase); - unsigned long getAndIncrementMoveSequenceNumber (); + uint32_t getAndIncrementMoveSequenceNumber (); uint32 getAuthServerProcessId () const; const int getCacheVersion () const; Client * getClient () const; @@ -540,7 +540,7 @@ class ServerObject : public Object int cancelMessageTo (std::string const & messageName); int cancelMessageToByMessageId (NetworkId const & messageId); int timeUntilMessageTo (std::string const & messageName) const; - unsigned long processQueuedMessageTos (unsigned long effectiveMessageToTime); + uint32_t processQueuedMessageTos (uint32_t effectiveMessageToTime); std::string debugGetMessageToList () const; bool handleTeleportFixup (bool force); bool serverObjectInitializeFirstTimeObject(ServerObject *cell, Transform const &transform); @@ -798,7 +798,7 @@ class ServerObject : public Object Archive::AutoDeltaVariableCallback m_authServerProcessId; Archive::AutoDeltaSet m_proxyServerProcessIds; - Archive::AutoDeltaVariable m_transformSequence; + Archive::AutoDeltaVariable m_transformSequence; Archive::AutoDeltaVariable m_cacheVersion; Archive::AutoDeltaVariable m_loadContents; @@ -844,7 +844,7 @@ class ServerObject : public Object private: Archive::AutoDeltaVector m_triggerVolumeInfo; - Archive::AutoDeltaMap, MessageToId>, MessageToPayload> m_messageTos; + Archive::AutoDeltaMap, MessageToId>, MessageToPayload> m_messageTos; Sphere m_worldSphere; diff --git a/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp b/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp index a547127b4..eba9e915b 100755 --- a/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp @@ -2341,8 +2341,8 @@ void TangibleObject::addHateOverTime(NetworkId const & target, float const hate, if (isAuthoritative()) { - unsigned long const currentGameTime = ServerClock::getInstance().getGameTimeSeconds(); - unsigned long const endGameTime = currentGameTime + seconds; + uint32_t const currentGameTime = ServerClock::getInstance().getGameTimeSeconds(); + uint32_t const endGameTime = currentGameTime + seconds; IGNORE_RETURN(addHate(target, hate)); @@ -5149,9 +5149,9 @@ void TangibleObject::handleCMessageTo(const MessageToPayload &message) if (!m_hateOverTime.empty()) { std::list expired; - unsigned long const currentGameTime = ServerClock::getInstance().getGameTimeSeconds(); + uint32_t const currentGameTime = ServerClock::getInstance().getGameTimeSeconds(); - for (std::map > >::const_iterator iter = m_hateOverTime.begin(); iter != m_hateOverTime.end(); ++iter) + for (std::map > >::const_iterator iter = m_hateOverTime.begin(); iter != m_hateOverTime.end(); ++iter) { if (iter->second.second.first < currentGameTime) { diff --git a/engine/server/library/serverGame/src/shared/object/TangibleObject.h b/engine/server/library/serverGame/src/shared/object/TangibleObject.h index 338cc71a4..035fed012 100755 --- a/engine/server/library/serverGame/src/shared/object/TangibleObject.h +++ b/engine/server/library/serverGame/src/shared/object/TangibleObject.h @@ -153,7 +153,7 @@ class TangibleObject : public ServerObject void addHateOverTime(NetworkId const & target, float const hate, int const seconds); bool setHate(NetworkId const & target, float const hate); float getHate(NetworkId const & target) const; - std::map > > const & getHateOverTime() const; + std::map > > const & getHateOverTime() const; float getMaxHate() const; CachedNetworkId const & getHateTarget() const; void removeHateTarget(NetworkId const & target); @@ -576,10 +576,10 @@ class TangibleObject : public ServerObject HateList m_hateList; // for applying "hate over time" - Archive::AutoDeltaMap > > m_hateOverTime; + Archive::AutoDeltaMap > > m_hateOverTime; Archive::AutoDeltaVariableCallback m_inCombat; - Archive::AutoDeltaVariable m_combatStartTime; + Archive::AutoDeltaVariable m_combatStartTime; // allows script to make an object (i.e. like a turret) attackable Archive::AutoDeltaVariableCallback m_attackableOverride; @@ -813,7 +813,7 @@ inline std::set const & TangibleObject::getPassiveRevealPlayerCharact //---------------------------------------------------------------------- -inline std::map > > const & TangibleObject::getHateOverTime() const +inline std::map > > const & TangibleObject::getHateOverTime() const { return m_hateOverTime.getMap(); } diff --git a/engine/server/library/serverGame/src/shared/objectTemplate/ServerIntangibleObjectTemplate.h b/engine/server/library/serverGame/src/shared/objectTemplate/ServerIntangibleObjectTemplate.h index f4720ff02..a0e4d6e80 100644 --- a/engine/server/library/serverGame/src/shared/objectTemplate/ServerIntangibleObjectTemplate.h +++ b/engine/server/library/serverGame/src/shared/objectTemplate/ServerIntangibleObjectTemplate.h @@ -67,7 +67,7 @@ class ServerIntangibleObjectTemplate : public ServerObjectTemplate struct Ingredient { - enum IngredientType ingredientType; + enum IngredientType ingredientType; std::vector ingredients; float complexity; std::string skillCommand; diff --git a/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp b/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp index 5cd42a725..d6e291ae3 100755 --- a/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp +++ b/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp @@ -843,14 +843,14 @@ int Pvp::calculateGcwImperialScorePercentile(std::string const & gcwCategory, st { std::map >::const_iterator const iterImperial = gcwImperialScore.find(gcwCategory); if (iterImperial != gcwImperialScore.end()) - totalImperial = static_cast(std::max(0l, iterImperial->second.first)) + static_cast(std::max(0l, iterImperial->second.second)); + totalImperial = static_cast(std::max(0ll, iterImperial->second.first)) + static_cast(std::max(0ll, iterImperial->second.second)); } uint64 total = totalImperial; { std::map >::const_iterator const iterRebel = gcwRebelScore.find(gcwCategory); if (iterRebel != gcwRebelScore.end()) - total += (static_cast(std::max(0l, iterRebel->second.first)) + static_cast(std::max(0l, iterRebel->second.second))); + total += (static_cast(std::max(0ll, iterRebel->second.first)) + static_cast(std::max(0ll, iterRebel->second.second))); } // if the score is less than 1, treat it as a tie; note that score is scaled by 1000 diff --git a/engine/server/library/serverNetworkMessages/src/shared/centralGameServer/MessageToPayloadImpl.h b/engine/server/library/serverNetworkMessages/src/shared/centralGameServer/MessageToPayloadImpl.h index 98754843c..5da198c7a 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/centralGameServer/MessageToPayloadImpl.h +++ b/engine/server/library/serverNetworkMessages/src/shared/centralGameServer/MessageToPayloadImpl.h @@ -68,7 +68,7 @@ class MessageToPayloadImpl MessageToId m_messageId; std::string m_method; std::vector m_packedData; - unsigned long m_callTime; + uint32_t m_callTime; bool m_guaranteed; bool m_persisted; MessageToPayload::DeliveryType m_deliveryType; diff --git a/engine/server/library/serverNetworkMessages/src/shared/core/SetupServerNetworkMessages.cpp b/engine/server/library/serverNetworkMessages/src/shared/core/SetupServerNetworkMessages.cpp index 007706a89..67af827e6 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/core/SetupServerNetworkMessages.cpp +++ b/engine/server/library/serverNetworkMessages/src/shared/core/SetupServerNetworkMessages.cpp @@ -217,20 +217,20 @@ namespace SetupServerNetworkMessagesNamespace return result; } - void packUnsignedLong(const MessageQueue::Data * data, Archive::ByteStream & target) + void packUnsignedInt(const MessageQueue::Data * data, Archive::ByteStream & target) { - const MessageQueueGenericValueType * msg = safe_cast *>(data); + const MessageQueueGenericValueType * msg = safe_cast *>(data); if(msg) { Archive::put(target, msg->getValue()); } } - MessageQueue::Data * unpackUnsignedLong(Archive::ReadIterator & source) + MessageQueue::Data * unpackUnsignedInt(Archive::ReadIterator & source) { - unsigned long v; + uint32_t v; Archive::get(source, v); - return new MessageQueueGenericValueType(v); + return new MessageQueueGenericValueType(v); } void packUnicodeString(const MessageQueue::Data * data, Archive::ByteStream & target) @@ -1391,9 +1391,9 @@ void SetupServerNetworkMessages::internalInstall () ControllerMessageFactory::registerControllerMessageHandler(CM_setCombatTargets, packNetworkIdArray, unpackNetworkIdArray); ControllerMessageFactory::registerControllerMessageHandler(CM_setCurrentWeapon, packNetworkId, unpackNetworkId); ControllerMessageFactory::registerControllerMessageHandler(CM_setGroup, packBoolNetworkId, unpackBoolNetworkId); - ControllerMessageFactory::registerControllerMessageHandler(CM_setMood, packUnsignedLong, unpackUnsignedLong); + ControllerMessageFactory::registerControllerMessageHandler(CM_setMood, packUnsignedInt, unpackUnsignedInt); ControllerMessageFactory::registerControllerMessageHandler(CM_setIncapacitated, packBoolNetworkId, unpackBoolNetworkId); - ControllerMessageFactory::registerControllerMessageHandler(CM_setSayMode, packUnsignedLong, unpackUnsignedLong); + ControllerMessageFactory::registerControllerMessageHandler(CM_setSayMode, packUnsignedInt, unpackUnsignedInt); ControllerMessageFactory::registerControllerMessageHandler(CM_setAnimationMood, packString, unpackString); ControllerMessageFactory::registerControllerMessageHandler(CM_setScaleFactor, packFloat, unpackFloat); ControllerMessageFactory::registerControllerMessageHandler(CM_setShockWounds, packInt, unpackInt); @@ -1550,7 +1550,7 @@ void SetupServerNetworkMessages::internalInstall () ControllerMessageFactory::registerControllerMessageHandler(CM_modifyNextGcwRatingCalcTime, packInt, unpackInt); ControllerMessageFactory::registerControllerMessageHandler(CM_cancelMessageTo, packString, unpackString); ControllerMessageFactory::registerControllerMessageHandler(CM_clearSessionActivity, packNothing, unpackNothing); - ControllerMessageFactory::registerControllerMessageHandler(CM_addSessionActivity, packUnsignedLong, unpackUnsignedLong); + ControllerMessageFactory::registerControllerMessageHandler(CM_addSessionActivity, packUnsignedInt, unpackUnsignedInt); ControllerMessageFactory::registerControllerMessageHandler(CM_incrementKillMeter, packInt, unpackInt); ControllerMessageFactory::registerControllerMessageHandler(CM_addPassiveReveal, packIntIntNetworkId, unpackIntIntNetworkId); ControllerMessageFactory::registerControllerMessageHandler(CM_removePassiveReveal, packNetworkId, unpackNetworkId); diff --git a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp index e274f15af..40b0e0c1a 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp +++ b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp @@ -223,7 +223,7 @@ GameClientMessage::GameClientMessage(const std::vector & d, bool newR if (reportMessages) { Archive::ReadIterator ri = byteStream.get().begin(); - unsigned long cmdCrc; + uint32_t cmdCrc; Archive::get(ri, cmdCrc); NetworkHandler::reportMessage("send.GameClientMessage." + GameNetworkMessage::getCmdName(cmdCrc), byteStream.get().getSize()); } @@ -246,7 +246,7 @@ GameClientMessage::GameClientMessage(Archive::ReadIterator & source) : if (reportMessages) { Archive::ReadIterator ri = byteStream.get().begin(); - unsigned long cmdCrc; + uint32_t cmdCrc; Archive::get(ri, cmdCrc); NetworkHandler::reportMessage("send.GameClientMessage." + GameNetworkMessage::getCmdName(cmdCrc), byteStream.get().getSize()); } diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp index 396e6d900..2e6ded6d8 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsCollection.cpp @@ -150,7 +150,7 @@ jlong JNICALL ScriptMethodsCollectionNamespace::getCollectionSlotValue(JNIEnv *e std::string slotNameString; JavaLibrary::convert(localSlotName, slotNameString); - unsigned long value; + uint32_t value; if (!playerObject->getCollectionSlotValue(slotNameString, value)) return static_cast(-1); diff --git a/engine/server/library/serverUtility/src/shared/ChatLogManager.cpp b/engine/server/library/serverUtility/src/shared/ChatLogManager.cpp index c883063eb..da6a508a3 100755 --- a/engine/server/library/serverUtility/src/shared/ChatLogManager.cpp +++ b/engine/server/library/serverUtility/src/shared/ChatLogManager.cpp @@ -33,7 +33,7 @@ namespace ChatLogManagerNamespace { public: - ChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const *text, Unicode::String const &channel, time_t const time) + ChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const *text, Unicode::String const &channel, uint32_t const time) : m_fromPlayer(Unicode::toLower(fromPlayer)) , m_toPlayer(Unicode::toLower(toPlayer)) , m_text(text) @@ -62,7 +62,7 @@ namespace ChatLogManagerNamespace return m_channel; } - time_t getTime() const + uint32_t getTime() const { return m_time; } @@ -73,14 +73,14 @@ namespace ChatLogManagerNamespace Unicode::String m_toPlayer; Unicode::String const *m_text; Unicode::String m_channel; - time_t m_time; + uint32_t m_time; // Disabled ChatLogEntry(); }; - typedef std::list > TimeLog; + typedef std::list > TimeLog; typedef std::map ChatLog; typedef std::map PlayerLog; typedef std::map MessageList; // Second parameter is the reference count @@ -89,14 +89,14 @@ namespace ChatLogManagerNamespace ChatLog s_chatLog; PlayerLog s_playerLog; MessageList s_chatMessageList; - time_t s_purgeTime = 0; + uint32_t s_purgeTime = 0; int s_currentIndex = 0; - time_t s_chatLogMemoryTimer = 0; + uint32_t s_chatLogMemoryTimer = 0; int s_cacheHits = 0; int s_cacheMisses = 0; void printPlayerLog(); - void addChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, time_t const time); + void addChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, uint32_t const time); bool removeChatLogEntry(int const messageIndex); void purgeChatLog(); std::string getTimeString(time_t const time); @@ -120,7 +120,7 @@ void ChatLogManagerNamespace::printPlayerLog() } //----------------------------------------------------------------------------- -void ChatLogManagerNamespace::addChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, time_t const time) +void ChatLogManagerNamespace::addChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, uint32_t const time) { ChatLog::const_iterator iterChatLog = s_chatLog.find(messageIndex); @@ -238,20 +238,20 @@ void ChatLogManagerNamespace::purgeChatLog() { // This purges the list of old data once a second - time_t const systemTime = Os::getRealSystemTime(); + uint32_t const systemTime = Os::getRealSystemTime(); if (s_purgeTime != systemTime) { s_purgeTime = systemTime; - time_t const chatLogPurgeTime = static_cast(ConfigServerUtility::getChatLogMinutes() * 60); + uint32_t const chatLogPurgeTime = static_cast(ConfigServerUtility::getChatLogMinutes() * 60); TimeLog::iterator iterTimeLog = s_timeLog.begin(); int chatLogCount = static_cast(s_timeLog.size()); int purgedMessages = 0; for (; iterTimeLog != s_timeLog.end(); ++iterTimeLog) { - time_t const time = iterTimeLog->first; + uint32_t const time = iterTimeLog->first; if ( (time < (systemTime - chatLogPurgeTime)) || (static_cast(s_chatMessageList.size()) > ConfigServerUtility::getServerMaxChatLogLines())) @@ -346,7 +346,7 @@ void ChatLogManager::remove() } //----------------------------------------------------------------------------- -void ChatLogManager::logChat(Unicode::String const & fromPlayer, Unicode::String const & toPlayer, Unicode::String const & message, Unicode::String const & channel, int const messageIndex, time_t const time) +void ChatLogManager::logChat(Unicode::String const & fromPlayer, Unicode::String const & toPlayer, Unicode::String const & message, Unicode::String const & channel, int const messageIndex, uint32_t const time) { addChatLogEntry(fromPlayer, toPlayer, message, channel, messageIndex, time); purgeChatLog(); @@ -386,7 +386,7 @@ bool ChatLogManager::getChatMessage(int const messageIndex, Unicode::String &cha } //----------------------------------------------------------------------------- -bool ChatLogManager::getChatMessage(int const messageIndex, Unicode::String &fromPlayer, Unicode::String &toPlayer, Unicode::String &text, Unicode::String &channel, time_t &time) +bool ChatLogManager::getChatMessage(int const messageIndex, Unicode::String &fromPlayer, Unicode::String &toPlayer, Unicode::String &text, Unicode::String &channel, uint32_t &time) { bool result = false; @@ -412,7 +412,7 @@ bool ChatLogManager::getChatMessage(int const messageIndex, Unicode::String &fro } //----------------------------------------------------------------------------- -void ChatLogManager::buildLogEntry(Unicode::String &result, Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, time_t const time) +void ChatLogManager::buildLogEntry(Unicode::String &result, Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, uint32_t const time) { result.clear(); result.append(Unicode::narrowToWide(getTimeStringShort(time))); diff --git a/engine/server/library/serverUtility/src/shared/ChatLogManager.h b/engine/server/library/serverUtility/src/shared/ChatLogManager.h index 62ab60ad1..978fe3ca0 100755 --- a/engine/server/library/serverUtility/src/shared/ChatLogManager.h +++ b/engine/server/library/serverUtility/src/shared/ChatLogManager.h @@ -18,11 +18,11 @@ class ChatLogManager static void install(); static void remove(); - static void logChat(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, time_t const time); - static bool getChatMessage(int const messageIndex, Unicode::String &fromPlayer, Unicode::String &toPlayer, Unicode::String &text, Unicode::String &channel, time_t &time); + static void logChat(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, uint32_t const time); + static bool getChatMessage(int const messageIndex, Unicode::String &fromPlayer, Unicode::String &toPlayer, Unicode::String &text, Unicode::String &channel, uint32_t &time); static bool getChatMessage(int const messageIndex, Unicode::String &chatMessage); - static int getNextMessageIndex(); - static void buildLogEntry(Unicode::String &result, Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, time_t const time); + static int getNextMessageIndex(); + static void buildLogEntry(Unicode::String &result, Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, uint32_t const time); static bool isPlayerInLogs(Unicode::String const &player); static void getReportHeader(Unicode::String & header, std::string const &reportingPlayer, NetworkId const &reportingPlayerNetworkId, std::string const &reportingPlayerStationName, uint32 reportingPlayerStationId, std::string const &harassingPlayer, NetworkId const &harassingPlayerNetworkId, std::string const &harassingPlayerStationName, uint32 harassingPlayerStationId); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp index 2aa0818e6..8693cdb4a 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp @@ -18,7 +18,7 @@ BindableLong::BindableLong() : Bindable(), value(-999) { } -BindableLong::BindableLong(long int _value) : Bindable(sizeof(value)), value(_value) +BindableLong::BindableLong(int32_t _value) : Bindable(sizeof(value)), value(_value) { } @@ -29,14 +29,14 @@ void *BindableLong::getBuffer() // ---------------------------------------------------------------------- -long int BindableLong::getValue() const +int32_t BindableLong::getValue() const { return value; } // ---------------------------------------------------------------------- -BindableLong &BindableLong::operator=(long int rhs) +BindableLong &BindableLong::operator=(int32_t rhs) { indicator=sizeof(value); value=rhs; @@ -45,7 +45,7 @@ BindableLong &BindableLong::operator=(long int rhs) // ---------------------------------------------------------------------- -void BindableLong::setValue(long int rhs) +void BindableLong::setValue(int32_t rhs) { indicator=sizeof(value); value=rhs; diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h index c76c2621b..b0d8651d9 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h @@ -23,73 +23,74 @@ namespace DB { { public: BindableLong(); - explicit BindableLong(long int _value); + explicit BindableLong(int32_t _value); - long int getValue() const; - void setValue(const long int rhs); - BindableLong &operator=(const long int rhs); + int32_t getValue() const; + void setValue(const int32_t rhs); + BindableLong &operator=(const int32_t rhs); // following alternate getValue's are provided for convenience, particularly in // the auto-generated code: - void getValue(unsigned int &buffer) const; -// void getValue(uint32 &buffer) const; // for some reason, our compiler is convinced that uint32 != unsigned int - void getValue(long int &buffer) const; - void getValue(int &buffer) const; void getValue(int8 &buffer) const; void getValue(uint8 &buffer) const; + void getValue(int16_t &buffer) const; + void getValue(uint16_t &buffer) const; + void getValue(int32_t &buffer) const; + void getValue(uint32_t &buffer) const; void *getBuffer(); virtual std::string outputValue() const; private: - long int value; + int32_t value; }; //lint !e1721 !e1509 // no virtual destructor, unusual operator = } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(unsigned int &buffer) const +inline void DB::BindableLong::getValue(int8 &buffer) const { - buffer=static_cast(getValue()); + buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -//inline void DB::BindableLong::getValue(uint32 &buffer) const -//{ -// buffer=static_cast(getValue()); -//} - +inline void DB::BindableLong::getValue(uint8 &buffer) const +{ + buffer=static_cast(getValue()); +} // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(long int &buffer) const +inline void DB::BindableLong::getValue(int16_t &buffer) const { buffer=getValue(); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(int &buffer) const +inline void DB::BindableLong::getValue(uint16_t &buffer) const { - buffer=getValue(); + buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(int8 &buffer) const +inline void DB::BindableLong::getValue(int32_t &buffer) const { - buffer=static_cast(getValue()); + buffer=getValue(); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint8 &buffer) const +inline void DB::BindableLong::getValue(uint32 &buffer) const { - buffer=static_cast(getValue()); + buffer=static_cast(getValue()); } + + // ====================================================================== #endif diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp index 39e3303a5..feb1e7cb3 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp @@ -120,7 +120,7 @@ OCIType* BindableVarray::getTDO() // ---------------------------------------------------------------------- -bool BindableVarrayNumber::push_back(int value) +bool BindableVarrayNumber::push_back(int16_t value) { OCINumber buffer; @@ -138,7 +138,7 @@ bool BindableVarrayNumber::push_back(int value) // ---------------------------------------------------------------------- -bool BindableVarrayNumber::push_back(long int value) +bool BindableVarrayNumber::push_back(int32_t value) { OCINumber buffer; @@ -154,22 +154,22 @@ bool BindableVarrayNumber::push_back(long int value) return true; } // ---------------------------------------------------------------------- -// -//bool BindableVarrayNumber::push_back(int64 value) -//{ -// OCINumber buffer; -// -// OCIInd buffer_indicator (OCI_IND_NOTNULL); -// -// OCISession *localSession = safe_cast(m_session); -// -// if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) -// return false; -// if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) -// return false; -// -// return true; -//} + +bool BindableVarrayNumber::push_back(int64 value) +{ + OCINumber buffer; + + OCIInd buffer_indicator (OCI_IND_NOTNULL); + + OCISession *localSession = safe_cast(m_session); + + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) + return false; + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) + return false; + + return true; +} // ---------------------------------------------------------------------- @@ -204,7 +204,7 @@ bool BindableVarrayNumber::push_back(double value) // ---------------------------------------------------------------------- -bool BindableVarrayNumber::push_back(bool IsNULL, int value) +bool BindableVarrayNumber::push_back(bool IsNULL, int16_t value) { OCINumber buffer; @@ -230,7 +230,7 @@ bool BindableVarrayNumber::push_back(bool IsNULL, int value) // ---------------------------------------------------------------------- -bool BindableVarrayNumber::push_back(bool IsNULL, long int value) +bool BindableVarrayNumber::push_back(bool IsNULL, int32_t value) { OCINumber buffer; @@ -255,31 +255,31 @@ bool BindableVarrayNumber::push_back(bool IsNULL, long int value) return true; } // ---------------------------------------------------------------------- -// -//bool BindableVarrayNumber::push_back(bool IsNULL, int64 value) -//{ -// OCINumber buffer; -// -// OCIInd buffer_indicator; -// -// if ( IsNULL ) -// { -// buffer_indicator = OCI_IND_NULL; -// } -// else -// { -// buffer_indicator = OCI_IND_NOTNULL; -// } -// -// OCISession *localSession = safe_cast(m_session); -// -// if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) -// return false; -// if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) -// return false; -// -// return true; -//} + +bool BindableVarrayNumber::push_back(bool IsNULL, int64 value) +{ + OCINumber buffer; + + OCIInd buffer_indicator; + + if ( IsNULL ) + { + buffer_indicator = OCI_IND_NULL; + } + else + { + buffer_indicator = OCI_IND_NOTNULL; + } + + OCISession *localSession = safe_cast(m_session); + + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) + return false; + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) + return false; + + return true; +} // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h index 297370059..2b3de3803 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h @@ -57,14 +57,14 @@ namespace DB class BindableVarrayNumber : public BindableVarray { public: - bool push_back(bool IsNULL, int value); + bool push_back(bool IsNULL, int16_t value); bool push_back(bool IsNULL, double value); - bool push_back(bool IsNULL, long int value); -// bool push_back(bool IsNULL, int64 value); - bool push_back(int value); + bool push_back(bool IsNULL, int32_t value); + bool push_back(bool IsNULL, int64 value); + bool push_back(int16_t value); bool push_back(double value); - bool push_back(long int value); -// bool push_back(int64 value); + bool push_back(int32_t value); + bool push_back(int64 value); virtual std::string outputValue() const; }; diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/chat/ChatOnRequestLog.h b/engine/shared/library/sharedNetworkMessages/src/shared/chat/ChatOnRequestLog.h index 776ac4859..01eceb9ba 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/chat/ChatOnRequestLog.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/chat/ChatOnRequestLog.h @@ -38,7 +38,7 @@ struct ChatLogEntry Unicode::String m_to; Unicode::String m_channel; Unicode::String m_message; - time_t m_time; + uint32_t m_time; }; namespace Archive diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h index 58021cc60..7226d3105 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h @@ -56,7 +56,7 @@ namespace Auction uint16 highBidderNameKey; int32 maxProxyBid; int32 myBid; - long itemType; + uint32_t itemType; int resourceContainerClassCrc; int32 flags; int32 entranceCharge; @@ -97,7 +97,7 @@ namespace Auction std::string highBidderName; int32 maxProxyBid; int32 myBid; - long itemType; + uint32_t itemType; int resourceContainerClassCrc; int32 flags; int32 entranceCharge; diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.cpp b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.cpp index bb737fde8..b253fe03c 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.cpp +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.cpp @@ -85,7 +85,7 @@ MessageQueue::Data* BuffBuilderChangeMessage::unpack(Archive::ReadIterator & sou NetworkId tempId; bool tempBool = false; int tempInt = 0; - time_t tempTime = 0; + uint32_t tempTime = 0; Archive::get(source, tempId); msg->setBufferId(tempId); diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.h index 824febe40..2a981cdfb 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/BuffBuilderChangeMessage.h @@ -33,7 +33,7 @@ class BuffBuilderChangeMessage : public MessageQueue::Data //accessors NetworkId const & getBufferId() const; NetworkId const & getRecipientId() const; - time_t getStartingTime() const; + uint32_t getStartingTime() const; int getBufferRequiredCredits() const; bool getAccepted() const; Origin getOrigin() const; @@ -56,7 +56,7 @@ class BuffBuilderChangeMessage : public MessageQueue::Data private: NetworkId m_bufferId; NetworkId m_recipientId; - time_t m_startingTime; + uint32_t m_startingTime; int m_bufferRequiredCredits; bool m_accepted; Origin m_origin; @@ -79,7 +79,7 @@ inline NetworkId const & BuffBuilderChangeMessage::getRecipientId() const //----------------------------------------------------------------------- -inline time_t BuffBuilderChangeMessage::getStartingTime() const +inline uint32_t BuffBuilderChangeMessage::getStartingTime() const { return m_startingTime; } diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp index a4c05ea5e..89f96c216 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp @@ -157,7 +157,7 @@ MessageQueue::Data* ImageDesignChangeMessage::unpack(Archive::ReadIterator & sou bool tempBool = false; std::string tempStr; int tempInt = 0; - time_t tempTime = 0; + int32_t tempTime = 0; Archive::get(source, tempId); msg->setDesignerId(tempId); diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h index 07c176e08..c727efc4f 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h @@ -47,7 +47,7 @@ class ImageDesignChangeMessage : public MessageQueue::Data std::string const & getNewHairAsset() const; std::string const & getHairCustomizationData() const; DesignType getDesignType() const; - time_t getStartingTime() const; + int32_t getStartingTime() const; int getDesignerRequiredCredits() const; int getRecipientPaidCredits() const; bool getAccepted() const; @@ -95,7 +95,7 @@ class ImageDesignChangeMessage : public MessageQueue::Data std::string m_newHairAsset; std::string m_hairCustomizationData; DesignType m_designType; - time_t m_startingTime; + int32_t m_startingTime; int m_designerRequiredCredits; int m_recipientPaidCredits; bool m_accepted; @@ -160,7 +160,7 @@ inline ImageDesignChangeMessage::DesignType ImageDesignChangeMessage::getDesignT //----------------------------------------------------------------------- -inline time_t ImageDesignChangeMessage::getStartingTime() const +inline int32_t ImageDesignChangeMessage::getStartingTime() const { return m_startingTime; } diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.cpp b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.cpp index 8089e4b20..7557ca3d7 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.cpp +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.cpp @@ -68,7 +68,7 @@ MessageQueue::Data * MessageQueueSlowDownEffect::unpack(Archive::ReadIterator & float coneLength; float coneAngle; float slopeAngle; - unsigned long expireTime; + uint32_t expireTime; Archive::get(source, target); Archive::get(source, coneLength); diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.h index fc4e9a67b..3511063cf 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/MessageQueueSlowDownEffect.h @@ -32,7 +32,7 @@ class MessageQueueSlowDownEffect: public MessageQueue::Data float getConeLength() const; float getConeAngle() const; float getSlopeAngle() const; - unsigned long getExpireTime() const; + uint32_t getExpireTime() const; private: MessageQueueSlowDownEffect(); @@ -42,7 +42,7 @@ class MessageQueueSlowDownEffect: public MessageQueue::Data float m_coneLength; float m_coneAngle; float m_slopeAngle; - unsigned long m_expireTime; + uint32_t m_expireTime; }; // ---------------------------------------------------------------------- @@ -67,7 +67,7 @@ inline float MessageQueueSlowDownEffect::getSlopeAngle() const return m_slopeAngle; } -inline unsigned long MessageQueueSlowDownEffect::getExpireTime() const +inline uint32_t MessageQueueSlowDownEffect::getExpireTime() const { return m_expireTime; } diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/planetWatch/ServerInfo.h b/engine/shared/library/sharedNetworkMessages/src/shared/planetWatch/ServerInfo.h index ca3b6b1ed..1640c0bf5 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/planetWatch/ServerInfo.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/planetWatch/ServerInfo.h @@ -10,8 +10,8 @@ struct ServerInfo { std::string ipAddress; - unsigned long serverId; - unsigned long systemPid; + uint32_t serverId; + uint32_t systemPid; std::string sceneId; }; diff --git a/game/server/library/swgServerNetworkMessages/src/shared/core/SetupSwgServerNetworkMessages.cpp b/game/server/library/swgServerNetworkMessages/src/shared/core/SetupSwgServerNetworkMessages.cpp index 864e26450..8621f0b1a 100755 --- a/game/server/library/swgServerNetworkMessages/src/shared/core/SetupSwgServerNetworkMessages.cpp +++ b/game/server/library/swgServerNetworkMessages/src/shared/core/SetupSwgServerNetworkMessages.cpp @@ -198,20 +198,20 @@ namespace SetupSwgServerNetworkMessagesNamespace return unpackGenericMessage > > >(source); } - void packUnsignedLong(const MessageQueue::Data * data, Archive::ByteStream & target) + void packUnsignedInt(const MessageQueue::Data * data, Archive::ByteStream & target) { - const MessageQueueGenericValueType * msg = safe_cast *>(data); + const MessageQueueGenericValueType * msg = safe_cast *>(data); if(msg) { Archive::put(target, msg->getValue()); } } - MessageQueue::Data * unpackUnsignedLong(Archive::ReadIterator & source) + MessageQueue::Data * unpackUnsignedInt(Archive::ReadIterator & source) { - unsigned long v; + uint32_t v; Archive::get(source, v); - return new MessageQueueGenericValueType(v); + return new MessageQueueGenericValueType(v); } void packUnicodeString(const MessageQueue::Data * data, Archive::ByteStream & target) @@ -594,20 +594,20 @@ namespace SetupSwgServerNetworkMessagesNamespace return new MessageQueueGenericValueType >(v); } - void packULongBool(const MessageQueue::Data * data, Archive::ByteStream & target) + void packUIntBool(const MessageQueue::Data * data, Archive::ByteStream & target) { - const MessageQueueGenericValueType > * msg = safe_cast > *>(data); + const MessageQueueGenericValueType > * msg = safe_cast > *>(data); if(msg) { Archive::put(target, msg->getValue()); } } - MessageQueue::Data * unpackULongBool(Archive::ReadIterator & source) + MessageQueue::Data * unpackUIntBool(Archive::ReadIterator & source) { - std::pair v; + std::pair v; Archive::get(source, v); - return new MessageQueueGenericValueType >(v); + return new MessageQueueGenericValueType >(v); } void packStringNetworkIdNetworkId(const MessageQueue::Data * data, Archive::ByteStream & target) diff --git a/game/shared/library/swgSharedNetworkMessages/src/shared/core/SetupSwgSharedNetworkMessages.cpp b/game/shared/library/swgSharedNetworkMessages/src/shared/core/SetupSwgSharedNetworkMessages.cpp index 399a513ca..88def1ca2 100755 --- a/game/shared/library/swgSharedNetworkMessages/src/shared/core/SetupSwgSharedNetworkMessages.cpp +++ b/game/shared/library/swgSharedNetworkMessages/src/shared/core/SetupSwgSharedNetworkMessages.cpp @@ -191,7 +191,7 @@ namespace SetupSwgSharedNetworkMessagesNamespace void packAddToPlayerSpawnQueueMessage(const MessageQueue::Data * data, Archive::ByteStream & target) { - const MessageQueueGenericValueType > * const msg = dynamic_cast > *>(data); + const MessageQueueGenericValueType > * const msg = dynamic_cast > *>(data); if(msg) { Archive::put(target, msg->getValue()); @@ -200,9 +200,9 @@ namespace SetupSwgSharedNetworkMessagesNamespace MessageQueue::Data* unpackAddToPlayerSpawnQueueMessage(Archive::ReadIterator & source) { - std::pair v; + std::pair v; Archive::get(source, v); - MessageQueueGenericValueType > * result = new MessageQueueGenericValueType >(v); + MessageQueueGenericValueType > * result = new MessageQueueGenericValueType >(v); return result; } From c87b327408fa05aca5185e4886d61edf0b852805 Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 22 Nov 2021 00:39:12 -0500 Subject: [PATCH 19/46] Updating badly chosen replacement data type --- .../src/shared/clientGameServer/AuctionData.h | 2 +- .../shared/clientGameServer/ImageDesignChangeMessage.cpp | 2 +- .../src/shared/clientGameServer/ImageDesignChangeMessage.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h index 7226d3105..ac21588cc 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/AuctionData.h @@ -56,7 +56,7 @@ namespace Auction uint16 highBidderNameKey; int32 maxProxyBid; int32 myBid; - uint32_t itemType; + int32_t itemType; int resourceContainerClassCrc; int32 flags; int32 entranceCharge; diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp index 89f96c216..11a53950d 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.cpp @@ -157,7 +157,7 @@ MessageQueue::Data* ImageDesignChangeMessage::unpack(Archive::ReadIterator & sou bool tempBool = false; std::string tempStr; int tempInt = 0; - int32_t tempTime = 0; + uint32_t tempTime = 0; Archive::get(source, tempId); msg->setDesignerId(tempId); diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h index c727efc4f..9bc3c3929 100755 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ImageDesignChangeMessage.h @@ -47,7 +47,7 @@ class ImageDesignChangeMessage : public MessageQueue::Data std::string const & getNewHairAsset() const; std::string const & getHairCustomizationData() const; DesignType getDesignType() const; - int32_t getStartingTime() const; + uint32_t getStartingTime() const; int getDesignerRequiredCredits() const; int getRecipientPaidCredits() const; bool getAccepted() const; @@ -95,7 +95,7 @@ class ImageDesignChangeMessage : public MessageQueue::Data std::string m_newHairAsset; std::string m_hairCustomizationData; DesignType m_designType; - int32_t m_startingTime; + uint32_t m_startingTime; int m_designerRequiredCredits; int m_recipientPaidCredits; bool m_accepted; @@ -160,7 +160,7 @@ inline ImageDesignChangeMessage::DesignType ImageDesignChangeMessage::getDesignT //----------------------------------------------------------------------- -inline int32_t ImageDesignChangeMessage::getStartingTime() const +inline uint32_t ImageDesignChangeMessage::getStartingTime() const { return m_startingTime; } From 8be3a301d3be514ac2c86696a8bfab9bf823541c Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 22 Nov 2021 00:55:50 -0500 Subject: [PATCH 20/46] Removed old crypto lib --- .../crypto/src/shared/original-old/config.h | 165 ---- .../src/shared/original-old/cryptlib.cpp | 488 ----------- .../crypto/src/shared/original-old/cryptlib.h | 818 ------------------ .../src/shared/original-old/filters.cpp | 424 --------- .../crypto/src/shared/original-old/filters.h | 560 ------------ .../src/shared/original-old/iterhash.cpp | 14 - .../crypto/src/shared/original-old/iterhash.h | 187 ---- .../crypto/src/shared/original-old/md5.cpp | 109 --- .../crypto/src/shared/original-old/md5.h | 24 - .../crypto/src/shared/original-old/misc.cpp | 77 -- .../crypto/src/shared/original-old/misc.h | 689 --------------- .../crypto/src/shared/original-old/mqueue.cpp | 44 - .../crypto/src/shared/original-old/mqueue.h | 61 -- .../crypto/src/shared/original-old/queue.cpp | 500 ----------- .../crypto/src/shared/original-old/queue.h | 128 --- .../crypto/src/shared/original-old/smartptr.h | 195 ----- .../src/shared/original-old/tftables.cpp | 317 ------- .../src/shared/original-old/twofish.cpp | 166 ---- .../crypto/src/shared/original-old/twofish.h | 53 -- .../crypto/src/shared/original-old/words.h | 103 --- 20 files changed, 5122 deletions(-) delete mode 100755 external/ours/library/crypto/src/shared/original-old/config.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/cryptlib.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/cryptlib.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/filters.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/filters.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/iterhash.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/iterhash.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/md5.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/md5.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/misc.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/misc.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/mqueue.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/mqueue.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/queue.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/queue.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/smartptr.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/tftables.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/twofish.cpp delete mode 100755 external/ours/library/crypto/src/shared/original-old/twofish.h delete mode 100755 external/ours/library/crypto/src/shared/original-old/words.h diff --git a/external/ours/library/crypto/src/shared/original-old/config.h b/external/ours/library/crypto/src/shared/original-old/config.h deleted file mode 100755 index f0dfb23ee..000000000 --- a/external/ours/library/crypto/src/shared/original-old/config.h +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef CRYPTOPP_CONFIG_H -#define CRYPTOPP_CONFIG_H - -// ***************** Important Settings ******************** - -// define this if running on a big-endian CPU -#if defined(__sparc__) || defined(__hppa__) || defined(__ppc__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__)) -#define IS_BIG_ENDIAN -#endif - -// define this if running on a little-endian CPU -// big endian will be assumed if IS_LITTLE_ENDIAN is not defined -#ifndef IS_BIG_ENDIAN -#define IS_LITTLE_ENDIAN -#endif - -// define this if you want to disable all OS-dependent features, -// such as sockets and OS-provided random number generators -// #define NO_OS_DEPENDENCE - -// Define this to use features provided by Microsoft's CryptoAPI. -// Currently the only feature used is random number generation. -// This macro will be ignored if NO_OS_DEPENDENCE is defined. -#define USE_MS_CRYPTOAPI - -// define this if your compiler does not support namespaces -// #define NO_NAMESPACE -#ifdef NO_NAMESPACE -#define std -#define CryptoPP -#define USING_NAMESPACE(x) -#define NAMESPACE_BEGIN(x) -#define NAMESPACE_END -#define ANONYMOUS_NAMESPACE_BEGIN -#else -#define USING_NAMESPACE(x) using namespace x; -#define NAMESPACE_BEGIN(x) namespace x { -#define ANONYMOUS_NAMESPACE_BEGIN namespace { -#define NAMESPACE_END } -#endif - -// ***************** Less Important Settings *************** - -// switch between different secure memory allocation mechnisms, this is the only -// one available right now -#define SECALLOC_DEFAULT - -#define GZIP_OS_CODE 0 - -// Try this if your CPU has 256K internal cache or a slow multiply instruction -// and you want a (possibly) faster IDEA implementation using log tables -// #define IDEA_LARGECACHE - -// Try this if you have a large cache or your CPU is slow manipulating -// individual bytes. -// #define DIAMOND_USE_PERMTABLE - -// Define this if, for the linear congruential RNG, you want to use -// the original constants as specified in S.K. Park and K.W. Miller's -// CACM paper. -// #define LCRNG_ORIGINAL_NUMBERS - -// choose which style of sockets to wrap (mostly useful for cygwin which has both) -#define PREFER_BERKELEY_STYLE_SOCKETS -// #define PREFER_WINDOWS_STYLE_SOCKETS - -// ***************** Important Settings Again ******************** -// But the defaults should be ok. - -typedef unsigned char byte; // moved outside namespace for Borland C++Builder 5 - -NAMESPACE_BEGIN(CryptoPP) - -typedef unsigned short word16; -#if defined(__alpha) && !defined(_MSC_VER) -typedef unsigned int word32; -#else -typedef unsigned long word32; -#endif - -#if defined(__GNUC__) || defined(__MWERKS__) -#define WORD64_AVAILABLE -typedef unsigned long long word64; -#define W64LIT(x) x##LL -#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) -#define WORD64_AVAILABLE -typedef unsigned __int64 word64; -#define W64LIT(x) x##ui64 -#endif - -// defined this if your CPU is not 64-bit -#if defined(WORD64_AVAILABLE) && !defined(__alpha) -#define SLOW_WORD64 -#endif - -// word should have the same size as your CPU registers -// dword should be twice as big as word - -#if (defined(__GNUC__) && !defined(__alpha)) || defined(__MWERKS__) -typedef unsigned long word; -typedef unsigned long long dword; -#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) -typedef unsigned __int32 word; -typedef unsigned __int64 dword; -#else -typedef unsigned int word; -typedef unsigned long dword; -#endif - -const unsigned int WORD_SIZE = sizeof(word); -const unsigned int WORD_BITS = WORD_SIZE * 8; - -#define LOW_WORD(x) (word)(x) - -union dword_union -{ - dword_union (const dword &dw) : dw(dw) {} - dword dw; - word w[2]; -}; - -#ifdef IS_LITTLE_ENDIAN -#define HIGH_WORD(x) (dword_union(x).w[1]) -#else -#define HIGH_WORD(x) (dword_union(x).w[0]) -#endif - -// if the above HIGH_WORD macro doesn't work (if you are not sure, compile it -// and run the validation tests), try this: -// #define HIGH_WORD(x) (word)((x)>>WORD_BITS) - -#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) -#define INTEL_INTRINSICS -#define FAST_ROTATE -#elif defined(__MWERKS__) && TARGET_CPU_PPC -#define PPC_INTRINSICS -#define FAST_ROTATE -#elif defined(__GNUC__) && defined(__i386__) -// GCC does peephole optimizations which should result in using rotate instructions -#define FAST_ROTATE -#endif - -// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0 -template -inline const _Tp& STDMIN(const _Tp& __a, const _Tp& __b) { - return __b < __a ? __b : __a; -} - -template -inline const _Tp& STDMAX(const _Tp& __a, const _Tp& __b) { - return __a < __b ? __b : __a; -} - -#ifdef _MSC_VER -// 4250: dominance -// 4660: explicitly instantiating a class that's already implicitly instantiated -// 4786: identifer was truncated in debug information -// 4355: 'this' : used in base member initializer list -// 4800: converting int to bool -#pragma warning(disable: 4250 4660 4786 4355 4800 4710) -#endif - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/cryptlib.cpp b/external/ours/library/crypto/src/shared/original-old/cryptlib.cpp deleted file mode 100755 index 174cea86d..000000000 --- a/external/ours/library/crypto/src/shared/original-old/cryptlib.cpp +++ /dev/null @@ -1,488 +0,0 @@ -// cryptlib.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "cryptlib.h" -#include "misc.h" -#include "filters.h" - -#include - -NAMESPACE_BEGIN(CryptoPP) - -const std::string BufferedTransformation::NULL_CHANNEL; - -unsigned int RandomNumberGenerator::GenerateBit() -{ - return Parity(GetByte()); -} - -void RandomNumberGenerator::GenerateBlock(byte *output, unsigned int size) -{ - while (size--) - *output++ = GetByte(); -} - -word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) -{ - word32 range = max-min; - const int maxBytes = BytePrecision(range); - const int maxBits = BitPrecision(range); - - word32 value; - - do - { - value = 0; - for (int i=0; i range); - - return value+min; -} - -void StreamCipher::ProcessString(byte *outString, const byte *inString, unsigned int length) -{ - while(length--) - *outString++ = ProcessByte(*inString++); -} - -void StreamCipher::ProcessString(byte *inoutString, unsigned int length) -{ - while(length--) { - (*inoutString)++; - *inoutString = ProcessByte(*inoutString); - } -} - -bool HashModule::Verify(const byte *digestIn) -{ - SecByteBlock digest(DigestSize()); - Final(digest); - return memcmp(digest, digestIn, DigestSize()) == 0; -} - -BufferedTransformation::Err::Err(ErrorType errorType, const std::string &s) - : Exception(s), m_errorType(errorType) -{ - if (GetWhat().empty()) - { - switch (errorType) - { - case CANNOT_FLUSH: - SetWhat("BufferedTransformation: cannot flush buffer"); - break; - case DATA_INTEGRITY_CHECK_FAILED: - SetWhat("BufferedTransformation: data integrity check failed"); - break; - case INVALID_DATA_FORMAT: - SetWhat("BufferedTransformation: invalid data format"); - break; - case OUTPUT_ERROR: - SetWhat("BufferedTransformation: cannot write to output device"); - break; - case OTHER_ERROR: - SetWhat("BufferedTransformation: unknown error"); - break; - default: - assert(false); - break; - } - } -} - -void BufferedTransformation::Put(byte b) -{ - if (AttachedTransformation()) - AttachedTransformation()->Put(b); -} - -void BufferedTransformation::Put(const byte *inString, unsigned int length) -{ - if (AttachedTransformation()) - AttachedTransformation()->Put(inString, length); -} - -void BufferedTransformation::Flush(bool completeFlush, int propagation) -{ - if (AttachedTransformation() && propagation) - AttachedTransformation()->Flush(completeFlush, propagation-1); -} - -void BufferedTransformation::MessageEnd(int propagation) -{ - if (AttachedTransformation() && propagation) - AttachedTransformation()->MessageEnd(propagation-1); -} - -void BufferedTransformation::MessageSeriesEnd(int propagation) -{ - if (AttachedTransformation() && propagation) - AttachedTransformation()->MessageSeriesEnd(propagation-1); -} - -void BufferedTransformation::PutMessageEnd(const byte *inString, unsigned int length, int propagation) -{ - Put(inString, length); - MessageEnd(propagation); -} - -void BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation) -{ - if (channel.empty()) - Flush(completeFlush, propagation); - else if (AttachedTransformation() && propagation) - AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation-1); -} - -void BufferedTransformation::ChannelMessageEnd(const std::string &channel, int propagation) -{ - if (channel.empty()) - MessageEnd(propagation); - else if (AttachedTransformation() && propagation) - AttachedTransformation()->ChannelMessageEnd(channel, propagation-1); -} - -void BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation) -{ - if (channel.empty()) - MessageSeriesEnd(propagation); - else if (AttachedTransformation() && propagation) - AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1); -} - -void BufferedTransformation::ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation) -{ - if (channel.empty()) - PutMessageEnd(inString, length, propagation); - else - { - ChannelPut(channel, inString, length); - ChannelMessageEnd(channel, propagation); - } -} - -unsigned long BufferedTransformation::MaxRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->MaxRetrievable(); - else - return CopyTo(g_bitBucket); -} - -bool BufferedTransformation::AnyRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->AnyRetrievable(); - else - { - byte b; - return Peek(b) != 0; - } -} - -unsigned int BufferedTransformation::Get(byte &outByte) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Get(outByte); - else - return Get(&outByte, 1); -} - -unsigned int BufferedTransformation::Get(byte *outString, unsigned int getMax) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Get(outString, getMax); - else - { - ArraySink arraySink(outString, getMax); - return TransferTo(arraySink, getMax); - } -} - -unsigned int BufferedTransformation::Peek(byte &outByte) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->Peek(outByte); - else - return Peek(&outByte, 1); -} - -unsigned int BufferedTransformation::Peek(byte *outString, unsigned int peekMax) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->Peek(outString, peekMax); - else - { - ArraySink arraySink(outString, peekMax); - return CopyTo(arraySink, peekMax); - } -} - -unsigned long BufferedTransformation::Skip(unsigned long skipMax) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Skip(skipMax); - else - return TransferTo(g_bitBucket, skipMax); -} - -unsigned long BufferedTransformation::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->CopyTo(target, copyMax); - else - return 0; -} - -unsigned long BufferedTransformation::TransferTo(BufferedTransformation &target, unsigned long size) -{ - if (AttachedTransformation()) - return AttachedTransformation()->TransferTo(target, size); - else - return 0; -} - -unsigned long BufferedTransformation::TotalBytesRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->TotalBytesRetrievable(); - else - return MaxRetrievable(); -} - -unsigned int BufferedTransformation::NumberOfMessages() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->NumberOfMessages(); - else - return CopyMessagesTo(g_bitBucket); -} - -bool BufferedTransformation::AnyMessages() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->NumberOfMessages(); - else - return NumberOfMessages() != 0; -} - -bool BufferedTransformation::GetNextMessage() -{ - if (AttachedTransformation()) - return AttachedTransformation()->GetNextMessage(); - else - return false; -} - -unsigned int BufferedTransformation::SkipMessages(unsigned int count) -{ - if (AttachedTransformation()) - return AttachedTransformation()->SkipMessages(count); - else - return TransferMessagesTo(g_bitBucket, count); -} - -unsigned int BufferedTransformation::TransferMessagesTo(BufferedTransformation &target, unsigned int count) -{ - if (AttachedTransformation()) - return AttachedTransformation()->TransferMessagesTo(target, count); - else - { - unsigned int i; - for (i=0; i (result); - target.MessageEnd(GetAutoSignalPropagation()); - } - return i; - } -} - -unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->CopyMessagesTo(target, count); - else - return 0; -} - -void BufferedTransformation::SkipAll() -{ - if (AttachedTransformation()) - AttachedTransformation()->SkipAll(); - else - { - while (SkipMessages()) {} - while (Skip()) {} - } -} - -void BufferedTransformation::TransferAllTo(BufferedTransformation &target) -{ - if (AttachedTransformation()) - AttachedTransformation()->TransferAllTo(target); - else - { - while (TransferMessagesTo(target)) {} - while (TransferTo(target)) {} - } -} - -void BufferedTransformation::CopyAllTo(BufferedTransformation &target) const -{ - if (AttachedTransformation()) - AttachedTransformation()->CopyAllTo(target); - else - { - CopyMessagesTo(target); - CopyTo(target); - } -} - -void BufferedTransformation::SetRetrievalChannel(const std::string &channel) -{ - if (AttachedTransformation()) - AttachedTransformation()->SetRetrievalChannel(channel); -} - -void BufferedTransformation::ChannelPut(const std::string &channel, byte inByte) -{ - if (channel.empty()) - Put(inByte); -} - -void BufferedTransformation::ChannelPut(const std::string &channel, const byte *inString, unsigned int length) -{ - if (channel.empty()) - Put(inString, length); -} - -void BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, bool highFirst) -{ - if (highFirst) - { - ChannelPut(channel, value>>8); - ChannelPut(channel, byte(value)); - } - else - { - ChannelPut(channel, byte(value)); - ChannelPut(channel, value>>8); - } -} - -void BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, bool highFirst) -{ - if (highFirst) - { - for (int i=0; i<4; i++) - ChannelPut(channel, byte(value>>((3-i)*8))); - } - else - { - for (int i=0; i<4; i++) - ChannelPut(channel, byte(value>>(i*8))); - } -} - -void BufferedTransformation::PutWord16(word16 value, bool highFirst) -{ - ChannelPutWord16(NULL_CHANNEL, value, highFirst); -} - -void BufferedTransformation::PutWord32(word32 value, bool highFirst) -{ - ChannelPutWord32(NULL_CHANNEL, value, highFirst); -} - -unsigned int BufferedTransformation::PeekWord16(word16 &value, bool highFirst) -{ - byte buf[2] = {0, 0}; - unsigned int len = Peek(buf, 2); - - if (highFirst) - value = (buf[0] << 8) | buf[1]; - else - value = (buf[1] << 8) | buf[0]; - - return len; -} - -unsigned int BufferedTransformation::PeekWord32(word32 &value, bool highFirst) -{ - byte buf[4] = {0, 0, 0, 0}; - unsigned int len = Peek(buf, 4); - - if (highFirst) - value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; - else - value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; - - return len; -} - -unsigned int BufferedTransformation::GetWord16(word16 &value, bool highFirst) -{ - return Skip(PeekWord16(value, highFirst)); -} - -unsigned int BufferedTransformation::GetWord32(word32 &value, bool highFirst) -{ - return Skip(PeekWord32(value, highFirst)); -} - -void BufferedTransformation::Attach(BufferedTransformation *newOut) -{ - if (!Attachable()) - return; - - if (AttachedTransformation() && AttachedTransformation()->Attachable()) - AttachedTransformation()->Attach(newOut); - else - Detach(newOut); -} - -unsigned int PK_FixedLengthCryptoSystem::MaxPlainTextLength(unsigned int cipherTextLength) const -{ - if (cipherTextLength == CipherTextLength()) - return MaxPlainTextLength(); - else - return 0; -} - -unsigned int PK_FixedLengthCryptoSystem::CipherTextLength(unsigned int plainTextLength) const -{ - if (plainTextLength <= MaxPlainTextLength()) - return CipherTextLength(); - else - return 0; -} - -unsigned int PK_FixedLengthDecryptor::Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) -{ - if (cipherTextLength != CipherTextLength()) - return 0; - - return Decrypt(cipherText, plainText); -} - -void PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const -{ - std::unique_ptr accumulator(NewMessageAccumulator()); - accumulator->Update(message, messageLen); - Sign(rng, accumulator.release(), signature); -} - -bool PK_Verifier::VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const -{ - std::unique_ptr accumulator(NewMessageAccumulator()); - accumulator->Update(message, messageLen); - return Verify(accumulator.release(), sig); -} - -NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/cryptlib.h b/external/ours/library/crypto/src/shared/original-old/cryptlib.h deleted file mode 100755 index fd2587063..000000000 --- a/external/ours/library/crypto/src/shared/original-old/cryptlib.h +++ /dev/null @@ -1,818 +0,0 @@ -// cryptlib.h - written and placed in the public domain by Wei Dai -/*! \file - This file contains the declarations for the abstract base - classes that provide a uniform interface to this library. -*/ - -/*! \mainpage Crypto++ Reference Manual -
-
Abstract Base Classes
- cryptlib.h -
Algebraic Structures
- Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, - ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, - GF2NP, GF256, GF2_32, EC2N, ECP -
Block Ciphers (in ECB mode)
- 3way.h, blowfish.h, cast.h, des.h, diamond.h, gost.h, - idea.h, lubyrack.h, mars.h, mdc.h, - rc2.h, rc5.h, rc6.h, rijndael.h, safer.h, serpent.h, shark.h, skipjack.h, - square.h, tea.h, twofish.h -
Block Cipher Modes
- modes.h, cbc.h -
Compression
- Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor -
Secret Sharing and Information Dispersal
- SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery -
Stream Ciphers
- ARC4, PanamaCipher, BlumBlumShub, SEAL, SapphireEncryption, WAKEEncryption -
Hash Functions
- HAVAL, MD2, MD5, PanamaHash, RIPEMD160, SHA, SHA256, SHA384, SHA512, Tiger -
Non-Cryptographic Checksums
- CRC32, Adler32 -
Message Authentication Codes
- MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC -
Random Number Generators
- NullRNG, LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool -
Public Key Cryptography
- blumgold.h, dh.h, dh2.h, dsa.h, eccrypto.h, luc.h, mqv.h, - nr.h, rsa.h, rabin.h, rw.h, xtrcrypt.h -
Input Source Classes
- StringSource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource -
Output Sink Classes
- StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink -
Filter Wrappers
- StreamCipherFilter, HashFilter, HashVerifier, SignerFilter, VerifierFilter -
Binary to Text Encoders and Decoders
- HexEncoder, HexDecoder, Base64Encoder, Base64Decoder -
Wrappers for OS features
- Timer, Socket, WindowsHandle, WindowsReadPipe, WindowsWritePipe -
- -

This reference manual is very much a work in progress. Many classes are still lacking detailed descriptions. -

Click here to download a zip archive containing this manual. -

Thanks to Ryan Phillips for providing the Doxygen configuration file -and getting me started with this manual. -*/ - -#ifndef CRYPTOPP_CRYPTLIB_H -#define CRYPTOPP_CRYPTLIB_H - -#include "config.h" -#include -#include -#include - -NAMESPACE_BEGIN(CryptoPP) - -//! base class for all exceptions thrown by Crypto++ - -class Exception : public std::exception -{ -public: - explicit Exception(const std::string &s) : m_what(s) {} - virtual ~Exception() throw() {} - const char *what() const throw() {return (m_what.c_str());} - const std::string &GetWhat() const {return m_what;} - void SetWhat(const std::string &s) {m_what = s;} - -private: - std::string m_what; -}; - -//! used to specify a direction for a cipher to operate in (encrypt or decrypt) -enum CipherDir { - //! - ENCRYPTION, - //! - DECRYPTION}; - - -//! abstract base class for block ciphers - -/*! All classes derived from BlockTransformation are block ciphers - in ECB mode (for example the DESEncryption class), which are stateless. - These classes should not be used directly, but only in combination with - a mode class (see CipherMode). - - Note: BlockTransformation objects may assume that pointers to input and - output blocks are aligned on 32-bit word boundaries. -*/ -class BlockTransformation -{ -public: - //! - virtual ~BlockTransformation() {} - - //! encrypt or decrypt one block in place - /*! \pre size of inoutBlock == BlockSize() */ - virtual void ProcessBlock(byte *inoutBlock) const =0; - - //! encrypt or decrypt one block, may assume inBlock != outBlock - /*! \pre size of inBlock and outBlock == BlockSize() */ - virtual void ProcessBlock(const byte *inBlock, byte *outBlock) const =0; - - //! block size of the cipher in bytes - virtual unsigned int BlockSize() const =0; -}; - -//! provides an implementation of BlockSize() -template -class FixedBlockSize : public BlockTransformation -{ -public: - enum {BLOCKSIZE = N}; - virtual unsigned int BlockSize() const {return BLOCKSIZE;} -}; - -//! abstract base class for stream ciphers - -class StreamCipher -{ -public: - //! - virtual ~StreamCipher() {} - - //! encrypt or decrypt one byte - virtual byte ProcessByte(byte input) =0; - - //! encrypt or decrypt an array of bytes of specified length in place - virtual void ProcessString(byte *inoutString, unsigned int length); - //! encrypt or decrypt an array of bytes of specified length, may assume inString != outString - virtual void ProcessString(byte *outString, const byte *inString, unsigned int length); -}; - -//! abstract base class for random access stream ciphers - -class RandomAccessStreamCipher : public virtual StreamCipher -{ -public: - //! - virtual ~RandomAccessStreamCipher() {} - /*/ specify that the next byte to be processed is at absolute position n - in the plaintext/ciphertext stream */ - virtual void Seek(unsigned long n) =0; -}; - -//! abstract base class for random number generators - -/*! All return values are uniformly distributed over the range specified. -*/ -class RandomNumberGenerator -{ -public: - //! - virtual ~RandomNumberGenerator() {} - - //! generate new random byte and return it - virtual byte GenerateByte() =0; - - //! generate new random bit and return it - /*! Default implementation is to call GenerateByte() and return its parity. */ - virtual unsigned int GenerateBit(); - - //! generate a random 32 bit word in the range min to max, inclusive - virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); - - //! generate random array of bytes - //* Default implementation is to call GenerateByte() size times. - virtual void GenerateBlock(byte *output, unsigned int size); - - //! randomly shuffle the specified array, resulting permutation is uniformly distributed - template void Shuffle(IT begin, IT end) - { - for (; begin != end; ++begin) - std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); - } - - // for backwards compatibility, maybe be remove later - byte GetByte() {return GenerateByte();} - unsigned int GetBit() {return GenerateBit();} - word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} - word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} - void GetBlock(byte *output, unsigned int size) {GenerateBlock(output, size);} -}; - -//! abstract base class for hash functions - -/*! HashModule objects are stateful. They are created in an initial state, - change state as Update() is called, and return to the initial - state when Final() is called. This interface allows a large message to - be hashed in pieces by calling Update() on each piece followed by - calling Final(). -*/ -class HashModule -{ -public: - //! - virtual ~HashModule() {} - - //! process more input - virtual void Update(const byte *input, unsigned int length) =0; - - /*/ calculate hash for the current message (the concatenation of all - inputs passed in via Update()), then reinitialize the object */ - //* Precondition: size of digest == DigestSize(). - virtual void Final(byte *digest) =0; - - //! size of the hash returned by Final() - virtual unsigned int DigestSize() const =0; - - //! use this if your input is short and you don't want to call Update() and Final() seperately - virtual void CalculateDigest(byte *digest, const byte *input, int length) - {Update(input, length); Final(digest);} - - //! verify that digest is a valid digest for the current message, then reinitialize the object - /*! Default implementation is to call Final() and do a bitwise comparison - between its output and digest. */ - virtual bool Verify(const byte *digest); - - //! use this if your input is short and you don't want to call Update() and Verify() seperately - virtual bool VerifyDigest(const byte *digest, const byte *input, int length) - {Update(input, length); return Verify(digest);} -}; - -//! abstract base class for message authentication codes - -/*! The main differences between a MAC and an hash function (in terms of - programmatic interface) is that a MAC is keyed, and that calculating - a MAC for the same message twice may produce two different results so - verifying a MAC may not be simply recalculating it and doing a bitwise - comparison. -*/ -class MessageAuthenticationCode : public virtual HashModule -{ -public: - //! - virtual ~MessageAuthenticationCode() {} -}; - -//! abstract base class for buffered transformations - -/*! BufferedTransformation is a generalization of BlockTransformation, - StreamCipher, and HashModule. - - A buffered transformation is an object that takes a stream of bytes - as input (this may be done in stages), does some computation on them, and - then places the result into an internal buffer for later retrieval. Any - partial result already in the output buffer is not modified by further - input. - - Computation is generally done as soon as possible, but some buffering - on the input may be done for performance reasons. - \nosubgrouping -*/ -class BufferedTransformation -{ -public: - //! - virtual ~BufferedTransformation() {} - - //! \name INPUT - //@{ - //! input a byte for processing - virtual void Put(byte inByte) =0; - //! input multiple bytes - virtual void Put(const byte *inString, unsigned int length) =0; - - //! input a 16-bit word, big-endian or little-endian depending on highFirst - void PutWord16(word16 value, bool highFirst=true); - //! input a 32-bit word - void PutWord32(word32 value, bool highFirst=true); - //@} - - //! \name SIGNALS - //@{ - //! process everything in internal buffers and output them - /*! throws exception if completeFlush == true and it's - not possible to flush everything */ - virtual void Flush(bool completeFlush, int propagation=-1); - //! mark end of an input segment, message, or packet - /*! propagation != 0 means pass on the signal to attached - BufferedTransformation objects, with propagation - decremented at each step until it reaches 0. - -1 means unlimited propagation. */ - virtual void MessageEnd(int propagation=-1); - //! same as Put() followed by MessageEnd() but may be more efficient - virtual void PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); - //! mark end of a series of messages - /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ - virtual void MessageSeriesEnd(int propagation=-1); - - //! set propagation of automatically generated and transfered signals - /*! propagation == 0 means do not automaticly generate signals */ - virtual void SetAutoSignalPropagation(int propagation) {} - - //! - virtual int GetAutoSignalPropagation() const {return 0;} - - // for backwards compatibility - void Close() {MessageEnd();} - //@} - - //! \name ERRORS - //@{ - //! error types - enum ErrorType { - //! received a Flush(true) signal but can't flush buffers - CANNOT_FLUSH, - //! data integerity check (such as CRC or MAC) failed - DATA_INTEGRITY_CHECK_FAILED, - //! received input data that doesn't conform to expected format - INVALID_DATA_FORMAT, - //! error reading from input device - INPUT_ERROR, - //! error writing to output device - OUTPUT_ERROR, - //! some error not belong to any of the above categories - OTHER_ERROR - }; - - //! exception thrown by BufferedTransformation - class Err : public Exception - { - public: - Err(ErrorType errorType, const std::string &s=""); - ErrorType GetErrorType() const {return m_errorType;} - void SetErrorType(ErrorType errorType) {m_errorType = errorType;} - private: - ErrorType m_errorType; - }; - //@} - - //! \name RETRIEVAL OF ONE MESSAGE - //@{ - //! returns number of bytes that is currently ready for retrieval - /*! All retrieval functions return the actual number of bytes - retrieved, which is the lesser of the request number and - MaxRetrievable(). */ - virtual unsigned long MaxRetrievable() const; - - // old mispelled name - unsigned long MaxRetrieveable() const {return MaxRetrievable();} - - //! returns whether any bytes are currently ready for retrieval - virtual bool AnyRetrievable() const; - - //! try to retrieve a single byte - virtual unsigned int Get(byte &outByte); - //! try to retrieve multiple bytes - virtual unsigned int Get(byte *outString, unsigned int getMax); - - //! peek at the next byte without removing it from the output buffer - virtual unsigned int Peek(byte &outByte) const; - //! peek at multiple bytes without removing them from the output buffer - virtual unsigned int Peek(byte *outString, unsigned int peekMax) const; - - //! try to retrieve a 16-bit word, big-endian or little-endian depending on highFirst - unsigned int GetWord16(word16 &value, bool highFirst=true); - //! try to retrieve a 32-bit word - unsigned int GetWord32(word32 &value, bool highFirst=true); - - //! try to peek at a 16-bit word, big-endian or little-endian depending on highFirst - unsigned int PeekWord16(word16 &value, bool highFirst=true); - //! try to peek at a 32-bit word - unsigned int PeekWord32(word32 &value, bool highFirst=true); - - //! move transferMax bytes of the buffered output to target as input - virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - - //! discard skipMax bytes from the output buffer - virtual unsigned long Skip(unsigned long skipMax=ULONG_MAX); - - //! copy copyMax bytes of the buffered output to target as input - virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - //@} - - //! \name RETRIEVAL OF MULTIPLE MESSAGES - //@{ - //! - virtual unsigned long TotalBytesRetrievable() const; - //! number of times MessageEnd() has been received minus messages retrieved or skipped - virtual unsigned int NumberOfMessages() const; - //! returns true if NumberOfMessages() > 0 - virtual bool AnyMessages() const; - //! start retrieving the next message - /*! - Returns false if no more messages exist or this message - is not completely retrieved. - */ - virtual bool GetNextMessage(); - //! skip count number of messages - virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); - //! - virtual unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX); - //! - virtual unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; - - //! - virtual void SkipAll(); - //! - virtual void TransferAllTo(BufferedTransformation &target); - //! - virtual void CopyAllTo(BufferedTransformation &target) const; - //@} - - //! \name CHANNELS - //@{ - virtual void ChannelPut(const std::string &channel, byte inByte); - virtual void ChannelPut(const std::string &channel, const byte *inString, unsigned int length); - - void ChannelPutWord16(const std::string &channel, word16 value, bool highFirst=true); - void ChannelPutWord32(const std::string &channel, word32 value, bool highFirst=true); - - virtual void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1); - virtual void ChannelMessageEnd(const std::string &channel, int propagation=-1); - virtual void ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation=-1); - virtual void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1); - - virtual void SetRetrievalChannel(const std::string &channel); - - static const std::string NULL_CHANNEL; - //@} - - /*! \name ATTACHMENT - Some BufferedTransformation objects (e.g. Filter objects) - allow other BufferedTransformation objects to be attached. When - this is done, the first object instead of buffering its output, - sents that output to the attached object as input. The entire - attachment chain is deleted when the anchor object is destructed. - */ - //@{ - //! returns whether this object allows attachment - virtual bool Attachable() {return false;} - //! returns the object immediately attached to this object or nullptr for no attachment - virtual BufferedTransformation *AttachedTransformation() {return 0;} - //! - virtual const BufferedTransformation *AttachedTransformation() const - {return const_cast(this)->AttachedTransformation();} - //! delete the current attachment chain and replace it with newAttachment - virtual void Detach(BufferedTransformation *newAttachment = 0) {} - //! add newAttachment to the end of attachment chain - virtual void Attach(BufferedTransformation *newAttachment); - //@} -}; - -//! abstract base class for public-key encryptors and decryptors - -/*! This class provides an interface common to encryptors and decryptors - for querying their plaintext and ciphertext lengths. -*/ -class PK_CryptoSystem -{ -public: - //! - virtual ~PK_CryptoSystem() {} - - //! maximum length of plaintext for a given ciphertext length - //* This function returns 0 if cipherTextLength is not valid (too long or too short). - virtual unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const =0; - - //! calculate length of ciphertext given length of plaintext - //* This function returns 0 if plainTextLength is not valid (too long). - virtual unsigned int CipherTextLength(unsigned int plainTextLength) const =0; -}; - -//! abstract base class for public-key encryptors - -/*! An encryptor is also a public encryption key. It contains both the - key and the algorithm to perform the encryption. -*/ -class PK_Encryptor : public virtual PK_CryptoSystem -{ -public: - //! encrypt a byte string - /*! Preconditions: - \begin{itemize} - \item CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long) - \item size of cipherText == CipherTextLength(plainTextLength) - \end{itemize} - */ - virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) =0; -}; - -//! abstract base class for public-key decryptors - -/*! An decryptor is also a private decryption key. It contains both the - key and the algorithm to perform the decryption. -*/ -class PK_Decryptor : public virtual PK_CryptoSystem -{ -public: - //! decrypt a byte string, and return the length of plaintext - /*! Precondition: size of plainText == MaxPlainTextLength(cipherTextLength) - bytes. - - The function returns the actual length of the plaintext, or 0 - if decryption fails. - */ - virtual unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) =0; -}; - -//! abstract base class for encryptors and decryptors with fixed length ciphertext - -/*! A simplified interface (as embodied in this - class and its subclasses) is provided for crypto systems (such - as RSA) whose ciphertext length depend only on the key, not on the length - of the plaintext. The maximum plaintext length also depend only on - the key. -*/ -class PK_FixedLengthCryptoSystem : public virtual PK_CryptoSystem -{ -public: - //! - virtual unsigned int MaxPlainTextLength() const =0; - //! - virtual unsigned int CipherTextLength() const =0; - - unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const; - unsigned int CipherTextLength(unsigned int plainTextLength) const; -}; - -//! abstract base class for encryptors with fixed length ciphertext - -class PK_FixedLengthEncryptor : public virtual PK_Encryptor, public virtual PK_FixedLengthCryptoSystem -{ -}; - -//! abstract base class for decryptors with fixed length ciphertext - -class PK_FixedLengthDecryptor : public virtual PK_Decryptor, public virtual PK_FixedLengthCryptoSystem -{ -public: - //! decrypt a byte string, and return the length of plaintext - /*! Preconditions: - \begin{itemize} - \item length of cipherText == CipherTextLength() - \item size of plainText == MaxPlainTextLength() - \end{itemize} - - The function returns the actual length of the plaintext, or 0 - if decryption fails. - */ - virtual unsigned int Decrypt(const byte *cipherText, byte *plainText) =0; - - unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText); -}; - -//! abstract base class for public-key signers and verifiers - -/*! This class provides an interface common to signers and verifiers - for querying their signature lengths and creating message - accumulators. -*/ -class PK_SignatureSystem -{ -public: - //! - virtual ~PK_SignatureSystem() {}; - - //! signature length support by this object (as either input or output) - virtual unsigned int SignatureLength() const =0; - - //! create a new HashModule to accumulate the message to be signed or verified - virtual HashModule * NewMessageAccumulator() const =0; -}; - -//! abstract base class for public-key signers - -/*! A signer is also a private signature key. It contains both the - key and the algorithm to perform the signature. -*/ -class PK_Signer : public virtual PK_SignatureSystem -{ -public: - //! key too short exception, may be thrown by Sign() or SignMessage() - class KeyTooShort : public Exception - { - public: - KeyTooShort() : Exception("PK_Signer: key too short") {} - }; - - //! sign and delete messageAccumulator - /*! Preconditions: - \begin{itemize} - \item messageAccumulator was obtained by calling NewMessageAccumulator() - \item HashModule::Final() has not been called on messageAccumulator - \item size of signature == SignatureLength() - \end{itemize} - */ - virtual void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const =0; - - //! sign a message - /*! Precondition: size of signature == SignatureLength() */ - virtual void SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const; -}; - -//! abstract base class for public-key verifiers - -/*! A verifier is also a public verification key. It contains both the - key and the algorithm to perform the verification. -*/ -class PK_Verifier : public virtual PK_SignatureSystem -{ -public: - //! check whether sig is a valid signature for messageAccumulator, and delete messageAccumulator - /*! Preconditions: - \begin{itemize} - \item messageAccumulator was obtained by calling NewMessageAccumulator() - \item HashModule::Final() has not been called on messageAccumulator - \item length of signature == SignatureLength() - \end{itemize} - */ - virtual bool Verify(HashModule *messageAccumulator, const byte *sig) const =0; - - //! check whether sig is a valid signature for message - /*! Precondition: size of signature == SignatureLength() */ - virtual bool VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const; -}; - -//! abstract base class for public-key signers and verifiers with recovery - -/*! In a signature scheme with recovery, a verifier is able to extract - a message from its valid signature. -*/ -class PK_SignatureSystemWithRecovery : public virtual PK_SignatureSystem -{ -public: - //! length of longest message that can be fully recovered - virtual unsigned int MaximumRecoverableLength() const =0; - - //! whether or not messages longer than MaximumRecoverableLength() can be signed - /*! If this function returns false, any message longer than - MaximumRecoverableLength() will be truncated for signature - and will fail verification. - */ - virtual bool AllowLeftoverMessage() const =0; -}; - -//! abstract base class for public-key signers with recovery - -class PK_SignerWithRecovery : public virtual PK_SignatureSystemWithRecovery, public PK_Signer -{ -}; - -//! abstract base class for public-key verifiers with recovery - -/*! A PK_VerifierWithRecovery can also be used the same way as a PK_Verifier, - where the signature and the entire message is given to Verify() or - VerifyMessage() as input. -*/ -class PK_VerifierWithRecovery : public virtual PK_SignatureSystemWithRecovery, public PK_Verifier -{ -public: - //! create a new HashModule to accumulate leftover message - virtual HashModule * NewLeftoverMessageAccumulator(const byte *signature) const =0; - - //! partially recover a message from its signature, return length of recoverd message, or 0 if signature is invalid - /*! Preconditions: - \begin{itemize} - \item leftoverMessageAccumulator was obtained by calling NewLeftoverMessageAccumulator(signature) - \item HashModule::Final() has not been called on leftoverMessageAccumulator - \item length of signature == SignatureLength() - \item size of recoveredMessage == MaximumRecoverableLength() - \end{itemize} - */ - virtual unsigned int PartialRecover(HashModule *leftoverMessageAccumulator, byte *recoveredMessage) const =0; - - //! recover a message from its signature, return length of message, or 0 if signature is invalid - /*! This function should be equivalent to PartialRecover(NewLeftoverMessageAccumulator(signature), recoveredMessage). - Preconditions: - \begin{itemize} - \item length of signature == SignatureLength() - \item size of recoveredMessage == MaximumRecoverableLength() - \end{itemize} - */ - virtual unsigned int Recover(const byte *signature, byte *recoveredMessage) const =0; -}; - -//! abstract base class for domains of simple key agreement protocols - -/*! A key agreement domain is a set of parameters that must be shared - by two parties in a key agreement protocol, along with the algorithms - for generating key pairs and deriving agreed values. -*/ -class PK_SimpleKeyAgreementDomain -{ -public: - virtual ~PK_SimpleKeyAgreementDomain() {} - - //! return whether the domain parameters stored in this object are valid - virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const =0; - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - //! return length of private keys in this domain - virtual unsigned int PrivateKeyLength() const =0; - //! return length of public keys in this domain - virtual unsigned int PublicKeyLength() const =0; - //! generate private/public key pair - /*! Preconditions: - \begin{itemize} - \item size of privateKey == PrivateKeyLength() - \item size of publicKey == PublicKeyLength() - \end{itemize} - */ - virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; - /*! derive agreed value from your private key and couterparty's public key, return false in case of failure - //! Note: If you have previously validated the public key, use validateOtherPublicKey=false to save time. - //! Preconditions: - \begin{itemize} - \item size of agreedValue == AgreedValueLength() - \item length of privateKey == PrivateKeyLength() - \item length of otherPublicKey == PublicKeyLength() - \end{itemize} - */ - virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; -}; - -//! abstract base class for domains of authenticated key agreement protocols - -/*! In an authenticated key agreement protocol, each party has two - key pairs. The long-lived key pair is called the static key pair, - and the short-lived key pair is called the ephemeral key pair. -*/ -class PK_AuthenticatedKeyAgreementDomain -{ -public: - virtual ~PK_AuthenticatedKeyAgreementDomain() {} - - //! return whether the domain parameters stored in this object are valid - virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const =0; - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - - //! return length of static private keys in this domain - virtual unsigned int StaticPrivateKeyLength() const =0; - //! return length of static public keys in this domain - virtual unsigned int StaticPublicKeyLength() const =0; - //! generate static private/public key pair - /*! Preconditions: - \begin{itemize} - \item size of privateKey == StaticPrivateKeyLength() - \item size of publicKey == StaticPublicKeyLength() - \end{itemize} - */ - virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; - - //! return length of ephemeral private keys in this domain - virtual unsigned int EphemeralPrivateKeyLength() const =0; - //! return length of ephemeral public keys in this domain - virtual unsigned int EphemeralPublicKeyLength() const =0; - //! generate ephemeral private/public key pair - /*! Preconditions: - \begin{itemize} - \item size of privateKey == EphemeralPrivateKeyLength() - \item size of publicKey == EphemeralPublicKeyLength() - \end{itemize} - */ - virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const =0; - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! Note: The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - Preconditions: - \begin{itemize} - \item size of agreedValue == AgreedValueLength() - \item length of staticPrivateKey == StaticPrivateKeyLength() - \item length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \item length of staticOtherPublicKey == StaticPublicKeyLength() - \item length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - \end{itemize} - */ - virtual bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const =0; -}; - -//! abstract base class for all objects that support precomputation - -/*! The class defines a common interface for doing precomputation, - and loading and saving precomputation. -*/ -class PK_Precomputation -{ -public: - //! - virtual ~PK_Precomputation() {} - - //! - /*! The exact semantics of Precompute() is varies, but - typically it means calculate a table of n objects - that can be used later to speed up computation. - */ - virtual void Precompute(unsigned int n) =0; - - //! retrieve previously saved precomputation - virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) =0; - //! save precomputation for later use - virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const =0; -}; - -//! . -template class PK_WithPrecomputation : public virtual T, public virtual PK_Precomputation -{ -}; - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/filters.cpp b/external/ours/library/crypto/src/shared/original-old/filters.cpp deleted file mode 100755 index 852a7b7fa..000000000 --- a/external/ours/library/crypto/src/shared/original-old/filters.cpp +++ /dev/null @@ -1,424 +0,0 @@ -// filters.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "filters.h" -#include "mqueue.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -BitBucket g_bitBucket; - -Filter::Filter(BufferedTransformation *outQ) - : m_outQueue(outQ ? outQ : new MessageQueue) -{ -} - -void Filter::Detach(BufferedTransformation *newOut) -{ - m_outQueue.reset(newOut ? newOut : new MessageQueue); - NotifyAttachmentChange(); -} - -void Filter::Insert(Filter *filter) -{ - filter->m_outQueue.reset(m_outQueue.release()); - m_outQueue.reset(filter); - NotifyAttachmentChange(); -} - -// ************************************************************* - -FilterWithBufferedInput::BlockQueue::BlockQueue(unsigned int blockSize, unsigned int maxBlocks) - : m_buffer(blockSize * maxBlocks) -{ - ResetQueue(blockSize, maxBlocks); -} - -void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int maxBlocks) -{ - m_buffer.Resize(blockSize * maxBlocks); - m_blockSize = blockSize; - m_maxBlocks = maxBlocks; - m_size = 0; - m_begin = m_buffer; -} - -const byte *FilterWithBufferedInput::BlockQueue::GetBlock() -{ - if (m_size >= m_blockSize) - { - const byte *ptr = m_begin; - if ((m_begin+=m_blockSize) == m_buffer.End()) - m_begin = m_buffer; - m_size -= m_blockSize; - return ptr; - } - else - return nullptr; -} - -const byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBlocks) -{ - numberOfBlocks = STDMIN(numberOfBlocks, STDMIN((unsigned int)(m_buffer.End()-m_begin), m_size)/m_blockSize); - const byte *ptr = m_begin; - if ((m_begin+=m_blockSize*numberOfBlocks) == m_buffer.End()) - m_begin = m_buffer; - m_size -= m_blockSize*numberOfBlocks; - return ptr; -} - -unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) -{ - unsigned int size = m_size; - unsigned int numberOfBlocks = m_maxBlocks; - const byte *ptr = GetContigousBlocks(numberOfBlocks); - memcpy(outString, ptr, numberOfBlocks*m_blockSize); - memcpy(outString+numberOfBlocks*m_blockSize, m_begin, m_size); - m_size = 0; - return size; -} - -void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length) -{ - assert(m_size + length <= m_buffer.size); - byte *end = (m_size < (unsigned)(m_buffer+m_buffer.size-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size; - unsigned int len = STDMIN(length, (unsigned int)(m_buffer+m_buffer.size-end)); - memcpy(end, inString, len); - if (len < length) - memcpy(m_buffer, inString+len, length-len); - m_size += length; -} - -FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ) - : Filter(outQ), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize) - , m_firstInputDone(false) - , m_queue(1, m_firstSize) -{ -} - -void FilterWithBufferedInput::Put(byte inByte) -{ - Put(&inByte, 1); -} - -void FilterWithBufferedInput::Put(const byte *inString, unsigned int length) -{ - if (length == 0) - return; - - unsigned int newLength = m_queue.CurrentSize() + length; - - if (!m_firstInputDone && newLength >= m_firstSize) - { - unsigned int len = m_firstSize - m_queue.CurrentSize(); - m_queue.Put(inString, len); - FirstPut(m_queue.GetContigousBlocks(m_firstSize)); - assert(m_queue.CurrentSize() == 0); - m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); - - inString += len; - newLength -= m_firstSize; - m_firstInputDone = true; - } - - if (m_firstInputDone) - { - if (m_blockSize == 1) - { - while (newLength > m_lastSize && m_queue.CurrentSize() > 0) - { - unsigned int len = newLength - m_lastSize; - const byte *ptr = m_queue.GetContigousBlocks(len); - NextPut(ptr, len); - newLength -= len; - } - - if (newLength > m_lastSize) - { - unsigned int len = newLength - m_lastSize; - NextPut(inString, len); - inString += len; - newLength -= len; - } - } - else - { - while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) - { - NextPut(m_queue.GetBlock(), m_blockSize); - newLength -= m_blockSize; - } - - if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) - { - assert(m_queue.CurrentSize() < m_blockSize); - unsigned int len = m_blockSize - m_queue.CurrentSize(); - m_queue.Put(inString, len); - inString += len; - NextPut(m_queue.GetBlock(), m_blockSize); - newLength -= m_blockSize; - } - - while (newLength >= m_blockSize + m_lastSize) - { - NextPut(inString, m_blockSize); - inString += m_blockSize; - newLength -= m_blockSize; - } - } - } - - m_queue.Put(inString, newLength - m_queue.CurrentSize()); -} - -void FilterWithBufferedInput::MessageEnd(int propagation) -{ - if (!m_firstInputDone && m_firstSize==0) - FirstPut(nullptr); - - SecByteBlock temp(m_queue.CurrentSize()); - m_queue.GetAll(temp); - LastPut(temp, temp.size); - - m_firstInputDone = false; - m_queue.ResetQueue(1, m_firstSize); - - Filter::MessageEnd(propagation); -} - -void FilterWithBufferedInput::ForceNextPut() -{ - if (m_firstInputDone && m_queue.CurrentSize() >= m_blockSize) - NextPut(m_queue.GetBlock(), m_blockSize); -} - -// ************************************************************* - - - -// ************************************************************* - -ProxyFilter::ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ) - : FilterWithBufferedInput(firstSize, 1, lastSize, outQ), m_filter(filter), m_proxy(nullptr) -{ - if (m_filter.get()) - m_filter->Attach(m_proxy = new OutputProxy(*this, false)); -} - -void ProxyFilter::Flush(bool completeFlush, int propagation) -{ - if (m_filter.get()) - { - bool passSignal = m_proxy->GetPassSignal(); - m_proxy->SetPassSignal(false); - m_filter->Flush(completeFlush, -1); - m_proxy->SetPassSignal(passSignal); - } - Filter::Flush(completeFlush, propagation); -} - -void ProxyFilter::SetFilter(Filter *filter) -{ - bool passSignal = m_proxy ? m_proxy->GetPassSignal() : false; - m_filter.reset(filter); - if (filter) - { - std::unique_ptr temp(m_proxy = new OutputProxy(*this, passSignal)); - m_filter->TransferAllTo(*m_proxy); - m_filter->Attach(temp.release()); - } - else - m_proxy=nullptr; -} - -void ProxyFilter::NextPut(const byte *s, unsigned int len) -{ - if (m_filter.get()) - m_filter->Put(s, len); -} - -// ************************************************************* - -void StreamCipherFilter::Put(const byte *inString, unsigned int length) -{ - SecByteBlock temp(length); - cipher.ProcessString(temp, inString, length); - AttachedTransformation()->Put(temp, length); -} - -void HashFilter::Put(byte inByte) -{ - m_hashModule.Update(&inByte, 1); - if (m_putMessage) - AttachedTransformation()->Put(inByte); -} - -void HashFilter::Put(const byte *inString, unsigned int length) -{ - m_hashModule.Update(inString, length); - if (m_putMessage) - AttachedTransformation()->Put(inString, length); -} - -void HashFilter::MessageEnd(int propagation) -{ - SecByteBlock buf(m_hashModule.DigestSize()); - m_hashModule.Final(buf); - AttachedTransformation()->Put(buf, buf.size); - Filter::MessageEnd(propagation); -} - -// ************************************************************* - -HashVerifier::HashVerifier(HashModule &hm, BufferedTransformation *outQueue, word32 flags) - : FilterWithBufferedInput(flags & HASH_AT_BEGIN ? hm.DigestSize() : 0, 1, flags & HASH_AT_BEGIN ? 0 : hm.DigestSize(), outQueue) - , m_hashModule(hm), m_flags(flags) - , m_expectedHash(flags & HASH_AT_BEGIN ? hm.DigestSize() : 0), m_verified(false) -{ -} - -void HashVerifier::FirstPut(const byte *inString) -{ - if (m_flags & HASH_AT_BEGIN) - { - memcpy(m_expectedHash, inString, m_expectedHash.size); - if (m_flags & PUT_HASH) - AttachedTransformation()->Put(inString, m_expectedHash.size); - } -} - -void HashVerifier::NextPut(const byte *inString, unsigned int length) -{ - m_hashModule.Update(inString, length); - if (m_flags & PUT_MESSAGE) - AttachedTransformation()->Put(inString, length); -} - -void HashVerifier::LastPut(const byte *inString, unsigned int length) -{ - if (m_flags & HASH_AT_BEGIN) - { - assert(length == 0); - m_verified = m_hashModule.Verify(m_expectedHash); - } - else - { - m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString)); - if (m_flags & PUT_HASH) - AttachedTransformation()->Put(inString, length); - } - - if (m_flags & PUT_RESULT) - AttachedTransformation()->Put(m_verified); - - if ((m_flags & THROW_EXCEPTION) && !m_verified) - throw HashVerificationFailed(); -} - -// ************************************************************* - -void SignerFilter::MessageEnd(int propagation) -{ - SecByteBlock buf(m_signer.SignatureLength()); - m_signer.Sign(m_rng, m_messageAccumulator.release(), buf); - AttachedTransformation()->Put(buf, buf.size); - Filter::MessageEnd(propagation); - m_messageAccumulator.reset(m_signer.NewMessageAccumulator()); -} - -void VerifierFilter::PutSignature(const byte *sig) -{ - memcpy(m_signature.ptr, sig, m_signature.size); -} - -void VerifierFilter::MessageEnd(int propagation) -{ - AttachedTransformation()->Put((byte)m_verifier.Verify(m_messageAccumulator.release(), m_signature)); - Filter::MessageEnd(propagation); - m_messageAccumulator.reset(m_verifier.NewMessageAccumulator()); -} - -// ************************************************************* - -void Source::PumpAll() -{ - while (PumpMessages()) {} - while (Pump()) {} -} - -StringSource::StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue) - : Source(outQueue), m_store(string) -{ - if (pumpAll) - PumpAll(); -} - -StringSource::StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue) - : Source(outQueue), m_store(string, length) -{ - if (pumpAll) - PumpAll(); -} - -bool Store::GetNextMessage() -{ - if (!m_messageEnd && !AnyRetrievable()) - { - m_messageEnd=true; - return true; - } - else - return false; -} - -unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const -{ - if (m_messageEnd || count == 0) - return 0; - else - { - CopyTo(target); - if (GetAutoSignalPropagation()) - target.MessageEnd(GetAutoSignalPropagation()-1); - return 1; - } -} - -unsigned long StringStore::TransferTo(BufferedTransformation &target, unsigned long transferMax) -{ - unsigned long result = CopyTo(target, transferMax); - m_count += result; - return result; -} - -unsigned long StringStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); - target.Put(m_store+m_count, len); - return len; -} - -unsigned long RandomNumberStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); - for (unsigned int i=0; i m_outQueue; -}; - -//! . -class TransparentFilter : public Filter -{ -public: - TransparentFilter(BufferedTransformation *outQ=nullptr) : Filter(outQ) {} - void Put(byte inByte) {AttachedTransformation()->Put(inByte);} - void Put(const byte *inString, unsigned int length) {AttachedTransformation()->Put(inString, length);} -}; - -//! . -class OpaqueFilter : public Filter -{ -public: - OpaqueFilter(BufferedTransformation *outQ=nullptr) : Filter(outQ) {} - void Put(byte inByte) {} - void Put(const byte *inString, unsigned int length) {} -}; - -/*! FilterWithBufferedInput divides up the input stream into - a first block, a number of middle blocks, and a last block. - First and last blocks are optional, and middle blocks may - be a stream instead (i.e. blockSize == 1). -*/ -class FilterWithBufferedInput : public Filter -{ -public: - /// firstSize and lastSize may be 0, blockSize must be at least 1 - FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ); - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - void MessageEnd(int propagation=-1); - - /*! the input buffer may contain more than blockSize bytes if lastSize != 0 - ForceNextPut() forces a call to NextPut() if this is the case - */ - void ForceNextPut(); - -protected: - bool DidFirstPut() {return m_firstInputDone;} - - // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize) - // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)) - virtual void FirstPut(const byte *inString) =0; - // NextPut() is called if totalLength >= firstSize+blockSize+lastSize - // length parameter is always blockSize unless blockSize == 1 - virtual void NextPut(const byte *inString, unsigned int length) =0; - // LastPut() is always called - // if totalLength < firstSize then length == totalLength - // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize - // else lastSize <= length < lastSize+blockSize - virtual void LastPut(const byte *inString, unsigned int length) =0; - -private: - class BlockQueue - { - public: - BlockQueue(unsigned int blockSize, unsigned int maxBlocks); - void ResetQueue(unsigned int blockSize, unsigned int maxBlocks); - const byte *GetBlock(); - const byte *GetContigousBlocks(unsigned int &numberOfBlocks); - unsigned int GetAll(byte *outString); - void Put(const byte *inString, unsigned int length); - unsigned int CurrentSize() const {return m_size;} - unsigned int MaxSize() const {return m_buffer.size;} - - private: - SecByteBlock m_buffer; - unsigned int m_blockSize, m_maxBlocks, m_size; - byte *m_begin; - }; - - unsigned int m_firstSize, m_blockSize, m_lastSize; - bool m_firstInputDone; - BlockQueue m_queue; -}; - -//! . -class FilterWithInputQueue : public Filter -{ -public: - FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {} - void Put(byte inByte) {m_inQueue.Put(inByte);} - void Put(const byte *inString, unsigned int length) {m_inQueue.Put(inString, length);} - -protected: - ByteQueue m_inQueue; -}; - -//! Filter Wrapper for StreamCipher -class StreamCipherFilter : public Filter -{ -public: - StreamCipherFilter(StreamCipher &c, - BufferedTransformation *outQueue = nullptr) - : cipher(c), Filter(outQueue) {} - - void Put(byte inByte) - {AttachedTransformation()->Put(cipher.ProcessByte(inByte));} - - void Put(const byte *inString, unsigned int length); - -private: - StreamCipher &cipher; -}; - -//! Filter Wrapper for HashModule -class HashFilter : public Filter -{ -public: - HashFilter(HashModule &hm, BufferedTransformation *outQueue = nullptr, bool putMessage=false) - : Filter(outQueue), m_hashModule(hm), m_putMessage(putMessage) {} - - void MessageEnd(int propagation=-1); - - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - -private: - HashModule &m_hashModule; - bool m_putMessage; -}; - -//! Filter Wrapper for HashModule -class HashVerifier : public FilterWithBufferedInput -{ -public: - class HashVerificationFailed : public BufferedTransformation::Err - { - public: - HashVerificationFailed() - : BufferedTransformation::Err(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not correct") {} - }; - - enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16}; - HashVerifier(HashModule &hm, BufferedTransformation *outQueue = nullptr, word32 flags = HASH_AT_BEGIN | PUT_RESULT); - - bool GetLastResult() const {return m_verified;} - -protected: - void FirstPut(const byte *inString); - void NextPut(const byte *inString, unsigned int length); - void LastPut(const byte *inString, unsigned int length); - -private: - HashModule &m_hashModule; - word32 m_flags; - SecByteBlock m_expectedHash; - bool m_verified; -}; - -//! Filter Wrapper for PK_Signer -class SignerFilter : public Filter -{ -public: - SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *outQueue = nullptr) - : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewMessageAccumulator()), Filter(outQueue) {} - - void MessageEnd(int propagation); - - void Put(byte inByte) - {m_messageAccumulator->Update(&inByte, 1);} - - void Put(const byte *inString, unsigned int length) - {m_messageAccumulator->Update(inString, length);} - -private: - RandomNumberGenerator &m_rng; - const PK_Signer &m_signer; - member_ptr m_messageAccumulator; -}; - -//! Filter Wrapper for PK_Verifier -class VerifierFilter : public Filter -{ -public: - VerifierFilter(const PK_Verifier &verifier, BufferedTransformation *outQueue = nullptr) - : m_verifier(verifier), m_messageAccumulator(verifier.NewMessageAccumulator()) - , m_signature(verifier.SignatureLength()), Filter(outQueue) {} - - // this function must be called before MessageEnd() - void PutSignature(const byte *sig); - - void MessageEnd(int propagation); - - void Put(byte inByte) - {m_messageAccumulator->Update(&inByte, 1);} - - void Put(const byte *inString, unsigned int length) - {m_messageAccumulator->Update(inString, length);} - -private: - const PK_Verifier &m_verifier; - member_ptr m_messageAccumulator; - SecByteBlock m_signature; -}; - -//! A BufferedTransformation that doesn't produce any retrievable output -class Sink : public BufferedTransformation -{ -}; - -//! . -class BitBucket : public Sink -{ -public: - void Put(byte) {} - void Put(const byte *, unsigned int) {} -}; - -extern BitBucket g_bitBucket; - -//! Redirect input to another BufferedTransformation without owning it -class Redirector : public Sink -{ -public: - Redirector() : m_target(nullptr), m_passSignal(true) {} - Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {} - - void Redirect(BufferedTransformation &target) {m_target = ⌖} - void StopRedirect() {m_target = nullptr;} - bool GetPassSignal() const {return m_passSignal;} - void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} - - void Put(byte b) - {if (m_target) m_target->Put(b);} - void Put(const byte *string, unsigned int len) - {if (m_target) m_target->Put(string, len);} - void Flush(bool completeFlush, int propagation=-1) - {if (m_target && m_passSignal) m_target->Flush(completeFlush, propagation);} - void MessageEnd(int propagation=-1) - {if (m_target && m_passSignal) m_target->MessageEnd(propagation);} - void MessageSeriesEnd(int propagation=-1) - {if (m_target && m_passSignal) m_target->MessageSeriesEnd(propagation);} - - void ChannelPut(const std::string &channel, byte b) - {if (m_target) m_target->ChannelPut(channel, b);} - void ChannelPut(const std::string &channel, const byte *string, unsigned int len) - {if (m_target) m_target->ChannelPut(channel, string, len);} - void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1) - {if (m_target && m_passSignal) m_target->ChannelFlush(channel, completeFlush, propagation);} - void ChannelMessageEnd(const std::string &channel, int propagation=-1) - {if (m_target && m_passSignal) m_target->ChannelMessageEnd(channel, propagation);} - void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) - {if (m_target && m_passSignal) m_target->ChannelMessageSeriesEnd(channel, propagation);} - -private: - BufferedTransformation *m_target; - bool m_passSignal; -}; - -// Used By ProxyFilter -class OutputProxy : public Sink -{ -public: - OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {} - - bool GetPassSignal() const {return m_passSignal;} - void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} - - void Put(byte b) - {m_owner.AttachedTransformation()->Put(b);} - void Put(const byte *string, unsigned int len) - {m_owner.AttachedTransformation()->Put(string, len);} - void Flush(bool completeFlush, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->Flush(completeFlush, propagation);} - void MessageEnd(int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->MessageEnd(propagation);} - void MessageSeriesEnd(int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->MessageSeriesEnd(propagation);} - - void ChannelPut(const std::string &channel, byte b) - {m_owner.AttachedTransformation()->ChannelPut(channel, b);} - void ChannelPut(const std::string &channel, const byte *string, unsigned int len) - {m_owner.AttachedTransformation()->ChannelPut(channel, string, len);} - void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation);} - void ChannelMessageEnd(const std::string &channel, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageEnd(channel, propagation);} - void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation);} - -private: - BufferedTransformation &m_owner; - bool m_passSignal; -}; - -//! Base class for Filter classes that are proxies for a chain of other filters. -class ProxyFilter : public FilterWithBufferedInput -{ -public: - ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ); - - void Flush(bool completeFlush, int propagation=-1); - - void SetFilter(Filter *filter); - void NextPut(const byte *s, unsigned int len); - -protected: - member_ptr m_filter; - OutputProxy *m_proxy; -}; - -//! Append input to a string object -template -class StringSinkTemplate : public Sink -{ -public: - // VC60 workaround: no T::char_type - typedef typename T::traits_type::char_type char_type; - - StringSinkTemplate(T &output) - : m_output(output) {assert(sizeof(output[0])==1);} - void Put(byte b) - {m_output += (char_type)b;} - void Put(const byte *str, unsigned int bc) - {m_output.append((const char_type *)str, bc);} - -private: - T &m_output; -}; - -//! Append input to an std::string -typedef StringSinkTemplate StringSink; - -//! Copy input to a memory buffer -class ArraySink : public Sink -{ -public: - ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {} - - unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);} - unsigned long TotalPutLength() {return m_total;} - - void Put(byte b) - { - if (m_total < m_size) - m_buf[m_total] = b; - m_total++; - } - - void Put(const byte *str, unsigned int len) - { - if (m_total < m_size) - memcpy(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total))); - m_total += len; - } - -protected: - byte *m_buf; - unsigned int m_size; - unsigned long m_total; -}; - -//! Xor input to a memory buffer -class ArrayXorSink : public ArraySink -{ -public: - ArrayXorSink(byte *buf, unsigned int size) - : ArraySink(buf, size) {} - - void Put(byte b) - { - if (m_total < m_size) - m_buf[m_total] ^= b; - m_total++; - } - - void Put(const byte *str, unsigned int len) - { - if (m_total < m_size) - xorbuf(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total))); - m_total += len; - } -}; - -//! Provide implementation of SetAutoSignalPropagation and GetAutoSignalPropagation -class BufferedTransformationWithAutoSignal : virtual public BufferedTransformation -{ -public: - BufferedTransformationWithAutoSignal(int propagation=-1) : m_autoSignalPropagation(propagation) {} - - void SetAutoSignalPropagation(int propagation) - {m_autoSignalPropagation = propagation;} - int GetAutoSignalPropagation() const - {return m_autoSignalPropagation;} - -private: - int m_autoSignalPropagation; -}; - -//! A BufferedTransformation that only contains pre-existing output -class Store : public BufferedTransformationWithAutoSignal -{ -public: - Store() : m_messageEnd(false) {} - - void Put(byte) - {} - void Put(const byte *, unsigned int length) - {} - - virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) =0; - virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const =0; - - unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;} - bool GetNextMessage(); - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; - -private: - bool m_messageEnd; -}; - -//! . -class StringStore : public Store -{ -public: - StringStore(const char *string) - : m_store((const byte *)string), m_length(strlen(string)), m_count(0) {} - StringStore(const byte *string, unsigned int length) - : m_store(string), m_length(length), m_count(0) {} - template StringStore(const T &string) - : m_store((const byte *)string.data()), m_length(string.length()), m_count(0) {assert(sizeof(string[0])==1);} - - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - -private: - const byte *m_store; - unsigned int m_length, m_count; -}; - -//! . -class RandomNumberStore : public Store -{ -public: - RandomNumberStore(RandomNumberGenerator &rng, unsigned long length) - : m_rng(rng), m_length(length), m_count(0) {} - - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - -private: - RandomNumberGenerator &m_rng; - unsigned long m_length, m_count; -}; - -//! A Filter that pumps data into its attachment as input -class Source : public Filter -{ -public: - Source(BufferedTransformation *outQ) - : Filter(outQ) {} - - virtual unsigned long Pump(unsigned long pumpMax=ULONG_MAX) =0; - virtual unsigned int PumpMessages(unsigned int count=UINT_MAX) {return 0;} - void PumpAll(); - - void Put(byte) - {Pump(1);} - void Put(const byte *, unsigned int length) - {Pump(length);} - void MessageEnd(int propagation=-1) - {PumpAll();} -}; - -//! Turn a Store into a Source -class GeneralSource : public Source -{ -public: - GeneralSource(BufferedTransformation &store, bool pumpAll, BufferedTransformation *outQueue = nullptr) - : Source(outQueue), m_store(store) - { - if (pumpAll) PumpAll(); - } - - unsigned long Pump(unsigned long pumpMax=ULONG_MAX) - {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} - -private: - BufferedTransformation &m_store; -}; - -//! . -class StringSource : public Source -{ -public: - StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue = nullptr); - StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = nullptr); - -#ifdef __MWERKS__ // CW60 workaround - StringSource(const std::string &string, bool pumpAll, BufferedTransformation *outQueue = nullptr) -#else - template StringSource(const T &string, bool pumpAll, BufferedTransformation *outQueue = nullptr) -#endif - : Source(outQueue), m_store(string) - { - if (pumpAll) - PumpAll(); - } - - unsigned long Pump(unsigned long pumpMax=ULONG_MAX) - {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} - -private: - StringStore m_store; -}; - -//! . -class RandomNumberSource : public Source -{ -public: - RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = nullptr); - - unsigned long Pump(unsigned long pumpMax=ULONG_MAX) - {return m_store.TransferTo(*AttachedTransformation(), pumpMax);} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {return m_store.TransferMessagesTo(*AttachedTransformation(), count);} - -private: - RandomNumberStore m_store; -}; - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/iterhash.cpp b/external/ours/library/crypto/src/shared/original-old/iterhash.cpp deleted file mode 100755 index 1730ce941..000000000 --- a/external/ours/library/crypto/src/shared/original-old/iterhash.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// iterhash.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef WORD64_AVAILABLE -template class IteratedHashBase; -#endif - -template class IteratedHashBase; - -NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/iterhash.h b/external/ours/library/crypto/src/shared/original-old/iterhash.h deleted file mode 100755 index a0abd0e73..000000000 --- a/external/ours/library/crypto/src/shared/original-old/iterhash.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef CRYPTOPP_ITERHASH_H -#define CRYPTOPP_ITERHASH_H - -#include "cryptlib.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -/*! The following classes are explicitly instantiated in iterhash.cpp - - IteratedHashBase - IteratedHashBase // #ifdef WORD64_AVAILABLE -*/ -template -class IteratedHashBase : public virtual HashModule -{ -public: - typedef T HashWordType; - - IteratedHashBase(unsigned int blockSize, unsigned int digestSize); - unsigned int DigestSize() const {return digest.size * sizeof(T);}; - void Update(const byte *input, unsigned int length); - -protected: - virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); - void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); - void Reinit(); - virtual void Init() =0; - virtual void HashBlock(const T *input) =0; - - unsigned int blockSize; - word32 countLo, countHi; // 64-bit bit count - SecBlock data; // Data buffer - SecBlock digest; // Message digest -}; - -template -IteratedHashBase::IteratedHashBase(unsigned int blockSize, unsigned int digestSize) - : blockSize(blockSize), countLo(0), countHi(0) - , data(blockSize/sizeof(T)), digest(digestSize/sizeof(T)) -{ -} - -template void IteratedHashBase::Update(const byte *input, unsigned int len) -{ - HashWordType tmp = countLo; - if ((countLo = tmp + ((word32)len << 3)) < tmp) - countHi++; // Carry from low to high - - int rshift = (8*sizeof(HashWordType)-3); - if (rshift<32) - { - countHi += len >> rshift; - } - - assert((blockSize & (blockSize-1)) == 0); // blockSize is a power of 2 - unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1); - - if (num != 0) - { - if ((num+len) >= blockSize) - { - memcpy((byte *)data.ptr+num, input, blockSize-num); - HashBlock(data); - input += (blockSize-num); - len-=(blockSize - num); - num=0; - // drop through and do the rest - } - else - { - memcpy((byte *)data.ptr+num, input, len); - return; - } - } - - // we now can process the input data in blocks of blockSize - // chars and save the leftovers to this->data. - if (len >= blockSize) - { - if (IsAligned(input)) - { - unsigned int leftOver = HashMultipleBlocks((T *)input, len); - input += (len - leftOver); - len = leftOver; - } - else - do - { // copy input first if it's not aligned correctly - memcpy(data, input, blockSize); - HashBlock(data); - input+=blockSize; - len-=blockSize; - } while (len >= blockSize); - } - - memcpy(data, input, len); -} - -template unsigned int IteratedHashBase::HashMultipleBlocks(const T *input, unsigned int length) -{ - do - { - HashBlock(input); - input += blockSize/sizeof(T); - length -= blockSize; - } - while (length >= blockSize); - return length; -} - -template void IteratedHashBase::PadLastBlock(unsigned int lastBlockSize, byte padFirst) -{ - unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1); - assert(num < blockSize); - ((byte *)data.ptr)[num++]=padFirst; - if (num <= lastBlockSize) - memset((byte *)data.ptr+num, 0, lastBlockSize-num); - else - { - memset((byte *)data.ptr+num, 0, blockSize-num); - HashBlock(data); - memset(data, 0, lastBlockSize); - } -} - -template void IteratedHashBase::Reinit() -{ - countLo = countHi = 0; - Init(); -} - -// provide empty definitions to avoid instantiation warnings -template void IteratedHashBase::Init() {} -template void IteratedHashBase::HashBlock(const T *input) {} - -//! . -template -class IteratedHash : public IteratedHashBase -{ -public: - typedef T HashWordType; - enum {HIGHFIRST = H, BLOCKSIZE = S}; - - IteratedHash(unsigned int digestSize) : IteratedHashBase(BLOCKSIZE, digestSize) {} - - inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount) - { - if (!CheckEndianess(HIGHFIRST)) - byteReverse(out, in, byteCount); - else if (in!=out) - memcpy(out, in, byteCount); - } - - void Final(byte *hash) - { - this->PadLastBlock(BLOCKSIZE - 2*sizeof(HashWordType)); - CorrectEndianess(this->data, this->data, BLOCKSIZE - 2*sizeof(HashWordType)); - - this->data[this->data.size-2] = HIGHFIRST ? this->countHi : this->countLo; - this->data[this->data.size-1] = HIGHFIRST ? this->countLo : this->countHi; - - vTransform(this->data); - CorrectEndianess(this->digest, this->digest, this->DigestSize()); - memcpy(hash, this->digest, this->DigestSize()); - - this->Reinit(); // reinit for next use - } - -protected: - void HashBlock(const HashWordType *input) - { - if (CheckEndianess(HIGHFIRST)) - vTransform(input); - else - { - byteReverse(this->data.ptr, input, (unsigned int)BLOCKSIZE); - vTransform(this->data); - } - } - - virtual void vTransform(const HashWordType *data) =0; -}; - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/md5.cpp b/external/ours/library/crypto/src/shared/original-old/md5.cpp deleted file mode 100755 index 68f60925a..000000000 --- a/external/ours/library/crypto/src/shared/original-old/md5.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// md5.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c -// any modifications are placed in the public domain - -#include "FirstCrypto.h" -#include "md5.h" - -NAMESPACE_BEGIN(CryptoPP) - -void MD5::Init() -{ - digest[0u] = 0x67452301L; - digest[1u] = 0xefcdab89L; - digest[2u] = 0x98badcfeL; - digest[3u] = 0x10325476L; -} - -void MD5::Transform (word32 *digest, const word32 *in) -{ -// #define F1(x, y, z) (x & y | ~x & z) -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -#define MD5STEP(f, w, x, y, z, data, s) \ - w = rotlFixed(w + f(x, y, z) + data, s) + x - - word32 a, b, c, d; - - a=digest[0]; - b=digest[1]; - c=digest[2]; - d=digest[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - digest[0]+=a; - digest[1]+=b; - digest[2]+=c; - digest[3]+=d; -} - -NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/md5.h b/external/ours/library/crypto/src/shared/original-old/md5.h deleted file mode 100755 index d58d6eabd..000000000 --- a/external/ours/library/crypto/src/shared/original-old/md5.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CRYPTOPP_MD5_H -#define CRYPTOPP_MD5_H - -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// MD5 -/** 128 Bit Hash */ -class MD5 : public IteratedHash -{ -public: - enum {DIGESTSIZE = 16}; - MD5() : IteratedHash(DIGESTSIZE) {Init();} - static void Transform(word32 *digest, const word32 *data); - -protected: - void Init(); - void vTransform(const word32 *data) {Transform(digest, data);} -}; - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/misc.cpp b/external/ours/library/crypto/src/shared/original-old/misc.cpp deleted file mode 100755 index c1a7d078f..000000000 --- a/external/ours/library/crypto/src/shared/original-old/misc.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// misc.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "misc.h" -#include "words.h" - -NAMESPACE_BEGIN(CryptoPP) - -byte OAEP_P_DEFAULT[1]; - -void xorbuf(byte *buf, const byte *mask, unsigned int count) -{ - if (((size_t)buf | (size_t)mask | count) % WORD_SIZE == 0) - XorWords((word *)buf, (const word *)mask, count/WORD_SIZE); - else - { - for (unsigned int i=0; i0; i/=2) - value ^= value >> i; - return (unsigned int)value&1; -} - -unsigned int BytePrecision(unsigned long value) -{ - unsigned int i; - for (i=sizeof(value); i; --i) - if (value >> (i-1)*8) - break; - - return i; -} - -unsigned int BitPrecision(unsigned long value) -{ - if (!value) - return 0; - - unsigned int l=0, h=8*sizeof(value); - - while (h-l > 1) - { - unsigned int t = (l+h)/2; - if (value >> t) - l = t; - else - h = t; - } - - return h; -} - -unsigned long Crop(unsigned long value, unsigned int size) -{ - if (size < 8*sizeof(value)) - return (value & ((1L << size) - 1)); - else - return value; -} - -NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/misc.h b/external/ours/library/crypto/src/shared/original-old/misc.h deleted file mode 100755 index 862970a96..000000000 --- a/external/ours/library/crypto/src/shared/original-old/misc.h +++ /dev/null @@ -1,689 +0,0 @@ -#ifndef CRYPTOPP_MISC_H -#define CRYPTOPP_MISC_H - -#include "config.h" -#include -#include // CodeWarrior doesn't have memory.h -#include -#include - -#ifdef INTEL_INTRINSICS -#include -#endif - -NAMESPACE_BEGIN(CryptoPP) - -// ************** misc functions *************** - -#define GETBYTE(x, y) (uint32_t)(((x)>>(8*(y)))&255) -// this one may be faster on a Pentium -// #define GETBYTE(x, y) (((byte *)&(x))[y]) - -uint32_t Parity(unsigned long); -uint32_t BytePrecision(unsigned long); -uint32_t BitPrecision(unsigned long); -unsigned long Crop(unsigned long, uint32_t size); - -inline uint32_t bitsToBytes(uint32_t bitCount) -{ - return ((bitCount+7)/(8)); -} - -inline uint32_t bytesToWords(uint32_t byteCount) -{ - return ((byteCount+WORD_SIZE-1)/WORD_SIZE); -} - -inline uint32_t bitsToWords(uint32_t bitCount) -{ - return ((bitCount+WORD_BITS-1)/(WORD_BITS)); -} - -void xorbuf(byte *buf, const byte *mask, uint32_t count); -void xorbuf(byte *output, const byte *input, const byte *mask, uint32_t count); - -inline uint32_t RoundDownToMultipleOf(uint32_t n, uint32_t m) -{ - return n - n%m; -} - -inline uint32_t RoundUpToMultipleOf(uint32_t n, uint32_t m) -{ - return RoundDownToMultipleOf(n+m-1, m); -} - -template -inline bool IsAligned(const void *p) -{ - return (uintptr_t)p % sizeof(T) == 0; -} - -inline bool CheckEndianess(bool highFirst) -{ -#ifdef IS_LITTLE_ENDIAN - return !highFirst; -#else - return highFirst; -#endif -} - -template // can't use because GCC 2.95.2 doesn't have it -std::string IntToString(T a) -{ - if (a == 0) - return "0"; - bool negate = false; - if (a < 0) - { - negate = true; - a = -a; - } - std::string result; - while (a > 0) - { - result = char('0' + a % 10) + result; - a = a / 10; - } - if (negate) - result = "-" + result; - return result; -} - -// ************** rotate functions *************** - -template inline T rotlFixed(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x<>(sizeof(T)*8-y)); -} - -template inline T rotrFixed(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x>>y) | (x<<(sizeof(T)*8-y)); -} - -template inline T rotlVariable(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x<>(sizeof(T)*8-y)); -} - -template inline T rotrVariable(T x, uint32_t y) -{ - assert(y < sizeof(T)*8); - return (x>>y) | (x<<(sizeof(T)*8-y)); -} - -template inline T rotlMod(T x, uint32_t y) -{ - y %= sizeof(T)*8; - return (x<>(sizeof(T)*8-y)); -} - -template inline T rotrMod(T x, uint32_t y) -{ - y %= sizeof(T)*8; - return (x>>y) | (x<<(sizeof(T)*8-y)); -} - -#ifdef INTEL_INTRINSICS - -template<> inline word32 rotlFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? _lrotl(x, y) : x; -} - -template<> inline word32 rotrFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? _lrotr(x, y) : x; -} - -template<> inline word32 rotlVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return _lrotl(x, y); -} - -template<> inline word32 rotrVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return _lrotr(x, y); -} - -template<> inline word32 rotlMod(word32 x, uint32_t y) -{ - return _lrotl(x, y); -} - -template<> inline word32 rotrMod(word32 x, uint32_t y) -{ - return _lrotr(x, y); -} - -#endif // #ifdef INTEL_INTRINSICS - -#ifdef PPC_INTRINSICS - -template<> inline word32 rotlFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? __rlwinm(x,y,0,31) : x; -} - -template<> inline word32 rotrFixed(word32 x, uint32_t y) -{ - assert(y < 32); - return y ? __rlwinm(x,32-y,0,31) : x; -} - -template<> inline word32 rotlVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrVariable(word32 x, uint32_t y) -{ - assert(y < 32); - return (__rlwnm(x,32-y,0,31)); -} - -template<> inline word32 rotlMod(word32 x, uint32_t y) -{ - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrMod(word32 x, uint32_t y) -{ - return (__rlwnm(x,32-y,0,31)); -} - -#endif // #ifdef PPC_INTRINSICS - -// ************** endian reversal *************** - -inline word16 byteReverse(word16 value) -{ - return rotlFixed(value, 8U); -} - -inline word32 byteReverse(word32 value) -{ -#ifdef PPC_INTRINSICS - // PPC: load reverse indexed instruction - return (word32)__lwbrx(&value,0); -#elif defined(FAST_ROTATE) - // 5 instructions with rotate instruction, 9 without - return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); -#else - // 6 instructions with rotate instruction, 8 without - value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); - return rotlFixed(value, 16U); -#endif -} - -#ifdef WORD64_AVAILABLE -inline word64 byteReverse(word64 value) -{ -#ifdef SLOW_WORD64 - return (word64(byteReverse(word32(value))) << 32) | byteReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); - value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); - return rotlFixed(value, 32U); -#endif -} -#endif - -inline byte bitReverse(byte value) -{ - value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); - value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); - return rotlFixed(value, 4); -} - -inline word16 bitReverse(word16 value) -{ - value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); - value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); - value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); - return byteReverse(value); -} - -inline word32 bitReverse(word32 value) -{ - value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1); - value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2); - value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4); - return byteReverse(value); -} - -#ifdef WORD64_AVAILABLE -inline word64 bitReverse(word64 value) -{ -#ifdef SLOW_WORD64 - return (word64(bitReverse(word32(value))) << 32) | bitReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1); - value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2); - value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); - return byteReverse(value); -#endif -} -#endif - -template -inline T bitReverse(T value) -{ - if (sizeof(T) == 1) - return bitReverse((byte)value); - else if (sizeof(T) == 2) - return bitReverse((word16)value); - else if (sizeof(T) == 4) - return bitReverse((word32)value); - else - { -#ifdef WORD64_AVAILABLE - assert(sizeof(T) == 8); - return bitReverse((word64)value); -#else - assert(false); - return 0; -#endif - } -} - -template -void byteReverse(T *out, const T *in, uint32_t byteCount) -{ - uint32_t count = (byteCount+sizeof(T)-1)/sizeof(T); - for (uint32_t i=0; i -inline void GetUserKeyLittleEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) -{ - const uint32_t U = sizeof(T); - assert(inlen <= outlen*U); - memcpy(out, in, inlen); - memset((byte *)out+inlen, 0, outlen*U-inlen); -#ifndef IS_LITTLE_ENDIAN - byteReverse(out, out, inlen); -#endif -} - -template -inline void GetUserKeyBigEndian(T *out, uint32_t outlen, const byte *in, uint32_t inlen) -{ - const uint32_t U = sizeof(T); - assert(inlen <= outlen*U); - memcpy(out, in, inlen); - memset((byte *)out+inlen, 0, outlen*U-inlen); -#ifdef IS_LITTLE_ENDIAN - byteReverse(out, out, inlen); -#endif -} - -// Fetch 2 words from user's buffer into "a", "b" in LITTLE-endian order -template -inline void GetBlockLittleEndian(const byte *block, T &a, T &b) -{ -#ifdef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); -#endif -} - -// Put 2 words back into user's buffer in LITTLE-endian order -template -inline void PutBlockLittleEndian(byte *block, T a, T b) -{ -#ifdef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); -#endif -} - -// Fetch 4 words from user's buffer into "a", "b", "c", "d" in LITTLE-endian order -template -inline void GetBlockLittleEndian(const byte *block, T &a, T &b, T &c, T &d) -{ -#ifdef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; - c = ((T *)block)[2]; - d = ((T *)block)[3]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); - c = byteReverse(((T *)block)[2]); - d = byteReverse(((T *)block)[3]); -#endif -} - -// Put 4 words back into user's buffer in LITTLE-endian order -template -inline void PutBlockLittleEndian(byte *block, T a, T b, T c, T d) -{ -#ifdef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; - ((T *)block)[2] = c; - ((T *)block)[3] = d; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); - ((T *)block)[2] = byteReverse(c); - ((T *)block)[3] = byteReverse(d); -#endif -} - -// Fetch 2 words from user's buffer into "a", "b" in BIG-endian order -template -inline void GetBlockBigEndian(const byte *block, T &a, T &b) -{ -#ifndef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); -#endif -} - -// Put 2 words back into user's buffer in BIG-endian order -template -inline void PutBlockBigEndian(byte *block, T a, T b) -{ -#ifndef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); -#endif -} - -// Fetch 4 words from user's buffer into "a", "b", "c", "d" in BIG-endian order -template -inline void GetBlockBigEndian(const byte *block, T &a, T &b, T &c, T &d) -{ -#ifndef IS_LITTLE_ENDIAN - a = ((T *)block)[0]; - b = ((T *)block)[1]; - c = ((T *)block)[2]; - d = ((T *)block)[3]; -#else - a = byteReverse(((T *)block)[0]); - b = byteReverse(((T *)block)[1]); - c = byteReverse(((T *)block)[2]); - d = byteReverse(((T *)block)[3]); -#endif -} - -// Put 4 words back into user's buffer in BIG-endian order -template -inline void PutBlockBigEndian(byte *block, T a, T b, T c, T d) -{ -#ifndef IS_LITTLE_ENDIAN - ((T *)block)[0] = a; - ((T *)block)[1] = b; - ((T *)block)[2] = c; - ((T *)block)[3] = d; -#else - ((T *)block)[0] = byteReverse(a); - ((T *)block)[1] = byteReverse(b); - ((T *)block)[2] = byteReverse(c); - ((T *)block)[3] = byteReverse(d); -#endif -} - -template -std::string WordToString(T value, bool highFirst = true) -{ - if (!CheckEndianess(highFirst)) - value = byteReverse(value); - - return std::string((char *)&value, sizeof(value)); -} - -template -T StringToWord(const std::string &str, bool highFirst = true) -{ - T value = 0; - memcpy(&value, str.data(), STDMIN(sizeof(value), str.size())); - return CheckEndianess(highFirst) ? value : byteReverse(value); -} - -// ************** key length query *************** - -/// support query of fixed key length -template -class FixedKeyLength -{ -public: - enum {KEYLENGTH=N, MIN_KEYLENGTH=N, MAX_KEYLENGTH=N, DEFAULT_KEYLENGTH=N}; - /// returns the key length - static uint32_t KeyLength(uint32_t) {return KEYLENGTH;} -}; - -/// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) -template -class VariableKeyLength -{ -public: - enum {MIN_KEYLENGTH=N, MAX_KEYLENGTH=M, DEFAULT_KEYLENGTH=D, KEYLENGTH_MULTIPLE=Q}; - /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) - static uint32_t KeyLength(uint32_t n) - { - assert(KEYLENGTH_MULTIPLE > 0 && MIN_KEYLENGTH % KEYLENGTH_MULTIPLE == 0 && MAX_KEYLENGTH % KEYLENGTH_MULTIPLE == 0); - if (n < MIN_KEYLENGTH) - return MIN_KEYLENGTH; - else if (n > MAX_KEYLENGTH) - return MAX_KEYLENGTH; - else - return RoundUpToMultipleOf(n, KEYLENGTH_MULTIPLE); - } -}; - -/// support query of key length that's the same as another class -template -class SameKeyLengthAs -{ -public: - enum {MIN_KEYLENGTH=T::MIN_KEYLENGTH, MAX_KEYLENGTH=T::MAX_KEYLENGTH, DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH}; - /// returns the smallest valid key length in bytes that is >= min(n, MAX_KEYLENGTH) - static uint32_t KeyLength(uint32_t keylength) - {return T::KeyLength(keylength);} -}; - -// ************** secure memory allocation *************** - -#ifdef SECALLOC_DEFAULT -#define SecAlloc(type, number) (new type[(number)]) -#define SecFree(ptr, number) (memset((ptr), 0, (number)*sizeof(*(ptr))), delete [] (ptr)) -#else -#define SecAlloc(type, number) (new type[(number)]) -#define SecFree(ptr, number) (delete [] (ptr)) -#endif - -//! a block of memory allocated using SecAlloc -template struct SecBlock -{ - explicit SecBlock(uint32_t size=0) - : size(size) {ptr = SecAlloc(T, size);} - SecBlock(const SecBlock &t) - : size(t.size) {ptr = SecAlloc(T, size); memcpy(ptr, t.ptr, size*sizeof(T));} - SecBlock(const T *t, uint32_t len) - : size(len) {ptr = SecAlloc(T, len); memcpy(ptr, t, len*sizeof(T));} - ~SecBlock() - {SecFree(ptr, size);} - -#if defined(__GNUC__) || defined(__BCPLUSPLUS__) - operator const void *() const - {return ptr;} - operator void *() - {return ptr;} -#endif -#if defined(__GNUC__) // reduce warnings - operator const void *() - {return ptr;} -#endif - - operator const T *() const - {return ptr;} - operator T *() - {return ptr;} -#if defined(__GNUC__) // reduce warnings - operator const T *() - {return ptr;} -#endif - -// CodeWarrior defines _MSC_VER -#if !defined(_MSC_VER) || defined(__MWERKS__) - T *operator +(uint32_t offset) - {return ptr+offset;} - const T *operator +(uint32_t offset) const - {return ptr+offset;} - T& operator[](uint32_t index) - {assert(index &t) - { - New(t.size); - memcpy(ptr, t.ptr, size*sizeof(T)); - } - - SecBlock& operator=(const SecBlock &t) - { - Assign(t); - return *this; - } - - bool operator==(const SecBlock &t) const - { - return size == t.size && memcmp(ptr, t.ptr, size*sizeof(T)) == 0; - } - - bool operator!=(const SecBlock &t) const - { - return !operator==(t); - } - - void New(uint32_t newSize) - { - if (newSize != size) - { - T *newPtr = SecAlloc(T, newSize); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void CleanNew(uint32_t newSize) - { - if (newSize != size) - { - T *newPtr = SecAlloc(T, newSize); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - memset(ptr, 0, size*sizeof(T)); - } - - void Grow(uint32_t newSize) - { - if (newSize > size) - { - T *newPtr = SecAlloc(T, newSize); - memcpy(newPtr, ptr, size*sizeof(T)); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void CleanGrow(uint32_t newSize) - { - if (newSize > size) - { - T *newPtr = SecAlloc(T, newSize); - memcpy(newPtr, ptr, size*sizeof(T)); - memset(newPtr+size, 0, (newSize-size)*sizeof(T)); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void Resize(uint32_t newSize) - { - if (newSize != size) - { - T *newPtr = SecAlloc(T, newSize); - memcpy(newPtr, ptr, STDMIN(newSize, size)*sizeof(T)); - SecFree(ptr, size); - ptr = newPtr; - size = newSize; - } - } - - void swap(SecBlock &b); - - uint32_t size; - T *ptr; -}; - -template void SecBlock::swap(SecBlock &b) -{ - std::swap(size, b.size); - std::swap(ptr, b.ptr); -} - -typedef SecBlock SecByteBlock; -typedef SecBlock SecWordBlock; - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template -inline void swap(CryptoPP::SecBlock &a, CryptoPP::SecBlock &b) -{ - a.swap(b); -} - -NAMESPACE_END - -#endif // MISC_H diff --git a/external/ours/library/crypto/src/shared/original-old/mqueue.cpp b/external/ours/library/crypto/src/shared/original-old/mqueue.cpp deleted file mode 100755 index 314d6f758..000000000 --- a/external/ours/library/crypto/src/shared/original-old/mqueue.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// mqueue.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "mqueue.h" - -NAMESPACE_BEGIN(CryptoPP) - -MessageQueue::MessageQueue(unsigned int nodeSize) - : m_queue(nodeSize), m_lengths(1, 0) -{ -} - -bool MessageQueue::RetrieveNextMessage() -{ - if (NumberOfMessages() > 0 && !AnyRetrievable()) - { - m_lengths.pop_front(); - return true; - } - else - return false; -} - -unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const -{ - ByteQueue::Walker walker(m_queue); - std::deque::const_iterator it = m_lengths.begin(); - unsigned int i; - for (i=0; i - -NAMESPACE_BEGIN(CryptoPP) - -//! Message Queue -class MessageQueue : public BufferedTransformationWithAutoSignal -{ -public: - MessageQueue(unsigned int nodeSize=256); - - void Put(byte inByte) - {m_queue.Put(inByte); m_lengths.back()++;} - void Put(const byte *inString, unsigned int length) - {m_queue.Put(inString, length); m_lengths.back()+=length;} - - unsigned long MaxRetrievable() const - {return m_lengths.front();} - bool AnyRetrievable() const - {return m_lengths.front() > 0;} - - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) - {return Got(m_queue.TransferTo(target, STDMIN(MaxRetrievable(), transferMax)));} - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const - {return m_queue.CopyTo(target, STDMIN(MaxRetrievable(), copyMax));} - - void MessageEnd(int=-1) - {m_lengths.push_back(0);} - - unsigned long TotalBytesRetrievable() const - {return m_queue.MaxRetrievable();} - unsigned int NumberOfMessages() const - {return m_lengths.size()-1;} - bool RetrieveNextMessage(); - - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const; - - void swap(MessageQueue &rhs); - -private: - unsigned long Got(unsigned long length) - {assert(m_lengths.front() >= length); m_lengths.front() -= length; return length;} - - ByteQueue m_queue; - std::deque m_lengths; -}; - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) -{ - a.swap(b); -} -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/queue.cpp b/external/ours/library/crypto/src/shared/original-old/queue.cpp deleted file mode 100755 index 590b8899d..000000000 --- a/external/ours/library/crypto/src/shared/original-old/queue.cpp +++ /dev/null @@ -1,500 +0,0 @@ -// queue.cpp - written and placed in the public domain by Wei Dai - -#include "FirstCrypto.h" -#include "queue.h" -#include "filters.h" - -NAMESPACE_BEGIN(CryptoPP) - -// this class for use by ByteQueue only -class ByteQueueNode -{ -public: - ByteQueueNode(unsigned int maxSize) - : buf(maxSize) - { - m_head = m_tail = 0; - next = 0; - } - - inline unsigned int MaxSize() const { return buf.size; } - - inline unsigned int CurrentSize() const - { - return m_tail - m_head; - } - - inline bool UsedUp() const - { - return (m_head == MaxSize()); - } - - inline void Clear() - { - m_head = m_tail = 0; - } - - inline unsigned int Put(byte inByte) - { - if (MaxSize() == m_tail) - return 0; - - buf[m_tail++] = inByte; - return 1; - } - - inline unsigned int Put(const byte *inString, unsigned int length) - { - unsigned int l = STDMIN(length, MaxSize() - m_tail); - memcpy(buf + m_tail, inString, l); - m_tail += l; - return l; - } - - inline unsigned int Peek(byte &outByte) const - { - if (m_tail == m_head) - return 0; - - outByte = buf[m_head]; - return 1; - } - - inline unsigned int Peek(byte *target, unsigned int copyMax) const - { - unsigned int len = STDMIN(copyMax, m_tail - m_head); - memcpy(target, buf + m_head, len); - return len; - } - - inline unsigned int CopyTo(BufferedTransformation &target) const - { - unsigned int len = m_tail - m_head; - target.Put(buf + m_head, len); - return len; - } - - inline unsigned int CopyTo(BufferedTransformation &target, unsigned int copyMax) const - { - unsigned int len = STDMIN(copyMax, m_tail - m_head); - target.Put(buf + m_head, len); - return len; - } - - inline unsigned int Get(byte &outByte) - { - unsigned int len = Peek(outByte); - m_head += len; - return len; - } - - inline unsigned int Get(byte *outString, unsigned int getMax) - { - unsigned int len = Peek(outString, getMax); - m_head += len; - return len; - } - - inline unsigned int TransferTo(BufferedTransformation &target) - { - unsigned int len = CopyTo(target); - m_head += len; - return len; - } - - inline unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax) - { - unsigned int len = CopyTo(target, transferMax); - m_head += len; - return len; - } - - inline unsigned int Skip(unsigned int skipMax) - { - unsigned int len = STDMIN(skipMax, m_tail - m_head); - m_head += len; - return len; - } - - inline byte operator[](unsigned int i) const - { - return buf[m_head + i]; - } - - ByteQueueNode *next; - - SecByteBlock buf; - unsigned int m_head, m_tail; -}; - -// ******************************************************** - -ByteQueue::ByteQueue(unsigned int m_nodeSize) - : m_nodeSize(0), m_lazyLength(0), m_lazyString(nullptr) -{ - m_head = m_tail = new ByteQueueNode(m_nodeSize); -} - -ByteQueue::ByteQueue(const ByteQueue ©) -{ - CopyFrom(copy); -} - -void ByteQueue::CopyFrom(const ByteQueue ©) -{ - m_lazyLength = 0; - m_nodeSize = copy.m_nodeSize; - m_head = m_tail = new ByteQueueNode(*copy.m_head); - - for (ByteQueueNode *current = copy.m_head->next; current; current = current->next) - { - m_tail->next = new ByteQueueNode(*current); - m_tail = m_tail->next; - } - - m_tail->next = nullptr; - - Put(copy.m_lazyString, copy.m_lazyLength); -} - -ByteQueue::~ByteQueue() -{ - Destroy(); -} - -void ByteQueue::Destroy() -{ - ByteQueueNode *next; - - for (ByteQueueNode *current = m_head; current; current = next) - { - next = current->next; - delete current; - } -} - -unsigned long ByteQueue::CurrentSize() const -{ - unsigned long size = 0; - - for (ByteQueueNode *current = m_head; current; current = current->next) - size += current->CurrentSize(); - - return size + m_lazyLength; -} - -bool ByteQueue::IsEmpty() const -{ - return m_head == m_tail && m_head->CurrentSize() == 0 && m_lazyLength == 0; -} - -void ByteQueue::Clear() -{ - Destroy(); - m_head = m_tail = new ByteQueueNode(m_nodeSize); - m_lazyLength = 0; -} - -void ByteQueue::Put(byte inByte) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - if (!m_tail->Put(inByte)) - { - m_tail->next = new ByteQueueNode(m_nodeSize); - m_tail = m_tail->next; - m_tail->Put(inByte); - } -} - -void ByteQueue::Put(const byte *inString, unsigned int length) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - unsigned int len; - while ((len = m_tail->Put(inString, length)) < length) - { - m_tail->next = new ByteQueueNode(m_nodeSize); - m_tail = m_tail->next; - inString += len; - length -= len; - } -} - -void ByteQueue::CleanupUsedNodes() -{ - while (m_head != m_tail && m_head->UsedUp()) - { - ByteQueueNode *temp = m_head; - m_head = m_head->next; - delete temp; - } - - if (m_head->CurrentSize() == 0) - m_head->Clear(); -} - -void ByteQueue::LazyPut(const byte *inString, unsigned int size) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - m_lazyString = inString; - m_lazyLength = size; -} - -void ByteQueue::FinalizeLazyPut() -{ - unsigned int len = m_lazyLength; - m_lazyLength = 0; - Put(m_lazyString, len); -} - -unsigned int ByteQueue::Get(byte &outByte) -{ - if (m_head->Get(outByte)) - { - if (m_head->UsedUp()) - CleanupUsedNodes(); - return 1; - } - else if (m_lazyLength > 0) - { - outByte = *m_lazyString++; - m_lazyLength--; - return 1; - } - else - return 0; -} - -unsigned int ByteQueue::Get(byte *outString, unsigned int getMax) -{ - ArraySink sink(outString, getMax); - return TransferTo(sink, getMax); -} - -unsigned int ByteQueue::Peek(byte &outByte) const -{ - if (m_head->Peek(outByte)) - return 1; - else if (m_lazyLength > 0) - { - outByte = *m_lazyString; - return 1; - } - else - return 0; -} - -unsigned int ByteQueue::Peek(byte *outString, unsigned int peekMax) const -{ - ArraySink sink(outString, peekMax); - return CopyTo(sink, peekMax); -} - -unsigned long ByteQueue::Skip(unsigned long skipMax) -{ - return TransferTo(g_bitBucket, skipMax); -} - -unsigned long ByteQueue::TransferTo(BufferedTransformation &target, unsigned long transferMax) -{ - unsigned long bytesLeft = transferMax; - for (ByteQueueNode *current = m_head; bytesLeft && current; current = current->next) - bytesLeft -= current->TransferTo(target, bytesLeft); - CleanupUsedNodes(); - - unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); - if (len) - { - target.Put(m_lazyString, len); - m_lazyString += len; - m_lazyLength -= len; - bytesLeft -= len; - } - return transferMax - bytesLeft; -} - -unsigned long ByteQueue::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - unsigned long bytesLeft = copyMax; - for (ByteQueueNode *current = m_head; bytesLeft && current; current = current->next) - bytesLeft -= current->CopyTo(target, bytesLeft); - if (bytesLeft && m_lazyLength) - { - unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); - target.Put(m_lazyString, len); - bytesLeft -= len; - } - return copyMax - bytesLeft; -} - -void ByteQueue::Unget(byte inByte) -{ - Unget(&inByte, 1); -} - -void ByteQueue::Unget(const byte *inString, unsigned int length) -{ - ByteQueueNode *newHead = new ByteQueueNode(length); - newHead->next = m_head; - m_head = newHead; - m_head->Put(inString, length); -} -/* -byte * ByteQueue::Spy(unsigned int &contiguousSize) -{ - contiguousSize = m_head->m_tail - m_head->m_head; - return m_head->buf + m_head->m_head; -} -*/ -const byte * ByteQueue::Spy(unsigned int &contiguousSize) const -{ - contiguousSize = m_head->m_tail - m_head->m_head; - if (contiguousSize == 0 && m_lazyLength > 0) - { - contiguousSize = m_lazyLength; - return m_lazyString; - } - else - return m_head->buf + m_head->m_head; -} - -byte * ByteQueue::MakeNewSpace(unsigned int &contiguousSize) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - if (m_tail->m_tail == m_tail->MaxSize()) - { - m_tail->next = new ByteQueueNode(m_nodeSize); - m_tail = m_tail->next; - } - - contiguousSize = m_tail->MaxSize() - m_tail->m_tail; - return m_tail->buf + m_tail->m_tail; -} - -void ByteQueue::OccupyNewSpace(unsigned int size) -{ - m_tail->m_tail += size; - assert(m_tail->m_tail <= m_tail->MaxSize()); -} - -ByteQueue & ByteQueue::operator=(const ByteQueue &rhs) -{ - Destroy(); - CopyFrom(rhs); - return *this; -} - -bool ByteQueue::operator==(const ByteQueue &rhs) const -{ - const unsigned long currentSize = CurrentSize(); - - if (currentSize != rhs.CurrentSize()) - return false; - - Walker walker1(*this), walker2(rhs); - byte b1, b2; - - while (walker1.Get(b1) && walker2.Get(b2)) - if (b1 != b2) - return false; - - return true; -} - -byte ByteQueue::operator[](unsigned long i) const -{ - for (ByteQueueNode *current = m_head; current; current = current->next) - { - if (i < current->CurrentSize()) - return (*current)[i]; - - i -= current->CurrentSize(); - } - - assert(i < m_lazyLength); - return m_lazyString[i]; -} - -void ByteQueue::swap(ByteQueue &rhs) -{ - std::swap(m_nodeSize, rhs.m_nodeSize); - std::swap(m_head, rhs.m_head); - std::swap(m_tail, rhs.m_tail); - std::swap(m_lazyString, rhs.m_lazyString); - std::swap(m_lazyLength, rhs.m_lazyLength); -} - -// ******************************************************** - -unsigned int ByteQueue::Walker::Get(byte &outByte) -{ - ArraySink sink(&outByte, 1); - return TransferTo(sink, 1); -} - -unsigned int ByteQueue::Walker::Get(byte *outString, unsigned int getMax) -{ - ArraySink sink(outString, getMax); - return TransferTo(sink, getMax); -} - -unsigned int ByteQueue::Walker::Peek(byte &outByte) const -{ - ArraySink sink(&outByte, 1); - return CopyTo(sink, 1); -} - -unsigned int ByteQueue::Walker::Peek(byte *outString, unsigned int peekMax) const -{ - ArraySink sink(outString, peekMax); - return CopyTo(sink, peekMax); -} - -unsigned long ByteQueue::Walker::TransferTo(BufferedTransformation &target, unsigned long transferMax) -{ - unsigned long bytesLeft = transferMax; - while (m_node) - { - unsigned int len = STDMIN(bytesLeft, (unsigned long)m_node->CurrentSize() - m_offset); - target.Put(m_node->buf + m_node->m_head + m_offset, len); - m_position += len; - bytesLeft -= len; - - if (!bytesLeft) - { - m_offset += len; - break; - } - - m_node = m_node->next; - m_offset = 0; - } - - unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); - if (len) - { - target.Put(m_lazyString, len); - m_lazyString += len; - m_lazyLength -= len; - bytesLeft -= len; - } - return transferMax - bytesLeft; -} - -unsigned long ByteQueue::Walker::Skip(unsigned long skipMax) -{ - return TransferTo(g_bitBucket, skipMax); -} - -unsigned long ByteQueue::Walker::CopyTo(BufferedTransformation &target, unsigned long copyMax) const -{ - return Walker(*this).TransferTo(target, copyMax); -} - -NAMESPACE_END \ No newline at end of file diff --git a/external/ours/library/crypto/src/shared/original-old/queue.h b/external/ours/library/crypto/src/shared/original-old/queue.h deleted file mode 100755 index 76cf58d7f..000000000 --- a/external/ours/library/crypto/src/shared/original-old/queue.h +++ /dev/null @@ -1,128 +0,0 @@ -// specification file for an unlimited queue for storing bytes - -#ifndef CRYPTOPP_QUEUE_H -#define CRYPTOPP_QUEUE_H - -#include "cryptlib.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -/** The queue is implemented as a linked list of arrays, but you don't need to - know about that. So just ignore this next line. :) */ -class ByteQueueNode; - -//! Byte Queue -class ByteQueue : public BufferedTransformation -{ -public: - ByteQueue(unsigned int m_nodeSize=256); - ByteQueue(const ByteQueue ©); - ~ByteQueue(); - - unsigned long MaxRetrievable() const - {return CurrentSize();} - bool AnyRetrievable() const - {return !IsEmpty();} - - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - - unsigned int Get(byte &outByte); - unsigned int Get(byte *outString, unsigned int getMax); - - unsigned int Peek(byte &outByte) const; - unsigned int Peek(byte *outString, unsigned int peekMax) const; - - unsigned long Skip(unsigned long skipMax=ULONG_MAX); - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - - // these member functions are not inherited - unsigned long CurrentSize() const; - bool IsEmpty() const; - - void Clear(); - - void Unget(byte inByte); - void Unget(const byte *inString, unsigned int length); - - const byte * Spy(unsigned int &contiguousSize) const; - - byte * MakeNewSpace(unsigned int &contiguousSize); - void OccupyNewSpace(unsigned int size); - - void LazyPut(const byte *inString, unsigned int size); - void FinalizeLazyPut(); - - ByteQueue & operator=(const ByteQueue &rhs); - bool operator==(const ByteQueue &rhs) const; - byte operator[](unsigned long i) const; - void swap(ByteQueue &rhs); - - class Walker : public BufferedTransformation - { - public: - Walker(const ByteQueue &queue) - : m_queue(queue), m_node(queue.m_head), m_position(0), m_offset(0) - , m_lazyString(queue.m_lazyString), m_lazyLength(queue.m_lazyLength) {} - - unsigned long MaxRetrievable() const - {return m_queue.CurrentSize() - m_position;} - - void Put(byte inByte) {} - void Put(const byte *inString, unsigned int length) {} - - unsigned int Get(byte &outByte); - unsigned int Get(byte *outString, unsigned int getMax); - - unsigned int Peek(byte &outByte) const; - unsigned int Peek(byte *outString, unsigned int peekMax) const; - - unsigned long Skip(unsigned long skipMax=ULONG_MAX); - unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX); - unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const; - - private: - const ByteQueue &m_queue; - const ByteQueueNode *m_node; - unsigned int m_position, m_offset; - const byte *m_lazyString; - unsigned int m_lazyLength; - }; - - friend class Walker; - -private: - void CleanupUsedNodes(); - void CopyFrom(const ByteQueue ©); - void Destroy(); - - unsigned int m_nodeSize; - ByteQueueNode *m_head, *m_tail; - const byte *m_lazyString; - unsigned int m_lazyLength; -}; - -//! use this to make sure LazyPut is finalized in event of exception -class LazyPutter -{ -public: - LazyPutter(ByteQueue &bq, const byte *inString, unsigned int size) - : m_bq(bq) {bq.LazyPut(inString, size);} - ~LazyPutter() - {try {m_bq.FinalizeLazyPut();} catch(...) {}} -private: - ByteQueue &m_bq; -}; - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) -{ - a.swap(b); -} -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/smartptr.h b/external/ours/library/crypto/src/shared/original-old/smartptr.h deleted file mode 100755 index f5c0b41bd..000000000 --- a/external/ours/library/crypto/src/shared/original-old/smartptr.h +++ /dev/null @@ -1,195 +0,0 @@ -#ifndef CRYPTOPP_SMARTPTR_H -#define CRYPTOPP_SMARTPTR_H - -#include "config.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -template class member_ptr -{ -public: - explicit member_ptr(T *p = nullptr) : m_p(p) {} - - ~member_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return m_p; } - - const T* get() const { return m_p; } - T* get() { return m_p; } - - T* release() - { - T *old_p = m_p; - m_p = 0; - return old_p; - } - - void reset(T *p = 0); - -protected: - member_ptr(const member_ptr& rhs); // copy not allowed - void operator=(const member_ptr& rhs); // assignment not allowed - - T *m_p; -}; - -template member_ptr::~member_ptr() {delete m_p;} -template void member_ptr::reset(T *p) {delete m_p; m_p = p;} - -// ******************************************************** - -template class value_ptr : public member_ptr -{ -public: - value_ptr(const T &obj) : member_ptr(new T(obj)) {} - value_ptr(T *p = nullptr) : member_ptr(p) {} - value_ptr(const value_ptr& rhs) - : member_ptr(rhs.m_p ? new T(*rhs.m_p) : nullptr) {} - - value_ptr& operator=(const value_ptr& rhs); - bool operator==(const value_ptr& rhs) - { - return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); - } -}; - -template value_ptr& value_ptr::operator=(const value_ptr& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? new T(*rhs.m_p) : nullptr; - delete old_p; - return *this; -} - -// ******************************************************** - -template class clonable_ptr : public member_ptr -{ -public: - clonable_ptr(const T &obj) : member_ptr(obj.Clone()) {} - clonable_ptr(T *p = nullptr) : member_ptr(p) {} - clonable_ptr(const clonable_ptr& rhs) - : member_ptr(rhs.m_p ? rhs.m_p->Clone() : nullptr) {} - - clonable_ptr& operator=(const clonable_ptr& rhs); -}; - -template clonable_ptr& clonable_ptr::operator=(const clonable_ptr& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? rhs.m_p->Clone() : nullptr; - delete old_p; - return *this; -} - -// ******************************************************** - -template class counted_ptr -{ -public: - explicit counted_ptr(T *p = 0); - counted_ptr(const counted_ptr& rhs); - - ~counted_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return m_p; } - - const T* get() const { return m_p; } - T* get() { return m_p; } - - counted_ptr & operator=(const counted_ptr& rhs); - -private: - T *m_p; -}; - -template counted_ptr::counted_ptr(T *p) - : m_p(p) -{ - if (m_p) - m_p->m_referenceCount = 1; -} - -template counted_ptr::counted_ptr(const counted_ptr& rhs) - : m_p(rhs.m_p) -{ - if (m_p) - m_p->m_referenceCount++; -} - -template counted_ptr::~counted_ptr() -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; -} - -template counted_ptr & counted_ptr::operator=(const counted_ptr& rhs) -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; - m_p = rhs.m_p; - if (m_p) - m_p->m_referenceCount++; - return *this; -} - -// ******************************************************** - -template class vector_member_ptrs -{ -public: - vector_member_ptrs(unsigned int size=0) - : _size(size) {ptr = new member_ptr[_size];} - ~vector_member_ptrs() - {delete [] ptr;} - - member_ptr& operator[](unsigned int index) - {assert(index<_size); return ptr[index];} - const member_ptr& operator[](unsigned int index) const - {assert(index<_size); return ptr[index];} - - unsigned int size() const {return _size;} - void resize(unsigned int newSize) - { - member_ptr *newPtr = new member_ptr[newSize]; - for (unsigned int i=0; i &c); // copy not allowed - void operator=(const vector_member_ptrs &x); // assignment not allowed - - unsigned int _size; - member_ptr *ptr; -}; - -// ******************************************************** - -// derive from this class for a temporary variable -// that can be used during base/member initialization -template -class ConstructorTemp -{ -protected: - ConstructorTemp(const ConstructorTemp ©) : m_temp(nullptr) {} - ConstructorTemp(T *t = nullptr) : m_temp(t) {} - ConstructorTemp(const T &t) : m_temp(new T(t)) {} - member_ptr m_temp; -}; - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/tftables.cpp b/external/ours/library/crypto/src/shared/original-old/tftables.cpp deleted file mode 100755 index 22fde97c5..000000000 --- a/external/ours/library/crypto/src/shared/original-old/tftables.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// Twofish tables - -#include "FirstCrypto.h" -#include "twofish.h" - -NAMESPACE_BEGIN(CryptoPP) - -const byte Twofish::q[2][256] = { - 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, - 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, - 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, - 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, - 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, - 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, - 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, - 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, - 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, - 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, - 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, - 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, - 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, - 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, - 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, - 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, - 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, - 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, - 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, - 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, - 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, - 0x4A, 0x5E, 0xC1, 0xE0, - - 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, - 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, - 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, - 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, - 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, - 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, - 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, - 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, - 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, - 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, - 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, - 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, - 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, - 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, - 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, - 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, - 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, - 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, - 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, - 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, - 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, - 0x55, 0x09, 0xBE, 0x91 -}; - -const word32 Twofish::mds[4][256] = { - 0xbcbc3275, 0xecec21f3, 0x202043c6, 0xb3b3c9f4, - 0xdada03db, 0x02028b7b, 0xe2e22bfb, 0x9e9efac8, - 0xc9c9ec4a, 0xd4d409d3, 0x18186be6, 0x1e1e9f6b, - 0x98980e45, 0xb2b2387d, 0xa6a6d2e8, 0x2626b74b, - 0x3c3c57d6, 0x93938a32, 0x8282eed8, 0x525298fd, - 0x7b7bd437, 0xbbbb3771, 0x5b5b97f1, 0x474783e1, - 0x24243c30, 0x5151e20f, 0xbabac6f8, 0x4a4af31b, - 0xbfbf4887, 0x0d0d70fa, 0xb0b0b306, 0x7575de3f, - 0xd2d2fd5e, 0x7d7d20ba, 0x666631ae, 0x3a3aa35b, - 0x59591c8a, 0x00000000, 0xcdcd93bc, 0x1a1ae09d, - 0xaeae2c6d, 0x7f7fabc1, 0x2b2bc7b1, 0xbebeb90e, - 0xe0e0a080, 0x8a8a105d, 0x3b3b52d2, 0x6464bad5, - 0xd8d888a0, 0xe7e7a584, 0x5f5fe807, 0x1b1b1114, - 0x2c2cc2b5, 0xfcfcb490, 0x3131272c, 0x808065a3, - 0x73732ab2, 0x0c0c8173, 0x79795f4c, 0x6b6b4154, - 0x4b4b0292, 0x53536974, 0x94948f36, 0x83831f51, - 0x2a2a3638, 0xc4c49cb0, 0x2222c8bd, 0xd5d5f85a, - 0xbdbdc3fc, 0x48487860, 0xffffce62, 0x4c4c0796, - 0x4141776c, 0xc7c7e642, 0xebeb24f7, 0x1c1c1410, - 0x5d5d637c, 0x36362228, 0x6767c027, 0xe9e9af8c, - 0x4444f913, 0x1414ea95, 0xf5f5bb9c, 0xcfcf18c7, - 0x3f3f2d24, 0xc0c0e346, 0x7272db3b, 0x54546c70, - 0x29294cca, 0xf0f035e3, 0x0808fe85, 0xc6c617cb, - 0xf3f34f11, 0x8c8ce4d0, 0xa4a45993, 0xcaca96b8, - 0x68683ba6, 0xb8b84d83, 0x38382820, 0xe5e52eff, - 0xadad569f, 0x0b0b8477, 0xc8c81dc3, 0x9999ffcc, - 0x5858ed03, 0x19199a6f, 0x0e0e0a08, 0x95957ebf, - 0x70705040, 0xf7f730e7, 0x6e6ecf2b, 0x1f1f6ee2, - 0xb5b53d79, 0x09090f0c, 0x616134aa, 0x57571682, - 0x9f9f0b41, 0x9d9d803a, 0x111164ea, 0x2525cdb9, - 0xafafdde4, 0x4545089a, 0xdfdf8da4, 0xa3a35c97, - 0xeaead57e, 0x353558da, 0xededd07a, 0x4343fc17, - 0xf8f8cb66, 0xfbfbb194, 0x3737d3a1, 0xfafa401d, - 0xc2c2683d, 0xb4b4ccf0, 0x32325dde, 0x9c9c71b3, - 0x5656e70b, 0xe3e3da72, 0x878760a7, 0x15151b1c, - 0xf9f93aef, 0x6363bfd1, 0x3434a953, 0x9a9a853e, - 0xb1b1428f, 0x7c7cd133, 0x88889b26, 0x3d3da65f, - 0xa1a1d7ec, 0xe4e4df76, 0x8181942a, 0x91910149, - 0x0f0ffb81, 0xeeeeaa88, 0x161661ee, 0xd7d77321, - 0x9797f5c4, 0xa5a5a81a, 0xfefe3feb, 0x6d6db5d9, - 0x7878aec5, 0xc5c56d39, 0x1d1de599, 0x7676a4cd, - 0x3e3edcad, 0xcbcb6731, 0xb6b6478b, 0xefef5b01, - 0x12121e18, 0x6060c523, 0x6a6ab0dd, 0x4d4df61f, - 0xcecee94e, 0xdede7c2d, 0x55559df9, 0x7e7e5a48, - 0x2121b24f, 0x03037af2, 0xa0a02665, 0x5e5e198e, - 0x5a5a6678, 0x65654b5c, 0x62624e58, 0xfdfd4519, - 0x0606f48d, 0x404086e5, 0xf2f2be98, 0x3333ac57, - 0x17179067, 0x05058e7f, 0xe8e85e05, 0x4f4f7d64, - 0x89896aaf, 0x10109563, 0x74742fb6, 0x0a0a75fe, - 0x5c5c92f5, 0x9b9b74b7, 0x2d2d333c, 0x3030d6a5, - 0x2e2e49ce, 0x494989e9, 0x46467268, 0x77775544, - 0xa8a8d8e0, 0x9696044d, 0x2828bd43, 0xa9a92969, - 0xd9d97929, 0x8686912e, 0xd1d187ac, 0xf4f44a15, - 0x8d8d1559, 0xd6d682a8, 0xb9b9bc0a, 0x42420d9e, - 0xf6f6c16e, 0x2f2fb847, 0xdddd06df, 0x23233934, - 0xcccc6235, 0xf1f1c46a, 0xc1c112cf, 0x8585ebdc, - 0x8f8f9e22, 0x7171a1c9, 0x9090f0c0, 0xaaaa539b, - 0x0101f189, 0x8b8be1d4, 0x4e4e8ced, 0x8e8e6fab, - 0xababa212, 0x6f6f3ea2, 0xe6e6540d, 0xdbdbf252, - 0x92927bbb, 0xb7b7b602, 0x6969ca2f, 0x3939d9a9, - 0xd3d30cd7, 0xa7a72361, 0xa2a2ad1e, 0xc3c399b4, - 0x6c6c4450, 0x07070504, 0x04047ff6, 0x272746c2, - 0xacaca716, 0xd0d07625, 0x50501386, 0xdcdcf756, - 0x84841a55, 0xe1e15109, 0x7a7a25be, 0x1313ef91, - - 0xa9d93939, 0x67901717, 0xb3719c9c, 0xe8d2a6a6, - 0x04050707, 0xfd985252, 0xa3658080, 0x76dfe4e4, - 0x9a084545, 0x92024b4b, 0x80a0e0e0, 0x78665a5a, - 0xe4ddafaf, 0xddb06a6a, 0xd1bf6363, 0x38362a2a, - 0x0d54e6e6, 0xc6432020, 0x3562cccc, 0x98bef2f2, - 0x181e1212, 0xf724ebeb, 0xecd7a1a1, 0x6c774141, - 0x43bd2828, 0x7532bcbc, 0x37d47b7b, 0x269b8888, - 0xfa700d0d, 0x13f94444, 0x94b1fbfb, 0x485a7e7e, - 0xf27a0303, 0xd0e48c8c, 0x8b47b6b6, 0x303c2424, - 0x84a5e7e7, 0x54416b6b, 0xdf06dddd, 0x23c56060, - 0x1945fdfd, 0x5ba33a3a, 0x3d68c2c2, 0x59158d8d, - 0xf321ecec, 0xae316666, 0xa23e6f6f, 0x82165757, - 0x63951010, 0x015befef, 0x834db8b8, 0x2e918686, - 0xd9b56d6d, 0x511f8383, 0x9b53aaaa, 0x7c635d5d, - 0xa63b6868, 0xeb3ffefe, 0xa5d63030, 0xbe257a7a, - 0x16a7acac, 0x0c0f0909, 0xe335f0f0, 0x6123a7a7, - 0xc0f09090, 0x8cafe9e9, 0x3a809d9d, 0xf5925c5c, - 0x73810c0c, 0x2c273131, 0x2576d0d0, 0x0be75656, - 0xbb7b9292, 0x4ee9cece, 0x89f10101, 0x6b9f1e1e, - 0x53a93434, 0x6ac4f1f1, 0xb499c3c3, 0xf1975b5b, - 0xe1834747, 0xe66b1818, 0xbdc82222, 0x450e9898, - 0xe26e1f1f, 0xf4c9b3b3, 0xb62f7474, 0x66cbf8f8, - 0xccff9999, 0x95ea1414, 0x03ed5858, 0x56f7dcdc, - 0xd4e18b8b, 0x1c1b1515, 0x1eada2a2, 0xd70cd3d3, - 0xfb2be2e2, 0xc31dc8c8, 0x8e195e5e, 0xb5c22c2c, - 0xe9894949, 0xcf12c1c1, 0xbf7e9595, 0xba207d7d, - 0xea641111, 0x77840b0b, 0x396dc5c5, 0xaf6a8989, - 0x33d17c7c, 0xc9a17171, 0x62ceffff, 0x7137bbbb, - 0x81fb0f0f, 0x793db5b5, 0x0951e1e1, 0xaddc3e3e, - 0x242d3f3f, 0xcda47676, 0xf99d5555, 0xd8ee8282, - 0xe5864040, 0xc5ae7878, 0xb9cd2525, 0x4d049696, - 0x44557777, 0x080a0e0e, 0x86135050, 0xe730f7f7, - 0xa1d33737, 0x1d40fafa, 0xaa346161, 0xed8c4e4e, - 0x06b3b0b0, 0x706c5454, 0xb22a7373, 0xd2523b3b, - 0x410b9f9f, 0x7b8b0202, 0xa088d8d8, 0x114ff3f3, - 0x3167cbcb, 0xc2462727, 0x27c06767, 0x90b4fcfc, - 0x20283838, 0xf67f0404, 0x60784848, 0xff2ee5e5, - 0x96074c4c, 0x5c4b6565, 0xb1c72b2b, 0xab6f8e8e, - 0x9e0d4242, 0x9cbbf5f5, 0x52f2dbdb, 0x1bf34a4a, - 0x5fa63d3d, 0x9359a4a4, 0x0abcb9b9, 0xef3af9f9, - 0x91ef1313, 0x85fe0808, 0x49019191, 0xee611616, - 0x2d7cdede, 0x4fb22121, 0x8f42b1b1, 0x3bdb7272, - 0x47b82f2f, 0x8748bfbf, 0x6d2caeae, 0x46e3c0c0, - 0xd6573c3c, 0x3e859a9a, 0x6929a9a9, 0x647d4f4f, - 0x2a948181, 0xce492e2e, 0xcb17c6c6, 0x2fca6969, - 0xfcc3bdbd, 0x975ca3a3, 0x055ee8e8, 0x7ad0eded, - 0xac87d1d1, 0x7f8e0505, 0xd5ba6464, 0x1aa8a5a5, - 0x4bb72626, 0x0eb9bebe, 0xa7608787, 0x5af8d5d5, - 0x28223636, 0x14111b1b, 0x3fde7575, 0x2979d9d9, - 0x88aaeeee, 0x3c332d2d, 0x4c5f7979, 0x02b6b7b7, - 0xb896caca, 0xda583535, 0xb09cc4c4, 0x17fc4343, - 0x551a8484, 0x1ff64d4d, 0x8a1c5959, 0x7d38b2b2, - 0x57ac3333, 0xc718cfcf, 0x8df40606, 0x74695353, - 0xb7749b9b, 0xc4f59797, 0x9f56adad, 0x72dae3e3, - 0x7ed5eaea, 0x154af4f4, 0x229e8f8f, 0x12a2abab, - 0x584e6262, 0x07e85f5f, 0x99e51d1d, 0x34392323, - 0x6ec1f6f6, 0x50446c6c, 0xde5d3232, 0x68724646, - 0x6526a0a0, 0xbc93cdcd, 0xdb03dada, 0xf8c6baba, - 0xc8fa9e9e, 0xa882d6d6, 0x2bcf6e6e, 0x40507070, - 0xdceb8585, 0xfe750a0a, 0x328a9393, 0xa48ddfdf, - 0xca4c2929, 0x10141c1c, 0x2173d7d7, 0xf0ccb4b4, - 0xd309d4d4, 0x5d108a8a, 0x0fe25151, 0x00000000, - 0x6f9a1919, 0x9de01a1a, 0x368f9494, 0x42e6c7c7, - 0x4aecc9c9, 0x5efdd2d2, 0xc1ab7f7f, 0xe0d8a8a8, - - 0xbc75bc32, 0xecf3ec21, 0x20c62043, 0xb3f4b3c9, - 0xdadbda03, 0x027b028b, 0xe2fbe22b, 0x9ec89efa, - 0xc94ac9ec, 0xd4d3d409, 0x18e6186b, 0x1e6b1e9f, - 0x9845980e, 0xb27db238, 0xa6e8a6d2, 0x264b26b7, - 0x3cd63c57, 0x9332938a, 0x82d882ee, 0x52fd5298, - 0x7b377bd4, 0xbb71bb37, 0x5bf15b97, 0x47e14783, - 0x2430243c, 0x510f51e2, 0xbaf8bac6, 0x4a1b4af3, - 0xbf87bf48, 0x0dfa0d70, 0xb006b0b3, 0x753f75de, - 0xd25ed2fd, 0x7dba7d20, 0x66ae6631, 0x3a5b3aa3, - 0x598a591c, 0x00000000, 0xcdbccd93, 0x1a9d1ae0, - 0xae6dae2c, 0x7fc17fab, 0x2bb12bc7, 0xbe0ebeb9, - 0xe080e0a0, 0x8a5d8a10, 0x3bd23b52, 0x64d564ba, - 0xd8a0d888, 0xe784e7a5, 0x5f075fe8, 0x1b141b11, - 0x2cb52cc2, 0xfc90fcb4, 0x312c3127, 0x80a38065, - 0x73b2732a, 0x0c730c81, 0x794c795f, 0x6b546b41, - 0x4b924b02, 0x53745369, 0x9436948f, 0x8351831f, - 0x2a382a36, 0xc4b0c49c, 0x22bd22c8, 0xd55ad5f8, - 0xbdfcbdc3, 0x48604878, 0xff62ffce, 0x4c964c07, - 0x416c4177, 0xc742c7e6, 0xebf7eb24, 0x1c101c14, - 0x5d7c5d63, 0x36283622, 0x672767c0, 0xe98ce9af, - 0x441344f9, 0x149514ea, 0xf59cf5bb, 0xcfc7cf18, - 0x3f243f2d, 0xc046c0e3, 0x723b72db, 0x5470546c, - 0x29ca294c, 0xf0e3f035, 0x088508fe, 0xc6cbc617, - 0xf311f34f, 0x8cd08ce4, 0xa493a459, 0xcab8ca96, - 0x68a6683b, 0xb883b84d, 0x38203828, 0xe5ffe52e, - 0xad9fad56, 0x0b770b84, 0xc8c3c81d, 0x99cc99ff, - 0x580358ed, 0x196f199a, 0x0e080e0a, 0x95bf957e, - 0x70407050, 0xf7e7f730, 0x6e2b6ecf, 0x1fe21f6e, - 0xb579b53d, 0x090c090f, 0x61aa6134, 0x57825716, - 0x9f419f0b, 0x9d3a9d80, 0x11ea1164, 0x25b925cd, - 0xafe4afdd, 0x459a4508, 0xdfa4df8d, 0xa397a35c, - 0xea7eead5, 0x35da3558, 0xed7aedd0, 0x431743fc, - 0xf866f8cb, 0xfb94fbb1, 0x37a137d3, 0xfa1dfa40, - 0xc23dc268, 0xb4f0b4cc, 0x32de325d, 0x9cb39c71, - 0x560b56e7, 0xe372e3da, 0x87a78760, 0x151c151b, - 0xf9eff93a, 0x63d163bf, 0x345334a9, 0x9a3e9a85, - 0xb18fb142, 0x7c337cd1, 0x8826889b, 0x3d5f3da6, - 0xa1eca1d7, 0xe476e4df, 0x812a8194, 0x91499101, - 0x0f810ffb, 0xee88eeaa, 0x16ee1661, 0xd721d773, - 0x97c497f5, 0xa51aa5a8, 0xfeebfe3f, 0x6dd96db5, - 0x78c578ae, 0xc539c56d, 0x1d991de5, 0x76cd76a4, - 0x3ead3edc, 0xcb31cb67, 0xb68bb647, 0xef01ef5b, - 0x1218121e, 0x602360c5, 0x6add6ab0, 0x4d1f4df6, - 0xce4ecee9, 0xde2dde7c, 0x55f9559d, 0x7e487e5a, - 0x214f21b2, 0x03f2037a, 0xa065a026, 0x5e8e5e19, - 0x5a785a66, 0x655c654b, 0x6258624e, 0xfd19fd45, - 0x068d06f4, 0x40e54086, 0xf298f2be, 0x335733ac, - 0x17671790, 0x057f058e, 0xe805e85e, 0x4f644f7d, - 0x89af896a, 0x10631095, 0x74b6742f, 0x0afe0a75, - 0x5cf55c92, 0x9bb79b74, 0x2d3c2d33, 0x30a530d6, - 0x2ece2e49, 0x49e94989, 0x46684672, 0x77447755, - 0xa8e0a8d8, 0x964d9604, 0x284328bd, 0xa969a929, - 0xd929d979, 0x862e8691, 0xd1acd187, 0xf415f44a, - 0x8d598d15, 0xd6a8d682, 0xb90ab9bc, 0x429e420d, - 0xf66ef6c1, 0x2f472fb8, 0xdddfdd06, 0x23342339, - 0xcc35cc62, 0xf16af1c4, 0xc1cfc112, 0x85dc85eb, - 0x8f228f9e, 0x71c971a1, 0x90c090f0, 0xaa9baa53, - 0x018901f1, 0x8bd48be1, 0x4eed4e8c, 0x8eab8e6f, - 0xab12aba2, 0x6fa26f3e, 0xe60de654, 0xdb52dbf2, - 0x92bb927b, 0xb702b7b6, 0x692f69ca, 0x39a939d9, - 0xd3d7d30c, 0xa761a723, 0xa21ea2ad, 0xc3b4c399, - 0x6c506c44, 0x07040705, 0x04f6047f, 0x27c22746, - 0xac16aca7, 0xd025d076, 0x50865013, 0xdc56dcf7, - 0x8455841a, 0xe109e151, 0x7abe7a25, 0x139113ef, - - 0xd939a9d9, 0x90176790, 0x719cb371, 0xd2a6e8d2, - 0x05070405, 0x9852fd98, 0x6580a365, 0xdfe476df, - 0x08459a08, 0x024b9202, 0xa0e080a0, 0x665a7866, - 0xddafe4dd, 0xb06addb0, 0xbf63d1bf, 0x362a3836, - 0x54e60d54, 0x4320c643, 0x62cc3562, 0xbef298be, - 0x1e12181e, 0x24ebf724, 0xd7a1ecd7, 0x77416c77, - 0xbd2843bd, 0x32bc7532, 0xd47b37d4, 0x9b88269b, - 0x700dfa70, 0xf94413f9, 0xb1fb94b1, 0x5a7e485a, - 0x7a03f27a, 0xe48cd0e4, 0x47b68b47, 0x3c24303c, - 0xa5e784a5, 0x416b5441, 0x06dddf06, 0xc56023c5, - 0x45fd1945, 0xa33a5ba3, 0x68c23d68, 0x158d5915, - 0x21ecf321, 0x3166ae31, 0x3e6fa23e, 0x16578216, - 0x95106395, 0x5bef015b, 0x4db8834d, 0x91862e91, - 0xb56dd9b5, 0x1f83511f, 0x53aa9b53, 0x635d7c63, - 0x3b68a63b, 0x3ffeeb3f, 0xd630a5d6, 0x257abe25, - 0xa7ac16a7, 0x0f090c0f, 0x35f0e335, 0x23a76123, - 0xf090c0f0, 0xafe98caf, 0x809d3a80, 0x925cf592, - 0x810c7381, 0x27312c27, 0x76d02576, 0xe7560be7, - 0x7b92bb7b, 0xe9ce4ee9, 0xf10189f1, 0x9f1e6b9f, - 0xa93453a9, 0xc4f16ac4, 0x99c3b499, 0x975bf197, - 0x8347e183, 0x6b18e66b, 0xc822bdc8, 0x0e98450e, - 0x6e1fe26e, 0xc9b3f4c9, 0x2f74b62f, 0xcbf866cb, - 0xff99ccff, 0xea1495ea, 0xed5803ed, 0xf7dc56f7, - 0xe18bd4e1, 0x1b151c1b, 0xada21ead, 0x0cd3d70c, - 0x2be2fb2b, 0x1dc8c31d, 0x195e8e19, 0xc22cb5c2, - 0x8949e989, 0x12c1cf12, 0x7e95bf7e, 0x207dba20, - 0x6411ea64, 0x840b7784, 0x6dc5396d, 0x6a89af6a, - 0xd17c33d1, 0xa171c9a1, 0xceff62ce, 0x37bb7137, - 0xfb0f81fb, 0x3db5793d, 0x51e10951, 0xdc3eaddc, - 0x2d3f242d, 0xa476cda4, 0x9d55f99d, 0xee82d8ee, - 0x8640e586, 0xae78c5ae, 0xcd25b9cd, 0x04964d04, - 0x55774455, 0x0a0e080a, 0x13508613, 0x30f7e730, - 0xd337a1d3, 0x40fa1d40, 0x3461aa34, 0x8c4eed8c, - 0xb3b006b3, 0x6c54706c, 0x2a73b22a, 0x523bd252, - 0x0b9f410b, 0x8b027b8b, 0x88d8a088, 0x4ff3114f, - 0x67cb3167, 0x4627c246, 0xc06727c0, 0xb4fc90b4, - 0x28382028, 0x7f04f67f, 0x78486078, 0x2ee5ff2e, - 0x074c9607, 0x4b655c4b, 0xc72bb1c7, 0x6f8eab6f, - 0x0d429e0d, 0xbbf59cbb, 0xf2db52f2, 0xf34a1bf3, - 0xa63d5fa6, 0x59a49359, 0xbcb90abc, 0x3af9ef3a, - 0xef1391ef, 0xfe0885fe, 0x01914901, 0x6116ee61, - 0x7cde2d7c, 0xb2214fb2, 0x42b18f42, 0xdb723bdb, - 0xb82f47b8, 0x48bf8748, 0x2cae6d2c, 0xe3c046e3, - 0x573cd657, 0x859a3e85, 0x29a96929, 0x7d4f647d, - 0x94812a94, 0x492ece49, 0x17c6cb17, 0xca692fca, - 0xc3bdfcc3, 0x5ca3975c, 0x5ee8055e, 0xd0ed7ad0, - 0x87d1ac87, 0x8e057f8e, 0xba64d5ba, 0xa8a51aa8, - 0xb7264bb7, 0xb9be0eb9, 0x6087a760, 0xf8d55af8, - 0x22362822, 0x111b1411, 0xde753fde, 0x79d92979, - 0xaaee88aa, 0x332d3c33, 0x5f794c5f, 0xb6b702b6, - 0x96cab896, 0x5835da58, 0x9cc4b09c, 0xfc4317fc, - 0x1a84551a, 0xf64d1ff6, 0x1c598a1c, 0x38b27d38, - 0xac3357ac, 0x18cfc718, 0xf4068df4, 0x69537469, - 0x749bb774, 0xf597c4f5, 0x56ad9f56, 0xdae372da, - 0xd5ea7ed5, 0x4af4154a, 0x9e8f229e, 0xa2ab12a2, - 0x4e62584e, 0xe85f07e8, 0xe51d99e5, 0x39233439, - 0xc1f66ec1, 0x446c5044, 0x5d32de5d, 0x72466872, - 0x26a06526, 0x93cdbc93, 0x03dadb03, 0xc6baf8c6, - 0xfa9ec8fa, 0x82d6a882, 0xcf6e2bcf, 0x50704050, - 0xeb85dceb, 0x750afe75, 0x8a93328a, 0x8ddfa48d, - 0x4c29ca4c, 0x141c1014, 0x73d72173, 0xccb4f0cc, - 0x09d4d309, 0x108a5d10, 0xe2510fe2, 0x00000000, - 0x9a196f9a, 0xe01a9de0, 0x8f94368f, 0xe6c742e6, - 0xecc94aec, 0xfdd25efd, 0xab7fc1ab, 0xd8a8e0d8}; - -NAMESPACE_END diff --git a/external/ours/library/crypto/src/shared/original-old/twofish.cpp b/external/ours/library/crypto/src/shared/original-old/twofish.cpp deleted file mode 100755 index 55ba2c493..000000000 --- a/external/ours/library/crypto/src/shared/original-old/twofish.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// twofish.cpp - modified by Wei Dai from Matthew Skala's twofish.c -// The original code and all modifications are in the public domain. - -#include "FirstCrypto.h" -#include "twofish.h" - -NAMESPACE_BEGIN(CryptoPP) - -// compute (c * x^4) mod (x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1) -// over GF(256) -static inline unsigned int Mod(unsigned int c) -{ - static const unsigned int modulus = 0x14d; - unsigned int c2 = (c<<1) ^ ((c & 0x80) ? modulus : 0); - unsigned int c1 = c2 ^ (c>>1) ^ ((c & 1) ? (modulus>>1) : 0); - return c | (c1 << 8) | (c2 << 16) | (c1 << 24); -} - -// compute RS(12,8) code with the above polynomial as generator -// this is equivalent to multiplying by the RS matrix -static word32 ReedSolomon(word32 high, word32 low) -{ - for (unsigned int i=0; i<8; i++) - { - high = Mod(high>>24) ^ (high<<8) ^ (low>>24); - low <<= 8; - } - return high; -} - -inline word32 Twofish::h0(word32 x, const word32 *key, unsigned int kLen) -{ - x = x | (x<<8) | (x<<16) | (x<<24); - switch(kLen) - { -#define Q(a, b, c, d, t) q[a][GETBYTE(t,0)] ^ (q[b][GETBYTE(t,1)] << 8) ^ (q[c][GETBYTE(t,2)] << 16) ^ (q[d][GETBYTE(t,3)] << 24) - case 4: x = Q(1, 0, 0, 1, x) ^ key[6]; - case 3: x = Q(1, 1, 0, 0, x) ^ key[4]; - case 2: x = Q(0, 1, 0, 1, x) ^ key[2]; - x = Q(0, 0, 1, 1, x) ^ key[0]; - } - return x; -} - -inline word32 Twofish::h(word32 x, const word32 *key, unsigned int kLen) -{ - x = h0(x, key, kLen); - return mds[0][GETBYTE(x,0)] ^ mds[1][GETBYTE(x,1)] ^ mds[2][GETBYTE(x,2)] ^ mds[3][GETBYTE(x,3)]; -} - -Twofish::Twofish(const byte *userKey, unsigned int keylength) - : m_k(40), m_s(4) -{ - assert(keylength == KeyLength(keylength)); - - unsigned int len = (keylength <= 16 ? 2 : (keylength <= 24 ? 3 : 4)); - SecBlock key(len*2); - GetUserKeyLittleEndian(key.ptr, len*2, userKey, keylength); - - unsigned int i; - for (i=0; i<40; i+=2) - { - word32 a = h(i, key, len); - word32 b = rotlFixed(h(i+1, key+1u, len), 8); - m_k[i] = a+b; - m_k[i+1] = rotlFixed(a+2*b, 9); - } - - SecBlock svec(2*len); - for (i=0; i, public VariableKeyLength<16, 0, 32> -{ -protected: - Twofish(const byte *userKey, unsigned int keylength); - static word32 h0(word32 x, const word32 *key, unsigned int kLen); - static word32 h(word32 x, const word32 *key, unsigned int kLen); - - static const byte q[2][256]; - static const word32 mds[4][256]; - - SecBlock m_k; - SecBlock m_s; -}; - -/// Twofish -class TwofishEncryption : public Twofish -{ -public: - TwofishEncryption(const byte *userKey, unsigned int keylength=DEFAULT_KEYLENGTH) - : Twofish(userKey, keylength) {} - - void ProcessBlock(const byte *inBlock, byte * outBlock) const; - void ProcessBlock(byte * inoutBlock) const - {TwofishEncryption::ProcessBlock(inoutBlock, inoutBlock);} -}; - -/// Twofish -class TwofishDecryption : public Twofish -{ -public: - TwofishDecryption(const byte *userKey, unsigned int keylength=DEFAULT_KEYLENGTH) - : Twofish(userKey, keylength) {} - - void ProcessBlock(const byte *inBlock, byte * outBlock) const; - void ProcessBlock(byte * inoutBlock) const - {TwofishDecryption::ProcessBlock(inoutBlock, inoutBlock);} -}; - -NAMESPACE_END - -#endif diff --git a/external/ours/library/crypto/src/shared/original-old/words.h b/external/ours/library/crypto/src/shared/original-old/words.h deleted file mode 100755 index 8849b6107..000000000 --- a/external/ours/library/crypto/src/shared/original-old/words.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef CRYPTOPP_WORDS_H -#define CRYPTOPP_WORDS_H - -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -inline unsigned int CountWords(const word *X, unsigned int N) -{ - while (N && X[N-1]==0) - N--; - return N; -} - -inline void SetWords(word *r, word a, unsigned int n) -{ - for (unsigned int i=0; i> (WORD_BITS-shiftBits); - } - return carry; -} - -inline word ShiftWordsRightByBits(word *r, unsigned int n, unsigned int shiftBits) -{ - assert (shiftBits=0; i--) - { - u = r[i]; - r[i] = (u >> shiftBits) | carry; - carry = u << (WORD_BITS-shiftBits); - } - return carry; -} - -inline void ShiftWordsLeftByWords(word *r, unsigned int n, unsigned int shiftWords) -{ - shiftWords = STDMIN(shiftWords, n); - if (shiftWords) - { - for (unsigned int i=n-1; i>=shiftWords; i--) - r[i] = r[i-shiftWords]; - SetWords(r, 0, shiftWords); - } -} - -inline void ShiftWordsRightByWords(word *r, unsigned int n, unsigned int shiftWords) -{ - shiftWords = STDMIN(shiftWords, n); - if (shiftWords) - { - for (unsigned int i=0; i+shiftWords Date: Fri, 26 Nov 2021 02:52:26 -0500 Subject: [PATCH 21/46] Added adjustments that allow compiling with CLang 9.0.1 or GCC 10 --- CMakeLists.txt | 11 +-- cmake/linux/FindOracle.cmake | 4 +- .../application/Miff/src/linux/miff.cpp | 70 +++++++++---------- .../library/serverGame/src/shared/pvp/Pvp.cpp | 4 +- .../src/shared/ScriptMethodsPlayerAccount.cpp | 17 ++--- .../src/shared/StlForwardDeclaration.h | 1 + 6 files changed, 51 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f99dadfd0..0b20dead0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,10 +70,10 @@ elseif (UNIX) # linker flags if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") + set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") else () set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s") - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s") + set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s") endif () # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS @@ -87,10 +87,12 @@ elseif (UNIX) set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}") # our "always on" flags - build by default for the system we're on but include all instruction sets - set(CMAKE_CXX_FLAGS "-m32 -pipe -march=native -mtune=native \ + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -march=native -mtune=native \ -Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \ -Wno-write-strings -Wno-unknown-pragmas \ -Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare -Wno-address-of-packed-member") + + message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}") # Ofast doesn't work with gcc builds if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") @@ -113,10 +115,9 @@ elseif (UNIX) # O3 and Ofast include one or more flags that cause java to crash when using gcc6 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fno-signed-zeros -freciprocal-math -fno-unroll-loops -fno-tree-loop-optimize -fno-plt") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "g++") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") endif () add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE) diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index 20abfc388..26627faac 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -30,14 +30,14 @@ if(DEFINED ENV{ORACLE_HOME}) find_path(ORACLE_INCLUDE_DIR NAMES oci.h PATHS - /usr/include/oracle/21/client + /usr/include/oracle/18.3/client ${ORACLE_HOME}/rdbms/public ${ORACLE_HOME}/include ${ORACLE_HOME}/sdk/include # Oracle SDK ${ORACLE_HOME}/OCI/include) # Oracle XE on Windows set(ORACLE_OCI_NAMES clntsh libclntsh oci) - set(ORACLE_NNZ_NAMES libnnz21 nnz21 ociw32) + set(ORACLE_NNZ_NAMES libnnz18 nnz18 libnnz21 nnz21 ociw32) set(ORACLE_OCCI_NAMES libocci occi oraocci10 oraocci11) set(ORACLE_LIB_DIR diff --git a/engine/client/application/Miff/src/linux/miff.cpp b/engine/client/application/Miff/src/linux/miff.cpp index d1f18bfc0..6927490e8 100755 --- a/engine/client/application/Miff/src/linux/miff.cpp +++ b/engine/client/application/Miff/src/linux/miff.cpp @@ -59,15 +59,15 @@ const int maxStringSize = 256; const char version[] = "1.3 September 18, 2000"; // vars set by pragmas or via command line -char drive[8]; // should be no more then 2 char "C:" -char directory[maxStringSize]; -char filename[maxStringSize]; -char extension[8]; // we'll truncate if the extension is more then 8 chars... -char inFileName[512]; +// char drive[8]; // should be no more then 2 char "C:" +// char directory[maxStringSize]; +// char filename[maxStringSize]; +// char extension[8]; // we'll truncate if the extension is more then 8 chars... +char local_inFileName[512]; // switches to be sent to mIFF Compiler char sourceBuffer[bufferSize]; -char outFileName[512]; // x2 to combine filename, dir, and ext +char local_outFileName[512]; // x2 to combine filename, dir, and ext bool usePragma = false; bool useCCCP = false; bool verboseMode = false; // default to non-verbose mode @@ -92,8 +92,8 @@ enum errorType { ERR_NONE = 0 }; -char err_msg[256]; -errorType errorFlag = ERR_NONE; // assume no error (default) +char local_err_msg[256]; +errorType local_errorFlag = ERR_NONE; // assume no error (default) // long and short name definitions for command line options @@ -220,7 +220,7 @@ int main( int argc, // number of args in commandline SetupSharedFoundation::remove(); SetupSharedThread::remove(); - return static_cast (errorFlag); + return static_cast (local_errorFlag); } //--------------------------------------------------------------------------- @@ -259,24 +259,24 @@ static void callbackFunction(void) #endif - errorFlag = evaluateArgs(); - if (ERR_NONE == errorFlag) + local_errorFlag = evaluateArgs(); + if (ERR_NONE == local_errorFlag) { - outfileHandler = new OutputFileHandler(outFileName); - MIFFCompile(sourceBuffer, inFileName); + outfileHandler = new OutputFileHandler(local_outFileName); + MIFFCompile(sourceBuffer, local_inFileName); } else - handleError(errorFlag); + handleError(local_errorFlag); if (outfileHandler) { // only write output IF there was no error - if (ERR_NONE == errorFlag) + if (ERR_NONE == local_errorFlag) { if (!outfileHandler->writeBuffer()) { - fprintf(stderr, "MIFF: failed to write output file \"%s\"\n", outFileName); - errorFlag = ERR_WRITEERROR; + fprintf(stderr, "MIFF: failed to write output file \"%s\"\n", local_outFileName); + local_errorFlag = ERR_WRITEERROR; } } delete outfileHandler; @@ -323,13 +323,13 @@ static errorType evaluateArgs(void) // setup input filename - strcpy(inFileName, CommandLine::getOptionString(SNAME_INPUT_FILE)); + strcpy(local_inFileName, CommandLine::getOptionString(SNAME_INPUT_FILE)); // handle output filename spec if (CommandLine::getOccurrenceCount(SNAME_OUTPUT_FILE)) { - strcpy(outFileName, CommandLine::getOptionString(SNAME_OUTPUT_FILE)); + strcpy(local_outFileName, CommandLine::getOptionString(SNAME_OUTPUT_FILE)); } else if (CommandLine::getOccurrenceCount(SNAME_PRAGMA_TARGET)) { @@ -342,15 +342,15 @@ static errorType evaluateArgs(void) char *terminator; // start with input file pathname - strcpy(outFileName, inFileName); + strcpy(local_outFileName, local_inFileName); // try to terminate at rightmost '.' - terminator = strrchr(outFileName, '.'); + terminator = strrchr(local_outFileName, '.'); if (terminator) *terminator = 0; // append the default iff extension - strcat(outFileName, ".iff"); + strcat(local_outFileName, ".iff"); } @@ -361,12 +361,12 @@ static errorType evaluateArgs(void) // preprocess the input file - if (0 == preprocessSource(inFileName)) + if (0 == preprocessSource(local_inFileName)) { if (verboseMode) { - sprintf(err_msg,"Now compiling %s...\n", inFileName); - MIFFMessage(err_msg, 0); + sprintf(local_err_msg,"Now compiling %s...\n", local_inFileName); + MIFFMessage(local_err_msg, 0); } if (ERR_NONE == retVal) retVal = loadInputToBuffer(sourceBuffer, bufferSize); @@ -563,7 +563,7 @@ extern "C" void MIFFMessage(char *message, // nullptr terminated string to be // Only call this via parser!!! extern "C" void MIFFSetError(void) { - errorFlag = ERR_PARSER; + local_errorFlag = ERR_PARSER; } //--------------------------------------------------------------------------- @@ -586,10 +586,10 @@ extern "C" int validateTargetFilename( char *targetFileName, // pointer to wher unsigned maxTargetBufSize // size of the filename string buffer ) { - if (strlen(outFileName) > maxTargetBufSize) + if (strlen(local_outFileName) > maxTargetBufSize) MIFFMessage("Internal error, increase string buffer size in parser.yac and recompile!", 1); - strcpy(targetFileName, outFileName); + strcpy(targetFileName, local_outFileName); return(usePragma); } @@ -667,7 +667,7 @@ static int preprocessSource(char *sourceName) extern "C" void MIFFSetIFFName(const char *newFileName) { - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return; if (outfileHandler) @@ -676,7 +676,7 @@ extern "C" void MIFFSetIFFName(const char *newFileName) extern "C" void MIFFinsertForm(const char *formName) { - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return; if (outfileHandler) @@ -685,7 +685,7 @@ extern "C" void MIFFinsertForm(const char *formName) extern "C" void MIFFinsertChunk(const char *chunkName) { - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return; if (outfileHandler) @@ -694,7 +694,7 @@ extern "C" void MIFFinsertChunk(const char *chunkName) extern "C" void MIFFinsertChunkData(void * buffer, unsigned bufferSize) { - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return; if (outfileHandler) @@ -705,7 +705,7 @@ extern "C" int MIFFloadRawData(char *fname, void * buffer, unsigned maxBufferSiz { int sizeRead = -1; - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return(sizeRead); // should be -1 InputFileHandler * inFileName = new InputFileHandler(fname); @@ -725,7 +725,7 @@ extern "C" int MIFFloadRawData(char *fname, void * buffer, unsigned maxBufferSiz extern "C" void MIFFexitChunk(void) { - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return; if (outfileHandler) @@ -733,7 +733,7 @@ extern "C" void MIFFexitChunk(void) } extern "C" void MIFFexitForm(void) { - if (ERR_NONE != errorFlag) + if (ERR_NONE != local_errorFlag) return; if (outfileHandler) diff --git a/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp b/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp index d6e291ae3..5f87f178a 100755 --- a/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp +++ b/engine/server/library/serverGame/src/shared/pvp/Pvp.cpp @@ -843,14 +843,14 @@ int Pvp::calculateGcwImperialScorePercentile(std::string const & gcwCategory, st { std::map >::const_iterator const iterImperial = gcwImperialScore.find(gcwCategory); if (iterImperial != gcwImperialScore.end()) - totalImperial = static_cast(std::max(0ll, iterImperial->second.first)) + static_cast(std::max(0ll, iterImperial->second.second)); + totalImperial = static_cast(std::max((int64)0, iterImperial->second.first)) + static_cast(std::max((int64)0, iterImperial->second.second)); } uint64 total = totalImperial; { std::map >::const_iterator const iterRebel = gcwRebelScore.find(gcwCategory); if (iterRebel != gcwRebelScore.end()) - total += (static_cast(std::max(0ll, iterRebel->second.first)) + static_cast(std::max(0ll, iterRebel->second.second))); + total += (static_cast(std::max((int64)0, iterRebel->second.first)) + static_cast(std::max((int64)0, iterRebel->second.second))); } // if the score is less than 1, treat it as a tie; note that score is scaled by 1000 diff --git a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp index 48fa7ad19..2b687ce62 100755 --- a/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp +++ b/engine/server/library/serverScript/src/shared/ScriptMethodsPlayerAccount.cpp @@ -991,25 +991,18 @@ jstring JNICALL ScriptMethodsPlayerAccountNamespace::getPlayerUsername(JNIEnv *e NOT_NULL(env); CreatureObject const * creatureObject = nullptr; - if (!JavaLibrary::getObject(player, creatureObject) || !creatureObject) - { - DEBUG_WARNING(true, ("JavaLibrary::getPlayerUsername: bad CreatureObject")); - return nullptr; - } - - if(creatureObject) + JavaLibrary::getObject(player, creatureObject); + DEBUG_WARNING(!creatureObject, ("JavaLibrary::getPlayerUsername: could not get creatureObject for player %d", player)); + if (creatureObject) { const Client * playerClient = creatureObject->getClient(); + DEBUG_WARNING(!playerClient, ("JavaLibrary::getPlayerUsername: could not get playerClient for player %d", player)); if(playerClient) { return JavaString(playerClient->getAccountName()).getReturnValue(); } - else { - DEBUG_WARNING(true, ("JavaLibrary::getPlayerUsername: bad playerClient")); - return nullptr; - } } - + return nullptr; } // ====================================================================== diff --git a/engine/shared/library/sharedFoundation/src/shared/StlForwardDeclaration.h b/engine/shared/library/sharedFoundation/src/shared/StlForwardDeclaration.h index cd1b0e754..c8daf4fa8 100755 --- a/engine/shared/library/sharedFoundation/src/shared/StlForwardDeclaration.h +++ b/engine/shared/library/sharedFoundation/src/shared/StlForwardDeclaration.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace Unicode { From f41c6ec149b00e9efd409e64fb3fbf7d8ce7fc3a Mon Sep 17 00:00:00 2001 From: Cekis Date: Sun, 28 Nov 2021 23:38:47 -0500 Subject: [PATCH 22/46] Fixed compiler warnings for mixing Strings with char * --- .../3rd/library/udplibrary/UdpLibrary.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/external/3rd/library/udplibrary/UdpLibrary.cpp b/external/3rd/library/udplibrary/UdpLibrary.cpp index 4105355fe..7862e4864 100755 --- a/external/3rd/library/udplibrary/UdpLibrary.cpp +++ b/external/3rd/library/udplibrary/UdpLibrary.cpp @@ -2896,21 +2896,21 @@ const char *UdpConnection::DisconnectReasonText(DisconnectReason reason) { sInitialized = true; memset(sDisconnectReason, 0, sizeof(sDisconnectReason)); - sDisconnectReason[cDisconnectReasonNone] = "DisconnectReasonNone"; - sDisconnectReason[cDisconnectReasonIcmpError] = "DisconnectReasonIcmpError"; - sDisconnectReason[cDisconnectReasonTimeout] = "DisconnectReasonTimeout"; - sDisconnectReason[cDisconnectReasonOtherSideTerminated] = "DisconnectReasonOtherSideTerminated"; - sDisconnectReason[cDisconnectReasonManagerDeleted] = "DisconnectReasonManagerDeleted"; - sDisconnectReason[cDisconnectReasonConnectFail] = "DisconnectReasonConnectFail"; - sDisconnectReason[cDisconnectReasonApplication] = "DisconnectReasonApplication"; - sDisconnectReason[cDisconnectReasonUnreachableConnection] = "DisconnectReasonUnreachableConnection"; - sDisconnectReason[cDisconnectReasonUnacknowledgedTimeout] = "DisconnectReasonUnacknowledgedTimeout"; - sDisconnectReason[cDisconnectReasonNewConnectionAttempt] = "DisconnectReasonNewConnectionAttempt"; - sDisconnectReason[cDisconnectReasonConnectionRefused] = "DisconnectReasonConnectionRefused"; - sDisconnectReason[cDisconnectReasonMutualConnectError] = "DisconnectReasonConnectError"; - sDisconnectReason[cDisconnectReasonConnectingToSelf] = "DisconnectReasonConnectingToSelf"; - sDisconnectReason[cDisconnectReasonReliableOverflow] = "DisconnectReasonReliableOverflow"; - sDisconnectReason[cDisconnectReasonDosAttack] = "DisconnectReasonDoSAttack"; + sDisconnectReason[cDisconnectReasonNone] = (char *) "DisconnectReasonNone"; + sDisconnectReason[cDisconnectReasonIcmpError] = (char *) "DisconnectReasonIcmpError"; + sDisconnectReason[cDisconnectReasonTimeout] = (char *) "DisconnectReasonTimeout"; + sDisconnectReason[cDisconnectReasonOtherSideTerminated] = (char *) "DisconnectReasonOtherSideTerminated"; + sDisconnectReason[cDisconnectReasonManagerDeleted] = (char *) "DisconnectReasonManagerDeleted"; + sDisconnectReason[cDisconnectReasonConnectFail] = (char *) "DisconnectReasonConnectFail"; + sDisconnectReason[cDisconnectReasonApplication] = (char *) "DisconnectReasonApplication"; + sDisconnectReason[cDisconnectReasonUnreachableConnection] = (char *) "DisconnectReasonUnreachableConnection"; + sDisconnectReason[cDisconnectReasonUnacknowledgedTimeout] = (char *) "DisconnectReasonUnacknowledgedTimeout"; + sDisconnectReason[cDisconnectReasonNewConnectionAttempt] = (char *) "DisconnectReasonNewConnectionAttempt"; + sDisconnectReason[cDisconnectReasonConnectionRefused] = (char *) "DisconnectReasonConnectionRefused"; + sDisconnectReason[cDisconnectReasonMutualConnectError] = (char *) "DisconnectReasonConnectError"; + sDisconnectReason[cDisconnectReasonConnectingToSelf] = (char *) "DisconnectReasonConnectingToSelf"; + sDisconnectReason[cDisconnectReasonReliableOverflow] = (char *) "DisconnectReasonReliableOverflow"; + sDisconnectReason[cDisconnectReasonDosAttack] = (char *) "DisconnectReasonDoSAttack"; } return(sDisconnectReason[reason]); From 966c7eef7922f77366a5cf09200752c03b65e9db Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 8 Dec 2021 20:50:13 -0500 Subject: [PATCH 23/46] Added Oracle 21 paths and fixed issue with naming --- build.xml | 26 +++++++++++++++++++++++++- cmake/linux/FindOracle.cmake | 5 +++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/build.xml b/build.xml index e0c32d6cb..e1765850d 100755 --- a/build.xml +++ b/build.xml @@ -52,6 +52,13 @@ Architecture is ${arch} + + + + + + + Compiling as ${bits}-bit application. @@ -83,7 +90,11 @@ - + + + + + @@ -99,6 +110,19 @@ + + + + + + + + + + + + + diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index 26627faac..d86c1bf8d 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -30,7 +30,8 @@ if(DEFINED ENV{ORACLE_HOME}) find_path(ORACLE_INCLUDE_DIR NAMES oci.h PATHS - /usr/include/oracle/18.3/client + /usr/include/oracle/18.3/client + /usr/include/oracle/21/client64 ${ORACLE_HOME}/rdbms/public ${ORACLE_HOME}/include ${ORACLE_HOME}/sdk/include # Oracle SDK @@ -74,6 +75,6 @@ endif(DEFINED ENV{ORACLE_HOME}) # Handle the QUIETLY and REQUIRED arguments and set ORACLE_FOUND to TRUE # if all listed variables are TRUE include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(ORACLE DEFAULT_MSG ORACLE_LIBRARY ORACLE_INCLUDE_DIR) +find_package_handle_standard_args(Oracle DEFAULT_MSG ORACLE_LIBRARY ORACLE_INCLUDE_DIR) mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY) \ No newline at end of file From a4e3f44feca3a4adb898454e681f010841658b78 Mon Sep 17 00:00:00 2001 From: Cekis Date: Fri, 10 Dec 2021 14:11:28 -0500 Subject: [PATCH 24/46] Fixed issues with CMake configuration --- CMakeLists.txt | 3 +-- cmake/linux/FindOracle.cmake | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b20dead0..f093b7167 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # shame on you cmake for auto-setting optimization flags! -set(CMAKE_CXX_FLAGS "") set(CMAKE_CXX_FLAGS_DEBUG "") set(CMAKE_CXX_FLAGS_RELEASE "") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "") @@ -107,7 +106,7 @@ elseif (UNIX) # RELWITHDEBINFO is used for building bins that produce profdata files # we only need the basics of our heavy optimizations here, i think - that and one of these flags # breaks JNI when we profile - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Ofast -finline-hint-functions -fprofile-instr-generate -g -fcoverage-mapping") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -Ofast -finline-hint-functions -fprofile-instr-generate -g -fcoverage-mapping") # MINSIZEREL is used for profiled, flto builds set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} -flto -fwhole-program-vtables") diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index d86c1bf8d..29091041e 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -25,13 +25,12 @@ # If ORACLE_HOME not defined, assume Oracle libraries not available if(DEFINED ENV{ORACLE_HOME}) - set(ORACLE_HOME $ENV{ORACLE_HOME}) + set(ORACLE_HOME ${CMAKE_ORACLE_DIR}) find_path(ORACLE_INCLUDE_DIR NAMES oci.h PATHS - /usr/include/oracle/18.3/client - /usr/include/oracle/21/client64 + ${CMAKE_ORACLE_INCLUDE_DIR} ${ORACLE_HOME}/rdbms/public ${ORACLE_HOME}/include ${ORACLE_HOME}/sdk/include # Oracle SDK From 78959d8034c28a089287fe7287deaaf629000a3c Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 11 Dec 2021 22:57:25 -0500 Subject: [PATCH 25/46] Fixed issue for newer compilers and adjusted Oracle and chat for compilation --- cmake/linux/FindOracle.cmake | 2 +- external/3rd/library/platform/utils/Base/Archive.cpp | 2 +- external/3rd/library/udplibrary/CMakeLists.txt | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index 29091041e..d6074ead5 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -25,7 +25,7 @@ # If ORACLE_HOME not defined, assume Oracle libraries not available if(DEFINED ENV{ORACLE_HOME}) - set(ORACLE_HOME ${CMAKE_ORACLE_DIR}) + set(ORACLE_HOME $ENV{ORACLE_HOME}) find_path(ORACLE_INCLUDE_DIR NAMES oci.h diff --git a/external/3rd/library/platform/utils/Base/Archive.cpp b/external/3rd/library/platform/utils/Base/Archive.cpp index 11e235b91..ec1a8c8b9 100755 --- a/external/3rd/library/platform/utils/Base/Archive.cpp +++ b/external/3rd/library/platform/utils/Base/Archive.cpp @@ -81,7 +81,7 @@ namespace Base { } - ByteStream::ReadIterator::~ReadIterator() + Base::ReadIterator::~ReadIterator() { stream = 0; } diff --git a/external/3rd/library/udplibrary/CMakeLists.txt b/external/3rd/library/udplibrary/CMakeLists.txt index a34988148..50c4163e7 100644 --- a/external/3rd/library/udplibrary/CMakeLists.txt +++ b/external/3rd/library/udplibrary/CMakeLists.txt @@ -21,3 +21,4 @@ add_library(udplibrary UdpLibrary.h ) +target_include_directories(udplibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) From 66fc6c48ddad97495686a5a7f7abb7ac85bae4df Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 13 Dec 2021 19:56:00 -0500 Subject: [PATCH 26/46] Updated CMake build flags --- CMakeLists.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f093b7167..4eafb78ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,13 +76,13 @@ elseif (UNIX) endif () # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS - set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -ggdb -pg -no-pie") + set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -ggdb -pg") # release specific cflags - optimizations beyond the default for both types is mostly just -O flags set(CMAKE_CXX_FLAGS_RELEASE "-DDEBUG_LEVEL=0 -DPRODUCTION=1") # we use fewer, if any, crazy optimizations for profile generation, and likewise release flags for the minsizerel - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb -pg -no-pie") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb -pg") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}") # our "always on" flags - build by default for the system we're on but include all instruction sets @@ -106,14 +106,15 @@ elseif (UNIX) # RELWITHDEBINFO is used for building bins that produce profdata files # we only need the basics of our heavy optimizations here, i think - that and one of these flags # breaks JNI when we profile - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -Ofast -finline-hint-functions -fprofile-instr-generate -g -fcoverage-mapping") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Ofast -finline-hint-functions -fprofile-instr-generate -g -fcoverage-mapping") # MINSIZEREL is used for profiled, flto builds - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} -flto -fwhole-program-vtables") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -fwhole-program-vtables") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # O3 and Ofast include one or more flags that cause java to crash when using gcc6 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fno-signed-zeros -freciprocal-math -fno-unroll-loops -fno-tree-loop-optimize -fno-plt") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -no-pie") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-pie") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") From 4d7c0de43f35e15fbd828f50059422937fa7ffaf Mon Sep 17 00:00:00 2001 From: Cekis Date: Tue, 21 Dec 2021 18:22:16 -0500 Subject: [PATCH 27/46] Adjusted DbBindableLong to be 64 bits if needed and adjusted timing for 64 bits --- CMakeLists.txt | 37 ++++++++-------- .../src/shared/ManagerConnection.cpp | 4 +- .../src/shared/TaskConnectionIdMessage.h | 6 +-- .../src/shared/core/DbBindableLong.cpp | 9 ++-- .../src/shared/core/DbBindableLong.h | 42 +++++++++++++------ .../src/shared/object/AlterScheduler.cpp | 2 +- 6 files changed, 60 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4eafb78ad..45c01642d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,24 +66,21 @@ if (WIN32) elseif (UNIX) find_package(Curses REQUIRED) - # linker flags - if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") - set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") - else () - set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s") - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s") + # Global Linker flags + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") + + # Strip debug symbols if RELEASE or MINSIZEREL + if (${CMAKE_BUILD_TYPE} STREQUAL "RELEASE" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS},-x,-s") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS},-x,-s") endif () # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS - set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -ggdb -pg") - - # release specific cflags - optimizations beyond the default for both types is mostly just -O flags - set(CMAKE_CXX_FLAGS_RELEASE "-DDEBUG_LEVEL=0 -DPRODUCTION=1") - - # we use fewer, if any, crazy optimizations for profile generation, and likewise release flags for the minsizerel + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb -pg") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") # our "always on" flags - build by default for the system we're on but include all instruction sets set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -march=native -mtune=native \ @@ -101,7 +98,7 @@ elseif (UNIX) -fno-coverage-mapping -fno-spell-checking \ -mno-retpoline") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g -fprofile-instr-generate -fcoverage-mapping") # RELWITHDEBINFO is used for building bins that produce profdata files # we only need the basics of our heavy optimizations here, i think - that and one of these flags @@ -113,7 +110,7 @@ elseif (UNIX) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # O3 and Ofast include one or more flags that cause java to crash when using gcc6 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fno-signed-zeros -freciprocal-math -fno-unroll-loops -fno-tree-loop-optimize -fno-plt") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -no-pie") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -ggdb -no-pie") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-pie") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") @@ -123,11 +120,17 @@ elseif (UNIX) add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE) # this is so some profile specific stuff is turned on in the code - if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO") + if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "DEBUG") add_definitions(-DENABLE_PROFILING) endif () endif () +message("Flags CXX: ${CMAKE_CXX_FLAGS}") +message("Flags DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") +message("Flags RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +message("Flags RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") +message("Flags MINSIZEREL: ${CMAKE_CXX_FLAGS_MINSIZEREL}") + add_subdirectory(external) add_subdirectory(engine) add_subdirectory(game) diff --git a/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp b/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp index d131eff9e..244ee8816 100755 --- a/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp +++ b/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp @@ -122,8 +122,8 @@ void ManagerConnection::onReceive(const Archive::ByteStream & message) } case constcrc("TaskConnectionIdMessage") : { - static long const clockDriftFatalTimePeriod = static_cast(TaskManager::getStartTime()) + ConfigTaskManager::getClockDriftFatalIntervalSeconds(); - long const currentTime = static_cast(::time(nullptr)); + static uint32_t const clockDriftFatalTimePeriod = static_cast(TaskManager::getStartTime()) + ConfigTaskManager::getClockDriftFatalIntervalSeconds(); + uint32_t const currentTime = static_cast(::time(nullptr)); TaskConnectionIdMessage t(r); WARNING_STRICT_FATAL(t.getServerType() != TaskConnectionIdMessage::TaskManager, ("ManagerConnection received wrong type identifier")); diff --git a/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h b/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h index 75bc92955..9580f6077 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h +++ b/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h @@ -34,7 +34,7 @@ class TaskConnectionIdMessage : public GameNetworkMessage const unsigned char getServerType () const; const std::string & getCommandLine () const; const std::string & getClusterName () const; - const long getCurrentEpochTime() const; + const uint32_t getCurrentEpochTime() const; private: TaskConnectionIdMessage & operator = (const TaskConnectionIdMessage & rhs); TaskConnectionIdMessage(const TaskConnectionIdMessage & source); @@ -42,7 +42,7 @@ class TaskConnectionIdMessage : public GameNetworkMessage Archive::AutoVariable serverType; Archive::AutoVariable commandLine; Archive::AutoVariable clusterName; - Archive::AutoVariable currentEpochTime; + Archive::AutoVariable currentEpochTime; }; //----------------------------------------------------------------------- @@ -68,7 +68,7 @@ inline const unsigned char TaskConnectionIdMessage::getServerType() const //----------------------------------------------------------------------- -inline const long TaskConnectionIdMessage::getCurrentEpochTime() const +inline const uint32_t TaskConnectionIdMessage::getCurrentEpochTime() const { return currentEpochTime.get(); } diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp index 8693cdb4a..c487f4285 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp @@ -18,7 +18,7 @@ BindableLong::BindableLong() : Bindable(), value(-999) { } -BindableLong::BindableLong(int32_t _value) : Bindable(sizeof(value)), value(_value) +BindableLong::BindableLong(int64_t _value) : Bindable(sizeof(value)), value(_value) { } @@ -29,14 +29,15 @@ void *BindableLong::getBuffer() // ---------------------------------------------------------------------- -int32_t BindableLong::getValue() const + +int64_t BindableLong::getValue() const { return value; } // ---------------------------------------------------------------------- -BindableLong &BindableLong::operator=(int32_t rhs) +BindableLong &BindableLong::operator=(int64_t rhs) { indicator=sizeof(value); value=rhs; @@ -45,7 +46,7 @@ BindableLong &BindableLong::operator=(int32_t rhs) // ---------------------------------------------------------------------- -void BindableLong::setValue(int32_t rhs) +void BindableLong::setValue(int64_t rhs) { indicator=sizeof(value); value=rhs; diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h index b0d8651d9..037b59f45 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h @@ -23,43 +23,45 @@ namespace DB { { public: BindableLong(); - explicit BindableLong(int32_t _value); + explicit BindableLong(int64_t _value); - int32_t getValue() const; - void setValue(const int32_t rhs); - BindableLong &operator=(const int32_t rhs); + int64_t getValue() const; + void setValue(const int64_t rhs); + BindableLong &operator=(const int64_t rhs); // following alternate getValue's are provided for convenience, particularly in // the auto-generated code: - void getValue(int8 &buffer) const; - void getValue(uint8 &buffer) const; + void getValue(int8_t &buffer) const; + void getValue(uint8_t &buffer) const; void getValue(int16_t &buffer) const; void getValue(uint16_t &buffer) const; void getValue(int32_t &buffer) const; void getValue(uint32_t &buffer) const; + void getValue(int64_t &buffer) const; + void getValue(uint64_t &buffer) const; void *getBuffer(); virtual std::string outputValue() const; private: - int32_t value; + int64_t value; }; //lint !e1721 !e1509 // no virtual destructor, unusual operator = } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(int8 &buffer) const +inline void DB::BindableLong::getValue(int8_t &buffer) const { - buffer=static_cast(getValue()); + buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint8 &buffer) const +inline void DB::BindableLong::getValue(uint8_t &buffer) const { - buffer=static_cast(getValue()); + buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- @@ -84,9 +86,23 @@ inline void DB::BindableLong::getValue(int32_t &buffer) const // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint32 &buffer) const +inline void DB::BindableLong::getValue(uint32_t &buffer) const { - buffer=static_cast(getValue()); + buffer=static_cast(getValue()); +} + +// ---------------------------------------------------------------------- + +inline void DB::BindableLong::getValue(int64_t &buffer) const +{ + buffer=getValue(); +} + +// ---------------------------------------------------------------------- + +inline void DB::BindableLong::getValue(uint64_t &buffer) const +{ + buffer=static_cast(getValue()); } diff --git a/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp b/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp index 24e46165e..5bd64e9bc 100755 --- a/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp +++ b/engine/shared/library/sharedObject/src/shared/object/AlterScheduler.cpp @@ -111,7 +111,7 @@ namespace AlterSchedulerNamespace // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - float const cs_schedulerTicksPerSecond = 1000.0f; // # schedule ticks per second. Frame rates will not be able to exceed this. + float const cs_schedulerTicksPerSecond = 2000.0f; // # schedule ticks per second. Frame rates will not be able to exceed this. float const cs_secondsPerSchedulerTick = 1.0f / cs_schedulerTicksPerSecond; uint64_t const cs_freeFillPattern = 0xEFEFEFEFEFEFEFEF; // this should match MemoryManager's free fill pattern. From a63877337eea5e33e470e629ed604dda4289796e Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 17 Jan 2022 03:31:45 -0500 Subject: [PATCH 28/46] Refactored DbBindableLong to be more appropriately named DbBindableInt32 --- .../src/shared/TaskChangeStationId.h | 4 +- .../src/shared/TaskClaimRewards.cpp | 26 +- .../src/shared/TaskCreateCharacter.h | 8 +- .../src/shared/TaskDeleteCharacter.h | 4 +- .../src/shared/TaskEnableCharacter.h | 4 +- .../src/shared/TaskGetAccountForPurge.cpp | 6 +- .../src/shared/TaskGetAvatarList.h | 10 +- .../src/shared/TaskGetClusterList.h | 14 +- .../src/shared/TaskGetValidationData.cpp | 22 +- .../LoginServer/src/shared/TaskMapAccount.h | 4 +- .../src/shared/TaskRegisterNewCluster.h | 2 +- .../src/shared/TaskRenameCharacter.h | 2 +- .../src/shared/TaskRestoreCharacter.h | 10 +- .../src/shared/TaskSetPurgeStatus.cpp | 4 +- .../src/shared/TaskToggleCharacterDisable.h | 4 +- .../src/shared/TaskToggleCompletedTutorial.h | 2 +- .../src/shared/TaskUpgradeAccount.h | 24 +- .../shared/TaskUpdateSPCharacterProfileData.h | 8 +- engine/server/library/codegen/make_queries.pl | 2 +- .../server/library/codegen/make_schema_h.pl | 10 +- .../src/shared/CharacterLocator.h | 2 +- .../src/shared/CharacterNameLocator.h | 6 +- .../src/shared/CharacterQueries.h | 6 +- .../shared/DeleteCharacterCustomPersistStep.h | 6 +- .../src/shared/FixLoadWithCustomPersistStep.h | 4 +- .../serverDatabase/src/shared/GetChunkQuery.h | 6 +- .../src/shared/GetGoldVersionNumberQuery.h | 4 +- .../src/shared/GetObjectIdsQuery.h | 2 +- .../src/shared/GetTimestampQuery.h | 2 +- .../src/shared/GetVersionNumberQuery.h | 4 +- .../src/shared/LazyDeleteQuery.h | 4 +- .../shared/MoveToPlayerCustomPersistStep.h | 4 +- .../src/shared/PreloadListQuery.h | 10 +- .../src/shared/SaveTimestampQuery.h | 2 +- .../serverDatabase/src/shared/ScriptQueries.h | 2 +- .../src/shared/StructureQueries.h | 2 +- .../serverDatabase/src/shared/TaskCSTasks.h | 8 +- .../src/shared/TaskChangeStationId.h | 4 +- .../src/shared/TaskCheckCharacterName.h | 2 +- .../src/shared/TaskGetStructuresForPurge.cpp | 4 +- .../src/shared/WorldContainerLocator.h | 4 +- .../sharedDatabaseInterface/DbBindableInt32.h | 1 + .../sharedDatabaseInterface/DbBindableLong.h | 1 - .../src/CMakeLists.txt | 4 +- .../src/shared/core/Bindable.h | 2 +- ...DbBindableLong.cpp => DbBindableInt32.cpp} | 18 +- .../{DbBindableLong.h => DbBindableInt32.h} | 50 +- .../src/shared/core/DbQuery.cpp | 4 +- .../src/shared/core/DbQuery.h | 6 +- .../src/shared/core/DbQueryImplementation.h | 6 +- .../src/shared/queue/DbTestQuery.h | 2 +- .../src_oci/OciQueryImplementation.cpp | 4 +- .../src_oci/OciQueryImplementation.h | 4 +- .../shared/cleanup/TaskBrokenObjectCleanup.h | 2 +- .../cleanup/TaskMarketAttributesCleanup.h | 2 +- .../src/shared/cleanup/TaskMessagesCleanup.h | 2 +- .../shared/cleanup/TaskObjvarNameCleanup.h | 2 +- .../cleanup/TaskOrphanedObjectCleanup.h | 2 +- .../shared/cleanup/TaskVendorObjectCleanup.h | 2 +- .../src/shared/core/SwgSnapshot.cpp | 4 +- .../src/shared/core/SwgSnapshot.h | 4 +- .../shared/generated/ObjectQueries_h.template | 48 +- .../src/shared/generated/Schema_h.template | 586 +++++++++--------- .../shared/queries/BountyHunterTargetQuery.h | 2 +- .../src/shared/queries/CommoditiesQuery.h | 8 +- .../src/shared/queries/CommoditiesSchema.h | 34 +- .../DeleteDemandLoadedContainerQuery.h | 2 +- .../src/shared/queries/LocationQuery.h | 10 +- .../ManufactureSchematicAttributeQuery.h | 2 +- .../src/shared/queries/MessageQuery.h | 12 +- .../shared/queries/ObjectVariableQueries.h | 4 +- .../src/shared/queries/ObjectsTableQuery.h | 2 +- .../queries/OfflineMoneyCustomPersistStep.cpp | 2 +- .../src/shared/queries/PropertyListQuery.h | 10 +- .../src/shared/queries/ResourceTypeQuery.h | 2 +- .../src/shared/queries/SkillQuery.h | 4 +- .../src/shared/tasks/TaskGetAuctionList.h | 16 +- .../src/shared/tasks/TaskGetBidList.h | 4 +- .../src/shared/tasks/TaskGetLocationList.h | 12 +- .../src/shared/tasks/TaskLoadObjvarNames.h | 2 +- .../src/shared/tasks/TaskLocateStructure.h | 6 +- .../src/shared/tasks/TaskMoveToPlayer.h | 2 +- .../src/shared/tasks/TaskRestoreCharacter.h | 6 +- .../src/shared/tasks/TaskRestoreHouse.h | 2 +- .../src/shared/tasks/TaskSaveObjvarNames.h | 2 +- .../src/shared/tasks/TaskUndeleteItem.h | 2 +- .../src/shared/tasks/TaskVerifyCharacter.h | 4 +- 87 files changed, 574 insertions(+), 592 deletions(-) create mode 100755 engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h delete mode 100755 engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h rename engine/shared/library/sharedDatabaseInterface/src/shared/core/{DbBindableLong.cpp => DbBindableInt32.cpp} (71%) rename engine/shared/library/sharedDatabaseInterface/src/shared/core/{DbBindableLong.h => DbBindableInt32.h} (61%) diff --git a/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h b/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h index 6ed1dad44..6a3030008 100755 --- a/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h +++ b/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h @@ -36,8 +36,8 @@ class TaskChangeStationId : public DB::TaskRequest public: ChangeStationIdQuery(); - DB::BindableLong destination_station_id; //lint !e1925 // public data member - DB::BindableLong source_station_id; //lint !e1925 // public data member + DB::BindableInt32 destination_station_id; //lint !e1925 // public data member + DB::BindableInt32 source_station_id; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp b/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp index ef741b018..195ac2666 100755 --- a/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp @@ -33,11 +33,11 @@ namespace TaskClaimRewardsNamespace bool getResult() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId character_id; - DB::BindableLong cluster_id; + DB::BindableInt32 cluster_id; DB::BindableString<255> event_id; - DB::BindableLong result; + DB::BindableInt32 result; private: //disable ConsumeEventQuery(); @@ -58,11 +58,11 @@ namespace TaskClaimRewardsNamespace bool getResult() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId character_id; - DB::BindableLong cluster_id; + DB::BindableInt32 cluster_id; DB::BindableString<255> item_id; - DB::BindableLong result; + DB::BindableInt32 result; private: //disable ClaimItemQuery(); @@ -83,12 +83,12 @@ namespace TaskClaimRewardsNamespace bool getResult() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId character_id; - DB::BindableLong cluster_id; + DB::BindableInt32 cluster_id; DB::BindableString<255> item_id; - DB::BindableLong count_adjustment; - DB::BindableLong result; + DB::BindableInt32 count_adjustment; + DB::BindableInt32 result; private: //disable UpdateFeatureIdTransactionQuery(); @@ -102,7 +102,7 @@ namespace TaskClaimRewardsNamespace GetFeatureIdTransactionsQuery(StationId stationId, NetworkId const & characterId, uint32 clusterId); DB::BindableString<255> item_id; - DB::BindableLong count; + DB::BindableInt32 count; virtual void getSQL(std::string &sql); virtual bool bindParameters(); @@ -110,9 +110,9 @@ namespace TaskClaimRewardsNamespace virtual QueryMode getExecutionMode() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId character_id; - DB::BindableLong cluster_id; + DB::BindableInt32 cluster_id; private: //disable GetFeatureIdTransactionsQuery(const GetFeatureIdTransactionsQuery&); diff --git a/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h b/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h index 3c53e296c..3004bc6d5 100755 --- a/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h @@ -33,12 +33,12 @@ class TaskCreateCharacter : public DB::TaskRequest public: CreateCharacterQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member DB::BindableString<127> character_name; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member - DB::BindableLong template_id; //lint !e1925 // public data member - DB::BindableLong character_type; //lint !e1925 // public data member + DB::BindableInt32 template_id; //lint !e1925 // public data member + DB::BindableInt32 character_type; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h b/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h index 5b3130a48..a8e391f0d 100755 --- a/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h @@ -35,9 +35,9 @@ class TaskDeleteCharacter : public DB::TaskRequest public: DeleteCharacterQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member - DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h b/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h index 321255324..a5ad5f458 100755 --- a/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h @@ -35,10 +35,10 @@ class TaskEnableCharacter : public DB::TaskRequest public: EnableCharacterQuery(); - DB::BindableLong station_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableInt32 station_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableNetworkId character_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableBool enabled; //lint !e1925 // public data member : suppressed because this is a private inner class - DB::BindableLong result; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableInt32 result; //lint !e1925 // public data member : suppressed because this is a private inner class virtual void getSQL(std::string &sql); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp b/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp index 061b1c4d3..62251e03f 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp @@ -32,9 +32,9 @@ namespace TaskGetAccountForPurgeNamespace StationId getAccount() const; private: - DB::BindableLong m_account; - DB::BindableLong m_min_age; - DB::BindableLong m_purge_phase; + DB::BindableInt32 m_account; + DB::BindableInt32 m_min_age; + DB::BindableInt32 m_purge_phase; private: //disable GetAccountForPurgeQuery(const GetAccountForPurgeQuery&); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h b/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h index 1c7c6cb1c..c76ed5f36 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h +++ b/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h @@ -37,13 +37,13 @@ class TaskGetAvatarList : public DB::TaskRequest class GetCharactersQuery : public DB::Query { public: - DB::BindableLong station_id; //lint !e1925 // public data member - DB::BindableLong cluster_group_id; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_group_id; //lint !e1925 // public data member DB::BindableString<128> character_name; //lint !e1925 // public data member - DB::BindableLong object_template_id; //lint !e1925 // public data member + DB::BindableInt32 object_template_id; //lint !e1925 // public data member DB::BindableNetworkId object_id; //lint !e1925 // public data member - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong character_type; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 character_type; //lint !e1925 // public data member GetCharactersQuery(); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h b/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h index 534c95f17..0c78ded8d 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h +++ b/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h @@ -31,20 +31,20 @@ class TaskGetClusterList : public DB::TaskRequest class GetClustersQuery : public DB::Query { public: - DB::BindableLong group_id; //lint !e1925 // public data member + DB::BindableInt32 group_id; //lint !e1925 // public data member - DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member DB::BindableString<255> cluster_name; //lint !e1925 // public data member DB::BindableString<255> address; //lint !e1925 // public data member - DB::BindableLong port; //lint !e1925 // public data member + DB::BindableInt32 port; //lint !e1925 // public data member DB::BindableBool secret; //lint !e1925 // public data member DB::BindableBool locked; //lint !e1925 // public data member DB::BindableBool not_recommended; //lint !e1925 // public data member - DB::BindableLong maxCharacterPerAccount; //lint !e1925 // public data member - DB::BindableLong online_player_limit; //lint !e1925 // public data member - DB::BindableLong online_free_trial_limit; //lint !e1925 // public data member + DB::BindableInt32 maxCharacterPerAccount; //lint !e1925 // public data member + DB::BindableInt32 online_player_limit; //lint !e1925 // public data member + DB::BindableInt32 online_free_trial_limit; //lint !e1925 // public data member DB::BindableBool free_trial_can_create_char; //lint !e1925 // public data member - DB::BindableLong online_tutorial_limit; //lint !e1925 // public data member + DB::BindableInt32 online_tutorial_limit; //lint !e1925 // public data member GetClustersQuery(); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp b/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp index 735e9e7a5..82e227edc 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp @@ -26,10 +26,10 @@ namespace TaskGetValidationDataNamespace public: GetValidationDataQuery(); - DB::BindableLong station_id; //lint !e1925 // public data member - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong character_type_id; //lint !e1925 // public data member - DB::BindableLong num_open_slots; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 character_type_id; //lint !e1925 // public data member + DB::BindableInt32 num_open_slots; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); @@ -46,7 +46,7 @@ namespace TaskGetValidationDataNamespace public: GetCompletedTutorialQuery(StationId stationId); - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableBool completed_tutorial; virtual void getSQL(std::string &sql); @@ -74,9 +74,9 @@ namespace TaskGetValidationDataNamespace NetworkId const getCharacterId() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableString<100> event_id; - DB::BindableLong cluster_id; + DB::BindableInt32 cluster_id; DB::BindableNetworkId character_id; private: //disable @@ -100,9 +100,9 @@ namespace TaskGetValidationDataNamespace NetworkId const getCharacterId() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableString<100> item_id; - DB::BindableLong cluster_id; + DB::BindableInt32 cluster_id; DB::BindableNetworkId character_id; private: //disable @@ -116,8 +116,8 @@ namespace TaskGetValidationDataNamespace public: IsClusterAtLimitQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong result; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 result; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/LoginServer/src/shared/TaskMapAccount.h b/engine/server/application/LoginServer/src/shared/TaskMapAccount.h index ad7f04e18..70e34c5b8 100644 --- a/engine/server/application/LoginServer/src/shared/TaskMapAccount.h +++ b/engine/server/application/LoginServer/src/shared/TaskMapAccount.h @@ -34,8 +34,8 @@ class TaskMapAccount : public DB::TaskRequest public: MapAccountQuery(); - DB::BindableLong parentID; //lint !e1925 // public data member - DB::BindableLong childID; //lint !e1925 // public data member + DB::BindableInt32 parentID; //lint !e1925 // public data member + DB::BindableInt32 childID; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h b/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h index e756e2d9b..d2f616ff9 100755 --- a/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h +++ b/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h @@ -34,7 +34,7 @@ class TaskRegisterNewCluster : public DB::TaskRequest public: RegisterClusterQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member DB::BindableString<255> cluster_name; //lint !e1925 // public data member DB::BindableString<255> address; //lint !e1925 // public data member diff --git a/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h b/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h index 525cc3acd..20ba975ba 100755 --- a/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h @@ -35,7 +35,7 @@ class TaskRenameCharacter : public DB::TaskRequest public: RenameCharacterQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member DB::BindableString<127> new_name; //lint !e1925 // public data member diff --git a/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h b/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h index d30d6abd1..2867bd3b3 100755 --- a/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h @@ -33,13 +33,13 @@ class TaskRestoreCharacter : public DB::TaskRequest public: RestoreCharacterQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member DB::BindableString<127> character_name; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member - DB::BindableLong template_id; //lint !e1925 // public data member - DB::BindableLong character_type; //lint !e1925 // public data member - DB::BindableLong result; //lint !e1925 // public data member + DB::BindableInt32 template_id; //lint !e1925 // public data member + DB::BindableInt32 character_type; //lint !e1925 // public data member + DB::BindableInt32 result; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp b/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp index 3f20de28e..4ee5e65ea 100755 --- a/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp @@ -29,8 +29,8 @@ namespace TaskSetPurgeStatusNamespace virtual QueryMode getExecutionMode() const; private: - DB::BindableLong m_account; - DB::BindableLong m_purge_phase; + DB::BindableInt32 m_account; + DB::BindableInt32 m_purge_phase; private: //disable SetPurgeStatusQuery(const SetPurgeStatusQuery&); diff --git a/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h b/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h index 32d21cb1e..118bc4fd4 100755 --- a/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h +++ b/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h @@ -35,9 +35,9 @@ class TaskToggleCharacterDisable : public DB::TaskRequest public: ToggleCharacterDisableQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableInt32 cluster_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableNetworkId character_id; //lint !e1925 // public data member : suppressed because this is a private inner class - DB::BindableLong station_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableInt32 station_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableBool enabled_flag; //lint !e1925 // public data member : suppressed because this is a private inner class diff --git a/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h b/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h index 1e1def17e..8c152a11d 100755 --- a/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h +++ b/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h @@ -34,7 +34,7 @@ class TaskToggleCompletedTutorial : public DB::TaskRequest public: ToggleCompletedTutorialQuery(); - DB::BindableLong station_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableInt32 station_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableBool completed_flag; //lint !e1925 // public data member : suppressed because this is a private inner class virtual void getSQL(std::string &sql); diff --git a/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h b/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h index 325014ff9..97b56c1ef 100755 --- a/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h +++ b/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h @@ -36,10 +36,10 @@ class TaskUpgradeAccount : public DB::TaskRequest public: SetCharacterTypeQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member DB::BindableNetworkId character; //lint !e1925 // public data member - DB::BindableLong character_type; //lint !e1925 // public data member + DB::BindableInt32 character_type; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); @@ -56,9 +56,9 @@ class TaskUpgradeAccount : public DB::TaskRequest public: QueryJediQuery(); - DB::BindableLong station_id; //lint !e1925 // public data member - DB::BindableLong character_type; //lint !e1925 // public data member - DB::BindableLong result; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableInt32 character_type; //lint !e1925 // public data member + DB::BindableInt32 result; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); @@ -76,8 +76,8 @@ class TaskUpgradeAccount : public DB::TaskRequest public: AddJediQuery(); - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); @@ -140,10 +140,10 @@ class TaskVacateUnlockedSlot : public DB::TaskRequest public: GetOnlyOpenCharacterSlotsQuery(); - DB::BindableLong station_id; //lint !e1925 // public data member - DB::BindableLong cluster_id; //lint !e1925 // public data member - DB::BindableLong character_type_id; //lint !e1925 // public data member - DB::BindableLong num_open_slots; //lint !e1925 // public data member + DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableInt32 character_type_id; //lint !e1925 // public data member + DB::BindableInt32 num_open_slots; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h b/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h index 712b95bd6..3a5cb54df 100755 --- a/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h +++ b/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h @@ -44,11 +44,11 @@ class TaskUpdateSPCharacterProfileData : public DB::TaskRequest DB::BindableDouble cash_balance; DB::BindableDouble bank_balance; DB::BindableString<500> objectTemplateName; - DB::BindableLong stationId; + DB::BindableInt32 stationId; DB::BindableNetworkId containedBy; - DB::BindableLong createTime; - DB::BindableLong playedTime; - DB::BindableLong numLots; + DB::BindableInt32 createTime; + DB::BindableInt32 playedTime; + DB::BindableInt32 numLots; virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/library/codegen/make_queries.pl b/engine/server/library/codegen/make_queries.pl index 7858d1c2c..01c72158c 100755 --- a/engine/server/library/codegen/make_queries.pl +++ b/engine/server/library/codegen/make_queries.pl @@ -126,7 +126,7 @@ sub writeHeader $i++; } - $newText.="\tDB::BindableLong\t\t\t m_numItems;\n"; + $newText.="\tDB::BindableInt32\t\t\t m_numItems;\n"; $newText.="};\n"; $newText.="\n"; diff --git a/engine/server/library/codegen/make_schema_h.pl b/engine/server/library/codegen/make_schema_h.pl index d79e1a5a9..89b5f384f 100755 --- a/engine/server/library/codegen/make_schema_h.pl +++ b/engine/server/library/codegen/make_schema_h.pl @@ -128,7 +128,7 @@ sub parseTable } if ($tablename eq "Object") { - $decl{$tablename}.="\n\tDB::BindableLong container_level;\n"; + $decl{$tablename}.="\n\tDB::BindableInt32 container_level;\n"; } $decl{$tablename}.="\n\tvirtual void copy(const DB::Row &rhs)\n"; @@ -205,8 +205,8 @@ sub translateType my($dbtype)=@_; SWITCH: { - if ($dbtype eq "int") { $ctype="DB::BindableLong"; last SWITCH; } - if ($dbtype eq "number") { $ctype="DB::BindableLong"; last SWITCH; } + if ($dbtype eq "int") { $ctype="DB::BindableInt32"; last SWITCH; } + if ($dbtype eq "number") { $ctype="DB::BindableInt32"; last SWITCH; } if ($dbtype eq "float") { $ctype="DB::BindableDouble"; last SWITCH; } if ($dbtype eq "date") { $ctype="DB::BindableTimestamp"; last SWITCH; } if ($dbtype eq "char(1)") { $ctype="DB::BindableBool"; last SWITCH; } @@ -224,8 +224,8 @@ sub translateBufferType my($dbtype)=@_; SWITCH: { - if ($dbtype eq "int") { $ctype="DB::BindableLong"; last SWITCH; } - if ($dbtype eq "number") { $ctype="DB::BindableLong"; last SWITCH; } + if ($dbtype eq "int") { $ctype="DB::BindableInt32"; last SWITCH; } + if ($dbtype eq "number") { $ctype="DB::BindableInt32"; last SWITCH; } if ($dbtype eq "float") { $ctype="DB::BindableDouble"; last SWITCH; } if ($dbtype eq "date") { $ctype="DB::BindableTimestamp"; last SWITCH; } if ($dbtype eq "char(1)") { $ctype="DB::BindableBool"; last SWITCH; } diff --git a/engine/server/library/serverDatabase/src/shared/CharacterLocator.h b/engine/server/library/serverDatabase/src/shared/CharacterLocator.h index fc1fa2030..8c655ee03 100755 --- a/engine/server/library/serverDatabase/src/shared/CharacterLocator.h +++ b/engine/server/library/serverDatabase/src/shared/CharacterLocator.h @@ -50,7 +50,7 @@ class CharacterLocator : public ObjectLocator LocateCharacterQuery& operator=(const LocateCharacterQuery&); //disable public: - DB::BindableLong object_count; + DB::BindableInt32 object_count; DB::BindableNetworkId object_id; private: diff --git a/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h index 3ca8cd557..b33777d8b 100755 --- a/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h +++ b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h @@ -32,11 +32,11 @@ class CharacterNameLocator : public ObjectLocator struct CharacterNameRow { DB::BindableNetworkId character_id; - DB::BindableLong character_station_id; + DB::BindableInt32 character_station_id; DB::BindableString<127> character_name; DB::BindableString<127> character_full_name; - DB::BindableLong character_create_time; - DB::BindableLong character_last_login_time; + DB::BindableInt32 character_create_time; + DB::BindableInt32 character_last_login_time; }; class CharacterNameQuery : public DB::Query diff --git a/engine/server/library/serverDatabase/src/shared/CharacterQueries.h b/engine/server/library/serverDatabase/src/shared/CharacterQueries.h index 9cc1dfc87..b4a4b8a20 100755 --- a/engine/server/library/serverDatabase/src/shared/CharacterQueries.h +++ b/engine/server/library/serverDatabase/src/shared/CharacterQueries.h @@ -36,7 +36,7 @@ namespace DBQuery { DB::BindableDouble x; DB::BindableDouble y; DB::BindableDouble z; - DB::BindableLong station_id; + DB::BindableInt32 station_id; }; GetCharacters() {} @@ -76,7 +76,7 @@ namespace DBQuery { virtual QueryMode getExecutionMode() const; private: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId object_id; DB::BindableString<127> character_name; DB::BindableString<127> normalized_name; @@ -105,7 +105,7 @@ namespace DBQuery { DB::BindableNetworkId object_id; DB::BindableString<127> character_name; DB::BindableString<127> normalized_name; - DB::BindableLong result; + DB::BindableInt32 result; private: RenameCharacter (const RenameCharacter&); // disable diff --git a/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h index 0ab8a0cc5..112c35151 100755 --- a/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h +++ b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h @@ -45,10 +45,10 @@ class DeleteCharacterCustomPersistStep : public CustomPersistStep virtual QueryMode getExecutionMode() const; public: - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId character_id; - DB::BindableLong delete_minutes; - DB::BindableLong result; + DB::BindableInt32 delete_minutes; + DB::BindableInt32 result; private: // disable: DeleteCharacterQuery(const DeleteCharacterQuery&); diff --git a/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h index e5e24bea1..5f28563e0 100755 --- a/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h +++ b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h @@ -12,7 +12,7 @@ #include "Unicode.h" #include "serverDatabase/CustomPersistStep.h" -#include "sharedDatabaseInterface/DbBindableLong.h" +#include "sharedDatabaseInterface/DbBindableInt32.h" #include "sharedDatabaseInterface/BindableNetworkId.h" #include "sharedDatabaseInterface/DbQuery.h" #include "sharedFoundation/NetworkId.h" @@ -50,7 +50,7 @@ class FixLoadWithCustomPersistStep : public CustomPersistStep FixLoadWithQuery &operator=(FixLoadWithQuery const &); DB::BindableNetworkId topmost_object; DB::BindableNetworkId starting_loadwith; - DB::BindableLong max_depth; + DB::BindableInt32 max_depth; }; private: diff --git a/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h index b99382d21..7ccb5abc3 100755 --- a/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h @@ -41,10 +41,10 @@ namespace DBQuery { GetChunkQuery& operator=(const GetChunkQuery&); //disable private: - DB::BindableLong object_count; + DB::BindableInt32 object_count; DB::BindableString<50> scene_id; - DB::BindableLong node_x; - DB::BindableLong node_z; + DB::BindableInt32 node_x; + DB::BindableInt32 node_z; std::string m_schema; }; diff --git a/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h index 5e854cc07..a79ed8778 100755 --- a/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h @@ -31,8 +31,8 @@ namespace DBQuery int getMinVersionNumber(); private: - DB::BindableLong current_version_number; - DB::BindableLong min_version_number; + DB::BindableInt32 current_version_number; + DB::BindableInt32 min_version_number; private: GetGoldVersionNumberQuery (const GetGoldVersionNumberQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h index 5e8f70b31..593510839 100755 --- a/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h @@ -43,7 +43,7 @@ namespace DBQuery GetOIDsQuery(const GetOIDsQuery&); GetOIDsQuery& operator=(const GetOIDsQuery&); - DB::BindableLong min_count; + DB::BindableInt32 min_count; DB::BindableNetworkId start_id; DB::BindableNetworkId end_id; }; diff --git a/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h index 08563f616..6789649c5 100755 --- a/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h @@ -30,7 +30,7 @@ namespace DBQuery int getTimestamp(); private: - DB::BindableLong timestamp; + DB::BindableInt32 timestamp; private: GetTimestampQuery(const GetTimestampQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h index 8871468fd..665765be2 100755 --- a/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h @@ -31,8 +31,8 @@ namespace DBQuery int getMinVersionNumber(); private: - DB::BindableLong current_version_number; - DB::BindableLong min_version_number; + DB::BindableInt32 current_version_number; + DB::BindableInt32 min_version_number; private: GetVersionNumberQuery (const GetVersionNumberQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h index 65e40e63c..0e6d412b3 100755 --- a/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h +++ b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h @@ -34,8 +34,8 @@ class LazyDeleteQuery : public DB::Query private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; - DB::BindableLong m_enableDatabaseLogging; + DB::BindableInt32 m_numItems; + DB::BindableInt32 m_enableDatabaseLogging; private: LazyDeleteQuery(const LazyDeleteQuery&); //disable diff --git a/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h index b5851bc98..03670391c 100755 --- a/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h +++ b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h @@ -12,7 +12,7 @@ #include "Unicode.h" #include "serverDatabase/CustomPersistStep.h" -#include "sharedDatabaseInterface/DbBindableLong.h" +#include "sharedDatabaseInterface/DbBindableInt32.h" #include "sharedDatabaseInterface/BindableNetworkId.h" #include "sharedDatabaseInterface/DbQuery.h" #include "sharedFoundation/NetworkId.h" @@ -52,7 +52,7 @@ class MoveToPlayerCustomPersistStep : public CustomPersistStep MoveToPlayerQuery &operator=(MoveToPlayerQuery const &); DB::BindableNetworkId object_id; DB::BindableNetworkId target_player; - DB::BindableLong max_depth; + DB::BindableInt32 max_depth; bool m_useBank; bool m_useDatapad; }; diff --git a/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h index 3f7695b8a..ad7cc24b5 100755 --- a/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h +++ b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h @@ -30,11 +30,11 @@ namespace DBQuery public: DB::BindableString<50> scene_id; DB::BindableNetworkId object_id; - DB::BindableLong chunk_x; - DB::BindableLong chunk_z; - DB::BindableLong preload_range; - DB::BindableLong city_server_id; - DB::BindableLong wilderness_server_id; + DB::BindableInt32 chunk_x; + DB::BindableInt32 chunk_z; + DB::BindableInt32 preload_range; + DB::BindableInt32 city_server_id; + DB::BindableInt32 wilderness_server_id; public: virtual bool bindParameters(); diff --git a/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h index 77d4e0779..7302ace93 100755 --- a/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h +++ b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h @@ -28,7 +28,7 @@ namespace DBQuery virtual bool bindColumns(); private: - DB::BindableLong timestamp; + DB::BindableInt32 timestamp; private: SaveTimestampQuery(const SaveTimestampQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/ScriptQueries.h b/engine/server/library/serverDatabase/src/shared/ScriptQueries.h index ec916eec4..2f5cbf81a 100755 --- a/engine/server/library/serverDatabase/src/shared/ScriptQueries.h +++ b/engine/server/library/serverDatabase/src/shared/ScriptQueries.h @@ -45,7 +45,7 @@ namespace DBQuery struct ScriptRow { DB::BindableNetworkId object_id; - DB::BindableLong index; + DB::BindableInt32 index; DB::BindableString<128> script_name; }; diff --git a/engine/server/library/serverDatabase/src/shared/StructureQueries.h b/engine/server/library/serverDatabase/src/shared/StructureQueries.h index cee4458de..3893f6afb 100755 --- a/engine/server/library/serverDatabase/src/shared/StructureQueries.h +++ b/engine/server/library/serverDatabase/src/shared/StructureQueries.h @@ -35,7 +35,7 @@ namespace DBQuery { DB::BindableDouble y; DB::BindableDouble z; DB::BindableNetworkId character_id; - DB::BindableLong deleted; + DB::BindableInt32 deleted; }; GetStructures() {} diff --git a/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h index db26fc168..2810b9ee6 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h +++ b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h @@ -44,7 +44,7 @@ class TaskGetCharactersForAccount:public DB::TaskRequest public: // input: - DB::BindableLong station_id; //lint !e1925 public data member Suppresed because it's in a private inner class + DB::BindableInt32 station_id; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class //output: @@ -122,7 +122,7 @@ class TaskGetDeletedItems:public DB::TaskRequest public: // input: DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class - DB::BindableLong page_number; + DB::BindableInt32 page_number; private: CSGetDeletedItemsQuery(const CSGetDeletedItemsQuery&); @@ -211,7 +211,7 @@ class TaskGetCharacterId:public DB::TaskRequest struct CharacterIdRow { DB::BindableNetworkId characterId; - DB::BindableLong stationId; + DB::BindableInt32 stationId; DB::BindableString characterName; }; @@ -310,7 +310,7 @@ class TaskCsUndeleteItem : public DB::TaskRequest private: DB::BindableNetworkId characterId; DB::BindableNetworkId itemId; - DB::BindableLong move; + DB::BindableInt32 move; private: CsUndeleteItemQuery(const CsUndeleteItemQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h index 6ed1dad44..6a3030008 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h +++ b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h @@ -36,8 +36,8 @@ class TaskChangeStationId : public DB::TaskRequest public: ChangeStationIdQuery(); - DB::BindableLong destination_station_id; //lint !e1925 // public data member - DB::BindableLong source_station_id; //lint !e1925 // public data member + DB::BindableInt32 destination_station_id; //lint !e1925 // public data member + DB::BindableInt32 source_station_id; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h index 6cf4d3e95..1ce96cf1c 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h @@ -44,7 +44,7 @@ class TaskCheckCharacterName : public DB::TaskRequest public: DB::BindableString<127> character_name; - DB::BindableLong result; + DB::BindableInt32 result; private: CheckCharacterNameQuery(const CheckCharacterNameQuery&); diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp index 5ea2e6c81..09711a525 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp +++ b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp @@ -35,7 +35,7 @@ namespace TaskGetStructuresForPurgeNamespace NetworkId getOwnerId() const; private: - DB::BindableLong m_station_id; + DB::BindableInt32 m_station_id; DB::BindableNetworkId m_structure_id; DB::BindableNetworkId m_owner_id; @@ -59,7 +59,7 @@ namespace TaskGetStructuresForPurgeNamespace Unicode::String getVendorName() const; private: - DB::BindableLong m_station_id; + DB::BindableInt32 m_station_id; DB::BindableNetworkId m_vendor_id; DB::BindableNetworkId m_owner_id; DB::BindableUnicode<128> m_vendor_name; diff --git a/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h index ed8272d51..7d6a9d29d 100755 --- a/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h +++ b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h @@ -58,8 +58,8 @@ class WorldContainerLocator : public ObjectLocator private: DB::BindableVarrayString container_ids; - DB::BindableLong num_containers; - DB::BindableLong num_objects_found; + DB::BindableInt32 num_containers; + DB::BindableInt32 num_objects_found; std::string m_schema; private: diff --git a/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h b/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h new file mode 100755 index 000000000..0689bee11 --- /dev/null +++ b/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h @@ -0,0 +1 @@ +#include "../../src/shared/core/DbBindableInt32.h" diff --git a/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h b/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h deleted file mode 100755 index b11e3a91e..000000000 --- a/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../src/shared/core/DbBindableLong.h" diff --git a/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt b/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt index 84c3cd983..39dedc43d 100644 --- a/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt +++ b/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt @@ -18,8 +18,8 @@ set(SHARED_SOURCES shared/core/DbBindableDouble.h shared/core/DbBindableInt64.cpp shared/core/DbBindableInt64.h - shared/core/DbBindableLong.cpp - shared/core/DbBindableLong.h + shared/core/DbBindableInt32.cpp + shared/core/DbBindableInt32.h shared/core/DbBindableString.cpp shared/core/DbBindableString.h shared/core/DbBindableUnicode.cpp diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h index 03c2d7dc4..c6f111509 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h @@ -23,7 +23,7 @@ #include "sharedDatabaseInterface/DbBindableBool.h" #include "sharedDatabaseInterface/DbBindableDouble.h" #include "sharedDatabaseInterface/DbBindableInt64.h" -#include "sharedDatabaseInterface/DbBindableLong.h" +#include "sharedDatabaseInterface/DbBindableInt32.h" #include "sharedDatabaseInterface/DbBindableString.h" #include "sharedDatabaseInterface/DbBindableUnicode.h" diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.cpp similarity index 71% rename from engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp rename to engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.cpp index c487f4285..efd31d58b 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.cpp @@ -1,12 +1,12 @@ // ====================================================================== // -// DBBindableLong.cpp +// DBBindableInt32.cpp // copyright (c) 2001 Sony Online Entertainment // // ====================================================================== #include "sharedDatabaseInterface/FirstSharedDatabaseInterface.h" -#include "sharedDatabaseInterface/DbBindableLong.h" +#include "sharedDatabaseInterface/DbBindableInt32.h" #include @@ -14,15 +14,15 @@ using namespace DB; -BindableLong::BindableLong() : Bindable(), value(-999) +BindableInt32::BindableInt32() : Bindable(), value(-999) { } -BindableLong::BindableLong(int64_t _value) : Bindable(sizeof(value)), value(_value) +BindableInt32::BindableInt32(int32_t _value) : Bindable(sizeof(value)), value(_value) { } -void *BindableLong::getBuffer() +void *BindableInt32::getBuffer() { return &value; //lint !e1536 // exposing private member } @@ -30,14 +30,14 @@ void *BindableLong::getBuffer() // ---------------------------------------------------------------------- -int64_t BindableLong::getValue() const +int32_t BindableInt32::getValue() const { return value; } // ---------------------------------------------------------------------- -BindableLong &BindableLong::operator=(int64_t rhs) +BindableInt32 &BindableInt32::operator=(int32_t rhs) { indicator=sizeof(value); value=rhs; @@ -46,7 +46,7 @@ BindableLong &BindableLong::operator=(int64_t rhs) // ---------------------------------------------------------------------- -void BindableLong::setValue(int64_t rhs) +void BindableInt32::setValue(int32_t rhs) { indicator=sizeof(value); value=rhs; @@ -54,7 +54,7 @@ void BindableLong::setValue(int64_t rhs) // ---------------------------------------------------------------------- -std::string BindableLong::outputValue() const +std::string BindableInt32::outputValue() const { char temp[255]; snprintf(temp,sizeof(temp),"%li",value); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.h similarity index 61% rename from engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h rename to engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.h index 037b59f45..4fccc63ff 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.h @@ -1,12 +1,12 @@ // ====================================================================== // -// DBBindableLong.h +// DBBindableInt32.h // copyright (c) 2001 Sony Online Entertainment // // ====================================================================== -#ifndef INCLUDED_DBBindableLong_H -#define INCLUDED_DBBindableLong_H +#ifndef INCLUDED_DBBindableInt32_H +#define INCLUDED_DBBindableInt32_H // ====================================================================== @@ -19,15 +19,15 @@ namespace DB { /** * Represents a long in C++, bound to an INTEGER or NUMBER database column */ - class BindableLong : public Bindable + class BindableInt32 : public Bindable { public: - BindableLong(); - explicit BindableLong(int64_t _value); + BindableInt32(); + explicit BindableInt32(int32_t _value); - int64_t getValue() const; - void setValue(const int64_t rhs); - BindableLong &operator=(const int64_t rhs); + int32_t getValue() const; + void setValue(const int32_t rhs); + BindableInt32 &operator=(const int32_t rhs); // following alternate getValue's are provided for convenience, particularly in // the auto-generated code: @@ -37,76 +37,58 @@ namespace DB { void getValue(uint16_t &buffer) const; void getValue(int32_t &buffer) const; void getValue(uint32_t &buffer) const; - void getValue(int64_t &buffer) const; - void getValue(uint64_t &buffer) const; void *getBuffer(); virtual std::string outputValue() const; private: - int64_t value; + int32_t value; }; //lint !e1721 !e1509 // no virtual destructor, unusual operator = } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(int8_t &buffer) const +inline void DB::BindableInt32::getValue(int8_t &buffer) const { buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint8_t &buffer) const +inline void DB::BindableInt32::getValue(uint8_t &buffer) const { buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(int16_t &buffer) const +inline void DB::BindableInt32::getValue(int16_t &buffer) const { buffer=getValue(); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint16_t &buffer) const +inline void DB::BindableInt32::getValue(uint16_t &buffer) const { buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(int32_t &buffer) const +inline void DB::BindableInt32::getValue(int32_t &buffer) const { buffer=getValue(); } // ---------------------------------------------------------------------- -inline void DB::BindableLong::getValue(uint32_t &buffer) const +inline void DB::BindableInt32::getValue(uint32_t &buffer) const { buffer=static_cast(getValue()); } -// ---------------------------------------------------------------------- - -inline void DB::BindableLong::getValue(int64_t &buffer) const -{ - buffer=getValue(); -} - -// ---------------------------------------------------------------------- - -inline void DB::BindableLong::getValue(uint64_t &buffer) const -{ - buffer=static_cast(getValue()); -} - - - // ====================================================================== #endif diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp index f78c6b2e5..9819b73c8 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp @@ -181,13 +181,13 @@ void Query::setColArrayMode(size_t skipSize, size_t numElements) impl->setColArrayMode(skipSize, numElements); } -bool Query::bindCol(BindableLong &buffer) +bool Query::bindCol(BindableInt32 &buffer) { NOT_NULL(impl); return impl->bindCol(buffer); } -bool Query::bindParameter(BindableLong &buffer) +bool Query::bindParameter(BindableInt32 &buffer) { NOT_NULL(impl); return impl->bindParameter(buffer); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h index e21e24c48..d316bceed 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h @@ -17,7 +17,7 @@ namespace DB { class Session; class QueryImpl; - class BindableLong; + class BindableInt32; class BindableVarray; class Query @@ -70,8 +70,8 @@ namespace DB { */ void setColArrayMode(size_t skipSize, size_t numElements); - bool bindCol(BindableLong &buffer); - bool bindParameter(BindableLong &buffer); + bool bindCol(BindableInt32 &buffer); + bool bindParameter(BindableInt32 &buffer); bool bindCol(BindableDouble &buffer); bool bindParameter(BindableDouble &buffer); bool bindCol(BindableStringBase &buffer); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h index a978dd771..1e13658ea 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h @@ -19,7 +19,7 @@ namespace DB class BindableBool; class BindableDouble; class BindableInt64; - class BindableLong; + class BindableInt32; class BindableStringBase; class BindableUnicodeBase; class BindableVarray; @@ -54,8 +54,8 @@ namespace DB virtual void setColArrayMode(size_t skipSize, size_t numElements)=0; - virtual bool bindCol(BindableLong &buffer) =0; - virtual bool bindParameter(BindableLong &buffer) =0; + virtual bool bindCol(BindableInt32 &buffer) =0; + virtual bool bindParameter(BindableInt32 &buffer) =0; virtual bool bindCol(BindableDouble &buffer) =0; virtual bool bindParameter(BindableDouble &buffer) =0; virtual bool bindCol(BindableStringBase &buffer) =0; diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h b/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h index cca5e8912..11556487b 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h @@ -7,7 +7,7 @@ class DBTestQuery : public DB::Query { public: - DB::BindableLong value; + DB::BindableInt32 value; DBTestQuery(); virtual void getSQL(std::string &sql); diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp index b4486dc8c..46e23a9cd 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp @@ -448,7 +448,7 @@ size_t DB::OCIQueryImpl::BindRec::getLengthSkipSize() // ====================================================================== -bool DB::OCIQueryImpl::bindCol(BindableLong &buffer) +bool DB::OCIQueryImpl::bindCol(BindableInt32 &buffer) { BindRec *br=addBindRec(buffer); @@ -478,7 +478,7 @@ bool DB::OCIQueryImpl::bindCol(BindableLong &buffer) // ---------------------------------------------------------------------- -bool DB::OCIQueryImpl::bindParameter(BindableLong &buffer) +bool DB::OCIQueryImpl::bindParameter(BindableInt32 &buffer) { BindRec *br=addBindRec(buffer); diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h index 6cf41e37b..9276c849e 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h @@ -50,8 +50,8 @@ namespace DB virtual void setColArrayMode(size_t skipSize, size_t numElements); - virtual bool bindCol(BindableLong &buffer); - virtual bool bindParameter(BindableLong &buffer); + virtual bool bindCol(BindableInt32 &buffer); + virtual bool bindParameter(BindableInt32 &buffer); virtual bool bindCol(BindableDouble &buffer); virtual bool bindParameter(BindableDouble &buffer); virtual bool bindCol(BindableStringBase &buffer); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h index ff96a9f02..0bdc0a646 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h @@ -41,7 +41,7 @@ class TaskBrokenObjectCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableLong result; + DB::BindableInt32 result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h index 2d35ab60e..7075c4853 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h @@ -41,7 +41,7 @@ class TaskMarketAttributesCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableLong result; + DB::BindableInt32 result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h index 0efeb8609..549ae6a6b 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h @@ -41,7 +41,7 @@ class TaskMessagesCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableLong result; + DB::BindableInt32 result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h index fd324d45e..0a8561f1d 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h @@ -41,7 +41,7 @@ class TaskObjvarNameCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableLong result; + DB::BindableInt32 result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h index baafd4c2a..cb097e531 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h @@ -41,7 +41,7 @@ class TaskOrphanedObjectCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableLong result; + DB::BindableInt32 result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h index e715be43b..68348d43b 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h @@ -41,7 +41,7 @@ class TaskVendorObjectCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableLong result; + DB::BindableInt32 result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp index dc9f96fac..756c06b86 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp @@ -1033,7 +1033,7 @@ void SwgSnapshot::encodeComponents(const NetworkId &objectId, Archive::ByteStrea // ---------------------------------------------------------------------- void -SwgSnapshot::decodeLocation(Archive::ReadIterator &data, DB::BindableDouble &x, DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableLong &planet) const { +SwgSnapshot::decodeLocation(Archive::ReadIterator &data, DB::BindableDouble &x, DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableInt32 &planet) const { Location temp; Archive::get(data, temp); Vector vec = temp.getCoordinates(); @@ -1047,7 +1047,7 @@ SwgSnapshot::decodeLocation(Archive::ReadIterator &data, DB::BindableDouble &x, // ---------------------------------------------------------------------- void -SwgSnapshot::encodeLocation(Archive::ByteStream &data, const DB::BindableDouble &x, const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableLong &planet) const { +SwgSnapshot::encodeLocation(Archive::ByteStream &data, const DB::BindableDouble &x, const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableInt32 &planet) const { Location temp(Vector(static_cast(x.getValue()), static_cast(y.getValue()), static_cast(z.getValue())), cell.getValue(), planet.getValue()); Archive::put(data, temp); } diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h index e1b77dba9..2f6e6c3a6 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h @@ -419,7 +419,7 @@ class SwgSnapshot : public Snapshot void decodeVector (Archive::ReadIterator &data, DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z) const; void decodeMatchMakingId (Archive::ReadIterator &data, DB::BufferString &column) const; void decodeComponents (NetworkId const & objectId, Archive::ReadIterator &data, bool isBaseline); - void decodeLocation (Archive::ReadIterator &data, DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableLong &planet) const; + void decodeLocation (Archive::ReadIterator &data, DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableInt32 &planet) const; void decodeWaypoints (const NetworkId &objectId, Archive::ReadIterator &data, bool isBaseline); void decodeSingleWaypoint (const NetworkId &objectId, Archive::ReadIterator &data, bool isBaseline); void decodeQuests (NetworkId const & networkId, Archive::ReadIterator &data, DB::BufferString &part1, DB::BufferString &part2, DB::BufferString &part3, DB::BufferString &part4) const; @@ -439,7 +439,7 @@ class SwgSnapshot : public Snapshot void encodeVector (Archive::ByteStream &data, const DB::BindableDouble &x, const DB::BindableDouble &y, const DB::BindableDouble &z) const; void encodeMatchMakingId (Archive::ByteStream &data, const DB::BufferString &column) const; void encodeComponents (const NetworkId &objectId, Archive::ByteStream &data) const; - void encodeLocation (Archive::ByteStream &data, const DB::BindableDouble &x,const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableLong &planet) const; + void encodeLocation (Archive::ByteStream &data, const DB::BindableDouble &x,const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableInt32 &planet) const; void encodeWaypoints (const NetworkId & objectId, Archive::ByteStream &data) const; void encodeSingleWaypoint (const NetworkId & objectId, Archive::ByteStream &data) const; void encodeQuests (Archive::ByteStream &data, DB::BufferString const &part1, DB::BufferString const &part2, DB::BufferString const &part3, DB::BufferString const &part4) const; diff --git a/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template b/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template index 327283d0e..21d290cc6 100644 --- a/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template +++ b/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template @@ -45,7 +45,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayString m_region_names; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class BattlefieldMarkerObjectQuerySelect : public DB::Query @@ -95,7 +95,7 @@ private: DB::BindableVarrayNumber m_time_last_checkeds; DB::BindableVarrayString m_is_publics; DB::BindableVarrayNumber m_city_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class BuildingObjectQuerySelect : public DB::Query @@ -143,7 +143,7 @@ private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_cell_numbers; DB::BindableVarrayString m_is_publics; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class CellObjectQuerySelect : public DB::Query @@ -189,7 +189,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class CityObjectQuerySelect : public DB::Query @@ -274,7 +274,7 @@ private: DB::BindableVarrayNumber m_ws_xs; DB::BindableVarrayNumber m_ws_ys; DB::BindableVarrayNumber m_ws_zs; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class CreatureObjectQuerySelect : public DB::Query @@ -320,7 +320,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class FactoryObjectQuerySelect : public DB::Query @@ -366,7 +366,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class GuildObjectQuerySelect : public DB::Query @@ -419,7 +419,7 @@ private: DB::BindableVarrayString m_hopper_resources; DB::BindableVarrayNumber m_hopper_amounts; DB::BindableVarrayString m_resource_types; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class HarvesterInstallationObjectQuerySelect : public DB::Query @@ -471,7 +471,7 @@ private: DB::BindableVarrayNumber m_activate_start_times; DB::BindableVarrayNumber m_powers; DB::BindableVarrayNumber m_power_rates; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class InstallationObjectQuerySelect : public DB::Query @@ -518,7 +518,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_counts; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class IntangibleObjectQuerySelect : public DB::Query @@ -569,7 +569,7 @@ private: DB::BindableVarrayNumber m_items_per_containers; DB::BindableVarrayNumber m_manufacture_times; DB::BindableVarrayNumber m_draft_schematics; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class ManufactureSchematicObjectQuerySelect : public DB::Query @@ -615,7 +615,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class ManufactureInstallationObjectQuerySelect : public DB::Query @@ -684,7 +684,7 @@ private: DB::BindableVarrayNumber m_mission_types; DB::BindableVarrayNumber m_target_appearances; DB::BindableVarrayString m_target_names; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class MissionObjectQuerySelect : public DB::Query @@ -731,7 +731,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayString m_planet_names; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class PlanetObjectQuerySelect : public DB::Query @@ -813,7 +813,7 @@ private: DB::BindableVarrayString m_show_backpacks; DB::BindableVarrayString m_show_helmets; DB::BindableVarrayString m_collections2s; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class PlayerObjectQuerySelect : public DB::Query @@ -888,7 +888,7 @@ private: DB::BindableVarrayString m_task_description11s; DB::BindableVarrayString m_task_title12s; DB::BindableVarrayString m_task_description12s; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class PlayerQuestObjectQuerySelect : public DB::Query @@ -937,7 +937,7 @@ private: DB::BindableVarrayString m_resource_types; DB::BindableVarrayNumber m_quantitys; DB::BindableVarrayString m_sources; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class ResourceContainerObjectQuerySelect : public DB::Query @@ -1034,7 +1034,7 @@ private: DB::BindableVarrayNumber m_cargo_hold_contents_maximums; DB::BindableVarrayNumber m_cargo_hold_contents_currents; DB::BindableVarrayString m_cargo_hold_contentss; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class ShipObjectQuerySelect : public DB::Query @@ -1080,7 +1080,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class StaticObjectQuerySelect : public DB::Query @@ -1139,7 +1139,7 @@ private: DB::BindableVarrayNumber m_conditions; DB::BindableVarrayString m_creator_ids; DB::BindableVarrayNumber m_source_draft_schematics; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class TangibleObjectQuerySelect : public DB::Query @@ -1189,7 +1189,7 @@ private: DB::BindableVarrayString m_target_server_template_names; DB::BindableVarrayString m_target_shared_template_names; DB::BindableVarrayString m_waypoints; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class TokenObjectQuerySelect : public DB::Query @@ -1235,7 +1235,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class UniverseObjectQuerySelect : public DB::Query @@ -1282,7 +1282,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_boguss; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class VehicleObjectQuerySelect : public DB::Query @@ -1340,7 +1340,7 @@ private: DB::BindableVarrayNumber m_damage_radiuss; DB::BindableVarrayNumber m_min_ranges; DB::BindableVarrayNumber m_max_ranges; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class WeaponObjectQuerySelect : public DB::Query diff --git a/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template b/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template index 7297cfd7a..9d4989a04 100644 --- a/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template +++ b/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template @@ -23,38 +23,38 @@ struct PlayerObjectRow : public DB::Row enum {QUEST_DATA_SIZE=4000}; DB::BindableNetworkId object_id; - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId house_id; - DB::BindableLong account_num_lots; + DB::BindableInt32 account_num_lots; DB::BindableBool account_is_outcast; DB::BindableDouble account_cheater_level; - DB::BindableLong account_max_lots_adjustment; + DB::BindableInt32 account_max_lots_adjustment; DB::BindableString<200> personal_profile_id; DB::BindableString<200> character_profile_id; DB::BindableString<200> skill_title; - DB::BindableLong born_date; - DB::BindableLong played_time; + DB::BindableInt32 born_date; + DB::BindableInt32 played_time; DB::BindableDouble force_regen_rate; - DB::BindableLong force_power; - DB::BindableLong max_force_power; + DB::BindableInt32 force_power; + DB::BindableInt32 max_force_power; DB::BindableBitArray<2047> active_quests; DB::BindableBitArray<2047> completed_quests; - DB::BindableLong current_quest; + DB::BindableInt32 current_quest; DB::BindableString quests; - DB::BindableLong role_icon_choice; + DB::BindableInt32 role_icon_choice; DB::BindableString quests2; DB::BindableString quests3; DB::BindableString quests4; DB::BindableString<200> skill_template; DB::BindableString<200> working_skill; - DB::BindableLong current_gcw_points; - DB::BindableLong current_gcw_rating; - DB::BindableLong current_pvp_kills; + DB::BindableInt32 current_gcw_points; + DB::BindableInt32 current_gcw_rating; + DB::BindableInt32 current_pvp_kills; DB::BindableInt64 lifetime_gcw_points; - DB::BindableLong max_gcw_imperial_rating; - DB::BindableLong max_gcw_rebel_rating; - DB::BindableLong lifetime_pvp_kills; - DB::BindableLong next_gcw_rating_calc_time; + DB::BindableInt32 max_gcw_imperial_rating; + DB::BindableInt32 max_gcw_rebel_rating; + DB::BindableInt32 lifetime_pvp_kills; + DB::BindableInt32 next_gcw_rating_calc_time; DB::BindableBitArray<16000> collections; DB::BindableBool show_backpack; DB::BindableBool show_helmet; @@ -80,38 +80,38 @@ struct PlayerObjectRow : public DB::Row struct PlayerObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong station_id; + DB::BindableInt32 station_id; DB::BindableNetworkId house_id; - DB::BindableLong account_num_lots; + DB::BindableInt32 account_num_lots; DB::BindableBool account_is_outcast; DB::BindableDouble account_cheater_level; - DB::BindableLong account_max_lots_adjustment; + DB::BindableInt32 account_max_lots_adjustment; DB::BufferString personal_profile_id; DB::BufferString character_profile_id; DB::BufferString skill_title; - DB::BindableLong born_date; - DB::BindableLong played_time; + DB::BindableInt32 born_date; + DB::BindableInt32 played_time; DB::BindableDouble force_regen_rate; - DB::BindableLong force_power; - DB::BindableLong max_force_power; + DB::BindableInt32 force_power; + DB::BindableInt32 max_force_power; DB::BindableBitArray<2047> active_quests; DB::BindableBitArray<2047> completed_quests; - DB::BindableLong current_quest; + DB::BindableInt32 current_quest; DB::BufferString quests; - DB::BindableLong role_icon_choice; + DB::BindableInt32 role_icon_choice; DB::BufferString quests2; DB::BufferString quests3; DB::BufferString quests4; DB::BufferString skill_template; DB::BufferString working_skill; - DB::BindableLong current_gcw_points; - DB::BindableLong current_gcw_rating; - DB::BindableLong current_pvp_kills; + DB::BindableInt32 current_gcw_points; + DB::BindableInt32 current_gcw_rating; + DB::BindableInt32 current_pvp_kills; DB::BindableInt64 lifetime_gcw_points; - DB::BindableLong max_gcw_imperial_rating; - DB::BindableLong max_gcw_rebel_rating; - DB::BindableLong lifetime_pvp_kills; - DB::BindableLong next_gcw_rating_calc_time; + DB::BindableInt32 max_gcw_imperial_rating; + DB::BindableInt32 max_gcw_rebel_rating; + DB::BindableInt32 lifetime_pvp_kills; + DB::BindableInt32 next_gcw_rating_calc_time; DB::BindableBitArray<16000> collections; DB::BindableBool show_backpack; DB::BindableBool show_helmet; @@ -219,10 +219,10 @@ struct PlayerObjectBufferRow : public DB::Row struct ObjectVariableRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong name_id; - DB::BindableLong type; + DB::BindableInt32 name_id; + DB::BindableInt32 type; DB::BindableString<1000> value; - DB::BindableLong detached; + DB::BindableInt32 detached; virtual void copy(const DB::Row &rhs) { @@ -234,14 +234,14 @@ struct WaypointRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableNetworkId waypoint_id; - DB::BindableLong appearance_name_crc; + DB::BindableInt32 appearance_name_crc; DB::BindableDouble location_x; DB::BindableDouble location_y; DB::BindableDouble location_z; DB::BindableNetworkId location_cell; - DB::BindableLong location_scene; + DB::BindableInt32 location_scene; DB::BindableUnicode<512> name; - DB::BindableLong color; + DB::BindableInt32 color; DB::BindableBool active; DB::BindableBool detached; @@ -255,19 +255,19 @@ struct WaypointRow : public DB::Row struct ArmorRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong layer; - DB::BindableLong effectiveness; - DB::BindableLong integrity; + DB::BindableInt32 layer; + DB::BindableInt32 effectiveness; + DB::BindableInt32 integrity; DB::BindableString<1000> special_protections; - DB::BindableLong encumberance_0; - DB::BindableLong encumberance_1; - DB::BindableLong encumberance_2; - DB::BindableLong encumberance_3; - DB::BindableLong encumberance_4; - DB::BindableLong encumberance_5; - DB::BindableLong encumberance_6; - DB::BindableLong encumberance_7; - DB::BindableLong encumberance_8; + DB::BindableInt32 encumberance_0; + DB::BindableInt32 encumberance_1; + DB::BindableInt32 encumberance_2; + DB::BindableInt32 encumberance_3; + DB::BindableInt32 encumberance_4; + DB::BindableInt32 encumberance_5; + DB::BindableInt32 encumberance_6; + DB::BindableInt32 encumberance_7; + DB::BindableInt32 encumberance_8; DB::BindableString<255> object_template; virtual void copy(const DB::Row &rhs) @@ -279,19 +279,19 @@ struct ArmorRow : public DB::Row struct ArmorBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong layer; - DB::BindableLong effectiveness; - DB::BindableLong integrity; + DB::BindableInt32 layer; + DB::BindableInt32 effectiveness; + DB::BindableInt32 integrity; DB::BufferString special_protections; - DB::BindableLong encumberance_0; - DB::BindableLong encumberance_1; - DB::BindableLong encumberance_2; - DB::BindableLong encumberance_3; - DB::BindableLong encumberance_4; - DB::BindableLong encumberance_5; - DB::BindableLong encumberance_6; - DB::BindableLong encumberance_7; - DB::BindableLong encumberance_8; + DB::BindableInt32 encumberance_0; + DB::BindableInt32 encumberance_1; + DB::BindableInt32 encumberance_2; + DB::BindableInt32 encumberance_3; + DB::BindableInt32 encumberance_4; + DB::BindableInt32 encumberance_5; + DB::BindableInt32 encumberance_6; + DB::BindableInt32 encumberance_7; + DB::BindableInt32 encumberance_8; DB::BufferString object_template; ArmorBufferRow() : @@ -396,7 +396,7 @@ struct BattlefieldParticipantRow : public DB::Row { DB::BindableNetworkId region_object_id; DB::BindableNetworkId character_object_id; - DB::BindableLong faction_id; + DB::BindableInt32 faction_id; virtual void copy(const DB::Row &rhs) { @@ -408,7 +408,7 @@ struct BattlefieldParticipantBufferRow : public DB::Row { DB::BindableNetworkId region_object_id; DB::BindableNetworkId character_object_id; - DB::BindableLong faction_id; + DB::BindableInt32 faction_id; BattlefieldParticipantBufferRow() : region_object_id(), @@ -467,10 +467,10 @@ struct BountyHunterTargetBufferRow : public DB::Row struct BuildingObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong maintenance_cost; + DB::BindableInt32 maintenance_cost; DB::BindableDouble time_last_checked; DB::BindableBool is_public; - DB::BindableLong city_id; + DB::BindableInt32 city_id; virtual void copy(const DB::Row &rhs) { @@ -491,10 +491,10 @@ struct BuildingObjectRow : public DB::Row struct BuildingObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong maintenance_cost; + DB::BindableInt32 maintenance_cost; DB::BindableDouble time_last_checked; DB::BindableBool is_public; - DB::BindableLong city_id; + DB::BindableInt32 city_id; BuildingObjectBufferRow() : object_id(), @@ -533,7 +533,7 @@ struct BuildingObjectBufferRow : public DB::Row struct CellObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong cell_number; + DB::BindableInt32 cell_number; DB::BindableBool is_public; virtual void copy(const DB::Row &rhs) @@ -555,7 +555,7 @@ struct CellObjectRow : public DB::Row struct CellObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong cell_number; + DB::BindableInt32 cell_number; DB::BindableBool is_public; CellObjectBufferRow() : @@ -640,7 +640,7 @@ struct CityObjectBufferRow : public DB::Row struct ClockRow : public DB::Row { - DB::BindableLong last_save_time; + DB::BindableInt32 last_save_time; virtual void copy(const DB::Row &rhs) { @@ -650,7 +650,7 @@ struct ClockRow : public DB::Row struct ClockBufferRow : public DB::Row { - DB::BindableLong last_save_time; + DB::BindableInt32 last_save_time; ClockBufferRow() : last_save_time() @@ -673,39 +673,39 @@ struct CreatureObjectRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableDouble scale_factor; DB::BindableInt64 states; - DB::BindableLong posture; - DB::BindableLong shock_wounds; + DB::BindableInt32 posture; + DB::BindableInt32 shock_wounds; DB::BindableNetworkId master_id; - DB::BindableLong rank; + DB::BindableInt32 rank; DB::BindableDouble base_walk_speed; DB::BindableDouble base_run_speed; - DB::BindableLong attribute_0; - DB::BindableLong attribute_1; - DB::BindableLong attribute_2; - DB::BindableLong attribute_3; - DB::BindableLong attribute_4; - DB::BindableLong attribute_5; - DB::BindableLong attribute_6; - DB::BindableLong attribute_7; - DB::BindableLong attribute_8; - DB::BindableLong attribute_9; - DB::BindableLong attribute_10; - DB::BindableLong attribute_11; - DB::BindableLong attribute_12; - DB::BindableLong attribute_13; - DB::BindableLong attribute_14; - DB::BindableLong attribute_15; - DB::BindableLong attribute_16; - DB::BindableLong attribute_17; - DB::BindableLong attribute_18; - DB::BindableLong attribute_19; - DB::BindableLong attribute_20; - DB::BindableLong attribute_21; - DB::BindableLong attribute_22; - DB::BindableLong attribute_23; - DB::BindableLong attribute_24; - DB::BindableLong attribute_25; - DB::BindableLong attribute_26; + DB::BindableInt32 attribute_0; + DB::BindableInt32 attribute_1; + DB::BindableInt32 attribute_2; + DB::BindableInt32 attribute_3; + DB::BindableInt32 attribute_4; + DB::BindableInt32 attribute_5; + DB::BindableInt32 attribute_6; + DB::BindableInt32 attribute_7; + DB::BindableInt32 attribute_8; + DB::BindableInt32 attribute_9; + DB::BindableInt32 attribute_10; + DB::BindableInt32 attribute_11; + DB::BindableInt32 attribute_12; + DB::BindableInt32 attribute_13; + DB::BindableInt32 attribute_14; + DB::BindableInt32 attribute_15; + DB::BindableInt32 attribute_16; + DB::BindableInt32 attribute_17; + DB::BindableInt32 attribute_18; + DB::BindableInt32 attribute_19; + DB::BindableInt32 attribute_20; + DB::BindableInt32 attribute_21; + DB::BindableInt32 attribute_22; + DB::BindableInt32 attribute_23; + DB::BindableInt32 attribute_24; + DB::BindableInt32 attribute_25; + DB::BindableInt32 attribute_26; DB::BindableString<1000> persisted_buffs; DB::BindableDouble ws_x; DB::BindableDouble ws_y; @@ -732,39 +732,39 @@ struct CreatureObjectBufferRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableDouble scale_factor; DB::BindableInt64 states; - DB::BindableLong posture; - DB::BindableLong shock_wounds; + DB::BindableInt32 posture; + DB::BindableInt32 shock_wounds; DB::BindableNetworkId master_id; - DB::BindableLong rank; + DB::BindableInt32 rank; DB::BindableDouble base_walk_speed; DB::BindableDouble base_run_speed; - DB::BindableLong attribute_0; - DB::BindableLong attribute_1; - DB::BindableLong attribute_2; - DB::BindableLong attribute_3; - DB::BindableLong attribute_4; - DB::BindableLong attribute_5; - DB::BindableLong attribute_6; - DB::BindableLong attribute_7; - DB::BindableLong attribute_8; - DB::BindableLong attribute_9; - DB::BindableLong attribute_10; - DB::BindableLong attribute_11; - DB::BindableLong attribute_12; - DB::BindableLong attribute_13; - DB::BindableLong attribute_14; - DB::BindableLong attribute_15; - DB::BindableLong attribute_16; - DB::BindableLong attribute_17; - DB::BindableLong attribute_18; - DB::BindableLong attribute_19; - DB::BindableLong attribute_20; - DB::BindableLong attribute_21; - DB::BindableLong attribute_22; - DB::BindableLong attribute_23; - DB::BindableLong attribute_24; - DB::BindableLong attribute_25; - DB::BindableLong attribute_26; + DB::BindableInt32 attribute_0; + DB::BindableInt32 attribute_1; + DB::BindableInt32 attribute_2; + DB::BindableInt32 attribute_3; + DB::BindableInt32 attribute_4; + DB::BindableInt32 attribute_5; + DB::BindableInt32 attribute_6; + DB::BindableInt32 attribute_7; + DB::BindableInt32 attribute_8; + DB::BindableInt32 attribute_9; + DB::BindableInt32 attribute_10; + DB::BindableInt32 attribute_11; + DB::BindableInt32 attribute_12; + DB::BindableInt32 attribute_13; + DB::BindableInt32 attribute_14; + DB::BindableInt32 attribute_15; + DB::BindableInt32 attribute_16; + DB::BindableInt32 attribute_17; + DB::BindableInt32 attribute_18; + DB::BindableInt32 attribute_19; + DB::BindableInt32 attribute_20; + DB::BindableInt32 attribute_21; + DB::BindableInt32 attribute_22; + DB::BindableInt32 attribute_23; + DB::BindableInt32 attribute_24; + DB::BindableInt32 attribute_25; + DB::BindableInt32 attribute_26; DB::BufferString persisted_buffs; DB::BindableDouble ws_x; DB::BindableDouble ws_y; @@ -878,7 +878,7 @@ struct ExperiencePointRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableString<500> experience_type; - DB::BindableLong points; + DB::BindableInt32 points; virtual void copy(const DB::Row &rhs) { @@ -890,7 +890,7 @@ struct ExperiencePointBufferRow : public DB::Row { DB::BindableNetworkId object_id; DB::BufferString experience_type; - DB::BindableLong points; + DB::BindableInt32 points; ExperiencePointBufferRow() : object_id(), @@ -964,8 +964,8 @@ struct FactoryObjectBufferRow : public DB::Row struct FreeObjectIdRow : public DB::Row { - DB::BindableLong start_id; - DB::BindableLong end_id; + DB::BindableInt32 start_id; + DB::BindableInt32 end_id; virtual void copy(const DB::Row &rhs) { @@ -975,8 +975,8 @@ struct FreeObjectIdRow : public DB::Row struct FreeObjectIdBufferRow : public DB::Row { - DB::BindableLong start_id; - DB::BindableLong end_id; + DB::BindableInt32 start_id; + DB::BindableInt32 end_id; FreeObjectIdBufferRow() : start_id(), @@ -1050,9 +1050,9 @@ struct HarvesterInstallationObjectRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableDouble installed_efficiency; - DB::BindableLong max_extraction_rate; + DB::BindableInt32 max_extraction_rate; DB::BindableDouble current_extraction_rate; - DB::BindableLong max_hopper_amount; + DB::BindableInt32 max_hopper_amount; DB::BindableNetworkId hopper_resource; DB::BindableDouble hopper_amount; DB::BindableNetworkId resource_type; @@ -1077,9 +1077,9 @@ struct HarvesterInstallationObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableDouble installed_efficiency; - DB::BindableLong max_extraction_rate; + DB::BindableInt32 max_extraction_rate; DB::BindableDouble current_extraction_rate; - DB::BindableLong max_hopper_amount; + DB::BindableInt32 max_hopper_amount; DB::BindableNetworkId hopper_resource; DB::BindableDouble hopper_amount; DB::BindableNetworkId resource_type; @@ -1127,7 +1127,7 @@ struct HarvesterInstallationObjectBufferRow : public DB::Row struct InstallationObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong installation_type; + DB::BindableInt32 installation_type; DB::BindableBool activated; DB::BindableDouble tick_count; DB::BindableDouble activate_start_time; @@ -1153,7 +1153,7 @@ struct InstallationObjectRow : public DB::Row struct InstallationObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong installation_type; + DB::BindableInt32 installation_type; DB::BindableBool activated; DB::BindableDouble tick_count; DB::BindableDouble activate_start_time; @@ -1201,7 +1201,7 @@ struct InstallationObjectBufferRow : public DB::Row struct IntangibleObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong count; + DB::BindableInt32 count; virtual void copy(const DB::Row &rhs) { @@ -1222,7 +1222,7 @@ struct IntangibleObjectRow : public DB::Row struct IntangibleObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong count; + DB::BindableInt32 count; IntangibleObjectBufferRow() : object_id(), @@ -1255,8 +1255,8 @@ struct IntangibleObjectBufferRow : public DB::Row struct LoadbeaconServerMapRow : public DB::Row { DB::BindableString<255> object_template; - DB::BindableLong server_id; - DB::BindableLong secondary_server_id; + DB::BindableInt32 server_id; + DB::BindableInt32 secondary_server_id; virtual void copy(const DB::Row &rhs) { @@ -1267,8 +1267,8 @@ struct LoadbeaconServerMapRow : public DB::Row struct LoadbeaconServerMapBufferRow : public DB::Row { DB::BufferString object_template; - DB::BindableLong server_id; - DB::BindableLong secondary_server_id; + DB::BindableInt32 server_id; + DB::BindableInt32 secondary_server_id; LoadbeaconServerMapBufferRow() : object_template(255), @@ -1345,9 +1345,9 @@ struct ManufactureSchematicObjectRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableNetworkId creator_id; DB::BindableString<127> creator_name; - DB::BindableLong items_per_container; + DB::BindableInt32 items_per_container; DB::BindableDouble manufacture_time; - DB::BindableLong draft_schematic; + DB::BindableInt32 draft_schematic; virtual void copy(const DB::Row &rhs) { @@ -1370,9 +1370,9 @@ struct ManufactureSchematicObjectBufferRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableNetworkId creator_id; DB::BufferString creator_name; - DB::BindableLong items_per_container; + DB::BindableInt32 items_per_container; DB::BindableDouble manufacture_time; - DB::BindableLong draft_schematic; + DB::BindableInt32 draft_schematic; ManufactureSchematicObjectBufferRow() : object_id(), @@ -1416,9 +1416,9 @@ struct MessageRow : public DB::Row DB::BindableNetworkId target; DB::BindableString<50> method; DB::BindableString<4000> data; - DB::BindableLong call_time; + DB::BindableInt32 call_time; DB::BindableBool guaranteed; - DB::BindableLong delivery_type; + DB::BindableInt32 delivery_type; virtual void copy(const DB::Row &rhs) { @@ -1437,9 +1437,9 @@ struct MessageBufferRow : public DB::Row DB::BindableNetworkId target; DB::BufferString method; DB::BufferString data; - DB::BindableLong call_time; + DB::BindableInt32 call_time; DB::BindableBool guaranteed; - DB::BindableLong delivery_type; + DB::BindableInt32 delivery_type; MessageBufferRow() : message_id(), @@ -1477,28 +1477,28 @@ struct MessageBufferRow : public DB::Row struct MissionObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong difficulty; + DB::BindableInt32 difficulty; DB::BindableDouble end_x; DB::BindableDouble end_y; DB::BindableDouble end_z; DB::BindableNetworkId end_cell; - DB::BindableLong end_scene; + DB::BindableInt32 end_scene; DB::BindableString<127> mission_creator; - DB::BindableLong reward; + DB::BindableInt32 reward; DB::BindableString<100> root_script_name; DB::BindableDouble start_x; DB::BindableDouble start_y; DB::BindableDouble start_z; DB::BindableNetworkId start_cell; - DB::BindableLong start_scene; + DB::BindableInt32 start_scene; DB::BindableString<100> description_table; DB::BindableString<100> description_text; DB::BindableString<100> title_table; DB::BindableString<100> title_text; DB::BindableNetworkId mission_holder_id; - DB::BindableLong status; - DB::BindableLong mission_type; - DB::BindableLong target_appearance; + DB::BindableInt32 status; + DB::BindableInt32 mission_type; + DB::BindableInt32 target_appearance; DB::BindableString<127> target_name; virtual void copy(const DB::Row &rhs) @@ -1520,28 +1520,28 @@ struct MissionObjectRow : public DB::Row struct MissionObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong difficulty; + DB::BindableInt32 difficulty; DB::BindableDouble end_x; DB::BindableDouble end_y; DB::BindableDouble end_z; DB::BindableNetworkId end_cell; - DB::BindableLong end_scene; + DB::BindableInt32 end_scene; DB::BufferString mission_creator; - DB::BindableLong reward; + DB::BindableInt32 reward; DB::BufferString root_script_name; DB::BindableDouble start_x; DB::BindableDouble start_y; DB::BindableDouble start_z; DB::BindableNetworkId start_cell; - DB::BindableLong start_scene; + DB::BindableInt32 start_scene; DB::BufferString description_table; DB::BufferString description_text; DB::BufferString title_table; DB::BufferString title_text; DB::BindableNetworkId mission_holder_id; - DB::BindableLong status; - DB::BindableLong mission_type; - DB::BindableLong target_appearance; + DB::BindableInt32 status; + DB::BindableInt32 mission_type; + DB::BindableInt32 target_appearance; DB::BufferString target_name; MissionObjectBufferRow() : @@ -1626,93 +1626,93 @@ struct ObjectRow : public DB::Row DB::BindableDouble quaternion_x; DB::BindableDouble quaternion_y; DB::BindableDouble quaternion_z; - DB::BindableLong node_x; - DB::BindableLong node_y; - DB::BindableLong node_z; - DB::BindableLong type_id; + DB::BindableInt32 node_x; + DB::BindableInt32 node_y; + DB::BindableInt32 node_z; + DB::BindableInt32 type_id; DB::BindableString<50> scene_id; - DB::BindableLong controller_type; - DB::BindableLong deleted; + DB::BindableInt32 controller_type; + DB::BindableInt32 deleted; DB::BindableString<127> object_name; - DB::BindableLong volume; + DB::BindableInt32 volume; DB::BindableNetworkId contained_by; - DB::BindableLong slot_arrangement; + DB::BindableInt32 slot_arrangement; DB::BindableBool player_controlled; - DB::BindableLong cache_version; + DB::BindableInt32 cache_version; DB::BindableBool load_contents; - DB::BindableLong cash_balance; - DB::BindableLong bank_balance; + DB::BindableInt32 cash_balance; + DB::BindableInt32 bank_balance; DB::BindableDouble complexity; DB::BindableString<500> name_string_table; DB::BindableString<500> name_string_text; - DB::BindableLong object_template_id; + DB::BindableInt32 object_template_id; DB::BindableString<128> static_item_name; - DB::BindableLong static_item_version; - DB::BindableLong conversion_id; + DB::BindableInt32 static_item_version; + DB::BindableInt32 conversion_id; DB::BindableNetworkId load_with; DB::BindableString<50> objvar_0_name; - DB::BindableLong objvar_0_type; + DB::BindableInt32 objvar_0_type; DB::BindableString<50> objvar_0_value; DB::BindableString<50> objvar_1_name; - DB::BindableLong objvar_1_type; + DB::BindableInt32 objvar_1_type; DB::BindableString<50> objvar_1_value; DB::BindableString<50> objvar_2_name; - DB::BindableLong objvar_2_type; + DB::BindableInt32 objvar_2_type; DB::BindableString<50> objvar_2_value; DB::BindableString<50> objvar_3_name; - DB::BindableLong objvar_3_type; + DB::BindableInt32 objvar_3_type; DB::BindableString<50> objvar_3_value; DB::BindableString<50> objvar_4_name; - DB::BindableLong objvar_4_type; + DB::BindableInt32 objvar_4_type; DB::BindableString<50> objvar_4_value; DB::BindableString<50> objvar_5_name; - DB::BindableLong objvar_5_type; + DB::BindableInt32 objvar_5_type; DB::BindableString<50> objvar_5_value; DB::BindableString<50> objvar_6_name; - DB::BindableLong objvar_6_type; + DB::BindableInt32 objvar_6_type; DB::BindableString<50> objvar_6_value; DB::BindableString<50> objvar_7_name; - DB::BindableLong objvar_7_type; + DB::BindableInt32 objvar_7_type; DB::BindableString<50> objvar_7_value; DB::BindableString<50> objvar_8_name; - DB::BindableLong objvar_8_type; + DB::BindableInt32 objvar_8_type; DB::BindableString<50> objvar_8_value; DB::BindableString<50> objvar_9_name; - DB::BindableLong objvar_9_type; + DB::BindableInt32 objvar_9_type; DB::BindableString<50> objvar_9_value; DB::BindableString<50> objvar_10_name; - DB::BindableLong objvar_10_type; + DB::BindableInt32 objvar_10_type; DB::BindableString<50> objvar_10_value; DB::BindableString<50> objvar_11_name; - DB::BindableLong objvar_11_type; + DB::BindableInt32 objvar_11_type; DB::BindableString<50> objvar_11_value; DB::BindableString<50> objvar_12_name; - DB::BindableLong objvar_12_type; + DB::BindableInt32 objvar_12_type; DB::BindableString<50> objvar_12_value; DB::BindableString<50> objvar_13_name; - DB::BindableLong objvar_13_type; + DB::BindableInt32 objvar_13_type; DB::BindableString<50> objvar_13_value; DB::BindableString<50> objvar_14_name; - DB::BindableLong objvar_14_type; + DB::BindableInt32 objvar_14_type; DB::BindableString<50> objvar_14_value; DB::BindableString<50> objvar_15_name; - DB::BindableLong objvar_15_type; + DB::BindableInt32 objvar_15_type; DB::BindableString<50> objvar_15_value; DB::BindableString<50> objvar_16_name; - DB::BindableLong objvar_16_type; + DB::BindableInt32 objvar_16_type; DB::BindableString<50> objvar_16_value; DB::BindableString<50> objvar_17_name; - DB::BindableLong objvar_17_type; + DB::BindableInt32 objvar_17_type; DB::BindableString<50> objvar_17_value; DB::BindableString<50> objvar_18_name; - DB::BindableLong objvar_18_type; + DB::BindableInt32 objvar_18_type; DB::BindableString<50> objvar_18_value; DB::BindableString<50> objvar_19_name; - DB::BindableLong objvar_19_type; + DB::BindableInt32 objvar_19_type; DB::BindableString<50> objvar_19_value; DB::BindableString<2000> script_list; - DB::BindableLong container_level; + DB::BindableInt32 container_level; virtual void copy(const DB::Row &rhs) { @@ -1740,89 +1740,89 @@ struct ObjectBufferRow : public DB::Row DB::BindableDouble quaternion_x; DB::BindableDouble quaternion_y; DB::BindableDouble quaternion_z; - DB::BindableLong node_x; - DB::BindableLong node_y; - DB::BindableLong node_z; - DB::BindableLong type_id; + DB::BindableInt32 node_x; + DB::BindableInt32 node_y; + DB::BindableInt32 node_z; + DB::BindableInt32 type_id; DB::BufferString scene_id; - DB::BindableLong controller_type; - DB::BindableLong deleted; + DB::BindableInt32 controller_type; + DB::BindableInt32 deleted; DB::BufferString object_name; - DB::BindableLong volume; + DB::BindableInt32 volume; DB::BindableNetworkId contained_by; - DB::BindableLong slot_arrangement; + DB::BindableInt32 slot_arrangement; DB::BindableBool player_controlled; - DB::BindableLong cache_version; + DB::BindableInt32 cache_version; DB::BindableBool load_contents; - DB::BindableLong cash_balance; - DB::BindableLong bank_balance; + DB::BindableInt32 cash_balance; + DB::BindableInt32 bank_balance; DB::BindableDouble complexity; DB::BufferString name_string_table; DB::BufferString name_string_text; - DB::BindableLong object_template_id; + DB::BindableInt32 object_template_id; DB::BufferString static_item_name; - DB::BindableLong static_item_version; - DB::BindableLong conversion_id; + DB::BindableInt32 static_item_version; + DB::BindableInt32 conversion_id; DB::BindableNetworkId load_with; DB::BufferString objvar_0_name; - DB::BindableLong objvar_0_type; + DB::BindableInt32 objvar_0_type; DB::BufferString objvar_0_value; DB::BufferString objvar_1_name; - DB::BindableLong objvar_1_type; + DB::BindableInt32 objvar_1_type; DB::BufferString objvar_1_value; DB::BufferString objvar_2_name; - DB::BindableLong objvar_2_type; + DB::BindableInt32 objvar_2_type; DB::BufferString objvar_2_value; DB::BufferString objvar_3_name; - DB::BindableLong objvar_3_type; + DB::BindableInt32 objvar_3_type; DB::BufferString objvar_3_value; DB::BufferString objvar_4_name; - DB::BindableLong objvar_4_type; + DB::BindableInt32 objvar_4_type; DB::BufferString objvar_4_value; DB::BufferString objvar_5_name; - DB::BindableLong objvar_5_type; + DB::BindableInt32 objvar_5_type; DB::BufferString objvar_5_value; DB::BufferString objvar_6_name; - DB::BindableLong objvar_6_type; + DB::BindableInt32 objvar_6_type; DB::BufferString objvar_6_value; DB::BufferString objvar_7_name; - DB::BindableLong objvar_7_type; + DB::BindableInt32 objvar_7_type; DB::BufferString objvar_7_value; DB::BufferString objvar_8_name; - DB::BindableLong objvar_8_type; + DB::BindableInt32 objvar_8_type; DB::BufferString objvar_8_value; DB::BufferString objvar_9_name; - DB::BindableLong objvar_9_type; + DB::BindableInt32 objvar_9_type; DB::BufferString objvar_9_value; DB::BufferString objvar_10_name; - DB::BindableLong objvar_10_type; + DB::BindableInt32 objvar_10_type; DB::BufferString objvar_10_value; DB::BufferString objvar_11_name; - DB::BindableLong objvar_11_type; + DB::BindableInt32 objvar_11_type; DB::BufferString objvar_11_value; DB::BufferString objvar_12_name; - DB::BindableLong objvar_12_type; + DB::BindableInt32 objvar_12_type; DB::BufferString objvar_12_value; DB::BufferString objvar_13_name; - DB::BindableLong objvar_13_type; + DB::BindableInt32 objvar_13_type; DB::BufferString objvar_13_value; DB::BufferString objvar_14_name; - DB::BindableLong objvar_14_type; + DB::BindableInt32 objvar_14_type; DB::BufferString objvar_14_value; DB::BufferString objvar_15_name; - DB::BindableLong objvar_15_type; + DB::BindableInt32 objvar_15_type; DB::BufferString objvar_15_value; DB::BufferString objvar_16_name; - DB::BindableLong objvar_16_type; + DB::BindableInt32 objvar_16_type; DB::BufferString objvar_16_value; DB::BufferString objvar_17_name; - DB::BindableLong objvar_17_type; + DB::BindableInt32 objvar_17_type; DB::BufferString objvar_17_value; DB::BufferString objvar_18_name; - DB::BindableLong objvar_18_type; + DB::BindableInt32 objvar_18_type; DB::BufferString objvar_18_value; DB::BufferString objvar_19_name; - DB::BindableLong objvar_19_type; + DB::BindableInt32 objvar_19_type; DB::BufferString objvar_19_value; DB::BufferString script_list; @@ -2096,8 +2096,8 @@ struct PlayerQuestObjectRow : public DB::Row DB::BindableString<256> title; DB::BindableString<4000> description; DB::BindableNetworkId creator; - DB::BindableLong total_tasks; - DB::BindableLong difficulty; + DB::BindableInt32 total_tasks; + DB::BindableInt32 difficulty; DB::BindableString<128> task_title1; DB::BindableString<4000> task_description1; DB::BindableString<128> task_title2; @@ -2145,8 +2145,8 @@ struct PlayerQuestObjectBufferRow : public DB::Row DB::BufferString title; DB::BufferString description; DB::BindableNetworkId creator; - DB::BindableLong total_tasks; - DB::BindableLong difficulty; + DB::BindableInt32 total_tasks; + DB::BindableInt32 difficulty; DB::BufferString task_title1; DB::BufferString task_description1; DB::BufferString task_title2; @@ -2259,7 +2259,7 @@ struct PlayerQuestObjectBufferRow : public DB::Row struct PropertyListRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong list_id; + DB::BindableInt32 list_id; DB::BindableString<500> value; virtual void copy(const DB::Row &rhs) @@ -2271,7 +2271,7 @@ struct PropertyListRow : public DB::Row struct PropertyListBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong list_id; + DB::BindableInt32 list_id; DB::BufferString value; PropertyListBufferRow() : @@ -2298,7 +2298,7 @@ struct ResourceContainerObjectRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableNetworkId resource_type; - DB::BindableLong quantity; + DB::BindableInt32 quantity; DB::BindableNetworkId source; virtual void copy(const DB::Row &rhs) @@ -2321,7 +2321,7 @@ struct ResourceContainerObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableNetworkId resource_type; - DB::BindableLong quantity; + DB::BindableInt32 quantity; DB::BindableNetworkId source; ResourceContainerObjectBufferRow() : @@ -2363,7 +2363,7 @@ struct ResourceTypeRow : public DB::Row DB::BindableString<100> resource_class; DB::BindableString<1024> attributes; DB::BindableString<1024> fractal_seeds; - DB::BindableLong depleted_timestamp; + DB::BindableInt32 depleted_timestamp; virtual void copy(const DB::Row &rhs) { @@ -2378,7 +2378,7 @@ struct ResourceTypeBufferRow : public DB::Row DB::BufferString resource_class; DB::BufferString attributes; DB::BufferString fractal_seeds; - DB::BindableLong depleted_timestamp; + DB::BindableInt32 depleted_timestamp; ResourceTypeBufferRow() : resource_id(), @@ -2409,9 +2409,9 @@ struct ResourceTypeBufferRow : public DB::Row struct ScriptRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong sequence_no; + DB::BindableInt32 sequence_no; DB::BindableString<100> script; - DB::BindableLong detached; + DB::BindableInt32 detached; virtual void copy(const DB::Row &rhs) { @@ -2422,9 +2422,9 @@ struct ScriptRow : public DB::Row struct ScriptBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong sequence_no; + DB::BindableInt32 sequence_no; DB::BufferString script; - DB::BindableLong detached; + DB::BindableInt32 detached; ScriptBufferRow() : object_id(), @@ -2454,7 +2454,7 @@ struct ShipObjectRow : public DB::Row DB::BindableDouble slide_dampener; DB::BindableDouble current_chassis_hit_points; DB::BindableDouble maximum_chassis_hit_points; - DB::BindableLong chassis_type; + DB::BindableInt32 chassis_type; DB::BindableString<400> cmp_armor_hp_maximum; DB::BindableString<400> cmp_armor_hp_current; DB::BindableString<400> cmp_efficiency_general; @@ -2499,8 +2499,8 @@ struct ShipObjectRow : public DB::Row DB::BindableNetworkId installed_dcd; DB::BindableDouble chassis_cmp_mass_maximum; DB::BindableString<400> cmp_creators; - DB::BindableLong cargo_hold_contents_maximum; - DB::BindableLong cargo_hold_contents_current; + DB::BindableInt32 cargo_hold_contents_maximum; + DB::BindableInt32 cargo_hold_contents_current; DB::BindableString<500> cargo_hold_contents; virtual void copy(const DB::Row &rhs) @@ -2525,7 +2525,7 @@ struct ShipObjectBufferRow : public DB::Row DB::BindableDouble slide_dampener; DB::BindableDouble current_chassis_hit_points; DB::BindableDouble maximum_chassis_hit_points; - DB::BindableLong chassis_type; + DB::BindableInt32 chassis_type; DB::BufferString cmp_armor_hp_maximum; DB::BufferString cmp_armor_hp_current; DB::BufferString cmp_efficiency_general; @@ -2570,8 +2570,8 @@ struct ShipObjectBufferRow : public DB::Row DB::BindableNetworkId installed_dcd; DB::BindableDouble chassis_cmp_mass_maximum; DB::BufferString cmp_creators; - DB::BindableLong cargo_hold_contents_maximum; - DB::BindableLong cargo_hold_contents_current; + DB::BindableInt32 cargo_hold_contents_maximum; + DB::BindableInt32 cargo_hold_contents_current; DB::BufferString cargo_hold_contents; ShipObjectBufferRow() : @@ -2755,19 +2755,19 @@ struct StaticObjectBufferRow : public DB::Row struct TangibleObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong max_hit_points; + DB::BindableInt32 max_hit_points; DB::BindableNetworkId owner_id; DB::BindableBool visible; DB::BindableString<2000> appearance_data; - DB::BindableLong interest_radius; - DB::BindableLong pvp_type; - DB::BindableLong pvp_faction; - DB::BindableLong damage_taken; + DB::BindableInt32 interest_radius; + DB::BindableInt32 pvp_type; + DB::BindableInt32 pvp_faction; + DB::BindableInt32 damage_taken; DB::BindableString<2000> custom_appearance; - DB::BindableLong count; - DB::BindableLong condition; + DB::BindableInt32 count; + DB::BindableInt32 condition; DB::BindableNetworkId creator_id; - DB::BindableLong source_draft_schematic; + DB::BindableInt32 source_draft_schematic; virtual void copy(const DB::Row &rhs) { @@ -2788,19 +2788,19 @@ struct TangibleObjectRow : public DB::Row struct TangibleObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong max_hit_points; + DB::BindableInt32 max_hit_points; DB::BindableNetworkId owner_id; DB::BindableBool visible; DB::BufferString appearance_data; - DB::BindableLong interest_radius; - DB::BindableLong pvp_type; - DB::BindableLong pvp_faction; - DB::BindableLong damage_taken; + DB::BindableInt32 interest_radius; + DB::BindableInt32 pvp_type; + DB::BindableInt32 pvp_faction; + DB::BindableInt32 damage_taken; DB::BufferString custom_appearance; - DB::BindableLong count; - DB::BindableLong condition; + DB::BindableInt32 count; + DB::BindableInt32 condition; DB::BindableNetworkId creator_id; - DB::BindableLong source_draft_schematic; + DB::BindableInt32 source_draft_schematic; TangibleObjectBufferRow() : object_id(), @@ -2973,7 +2973,7 @@ struct UniverseObjectBufferRow : public DB::Row struct VehicleObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong bogus; + DB::BindableInt32 bogus; virtual void copy(const DB::Row &rhs) { @@ -2994,7 +2994,7 @@ struct VehicleObjectRow : public DB::Row struct VehicleObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong bogus; + DB::BindableInt32 bogus; VehicleObjectBufferRow() : object_id(), @@ -3027,15 +3027,15 @@ struct VehicleObjectBufferRow : public DB::Row struct WeaponObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong min_damage; - DB::BindableLong max_damage; - DB::BindableLong damage_type; - DB::BindableLong elemental_type; - DB::BindableLong elemental_value; + DB::BindableInt32 min_damage; + DB::BindableInt32 max_damage; + DB::BindableInt32 damage_type; + DB::BindableInt32 elemental_type; + DB::BindableInt32 elemental_value; DB::BindableDouble attack_speed; DB::BindableDouble wound_chance; - DB::BindableLong accuracy; - DB::BindableLong attack_cost; + DB::BindableInt32 accuracy; + DB::BindableInt32 attack_cost; DB::BindableDouble damage_radius; DB::BindableDouble min_range; DB::BindableDouble max_range; @@ -3059,15 +3059,15 @@ struct WeaponObjectRow : public DB::Row struct WeaponObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong min_damage; - DB::BindableLong max_damage; - DB::BindableLong damage_type; - DB::BindableLong elemental_type; - DB::BindableLong elemental_value; + DB::BindableInt32 min_damage; + DB::BindableInt32 max_damage; + DB::BindableInt32 damage_type; + DB::BindableInt32 elemental_type; + DB::BindableInt32 elemental_value; DB::BindableDouble attack_speed; DB::BindableDouble wound_chance; - DB::BindableLong accuracy; - DB::BindableLong attack_cost; + DB::BindableInt32 accuracy; + DB::BindableInt32 attack_cost; DB::BindableDouble damage_radius; DB::BindableDouble min_range; DB::BindableDouble max_range; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h index 0284094be..3f2a06ed9 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h @@ -41,7 +41,7 @@ namespace DBQuery private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayString m_target_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h index 55469272f..7f50272cc 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h @@ -51,7 +51,7 @@ class AuctionLocationsQuery : public DatabaseProcessQuery DB::BindableVarrayNumber m_status; DB::BindableVarrayString m_search_enabled; DB::BindableVarrayNumber m_entrance_charge; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class AuctionLocationsQuerySelect : public DB::Query @@ -114,7 +114,7 @@ class MarketAuctionsQuery : public DatabaseProcessQuery DB::BindableVarrayNumber m_actives; DB::BindableVarrayNumber m_item_sizes; DB::BindableVarrayNumber m_object_template_ids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class MarketAuctionsQuerySelect : public DB::Query @@ -165,7 +165,7 @@ class MarketAuctionBidsQuery : public DatabaseProcessQuery DB::BindableVarrayString m_bidder_ids; DB::BindableVarrayNumber m_bids; DB::BindableVarrayNumber m_max_proxy_bids; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class MarketAuctionBidsQuerySelect : public DB::Query @@ -215,7 +215,7 @@ class MarketAuctionsAttributesQuery : public DatabaseProcessQuery DB::BindableVarrayString m_item_ids; DB::BindableVarrayString m_attribute_names; DB::BindableVarrayString m_attribute_values; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; // ====================================================================== diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h index f9ed09f9b..0e155ad36 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h @@ -23,14 +23,14 @@ struct AuctionLocationsRow : public DB::Row DB::BindableNetworkId location_id; DB::BindableString<256> location_name; DB::BindableNetworkId owner_id; - DB::BindableLong sales_tax; + DB::BindableInt32 sales_tax; DB::BindableNetworkId sales_tax_bank_id; - DB::BindableLong empty_date; - DB::BindableLong last_access_date; - DB::BindableLong inactive_date; - DB::BindableLong status; + DB::BindableInt32 empty_date; + DB::BindableInt32 last_access_date; + DB::BindableInt32 inactive_date; + DB::BindableInt32 status; DB::BindableBool search_enabled; - DB::BindableLong entrance_charge; + DB::BindableInt32 entrance_charge; virtual void copy(const DB::Row &rhs) { @@ -71,17 +71,17 @@ struct MarketAuctionsRow : public DB::Row DB::BindableNetworkId owner_id; DB::BindableNetworkId creator_id; DB::BindableNetworkId location_id; - DB::BindableLong min_bid; - DB::BindableLong buy_now_price; - DB::BindableLong auction_timer; + DB::BindableInt32 min_bid; + DB::BindableInt32 buy_now_price; + DB::BindableInt32 auction_timer; DB::BindableString<4000> oob; DB::BindableUnicode<1024>user_description; - DB::BindableLong category; + DB::BindableInt32 category; DB::BindableUnicode<1024>item_name; - DB::BindableLong item_timer; - DB::BindableLong active; - DB::BindableLong item_size; - DB::BindableLong object_template_id; + DB::BindableInt32 item_timer; + DB::BindableInt32 active; + DB::BindableInt32 item_size; + DB::BindableInt32 object_template_id; virtual void copy(const DB::Row &rhs) { @@ -155,7 +155,7 @@ struct MarketAuctionsRowUpdate : public DB::Row DB::BindableNetworkId item_id; DB::BindableNetworkId owner_id; - DB::BindableLong active; + DB::BindableInt32 active; virtual void copy(const DB::Row &rhs) { @@ -193,8 +193,8 @@ struct MarketAuctionBidsRow : public DB::Row DB::BindableNetworkId item_id; DB::BindableNetworkId bidder_id; - DB::BindableLong bid; - DB::BindableLong max_proxy_bid; + DB::BindableInt32 bid; + DB::BindableInt32 max_proxy_bid; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h index 614e36ca1..44fe7b1ca 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h @@ -38,7 +38,7 @@ namespace DBQuery private: DB::BindableVarrayString object_ids; DB::BindableVarrayNumber reasons; - DB::BindableLong num_items; + DB::BindableInt32 num_items; private: DeleteDemandLoadedContainerQuery(const DeleteDemandLoadedContainerQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h index 21eb81f12..188ff1df2 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h @@ -32,9 +32,9 @@ namespace DBQuery public: DB::BindableNetworkId object_id; - DB::BindableLong list_id; - DB::BindableLong index; - DB::BindableLong action; + DB::BindableInt32 list_id; + DB::BindableInt32 index; + DB::BindableInt32 action; DB::BindableUnicode<255> name; DB::BindableString<50> scene; DB::BindableDouble x; @@ -55,8 +55,8 @@ namespace DBQuery struct LocationRow { DB::BindableNetworkId object_id; - DB::BindableLong list_id; - DB::BindableLong index; + DB::BindableInt32 list_id; + DB::BindableInt32 index; DB::BindableUnicode<255> name; DB::BindableString<50> scene; DB::BindableDouble x; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h index 61fa760e2..517cfea6c 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h @@ -21,7 +21,7 @@ namespace DBSchema struct ManufactureSchematicAttributeRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableLong action; + DB::BindableInt32 action; DB::BindableString<500> attribute_type; DB::BindableDouble value; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h index dcd9cf559..2f52712ba 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h @@ -46,8 +46,8 @@ namespace DBQuery DB::BindableVarrayNumber m_call_times; DB::BindableVarrayString m_guaranteeds; DB::BindableVarrayNumber m_delivery_types; - DB::BindableLong m_numItems; - DB::BindableLong m_enableDatabaseLogging; + DB::BindableInt32 m_numItems; + DB::BindableInt32 m_enableDatabaseLogging; private: SaveMessageQuery(const SaveMessageQuery&); // disable @@ -74,8 +74,8 @@ namespace DBQuery private: DB::BindableVarrayString m_message_ids; - DB::BindableLong m_numItems; - DB::BindableLong m_enableDatabaseLogging; + DB::BindableInt32 m_numItems; + DB::BindableInt32 m_enableDatabaseLogging; private: AckMessageQuery(const AckMessageQuery&); // disable @@ -94,9 +94,9 @@ namespace DBQuery DB::BindableNetworkId object_id; DB::BindableString<50> method; DB::BindableString<4000> packed_data; - DB::BindableLong call_time; + DB::BindableInt32 call_time; DB::BindableBool guaranteed; - DB::BindableLong delivery_type; + DB::BindableInt32 delivery_type; }; public: diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h index 44aef98fe..aeec7b3cd 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h @@ -47,7 +47,7 @@ namespace DBQuery DB::BindableVarrayNumber m_nameIds; DB::BindableVarrayNumber m_types; DB::BindableVarrayString m_values; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class AddObjectVariableQuery : public GenericObjectVariableQuery @@ -93,7 +93,7 @@ namespace DBQuery private: DB::BindableVarrayString m_objectIds; DB::BindableVarrayNumber m_nameIds; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; /** diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h index 2817fe3d8..d3640f9f6 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h @@ -135,7 +135,7 @@ namespace DBQuery DB::BindableVarrayString m_objvar_19_values; DB::BindableVarrayString m_script_lists; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; class ObjectsTableQuerySelect : public DB::Query diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp b/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp index e70e9a61d..d1d2b1e5d 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp @@ -49,7 +49,7 @@ namespace OfflineMoneyCustomPersistStepNamespace private: DB::BindableNetworkId m_sourceObject; - DB::BindableLong m_amount; + DB::BindableInt32 m_amount; DB::BindableBool m_result; private: diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h index 32a49ffa1..76e363d47 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h @@ -30,8 +30,8 @@ namespace DBSchema }; DB::BindableNetworkId object_id; - DB::BindableLong list_id; - DB::BindableLong operation; + DB::BindableInt32 list_id; + DB::BindableInt32 operation; DB::BindableString<500> value; //TODO: size virtual void copy(const DB::Row &rhs) @@ -67,9 +67,9 @@ namespace DBQuery DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_list_ids; DB::BindableVarrayString m_values; - DB::BindableLong m_operations; - DB::BindableLong m_numItems; - DB::BindableLong m_enableDatabaseLogging; + DB::BindableInt32 m_operations; + DB::BindableInt32 m_numItems; + DB::BindableInt32 m_enableDatabaseLogging; PropertyListQuery(const PropertyListQuery&); // disable PropertyListQuery& operator=(const PropertyListQuery&); // disable diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h index 3a364ddf1..5b1103fad 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h @@ -45,7 +45,7 @@ namespace DBQuery DB::BindableVarrayString m_attributes; DB::BindableVarrayString m_fractal_seeds; DB::BindableVarrayNumber m_depleted_timestamps; - DB::BindableLong m_numItems; + DB::BindableInt32 m_numItems; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h index b0514a7e9..66b950e7f 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h @@ -28,8 +28,8 @@ namespace DBSchema }; DB::BindableNetworkId object_id; - DB::BindableLong index; - DB::BindableLong operation; + DB::BindableInt32 index; + DB::BindableInt32 operation; DB::BindableString<500> skill; //TODO: size virtual void copy(const DB::Row &rhs) diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h index 418710dfc..0ca44a375 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h @@ -28,20 +28,20 @@ namespace DBSchema struct AuctionRow : public DB::Row { DB::BindableNetworkId creatorId; - DB::BindableLong minBid; - DB::BindableLong auctionTimer; - DB::BindableLong buyNowPrice; + DB::BindableInt32 minBid; + DB::BindableInt32 auctionTimer; + DB::BindableInt32 buyNowPrice; DB::BindableUnicode<1024> userDescription; DB::BindableString<4000> oob; DB::BindableNetworkId locationId; DB::BindableNetworkId itemId; - DB::BindableLong category; - DB::BindableLong itemTimer; + DB::BindableInt32 category; + DB::BindableInt32 itemTimer; DB::BindableUnicode<1024> itemName; DB::BindableNetworkId ownerId; - DB::BindableLong active; - DB::BindableLong itemSize; - DB::BindableLong itemTemplateId; + DB::BindableInt32 active; + DB::BindableInt32 itemSize; + DB::BindableInt32 itemTemplateId; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h index 021147a3c..adb4f6eb9 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h @@ -27,8 +27,8 @@ namespace DBSchema { DB::BindableNetworkId itemId; DB::BindableNetworkId bidderId; - DB::BindableLong bid; - DB::BindableLong maxProxyBid; + DB::BindableInt32 bid; + DB::BindableInt32 maxProxyBid; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h index 4529ad903..198717237 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h @@ -28,14 +28,14 @@ namespace DBSchema DB::BindableNetworkId locationId; DB::BindableNetworkId ownerId; DB::BindableString<256> locationString; - DB::BindableLong salesTax; + DB::BindableInt32 salesTax; DB::BindableNetworkId salesTaxBankId; - DB::BindableLong emptyDate; - DB::BindableLong lastAccessDate; - DB::BindableLong inactiveDate; - DB::BindableLong status; + DB::BindableInt32 emptyDate; + DB::BindableInt32 lastAccessDate; + DB::BindableInt32 inactiveDate; + DB::BindableInt32 status; DB::BindableBool searchEnabled; - DB::BindableLong entranceCharge; + DB::BindableInt32 entranceCharge; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h index 0c85a1d0e..3b11d4c7d 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h @@ -29,7 +29,7 @@ class TaskLoadObjvarNames : public DB::TaskRequest private: struct ObjvarNameRow { - DB::BindableLong name_id; + DB::BindableInt32 name_id; DB::BindableString<500> name; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h index 9723fe220..e34903d41 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h @@ -42,10 +42,10 @@ class TaskLocateStructure:public DB::TaskRequest DB::BindableNetworkId item_id; //output: - DB::BindableLong x; - DB::BindableLong z; + DB::BindableInt32 x; + DB::BindableInt32 z; DB::BindableString<50> sceneId; - DB::BindableLong found; + DB::BindableInt32 found; private: LocateStructureQuery(const LocateStructureQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h index 9d1ccc699..115430096 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h @@ -43,7 +43,7 @@ class TaskMoveToPlayer:public DB::TaskRequest DB::BindableNetworkId player; //output: - DB::BindableLong result; + DB::BindableInt32 result; private: MoveToPlayerQuery(const MoveToPlayerQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h index 2e043f3d1..d0f3eb099 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h @@ -43,10 +43,10 @@ class TaskRestoreCharacter:public DB::TaskRequest DB::BindableNetworkId character_id; //output: - DB::BindableLong result; + DB::BindableInt32 result; DB::BindableString<127> character_name; - DB::BindableLong account; - DB::BindableLong template_id; + DB::BindableInt32 account; + DB::BindableInt32 template_id; private: RestoreCharacterQuery(const RestoreCharacterQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h index 8b04e6bd2..ffe5bc901 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h @@ -42,7 +42,7 @@ class TaskRestoreHouse:public DB::TaskRequest DB::BindableNetworkId house_id; //output: - DB::BindableLong result; + DB::BindableInt32 result; private: RestoreHouseQuery(const RestoreHouseQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h index 9dcfc58b8..e7422d7bb 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h @@ -39,7 +39,7 @@ class TaskSaveObjvarNames : public DB::TaskRequest virtual QueryMode getExecutionMode () const; public: - DB::BindableLong name_id; + DB::BindableInt32 name_id; DB::BindableString<500> name; private: diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h index c5d08f766..dd5d649fd 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h @@ -42,7 +42,7 @@ class TaskUndeleteItem:public DB::TaskRequest DB::BindableNetworkId item_id; //output: - DB::BindableLong result; + DB::BindableInt32 result; private: UndeleteItemQuery(const UndeleteItemQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h index c9d69a693..5da1d837b 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h @@ -47,7 +47,7 @@ class TaskVerifyCharacter:public DB::TaskRequest public: // input: - DB::BindableLong station_id; //lint !e1925 public data member Suppresed because it's in a private inner class + DB::BindableInt32 station_id; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableString<50> gold_schema; //lint !e1925 public data member Suppresed because it's in a private inner class @@ -59,7 +59,7 @@ class TaskVerifyCharacter:public DB::TaskRequest DB::BindableDouble x; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableDouble y; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableDouble z; //lint !e1925 public data member Suppresed because it's in a private inner class - DB::BindableLong containment_flag; + DB::BindableInt32 containment_flag; private: VerifyCharacterQuery(const VerifyCharacterQuery&); From c3c081bf8d1de992d274244b134b0b1f3a4a3072 Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 19 Jan 2022 01:01:16 -0500 Subject: [PATCH 29/46] Updating CMake build files to be more reliable and readable. --- CMakeLists.txt | 163 +++++++++++++++++++------------------------------ 1 file changed, 63 insertions(+), 100 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45c01642d..9b2c2e7f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,7 @@ cmake_minimum_required(VERSION 2.8) project(stellabellum C CXX) -if (WIN32) - set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/win32") -elseif (UNIX) - set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") -endif () +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") set(SWG_ROOT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SWG_ENGINE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/engine) @@ -16,8 +12,6 @@ set(SWG_GAME_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/game) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) -include_directories(/usr/include/i386-linux-gnu) - find_package(BISON REQUIRED) find_package(FLEX REQUIRED) find_package(JNI REQUIRED) @@ -28,108 +22,77 @@ find_package(Perl REQUIRED) find_package(Threads) find_package(ZLIB REQUIRED) find_package(CURL REQUIRED) +find_package(Curses REQUIRED) # c++17 yeah! set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -# shame on you cmake for auto-setting optimization flags! -set(CMAKE_CXX_FLAGS_DEBUG "") -set(CMAKE_CXX_FLAGS_RELEASE "") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "") -set(CMAKE_CXX_FLAGS_MINSIZEREL "") - -# I'll be honest, win32 is probably very very broken and won't build - it will need worked on so that MSVC uses -# the vs2013+ STL instead of stlport, and probably will thus need removal/modification/addition of TONS of the ifdef blocks for WIN32 -if (WIN32) - find_package(Iconv REQUIRED) - - # Dont-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:libc.lib /SAFESEH:NO") - - # Do-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed) - #set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DWIN32 -Dwin32 -DUDP_LIBRARY -DDEBUG_LEVEL=0 \ - # -DPRODUCTION=1 /Oi /Ot /Oy /O2 /GF /Gy /Zi /MT -D_USE_32BIT_TIME_T=1 -D_MBCS \ - # -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS /MP /wd4244 /wd4996 /wd4018 /wd4351 \ - # /Zc:wchar_t- /Ob1 /FC") - - # Dont-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DWIN32 -Dwin32 -DUDP_LIBRARY -DDEBUG_LEVEL=0 -DPRODUCTION=1 \ - /Oi /Ot /Oy /O2 /GF /Gy /MT -D_USE_32BIT_TIME_T=1 -D_MBCS -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS \ - /MP /wd4244 /wd4996 /wd4018 /wd4351 /Zc:wchar_t- /Ob1 /FC") - - # Standard DEBUG build use the following (by either commenting---uncommenting the line as needed) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DWIN32 -Dwin32 -D_DEBUG -DUDP_LIBRARY -DDEBUG_LEVEL=2 -DPRODUCTION=0 /MTd \ - -D_USE_32BIT_TIME_T=1 -D_MBCS -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS /MP /wd4244 /wd4996 /wd4018 /wd4351 \ - /Zc:wchar_t- /Ob1 /FC") -elseif (UNIX) - find_package(Curses REQUIRED) - - # Global Linker flags - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") - - # Strip debug symbols if RELEASE or MINSIZEREL - if (${CMAKE_BUILD_TYPE} STREQUAL "RELEASE" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS},-x,-s") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS},-x,-s") - endif () - - # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb -pg") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") - - # our "always on" flags - build by default for the system we're on but include all instruction sets - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -march=native -mtune=native \ - -Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \ - -Wno-write-strings -Wno-unknown-pragmas \ - -Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare -Wno-address-of-packed-member") - - message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}") - - # Ofast doesn't work with gcc builds - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast \ - -fno-threadsafe-statics -fslp-vectorize \ - -fno-stack-protector -fstrict-enums -finline-hint-functions \ - -fno-coverage-mapping -fno-spell-checking \ - -mno-retpoline") - - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g -fprofile-instr-generate -fcoverage-mapping") - - # RELWITHDEBINFO is used for building bins that produce profdata files - # we only need the basics of our heavy optimizations here, i think - that and one of these flags - # breaks JNI when we profile - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Ofast -finline-hint-functions -fprofile-instr-generate -g -fcoverage-mapping") - - # MINSIZEREL is used for profiled, flto builds - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -fwhole-program-vtables") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # O3 and Ofast include one or more flags that cause java to crash when using gcc6 - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fno-signed-zeros -freciprocal-math -fno-unroll-loops -fno-tree-loop-optimize -fno-plt") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -ggdb -no-pie") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-pie") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") - elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") - endif () - - add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE) - - # this is so some profile specific stuff is turned on in the code - if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "DEBUG") - add_definitions(-DENABLE_PROFILING) - endif () +# Global CMake CXX Flags +# our "always on" flags - build by default for the system we're on but include all instruction sets +set(CMAKE_CXX_FLAGS "\ + ${CMAKE_CXX_FLAGS} \ + -pipe \ + -march=native \ + -mtune=native \ + -maes \ + -Wformat \ + -Wno-overloaded-virtual \ + -Wno-missing-braces \ + -Wno-format \ + -Wno-write-strings \ + -Wno-unknown-pragmas \ + -Wno-uninitialized \ + -Wno-reorder \ + -Wno-tautological-constant-out-of-range-compare \ + -Wno-address-of-packed-member \ +") + +# Global Linker flags +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") + +string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) + +# Add on flags to strip debug symbols if RELEASE or MINSIZEREL +if (${CMAKE_BUILD_TYPE} STREQUAL "RELEASE" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS},-x,-s") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS},-x,-s") +endif () + +if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -pg -ggdb") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -O3 -pg -ggdb -no-pie") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Og -no-pie -flto -fwhole-program-vtables") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -O3") +elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "CLang") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -pg -ggdb -g -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -Ofast -pg -ggdb") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Og -no-pie -flto -fwhole-program-vtables") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Ofast") +endif() + +message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}") + +add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE) + +# this is so some profile specific stuff is turned on in the code +if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "DEBUG") + add_definitions(-DENABLE_PROFILING) endif () message("Flags CXX: ${CMAKE_CXX_FLAGS}") -message("Flags DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") -message("Flags RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") -message("Flags RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") -message("Flags MINSIZEREL: ${CMAKE_CXX_FLAGS_MINSIZEREL}") +if (${CMAKE_BUILD_TYPE} STREQUAL "DEBUG") + message("Flags DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") +elseif (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO") + message("Flags RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") +elseif (${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") + message("Flags MINSIZEREL: ${CMAKE_CXX_FLAGS_MINSIZEREL}") +elseif (${CMAKE_BUILD_TYPE} STREQUAL "RELEASE") + message("Flags RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") +endif () add_subdirectory(external) add_subdirectory(engine) From 7957b543fd8411a1fb1ffdb26149f65d1ccfd0e4 Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 19 Jan 2022 14:55:14 -0500 Subject: [PATCH 30/46] Added comments and removed setting defaults again for CMake --- CMakeLists.txt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b2c2e7f5..2572d9a2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,28 +49,31 @@ set(CMAKE_CXX_FLAGS "\ -Wno-address-of-packed-member \ ") +string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) + # Global Linker flags set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic") -string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) - # Add on flags to strip debug symbols if RELEASE or MINSIZEREL if (${CMAKE_BUILD_TYPE} STREQUAL "RELEASE" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS},-x,-s") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS},-x,-s") endif () +# Compiler specific settings. +# GNU - These are for GCC 7.5 (the version on the 3.0.x VM) +# Clang - These are for CLang 11 (current version as of Jan-2022), but it is not installed on the 3.0.x VM if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -pg -ggdb") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -O3 -pg -ggdb -no-pie") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Og -no-pie -flto -fwhole-program-vtables") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -O3") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg -ggdb") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -pg -ggdb -no-pie") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -no-pie -flto -fwhole-program-vtables") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1") elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "CLang") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -pg -ggdb -g -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg -ggdb -g -fprofile-instr-generate -fcoverage-mapping") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -Ofast -pg -ggdb") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Og -no-pie -flto -fwhole-program-vtables") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -no-pie -flto -fwhole-program-vtables") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Ofast") endif() From f8aaa0efdf60fc29e8383ff9ff1a49fb7d13677d Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 24 Jan 2022 23:34:28 -0800 Subject: [PATCH 31/46] Addressed several compiler warnings from GCC --- .gitattributes | 1 + CMakeLists.txt | 2 +- .../AuctionTransferGameAPI/Base/Archive.h | 3 +- .../LoginServer/src/shared/LoginServer.cpp | 4 +- .../src/shared/ManagerConnection.cpp | 4 +- .../server/library/codegen/make_packages.pl | 3 +- .../src/shared/DatabaseProcess.cpp | 7 +- .../src/shared/ai/AiCreatureWeaponActions.cpp | 6 +- .../src/shared/command/CommandCppFuncs.cpp | 13 ++- .../src/shared/command/CommandQueue.cpp | 2 +- .../console/ConsoleCommandParserObject.cpp | 5 +- .../src/shared/core/ServerWorld.cpp | 60 +++++++------ .../serverGame/src/shared/network/Chat.cpp | 2 +- .../src/shared/object/CellPermissions.cpp | 2 +- .../src/shared/object/CreatureObject.cpp | 5 +- .../src/shared/object/GroupObject.cpp | 13 ++- .../src/shared/object/GroupObject.h | 4 +- .../src/shared/object/PlayerObject.h | 12 +-- .../src/shared/object/TangibleObject.cpp | 3 +- .../src/shared/TaskConnectionIdMessage.h | 6 +- .../src/shared/GameScriptObject.cpp | 3 +- .../serverScript/src/shared/JavaLibrary.cpp | 5 ++ .../src/shared/core/CollisionProperty.cpp | 24 +++-- .../src/shared/core/CollisionWorld.cpp | 43 ++++----- .../src_oci/OciSession.cpp | 22 ----- .../sharedFile/src/shared/FileManifest.cpp | 5 +- .../src/shared/CommandLine.cpp | 7 +- .../library/sharedNetwork/src/linux/Sock.cpp | 33 +++---- .../sharedObject/src/shared/object/Object.cpp | 4 +- .../src/shared/FastRandomGenerator.h | 16 ++-- .../src/shared/generator/CoordinateHash.cpp | 20 ++--- .../src/shared/generator/CoordinateHash.h | 4 +- .../3rd/library/platform/utils/Base/Archive.h | 3 +- .../soePlatform/CSAssist/utils/Base/Archive.h | 3 +- .../CTServiceGameAPI/Base/Archive.h | 3 +- .../ChatAPI/projects/ChatAPI/ChatAvatar.cpp | 4 +- .../ChatAPI/projects/ChatAPI/ChatAvatar.h | 4 +- .../projects/ChatAPI/ChatAvatarCore.cpp | 14 +-- .../ChatAPI/projects/ChatAPI/ChatAvatarCore.h | 16 ++-- .../ChatAPI/projects/ChatAPI/Response.cpp | 2 +- .../ChatAPI/projects/ChatAPI/Response.h | 4 +- .../soePlatform/ChatAPI/utils/Base/Archive.h | 3 +- .../utils/UdpLibrary/UdpDriverLinux.cpp | 17 ++-- .../utils2.0/utils/Base/serializeClasses.h | 88 ++++++++----------- .../utils2.0/utils/UdpLibrary/UdpLibrary.cpp | 24 +++-- .../3rd/library/udplibrary/UdpLibrary.cpp | 27 +++--- .../archive/src/shared/AutoDeltaByteStream.h | 2 +- .../library/archive/src/shared/AutoDeltaMap.h | 4 +- .../archive/src/shared/AutoDeltaQueue.h | 4 +- .../library/archive/src/shared/AutoDeltaSet.h | 8 +- .../archive/src/shared/AutoDeltaVector.h | 42 ++++----- 51 files changed, 315 insertions(+), 300 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..aecf25037 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* -crlf diff --git a/CMakeLists.txt b/CMakeLists.txt index 2572d9a2a..8f0bbc1f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg -ggdb") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -pg -ggdb -no-pie") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -no-pie -flto -fwhole-program-vtables") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 ") elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "CLang") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg -ggdb -g -fprofile-instr-generate -fcoverage-mapping") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -Ofast -pg -ggdb") diff --git a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/Archive.h b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/Archive.h index a15f6cbae..00ae65cd1 100755 --- a/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/Archive.h +++ b/engine/server/application/CentralServer/src/shared/AuctionTransferGameAPI/Base/Archive.h @@ -724,8 +724,9 @@ const unsigned MAX_ARRAY_SIZE = 1024; Base::get(source, arraySize); ValueType v; - if (arraySize > MAX_ARRAY_SIZE) + if (arraySize > MAX_ARRAY_SIZE) { arraySize = 0; + } for(unsigned int i = 0; i < arraySize; ++i) { diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index bd053af2e..869f6b8bd 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -480,7 +480,9 @@ void LoginServer::receiveMessage(const MessageDispatch::Emitter &source, const M break; } } - DEBUG_REPORT_LOG(!found, ("Tried to remove a connection server that wasn't in our list.\n")); + if(!found) { + DEBUG_REPORT_LOG(true, ("Tried to remove a connection server that wasn't in our list.\n")); + } m_clusterStatusChanged = true; } else { WARNING_STRICT_FATAL(true, ("Programmer bug: Got ConnectionServerDown from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); diff --git a/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp b/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp index 244ee8816..b67798826 100755 --- a/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp +++ b/engine/server/application/TaskManager/src/shared/ManagerConnection.cpp @@ -122,8 +122,8 @@ void ManagerConnection::onReceive(const Archive::ByteStream & message) } case constcrc("TaskConnectionIdMessage") : { - static uint32_t const clockDriftFatalTimePeriod = static_cast(TaskManager::getStartTime()) + ConfigTaskManager::getClockDriftFatalIntervalSeconds(); - uint32_t const currentTime = static_cast(::time(nullptr)); + static int32_t const clockDriftFatalTimePeriod = static_cast(TaskManager::getStartTime()) + ConfigTaskManager::getClockDriftFatalIntervalSeconds(); + int32_t const currentTime = static_cast(::time(nullptr)); TaskConnectionIdMessage t(r); WARNING_STRICT_FATAL(t.getServerType() != TaskConnectionIdMessage::TaskManager, ("ManagerConnection received wrong type identifier")); diff --git a/engine/server/library/codegen/make_packages.pl b/engine/server/library/codegen/make_packages.pl index 2b580a3d1..65c55c913 100755 --- a/engine/server/library/codegen/make_packages.pl +++ b/engine/server/library/codegen/make_packages.pl @@ -307,8 +307,9 @@ sub makeEncodeFunction } print OUTFILE "\tconst DBSchema::${rowtype} *row=m_\l${buffer}.findConstRowByIndex(objectId);\n"; print OUTFILE "\tWARNING_STRICT_FATAL(row==NULL,(\"Loading object %s, no ${rowtype} in the buffer\\n\",objectId.getValueString().c_str()));\n"; - print OUTFILE "\tif (!row)\n"; + print OUTFILE "\tif (!row) {\n"; print OUTFILE "\t\treturn false;\n"; + print OUTFILE "\t}\n"; print OUTFILE "\n"; foreach $member (@{ $packageMembers{"$classname.$package"} }) diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp index 5b097f2c8..69aa99cdb 100755 --- a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp @@ -195,7 +195,8 @@ DatabaseProcess::~DatabaseProcess() void DatabaseProcess::run(void) { static bool shouldSleep = ConfigServerDatabase::getShouldSleep(); - bool idle=false; + // unused. + // bool idle=false; int loopcount=0; float nextQueryCountTime=0; @@ -261,7 +262,7 @@ void DatabaseProcess::run(void) if (Persister::getInstance().isIdle() && Loader::getInstance().isIdle() && DataLookup::getInstance().isIdle()) { DEBUG_REPORT_LOG(ConfigServerDatabase::getReportSaveTimes() && !idle,("Database process is idle.\n")); - idle=true; + // idle=true; if (taskService) { ServerIdleMessage msg(true); @@ -270,7 +271,7 @@ void DatabaseProcess::run(void) } else { - idle=false; + // idle=false; if (taskService) { ServerIdleMessage msg(false); diff --git a/engine/server/library/serverGame/src/shared/ai/AiCreatureWeaponActions.cpp b/engine/server/library/serverGame/src/shared/ai/AiCreatureWeaponActions.cpp index 4d5498f8b..66e8cb8c4 100755 --- a/engine/server/library/serverGame/src/shared/ai/AiCreatureWeaponActions.cpp +++ b/engine/server/library/serverGame/src/shared/ai/AiCreatureWeaponActions.cpp @@ -102,7 +102,7 @@ PersistentCrcString const & AiCreatureWeaponActions::getCombatAction() { unsigned int expiredCount = 0; - for (unsigned int i = 0; i < m_singleUseActionList.size(); ++i) + for (uint32_t i = 0; i < m_singleUseActionList.size(); ++i) { if (m_singleUseActionList[i] != 0) { @@ -133,7 +133,7 @@ PersistentCrcString const & AiCreatureWeaponActions::getCombatAction() // Delayed repeat actions { - for (unsigned int i = 0; i < m_delayRepeatActionList.size(); ++i) + for (uint32_t i = 0; i < m_delayRepeatActionList.size(); ++i) { if (osTime > time_t(m_delayRepeatActionList[i])) { @@ -160,7 +160,7 @@ PersistentCrcString const & AiCreatureWeaponActions::getCombatAction() time_t nextActionTime = 0; unsigned int nextActionIndex = 0; - for (unsigned int i = 0; i < m_instantRepeatActionList.size(); ++i) + for (uint32_t i = 0; i < m_instantRepeatActionList.size(); ++i) { if (osTime >= time_t(m_instantRepeatActionList[i])) { diff --git a/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp b/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp index 7fc71ebde..333d1a2a4 100755 --- a/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp +++ b/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp @@ -1800,11 +1800,11 @@ static void commandFuncSpatialChatInternal(Command const &, NetworkId const &act else if (!squelched && (ConfigServerGame::getChatSpamNotifyPlayerWhenLimitedIntervalSeconds() > 0) && obj->getClient()) { // send message telling character he can no longer talk - const int timeNow = static_cast(::time(nullptr)); - const int chatSpamTimeEndInterval = playerObject->getChatSpamTimeEndInterval(); + const int32_t timeNow = static_cast(::time(nullptr)); + const int32_t chatSpamTimeEndInterval = playerObject->getChatSpamTimeEndInterval(); if ((chatSpamTimeEndInterval > timeNow) && (timeNow >= playerObject->getChatSpamNextTimeToNotifyPlayerWhenLimited())) { - GenericValueTypeMessage csl("ChatSpamLimited", (chatSpamTimeEndInterval - timeNow)); + GenericValueTypeMessage csl("ChatSpamLimited", (chatSpamTimeEndInterval - timeNow)); obj->getClient()->send(csl, true); playerObject->setChatSpamNextTimeToNotifyPlayerWhenLimited((timeNow + ConfigServerGame::getChatSpamNotifyPlayerWhenLimitedIntervalSeconds())); @@ -1937,8 +1937,8 @@ static void commandFuncSpatialChat(Command const &, NetworkId const &actor, Netw else if (!squelched && (ConfigServerGame::getChatSpamNotifyPlayerWhenLimitedIntervalSeconds() > 0) && obj->getClient()) { // send message telling character he can no longer talk - const int timeNow = static_cast(::time(nullptr)); - const int chatSpamTimeEndInterval = playerObject->getChatSpamTimeEndInterval(); + const int32_t timeNow = static_cast(::time(nullptr)); + const int32_t chatSpamTimeEndInterval = playerObject->getChatSpamTimeEndInterval(); if ((chatSpamTimeEndInterval > timeNow) && (timeNow >= playerObject->getChatSpamNextTimeToNotifyPlayerWhenLimited())) { GenericValueTypeMessage csl("ChatSpamLimited", (chatSpamTimeEndInterval - timeNow)); @@ -2877,7 +2877,7 @@ static void commandFuncPermissionListModify(Command const &, NetworkId const &ac Unicode::UnicodeStringVector tokens; Unicode::tokenize(params, tokens); Unicode::String temp; - for (int i = 0; i < tokens.size(); i++) + for (uint32_t i = 0; i < tokens.size(); i++) { if(i < tokens.size() - 2) { @@ -2888,7 +2888,6 @@ static void commandFuncPermissionListModify(Command const &, NetworkId const &ac } } } - size_t curpos = 0; const Unicode::String & playerName = temp; const Unicode::String & listName = tokens[tokens.size()-2]; const Unicode::String & action = tokens[tokens.size()-1]; diff --git a/engine/server/library/serverGame/src/shared/command/CommandQueue.cpp b/engine/server/library/serverGame/src/shared/command/CommandQueue.cpp index b80d30b36..0d16fad49 100755 --- a/engine/server/library/serverGame/src/shared/command/CommandQueue.cpp +++ b/engine/server/library/serverGame/src/shared/command/CommandQueue.cpp @@ -684,7 +684,7 @@ void CommandQueue::switchState() m_eventStartTime = s_currentTime; - const unsigned int savedQueueSize = m_queue.size(); + const uint32_t savedQueueSize = m_queue.size(); switch ( m_state.get() ) { case State_Waiting: diff --git a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserObject.cpp b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserObject.cpp index dc2fd5f03..26a51317f 100755 --- a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserObject.cpp +++ b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserObject.cpp @@ -101,10 +101,7 @@ namespace ConsoleCommandParserObjectNamespace //test handler, this should eventually be removed void testConsentHandler(const NetworkId& player, int id, bool response) { - int i = 0; - if (response == true) - i = 1; - DEBUG_REPORT_LOG(true, ("We received a test consent back with values NetworkId:%s Id:%d Response:%d\n", player.getValueString().c_str(), id, i)); + DEBUG_REPORT_LOG(true, ("We received a test consent back with values NetworkId: %s Id: %d Response: %d\n", player.getValueString().c_str(), id, (response ? 1 : 0))); } ServerObjectTemplate const *getObjectTemplateForCreation(std::string const &templateName) diff --git a/engine/server/library/serverGame/src/shared/core/ServerWorld.cpp b/engine/server/library/serverGame/src/shared/core/ServerWorld.cpp index 0a45f4a70..e5b7fb2cd 100755 --- a/engine/server/library/serverGame/src/shared/core/ServerWorld.cpp +++ b/engine/server/library/serverGame/src/shared/core/ServerWorld.cpp @@ -320,20 +320,22 @@ void ServerWorldNamespace::issueCollisionNearWarpWarning(Object const &object, V //-- Only issue these for authoritative server objects. Proxy server objects will hit this condition after an intra-planet teleport. // @todo allow proxies to know about a teleport and inform CollisionWorld so that we can always report these. - DEBUG_WARNING(!serverObject || serverObject->isAuthoritative(), - ("CollisionWorld::update() had %d segments for object id=[%s], template=[%s], authority=[%s], game sever id=[%d], start position=[%.2f,%.2f,%.2f], end position=[%.2f,%.2f,%.2f], object probably should have warped but collision system is not warping it.", - segmentCount, - object.getNetworkId().getValueString().c_str(), - object.getObjectTemplateName(), - serverObject ? (serverObject->isAuthoritative() ? "authoritative" : "proxy") : "", - static_cast(GameServer::getInstance().getProcessId()), - oldPosition_w.x, - oldPosition_w.y, - oldPosition_w.z, - newPosition_w.x, - newPosition_w.y, - newPosition_w.z - )); + if(!serverObject || serverObject->isAuthoritative()) { + DEBUG_WARNING(true, + ("CollisionWorld::update() had %d segments for object id=[%s], template=[%s], authority=[%s], game sever id=[%d], start position=[%.2f,%.2f,%.2f], end position=[%.2f,%.2f,%.2f], object probably should have warped but collision system is not warping it.", + segmentCount, + object.getNetworkId().getValueString().c_str(), + object.getObjectTemplateName(), + serverObject ? (serverObject->isAuthoritative() ? "authoritative" : "proxy") : "", + static_cast(GameServer::getInstance().getProcessId()), + oldPosition_w.x, + oldPosition_w.y, + oldPosition_w.z, + newPosition_w.x, + newPosition_w.y, + newPosition_w.z + )); + } } // ---------------------------------------------------------------------- @@ -344,20 +346,22 @@ void ServerWorldNamespace::issueCollisionFarWarpWarning(Object const &object, Ve //-- Only issue these for authoritative server objects. Proxy server objects will hit this condition after an intra-planet teleport. // @todo allow proxies to know about a teleport and inform CollisionWorld so that we can always report these. - DEBUG_WARNING(!serverObject || serverObject->isAuthoritative(), - ("CollisionWorld::update() had %d segments for object id=[%s], template=[%s], authority=[%s], game sever id=[%d], start position=[%.2f,%.2f,%.2f], end position=[%.2f,%.2f,%.2f], collision system will consider this a warp and adjust accordingly.", - segmentCount, - object.getNetworkId().getValueString().c_str(), - object.getObjectTemplateName(), - serverObject ? (serverObject->isAuthoritative() ? "authoritative" : "proxy") : "", - static_cast(GameServer::getInstance().getProcessId()), - oldPosition_w.x, - oldPosition_w.y, - oldPosition_w.z, - newPosition_w.x, - newPosition_w.y, - newPosition_w.z - )); + if(!serverObject || serverObject->isAuthoritative()) { + DEBUG_WARNING(!serverObject || serverObject->isAuthoritative(), + ("CollisionWorld::update() had %d segments for object id=[%s], template=[%s], authority=[%s], game sever id=[%d], start position=[%.2f,%.2f,%.2f], end position=[%.2f,%.2f,%.2f], collision system will consider this a warp and adjust accordingly.", + segmentCount, + object.getNetworkId().getValueString().c_str(), + object.getObjectTemplateName(), + serverObject ? (serverObject->isAuthoritative() ? "authoritative" : "proxy") : "", + static_cast(GameServer::getInstance().getProcessId()), + oldPosition_w.x, + oldPosition_w.y, + oldPosition_w.z, + newPosition_w.x, + newPosition_w.y, + newPosition_w.z + )); + } } // ---------------------------------------------------------------------- diff --git a/engine/server/library/serverGame/src/shared/network/Chat.cpp b/engine/server/library/serverGame/src/shared/network/Chat.cpp index 345494639..319e82147 100755 --- a/engine/server/library/serverGame/src/shared/network/Chat.cpp +++ b/engine/server/library/serverGame/src/shared/network/Chat.cpp @@ -697,7 +697,7 @@ unsigned int Chat::isAllowedToEnterRoom(const CreatureObject & who, const std::s // thus requiring more work from us here bool isMayor = false; std::vector cityId = CityInterface::getCitizenOfCityId(who.getNetworkId()); - for(int i = 0; i < cityId.size(); ++i){ + for(uint32_t i = 0; i < cityId.size(); ++i){ NetworkId leader = CityInterface::getCityInfo(cityId[i]).getLeaderId(); if(playerObject && who.getNetworkId() == leader) { isMayor = true; diff --git a/engine/server/library/serverGame/src/shared/object/CellPermissions.cpp b/engine/server/library/serverGame/src/shared/object/CellPermissions.cpp index 9d1dc0d09..8c7bc82be 100755 --- a/engine/server/library/serverGame/src/shared/object/CellPermissions.cpp +++ b/engine/server/library/serverGame/src/shared/object/CellPermissions.cpp @@ -620,7 +620,7 @@ bool CellPermissions::isOnList(PermissionList const &permList, CreatureObject co } if (name.rfind("account:", 0) == 0) { - if (std::stoi(name.substr(8, name.length())) == stationId) + if (static_cast(std::stoi(name.substr(8, name.length()))) == stationId) { return true; } diff --git a/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp b/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp index 151130db5..52082f6dd 100755 --- a/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/CreatureObject.cpp @@ -485,7 +485,7 @@ namespace CreatureObjectNamespace { bool creatureIsContainedInPOBShip(CreatureObject const * creatureObject); void findAllTargetsForGroup(CreatureObject * const targetObj, std::vector & targets); - bool roomInGroup(GroupObject const * groupObj, int additionalMembers); + bool roomInGroup(GroupObject const * groupObj, uint32_t additionalMembers); GroupMemberParam const buildGroupMemberParam(CreatureObject const * creatureObject); void buildGroupMemberParamsFromCreatures(std::vector const & targets, GroupObject::GroupMemberParamVector & targetMemberParams); } @@ -14996,14 +14996,13 @@ void CreatureObjectNamespace::GroupHelpers::findAllTargetsForGroup(CreatureObjec // ---------------------------------------------------------------------- -bool CreatureObjectNamespace::GroupHelpers::roomInGroup(GroupObject const * groupObj, int additionalMembers) +bool CreatureObjectNamespace::GroupHelpers::roomInGroup(GroupObject const * groupObj, uint32_t additionalMembers) { if (groupObj != 0) { return groupObj->doesGroupHaveRoomFor(additionalMembers); } - additionalMembers = std::max(0, additionalMembers); return additionalMembers < GroupObject::maximumMembersInGroup(); } diff --git a/engine/server/library/serverGame/src/shared/object/GroupObject.cpp b/engine/server/library/serverGame/src/shared/object/GroupObject.cpp index 2aad93283..cfc0795ee 100755 --- a/engine/server/library/serverGame/src/shared/object/GroupObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/GroupObject.cpp @@ -55,7 +55,7 @@ namespace GroupObjectNamespace { // ---------------------------------------------------------------------- - unsigned int const cs_maximumNumberInGroup = 8; + const uint32_t cs_maximumNumberInGroup = 8; char const * const DEFAULT_GROUP_TEMPLATE = "object/group/group.iff"; std::map s_leaderMap; static const std::string cs_emptyString; @@ -226,7 +226,7 @@ void GroupObject::createAllGroupChatRooms() // static // ---------------------------------------------------------------------- -int GroupObject::maximumMembersInGroup() +uint32_t GroupObject::maximumMembersInGroup() { return cs_maximumNumberInGroup; } @@ -327,9 +327,8 @@ bool GroupObject::isMemberPC(NetworkId const & memberId) const // ---------------------------------------------------------------------- -bool GroupObject::doesGroupHaveRoomFor(int additionalMembers) const +bool GroupObject::doesGroupHaveRoomFor(uint32_t additionalMembers) const { - additionalMembers = std::max(0, additionalMembers); return (m_groupMembers.size() + additionalMembers) <= cs_maximumNumberInGroup; } @@ -519,7 +518,7 @@ void GroupObject::removeGroupMember(NetworkId const &memberId) else { GroupUpdateObserver updater(this, Archive::ADOO_generic); - for (unsigned int i = 0; i < m_groupMembers.size(); ++i) + for (uint32_t i = 0; i < m_groupMembers.size(); ++i) { GroupMember const & member = m_groupMembers.get(i); if (member.first == memberId) @@ -535,7 +534,7 @@ void GroupObject::removeGroupMember(NetworkId const &memberId) m_groupMemberProfessions.erase(i); calcGroupLevel(); - for (unsigned int j = 0; j < m_groupPOBShipAndOwners.size(); ++j) + for (uint32_t j = 0; j < m_groupPOBShipAndOwners.size(); ++j) { if (m_groupPOBShipAndOwners.get(j).second == memberId) { @@ -603,7 +602,7 @@ void GroupObject::disbandGroup() } else if (!getKill()) { - for (unsigned int i = 0; i < m_groupMembers.size(); ++i) + for (uint32_t i = 0; i < m_groupMembers.size(); ++i) { GroupMember const & member = m_groupMembers.get(i); removeFromGroupVoiceChatRoom(member.first, member.second); diff --git a/engine/server/library/serverGame/src/shared/object/GroupObject.h b/engine/server/library/serverGame/src/shared/object/GroupObject.h index e9e98519f..aa143b23f 100755 --- a/engine/server/library/serverGame/src/shared/object/GroupObject.h +++ b/engine/server/library/serverGame/src/shared/object/GroupObject.h @@ -47,7 +47,7 @@ class GroupObject: public UniverseObject static void removeFromLeaderMap (NetworkId const &leaderId, NetworkId const &groupId); static NetworkId getGroupIdForLeader (NetworkId const &leaderId); static void createAllGroupChatRooms (); - static int maximumMembersInGroup(); + static uint32_t maximumMembersInGroup(); typedef std::pair GroupMember; typedef std::vector GroupMemberVector; @@ -61,7 +61,7 @@ class GroupObject: public UniverseObject bool isGroupFull () const; int getPCMemberCount () const; bool isMemberPC(NetworkId const & memberId) const; - bool doesGroupHaveRoomFor(int additionalMembers) const; + bool doesGroupHaveRoomFor(uint32_t additionalMembers) const; GroupMemberVector const & getGroupMembers () const; int getGroupLevel () const; uint32 getFormationNameCrc() const; diff --git a/engine/server/library/serverGame/src/shared/object/PlayerObject.h b/engine/server/library/serverGame/src/shared/object/PlayerObject.h index b2f308084..0d669f939 100755 --- a/engine/server/library/serverGame/src/shared/object/PlayerObject.h +++ b/engine/server/library/serverGame/src/shared/object/PlayerObject.h @@ -395,8 +395,8 @@ class PlayerObject : public IntangibleObject int getChatSpamTimeEndInterval() const; - uint32_t getChatSpamNextTimeToNotifyPlayerWhenLimited() const; - void setChatSpamNextTimeToNotifyPlayerWhenLimited(uint32_t chatSpamNextTimeToNotifyPlayerWhenLimited); + int32_t getChatSpamNextTimeToNotifyPlayerWhenLimited() const; + void setChatSpamNextTimeToNotifyPlayerWhenLimited(int32_t chatSpamNextTimeToNotifyPlayerWhenLimited); // citizenship info void updateCitizenshipInfo(); @@ -585,7 +585,7 @@ class PlayerObject : public IntangibleObject Archive::AutoDeltaVariable m_aggroImmuneStartTime; ChatLog * const m_chatLog; - uint32_t m_chatLogPurgeTime; + time_t m_chatLogPurgeTime; bool m_isUnsticking; //when asking a player to accept or complete a quest, remember the quest that we asked them about @@ -641,7 +641,7 @@ class PlayerObject : public IntangibleObject Archive::AutoDeltaVariable m_chatSpamNonSpatialNumCharacters; Archive::AutoDeltaVariable m_chatSpamTimeEndInterval; Archive::AutoDeltaVariable m_chatSpamNextTimeToSyncWithChatServer; - uint32_t m_chatSpamNextTimeToNotifyPlayerWhenLimited; + int32_t m_chatSpamNextTimeToNotifyPlayerWhenLimited; // citizenship info Archive::AutoDeltaVariable m_citizenshipCity; @@ -1053,14 +1053,14 @@ inline int PlayerObject::getChatSpamTimeEndInterval() const // ---------------------------------------------------------------------- -inline uint32_t PlayerObject::getChatSpamNextTimeToNotifyPlayerWhenLimited() const +inline int32_t PlayerObject::getChatSpamNextTimeToNotifyPlayerWhenLimited() const { return m_chatSpamNextTimeToNotifyPlayerWhenLimited; } // ---------------------------------------------------------------------- -inline void PlayerObject::setChatSpamNextTimeToNotifyPlayerWhenLimited(uint32_t chatSpamNextTimeToNotifyPlayerWhenLimited) +inline void PlayerObject::setChatSpamNextTimeToNotifyPlayerWhenLimited(int32_t chatSpamNextTimeToNotifyPlayerWhenLimited) { m_chatSpamNextTimeToNotifyPlayerWhenLimited = chatSpamNextTimeToNotifyPlayerWhenLimited; } diff --git a/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp b/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp index eba9e915b..b5eabfa6f 100755 --- a/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/TangibleObject.cpp @@ -570,7 +570,8 @@ TangibleObject::~TangibleObject() // look up the caller's file and line if (callStack[callStackOffset]) { - char lib[4 * 1024] = { '\0' }; + // unused. + // char lib[4 * 1024] = { '\0' }; char file[4 * 1024] = { '\0' }; int line = 0; REPORT_LOG(true, ("\tCall stack:")); diff --git a/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h b/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h index 9580f6077..4ec6ff554 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h +++ b/engine/server/library/serverNetworkMessages/src/shared/TaskConnectionIdMessage.h @@ -34,7 +34,7 @@ class TaskConnectionIdMessage : public GameNetworkMessage const unsigned char getServerType () const; const std::string & getCommandLine () const; const std::string & getClusterName () const; - const uint32_t getCurrentEpochTime() const; + const int32_t getCurrentEpochTime() const; private: TaskConnectionIdMessage & operator = (const TaskConnectionIdMessage & rhs); TaskConnectionIdMessage(const TaskConnectionIdMessage & source); @@ -42,7 +42,7 @@ class TaskConnectionIdMessage : public GameNetworkMessage Archive::AutoVariable serverType; Archive::AutoVariable commandLine; Archive::AutoVariable clusterName; - Archive::AutoVariable currentEpochTime; + Archive::AutoVariable currentEpochTime; }; //----------------------------------------------------------------------- @@ -68,7 +68,7 @@ inline const unsigned char TaskConnectionIdMessage::getServerType() const //----------------------------------------------------------------------- -inline const uint32_t TaskConnectionIdMessage::getCurrentEpochTime() const +inline const int32_t TaskConnectionIdMessage::getCurrentEpochTime() const { return currentEpochTime.get(); } diff --git a/engine/server/library/serverScript/src/shared/GameScriptObject.cpp b/engine/server/library/serverScript/src/shared/GameScriptObject.cpp index ab118b52b..5eefb97eb 100755 --- a/engine/server/library/serverScript/src/shared/GameScriptObject.cpp +++ b/engine/server/library/serverScript/src/shared/GameScriptObject.cpp @@ -100,8 +100,9 @@ bool GameScriptObject::installScriptEngine(void) ms_scriptDataMap = new GameScriptObject::ScriptDataMap; Scripting::InitScriptFuncHashMap(); JavaLibrary::install(); - if (JavaLibrary::instance() == nullptr) + if (JavaLibrary::instance() == nullptr) { return false; + } enableNewJediTracking(ConfigServerGame::getEnableNewJedi()); return true; } // GameScriptObject::installScriptEngine diff --git a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp index c373980a2..f5f415b79 100755 --- a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp +++ b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp @@ -803,6 +803,10 @@ void JavaLibrary::fatalHandler(int signum) void *frameAddressB = nullptr; uint64 frameAddressHigh = (reinterpret_cast(frameAddress) >> 16); crashAddress2a = __builtin_return_address(0); +// Suppress Wframe-address for these lines - we could crash the program calling __builtin_return_address and frame_address +// with non-zero values. However, we likely don't care as we're crashing at this point anyway due to bad Java. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-address" if (crashAddress2a != nullptr) { frameAddressA = __builtin_frame_address(1); @@ -826,6 +830,7 @@ void JavaLibrary::fatalHandler(int signum) } } } +#pragma GCC diagnostic pop bool javaCrash = true; if ((result1 || result2) && strstr(lib1, "libjvm.so") == nullptr && strstr(lib2, "libjvm.so") == nullptr) diff --git a/engine/shared/library/sharedCollision/src/shared/core/CollisionProperty.cpp b/engine/shared/library/sharedCollision/src/shared/core/CollisionProperty.cpp index b8cc93323..3aa8d90fd 100755 --- a/engine/shared/library/sharedCollision/src/shared/core/CollisionProperty.cpp +++ b/engine/shared/library/sharedCollision/src/shared/core/CollisionProperty.cpp @@ -549,7 +549,9 @@ BaseExtent * convertToSimpleExtent ( BaseExtent const * sourceExtent ) { Extent const * extent = safe_cast(sourceExtent); - if(!extent) return nullptr; + if(!extent) { + return nullptr; + } return new SimpleExtent( MultiShape( extent->getShape() ) ); } @@ -558,7 +560,9 @@ BaseExtent * convertToSimpleExtent ( BaseExtent const * sourceExtent ) { CylinderExtent const * extent = safe_cast(sourceExtent); - if(!extent) return nullptr; + if(!extent) { + return nullptr; + } return new SimpleExtent( MultiShape( extent->getShape() ) ); } @@ -567,7 +571,9 @@ BaseExtent * convertToSimpleExtent ( BaseExtent const * sourceExtent ) { BoxExtent const * extent = safe_cast(sourceExtent); - if(!extent) return nullptr; + if(!extent) { + return nullptr; + } return new SimpleExtent( MultiShape( extent->getShape() ) ); } @@ -576,7 +582,9 @@ BaseExtent * convertToSimpleExtent ( BaseExtent const * sourceExtent ) { MeshExtent const * extent = safe_cast(sourceExtent); - if(!extent) return nullptr; + if(!extent) { + return nullptr; + } return extent->clone(); } @@ -585,7 +593,9 @@ BaseExtent * convertToSimpleExtent ( BaseExtent const * sourceExtent ) { DetailExtent const * extent = safe_cast(sourceExtent); - if(!extent) return nullptr; + if(!extent) { + return nullptr; + } DetailExtent * newExtent = new DetailExtent(); @@ -603,7 +613,9 @@ BaseExtent * convertToSimpleExtent ( BaseExtent const * sourceExtent ) { ComponentExtent const * extent = safe_cast(sourceExtent); - if(!extent) return nullptr; + if(!extent) { + return nullptr; + } ComponentExtent * newExtent = new ComponentExtent(); diff --git a/engine/shared/library/sharedCollision/src/shared/core/CollisionWorld.cpp b/engine/shared/library/sharedCollision/src/shared/core/CollisionWorld.cpp index 71a06f867..e6973d1b7 100755 --- a/engine/shared/library/sharedCollision/src/shared/core/CollisionWorld.cpp +++ b/engine/shared/library/sharedCollision/src/shared/core/CollisionWorld.cpp @@ -1128,27 +1128,30 @@ void CollisionWorld::addObject(Object * object) name = appearance->getAppearanceTemplateName(); } } - - int index = 0; - switch (query) - { - case SpatialDatabase::Q_Static: - index = 1; - break; - case SpatialDatabase::Q_Dynamic: - index = 2; - break; - case SpatialDatabase::Q_Barriers: - index = 3; - break; - case SpatialDatabase::Q_Doors: - index = 4; - break; - default: - break; +#if _DEBUG + if(ConfigSharedCollision::getReportChanges()) { + int index = 0; + switch (query) + { + case SpatialDatabase::Q_Static: + index = 1; + break; + case SpatialDatabase::Q_Dynamic: + index = 2; + break; + case SpatialDatabase::Q_Barriers: + index = 3; + break; + case SpatialDatabase::Q_Doors: + index = 4; + break; + default: + break; + } + + DEBUG_REPORT_LOG(true, ("Added object %s to collision world [%s] at (%f,%f,%f)\n", name, ms_sptatialDatabaseNames[index], object->getPosition_w().x, object->getPosition_w().y, object->getPosition_w().z)); } - - DEBUG_REPORT_LOG(ConfigSharedCollision::getReportChanges(), ("Added object %s to collision world [%s] at (%f,%f,%f)\n", name, ms_sptatialDatabaseNames[index], object->getPosition_w().x, object->getPosition_w().y, object->getPosition_w().z)); +#endif } } diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp index eb6e9d2c7..f1fee1544 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp @@ -32,28 +32,6 @@ using namespace DB::OCISessionNamespace; // ====================================================================== -static dvoid *mallocHook(dvoid *, size_t size) -{ - return reinterpret_cast(new char[size]); -} - -// ---------------------------------------------------------------------- - -static dvoid *reallocHook(dvoid *, dvoid *memptr, size_t newsize) -{ - return reinterpret_cast(realloc(memptr, newsize)); -} - -// ---------------------------------------------------------------------- - -static void freeHook(dvoid *, dvoid *memptr) -{ - if (memptr) - delete [] reinterpret_cast(memptr); -} - -// ====================================================================== - DB::OCISession::OCISession(DB::OCIServer *server) : m_server(server), envhp(nullptr), diff --git a/engine/shared/library/sharedFile/src/shared/FileManifest.cpp b/engine/shared/library/sharedFile/src/shared/FileManifest.cpp index c55527755..26117a633 100755 --- a/engine/shared/library/sharedFile/src/shared/FileManifest.cpp +++ b/engine/shared/library/sharedFile/src/shared/FileManifest.cpp @@ -40,10 +40,13 @@ namespace FileManifestNamespace static TransitionVector s_transitionVector; static bool s_installed = false; static bool s_updateManifest = false; + static std::string s_currentSceneId = "none"; + +#if PRODUCTION == 0 static int s_accessThreshold = -1; - static std::string s_currentSceneId = "none"; static bool s_isValidScene = false; static bool s_isTransitionScene = true; +#endif const static std::string s_manifestDataTable = "datatables/manifest/skufree.iff"; diff --git a/engine/shared/library/sharedFoundation/src/shared/CommandLine.cpp b/engine/shared/library/sharedFoundation/src/shared/CommandLine.cpp index 5209d788d..8fba42e97 100755 --- a/engine/shared/library/sharedFoundation/src/shared/CommandLine.cpp +++ b/engine/shared/library/sharedFoundation/src/shared/CommandLine.cpp @@ -1385,12 +1385,11 @@ void CommandLine::absorbString(const char *newString) DEBUG_FATAL(!newString, ("nullptr newString arg")); const int stringLength = static_cast(strlen(newString)); - int requiredBufferSpace; + if (absorbedStringCount) - requiredBufferSpace = stringLength + 2; + DEBUG_FATAL(bufferSize + stringLength + 2 >= STATIC_BUFFER_SIZE, ("newString too large by %d bytes", bufferSize + stringLength + 2 - STATIC_BUFFER_SIZE)); else - requiredBufferSpace = stringLength + 1; - DEBUG_FATAL(bufferSize + requiredBufferSpace >= STATIC_BUFFER_SIZE, ("newString too large by %d bytes", bufferSize + requiredBufferSpace - STATIC_BUFFER_SIZE)); + DEBUG_FATAL(bufferSize + stringLength + 1 >= STATIC_BUFFER_SIZE, ("newString too large by %d bytes", bufferSize + stringLength + 1 - STATIC_BUFFER_SIZE)); if (absorbedStringCount) { diff --git a/engine/shared/library/sharedNetwork/src/linux/Sock.cpp b/engine/shared/library/sharedNetwork/src/linux/Sock.cpp index 22b293589..5ff32be6e 100755 --- a/engine/shared/library/sharedNetwork/src/linux/Sock.cpp +++ b/engine/shared/library/sharedNetwork/src/linux/Sock.cpp @@ -1,6 +1,12 @@ //--------------------------------------------------------------------- #pragma warning(disable : 4127) +#ifdef NDEBUG +#define SWG_ASSERT(exp) ((void) (exp)) +#else +#define SWG_ASSERT assert +#endif + #include "FirstSharedNetwork.h" #include #include "Sock.h" @@ -28,9 +34,8 @@ Sock::~Sock() { // ensure we don't block, and that pending // data is sent with a graceful shutdown - int err; - err = close(handle); - assert(err == 0); + int err = close(handle); + SWG_ASSERT(err == 0); handle = INVALID_SOCKET; } @@ -55,7 +60,7 @@ bool Sock::bind(const Address & newBindAddress) struct sockaddr_in a; int r; r = getsockname(handle, reinterpret_cast(&a), &namelen); - assert(r == 0); + SWG_ASSERT(r == 0); bindAddress = a; } else @@ -83,9 +88,8 @@ bool Sock::bind() if(err == 0) { result = true; - int r; - r = getsockname(handle, reinterpret_cast(&a), &namelen); - assert(r == 0); + int r = getsockname(handle, reinterpret_cast(&a), &namelen); + SWG_ASSERT(r == 0); bindAddress = a; } assert(err == 0); @@ -144,9 +148,8 @@ bool Sock::canSend() const const unsigned int Sock::getInputBytesPending() const { unsigned long int bytes = 0; - int err; - err = ioctl(handle, FIONREAD, &bytes); //lint !e1924 (I don't know WHAT Microsoft is doing here!) - assert(err == 0); + int err = ioctl(handle, FIONREAD, &bytes); //lint !e1924 (I don't know WHAT Microsoft is doing here!) + SWG_ASSERT(err == 0); return bytes; } @@ -199,9 +202,8 @@ const std::string Sock::getLastError() const void Sock::getPeerName(struct sockaddr_in & target, int s) { socklen_t namelen = sizeof(struct sockaddr_in); - int err; - err = getpeername(s, reinterpret_cast(&(target)), &namelen); - assert(err != -1); + int err = getpeername(s, reinterpret_cast(&(target)), &namelen); + SWG_ASSERT(err != -1); } //----------------------------------------------------------------------- @@ -227,9 +229,8 @@ void Sock::setNonBlocking() const { assert(handle != INVALID_SOCKET); unsigned long int nb = 1; - int err; - err = ioctl(handle, FIONBIO, &nb); //lint !e569 // loss of precision in the FIONBIO macro, beyond my control - assert(err == 0); + int err = ioctl(handle, FIONBIO, &nb); //lint !e569 // loss of precision in the FIONBIO macro, beyond my control + SWG_ASSERT(err == 0); } //--------------------------------------------------------------------- diff --git a/engine/shared/library/sharedObject/src/shared/object/Object.cpp b/engine/shared/library/sharedObject/src/shared/object/Object.cpp index e59224302..04713352f 100755 --- a/engine/shared/library/sharedObject/src/shared/object/Object.cpp +++ b/engine/shared/library/sharedObject/src/shared/object/Object.cpp @@ -149,7 +149,9 @@ Object::NotificationList::NotificationList(const NotificationList &otherList, co m_notificationList.push_back(add); } - DEBUG_FATAL(!deletedOtherEntry, ("didn't find notification [0x%08x] in source list for deletion", &otherEntry)); + if(!deletedOtherEntry) { + DEBUG_FATAL(true, ("didn't find notification [0x%08x] in source list for deletion", &otherEntry)); + } DEBUG_FATAL(m_notificationList.size() != otherList.m_notificationList.size() - 1, ("failed to build new notification list correctly")); } diff --git a/engine/shared/library/sharedRandom/src/shared/FastRandomGenerator.h b/engine/shared/library/sharedRandom/src/shared/FastRandomGenerator.h index 7896ca5ae..131694e44 100755 --- a/engine/shared/library/sharedRandom/src/shared/FastRandomGenerator.h +++ b/engine/shared/library/sharedRandom/src/shared/FastRandomGenerator.h @@ -16,18 +16,18 @@ class FastRandomGenerator { public: FastRandomGenerator() { m_I=ZERO_ALT; } - FastRandomGenerator(long s) { setSeed(s); } + FastRandomGenerator(uint32 s) { setSeed(s); } - void setSeed(long s) + void setSeed(uint32 s) { - const long ps = s&0x7fffffff; + const uint32 ps = s&0x7fffffff; m_I = (ps==0) ? ZERO_ALT : ps; } // return a random number r where 0<=r<1 float randomFloat() { - long f = (_rand()>>8)|IEEE_FLOAT_BITS; + float f = static_cast((_rand()>>8)|IEEE_FLOAT_BITS); return (*(float *)(void *)&f)-1.0f; } float randomFloat(float range) { return randomFloat()*range; } @@ -49,9 +49,9 @@ class FastRandomGenerator ZERO_ALT = 123459876 }; - long _rand() + uint32 _rand() { - long k; + uint32 k; k=m_I/IQ; m_I=IA*(m_I-k*IQ)-IR*k; if (m_I<0) m_I += IM; @@ -59,9 +59,9 @@ class FastRandomGenerator return k; } - long _randMax() { return IM-1; } + uint32 _randMax() { return IM-1; } - long m_I; + uint32 m_I; }; // ====================================================================== diff --git a/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.cpp b/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.cpp index e6d8c6f50..d1c9393b7 100755 --- a/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.cpp +++ b/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.cpp @@ -183,28 +183,28 @@ namespace //=================================================================== -unsigned long CoordinateHash::hashTuple(float x, float z) +uint32 CoordinateHash::hashTuple(float x, float z) { - const uint32 ix = (*(uint32 *)&x); - const uint32 iz = (*(uint32 *)&z)^0xa5a5a5a5; + const uint32 ix = (*reinterpret_cast(&x)); + const uint32 iz = (*reinterpret_cast(&z)) ^ 0xa5a5a5a5; - const uint32 hx = inthash(ix); - const uint32 hz = inthash(iz); + const uint32 hx = inthash(ix); + const uint32 hz = inthash(iz); - const uint32 h = inthash(hx^hz); + const uint32 h = inthash(hx ^ hz); - return h; + return h; } -float CoordinateHash::makeFloat(unsigned long hash) +float CoordinateHash::makeFloat(uint32 hash) { enum { IEEE_FLOAT_BITS=0x3f800000 }; const uint32 mask = ~uint32(0xff800000); const uint32 maskedHash = (hash + (hash>>9))&mask; - const uint32 iFloat = IEEE_FLOAT_BITS | maskedHash; - const float returnValue = (*(float *)&iFloat) - 1.0f; + uint32 iFloat = static_cast(IEEE_FLOAT_BITS) | maskedHash; + const float returnValue = (*reinterpret_cast(&iFloat)) - 1.0F; return returnValue; } diff --git a/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.h b/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.h index f01d06455..7e70609d9 100755 --- a/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.h +++ b/engine/shared/library/sharedTerrain/src/shared/generator/CoordinateHash.h @@ -19,8 +19,8 @@ class CoordinateHash { public: - static unsigned long hashTuple(float x, float z); - static float makeFloat(unsigned long hash); + static uint32 hashTuple(float x, float z); + static float makeFloat(uint32 hash); }; //=================================================================== diff --git a/external/3rd/library/platform/utils/Base/Archive.h b/external/3rd/library/platform/utils/Base/Archive.h index f8f5ef394..1020a05dc 100755 --- a/external/3rd/library/platform/utils/Base/Archive.h +++ b/external/3rd/library/platform/utils/Base/Archive.h @@ -656,8 +656,9 @@ const unsigned MAX_ARRAY_SIZE = 1024; Base::get(source, arraySize); ValueType v; - if (arraySize > MAX_ARRAY_SIZE) + if (arraySize > MAX_ARRAY_SIZE) { arraySize = 0; + } using Base::get; for(unsigned int i = 0; i < arraySize; ++i) diff --git a/external/3rd/library/soePlatform/CSAssist/utils/Base/Archive.h b/external/3rd/library/soePlatform/CSAssist/utils/Base/Archive.h index 212872204..8141f1d66 100755 --- a/external/3rd/library/soePlatform/CSAssist/utils/Base/Archive.h +++ b/external/3rd/library/soePlatform/CSAssist/utils/Base/Archive.h @@ -667,8 +667,9 @@ const unsigned MAX_ARRAY_SIZE = 1024; Base::get(source, arraySize); ValueType v; - if (arraySize > MAX_ARRAY_SIZE) + if (arraySize > MAX_ARRAY_SIZE) { arraySize = 0; + } for(unsigned int i = 0; i < arraySize; ++i) { diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h index 856dcd95e..1cfc696f7 100755 --- a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h @@ -653,8 +653,9 @@ const unsigned MAX_ARRAY_SIZE = 1024; Base::get(source, arraySize); ValueType v; - if (arraySize > MAX_ARRAY_SIZE) + if (arraySize > MAX_ARRAY_SIZE) { arraySize = 0; + } for(unsigned int i = 0; i < arraySize; ++i) { diff --git a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.cpp b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.cpp index 8ec60bc8b..ab25b4b81 100755 --- a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.cpp +++ b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.cpp @@ -148,7 +148,7 @@ const ChatUnicodeString& ChatAvatar::getStatusMessage() const return m_cStatusMessage; } -void ChatAvatar::setAttributes(unsigned long attributes) +void ChatAvatar::setAttributes(uint32_t attributes) { m_core->setAttributes(attributes); } @@ -158,7 +158,7 @@ void ChatAvatar::setLoginPriority(int loginPriority) m_core->setLoginPriority(loginPriority); } -void ChatAvatar::setInboxLimit(unsigned inboxLimit) +void ChatAvatar::setInboxLimit(uint32_t inboxLimit) { m_core->setInboxLimit(inboxLimit); } diff --git a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.h b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.h index 998738da5..43fbd1e3e 100755 --- a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.h +++ b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatar.h @@ -61,9 +61,9 @@ namespace ChatSystem const ChatUnicodeString &getForwardingEmail() const; const ChatUnicodeString& getStatusMessage() const; - void setAttributes(unsigned long attributes); + void setAttributes(uint32_t attributes); void setLoginPriority(int loginPriority); - void setInboxLimit(unsigned inboxLimit); + void setInboxLimit(uint32_t inboxLimit); void setForwardingEmail(const ChatUnicodeString &forwardingEmail); void setStatusMessage(const ChatUnicodeString& statusMessage); diff --git a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.cpp b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.cpp index 871f63d7a..838aaa752 100755 --- a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.cpp +++ b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.cpp @@ -17,7 +17,7 @@ namespace ChatSystem { } - ChatAvatarCore::ChatAvatarCore(unsigned avatarID, unsigned userID, const unsigned short *name, const unsigned short *address, const unsigned short *gateway, const unsigned short *server, unsigned gatewayID, unsigned serverID, const unsigned short *loginLocation, unsigned attributes) + ChatAvatarCore::ChatAvatarCore(unsigned avatarID, unsigned userID, const unsigned short *name, const unsigned short *address, const unsigned short *gateway, const unsigned short *server, unsigned gatewayID, unsigned serverID, const unsigned short *loginLocation, uint32_t attributes) : m_name(name), m_address(address), m_server(server), @@ -33,7 +33,7 @@ namespace ChatSystem { } - ChatAvatarCore::ChatAvatarCore(unsigned avatarID, unsigned userID, const ChatUnicodeString &name, const ChatUnicodeString &address, const ChatUnicodeString &gateway, const ChatUnicodeString &server, unsigned gatewayID, unsigned serverID, const ChatUnicodeString &loginLocation, unsigned attributes) + ChatAvatarCore::ChatAvatarCore(unsigned avatarID, unsigned userID, const ChatUnicodeString &name, const ChatUnicodeString &address, const ChatUnicodeString &gateway, const ChatUnicodeString &server, unsigned gatewayID, unsigned serverID, const ChatUnicodeString &loginLocation, uint32_t attributes) : m_name(name.string_data, name.string_length), m_address(address.string_data, address.string_length), m_server(server.string_data, server.string_length), @@ -49,7 +49,7 @@ namespace ChatSystem { } - ChatAvatarCore::ChatAvatarCore(unsigned avatarID, unsigned userID, const String &name, const String &address, const String &gateway, const String &server, unsigned gatewayID, unsigned serverID, const Plat_Unicode::String &loginLocation, unsigned attributes) + ChatAvatarCore::ChatAvatarCore(unsigned avatarID, unsigned userID, const String &name, const String &address, const String &gateway, const String &server, unsigned gatewayID, unsigned serverID, const Plat_Unicode::String &loginLocation, uint32_t attributes) : m_name(name), m_address(address), m_server(server), @@ -71,7 +71,7 @@ namespace ChatSystem get(iter, m_userID); ASSERT_VALID_STRING_LENGTH(get(iter, m_name)); ASSERT_VALID_STRING_LENGTH(get(iter, m_address)); - get(iter, (uint32 &)m_attributes); + get(iter, m_attributes); ASSERT_VALID_STRING_LENGTH(get(iter, m_loginLocation)); ASSERT_VALID_STRING_LENGTH(get(iter, m_server)); ASSERT_VALID_STRING_LENGTH(get(iter, m_gateway)); @@ -153,11 +153,11 @@ namespace ChatSystem put(msg, m_userID); put(msg, m_name); put(msg, m_address); - put(msg, (uint32)m_attributes); + put(msg, m_attributes); put(msg, m_loginLocation); } - void ChatAvatarCore::setAttributes(unsigned long attributes) + void ChatAvatarCore::setAttributes(uint32_t attributes) { m_attributes = attributes; } @@ -172,7 +172,7 @@ namespace ChatSystem m_email = email; } - void ChatAvatarCore::setInboxLimit(unsigned inboxLimit) + void ChatAvatarCore::setInboxLimit(uint32_t inboxLimit) { m_inboxLimit = inboxLimit; } diff --git a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.h b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.h index ebd3fc81e..e01d6b450 100755 --- a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.h +++ b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/ChatAvatarCore.h @@ -20,9 +20,9 @@ namespace ChatSystem public: ChatAvatarCore(); ChatAvatarCore(Base::ByteStream::ReadIterator &iter); - ChatAvatarCore(unsigned avatarID, unsigned userID, const unsigned short *name, const unsigned short *address, const unsigned short *gateway, const unsigned short *server, unsigned gatewayID, unsigned serverID, const unsigned short *loginLocation, unsigned attributes); - ChatAvatarCore(unsigned avatarID, unsigned userID, const ChatUnicodeString &name, const ChatUnicodeString &address, const ChatUnicodeString &gateway, const ChatUnicodeString &server, unsigned gatewayID, unsigned serverID, const ChatUnicodeString &loginLocation, unsigned attributes); - ChatAvatarCore(unsigned avatarID, unsigned userID, const Plat_Unicode::String &name, const Plat_Unicode::String &address, const Plat_Unicode::String &gateway, const Plat_Unicode::String &server, unsigned gatewayID, unsigned serverID, const Plat_Unicode::String &loginLocation, unsigned attributes); + ChatAvatarCore(unsigned avatarID, unsigned userID, const unsigned short *name, const unsigned short *address, const unsigned short *gateway, const unsigned short *server, unsigned gatewayID, unsigned serverID, const unsigned short *loginLocation, uint32_t attributes); + ChatAvatarCore(unsigned avatarID, unsigned userID, const ChatUnicodeString &name, const ChatUnicodeString &address, const ChatUnicodeString &gateway, const ChatUnicodeString &server, unsigned gatewayID, unsigned serverID, const ChatUnicodeString &loginLocation, uint32_t attributes); + ChatAvatarCore(unsigned avatarID, unsigned userID, const Plat_Unicode::String &name, const Plat_Unicode::String &address, const Plat_Unicode::String &gateway, const Plat_Unicode::String &server, unsigned gatewayID, unsigned serverID, const Plat_Unicode::String &loginLocation, uint32_t attributes); ChatAvatarCore(const ChatAvatarCore &rhs); @@ -34,9 +34,9 @@ namespace ChatSystem unsigned getAvatarID() const { return m_avatarID; } const Plat_Unicode::String &getLoginLocation() const { return m_loginLocation; } int getLoginPriority() const { return m_loginPriority; } - unsigned getAttributes() const { return m_attributes; } + uint32_t getAttributes() const { return m_attributes; } const Plat_Unicode::String &getEmail() const { return m_email; } - unsigned getInboxLimit() const { return m_inboxLimit; } + uint32_t getInboxLimit() const { return m_inboxLimit; } const Plat_Unicode::String &getServer() const { return m_server; } const Plat_Unicode::String &getGateway() const { return m_gateway; } unsigned getServerID() const { return m_serverID; } @@ -45,7 +45,7 @@ namespace ChatSystem ChatAvatar *getNewChatAvatar() const; - void setAttributes(unsigned long attributes); + void setAttributes(uint32_t attributes); void setLoginPriority(int loginPriority); void setEmail(const Plat_Unicode::String email); void setInboxLimit(unsigned inboxLimit); @@ -63,8 +63,8 @@ namespace ChatSystem Plat_Unicode::String m_email; Plat_Unicode::String m_statusMessage; - unsigned long m_attributes; - unsigned long m_inboxLimit; + uint32_t m_attributes; + uint32_t m_inboxLimit; int m_loginPriority; unsigned m_userID; diff --git a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.cpp b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.cpp index ad0894994..ba8e8efb5 100755 --- a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.cpp +++ b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.cpp @@ -1471,7 +1471,7 @@ namespace ChatSystem get(iter, m_type); get(iter, m_track); get(iter, m_result); - get(iter, (uint32 &)m_serverVersion); + get(iter, m_serverVersion); } ResAddSnoopAvatar::ResAddSnoopAvatar(void *user, unsigned srcAvatarID, const ChatUnicodeString &destName, const ChatUnicodeString &destAddress) diff --git a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.h b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.h index b12077468..edd3edba1 100755 --- a/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.h +++ b/external/3rd/library/soePlatform/ChatAPI/projects/ChatAPI/Response.h @@ -1186,9 +1186,9 @@ namespace ChatSystem virtual void unpack(Base::ByteStream::ReadIterator &iter); - unsigned long getServerVersion() const { return m_serverVersion; } + uint32_t getServerVersion() const { return m_serverVersion; } private: - unsigned long m_serverVersion; + uint32_t m_serverVersion; }; class ResAddSnoopAvatar : public GenericAPI::GenericResponse diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/Base/Archive.h b/external/3rd/library/soePlatform/ChatAPI/utils/Base/Archive.h index 8e13f2c01..95c0c6f4c 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/Base/Archive.h +++ b/external/3rd/library/soePlatform/ChatAPI/utils/Base/Archive.h @@ -664,8 +664,9 @@ const unsigned MAX_ARRAY_SIZE = 1024; Base::get(source, arraySize); ValueType v; - if (arraySize > MAX_ARRAY_SIZE) + if (arraySize > MAX_ARRAY_SIZE) { arraySize = 0; + } for(unsigned int i = 0; i < arraySize; ++i) { diff --git a/external/3rd/library/soePlatform/ChatAPI/utils/UdpLibrary/UdpDriverLinux.cpp b/external/3rd/library/soePlatform/ChatAPI/utils/UdpLibrary/UdpDriverLinux.cpp index aa11f5cdc..9ca240140 100755 --- a/external/3rd/library/soePlatform/ChatAPI/utils/UdpLibrary/UdpDriverLinux.cpp +++ b/external/3rd/library/soePlatform/ChatAPI/utils/UdpLibrary/UdpDriverLinux.cpp @@ -1,6 +1,12 @@ // Copyright 2004 Sony Online Entertainment, all rights reserved. // Author: Jeff Petersen +#ifdef NDEBUG +#define SWG_ASSERT(exp) ((void) (exp)) +#else +#define SWG_ASSERT assert +#endif + #include "UdpDriver.h" #include "UdpHelper.h" @@ -17,7 +23,6 @@ #include // needed by gcc 3.1 for linux #include - namespace UdpLibrary { @@ -80,19 +85,19 @@ bool UdpPlatformDriver::SocketOpen(int port, int incomingBufferSize, int outgoin // open socket stuff unsigned long nb = 1; int err = ioctl(mData->socket, FIONBIO, &nb); - assert(err != -1); + SWG_ASSERT(err != -1); nb = outgoingBufferSize; err = setsockopt(mData->socket, SOL_SOCKET, SO_SNDBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = incomingBufferSize; err = setsockopt(mData->socket, SOL_SOCKET, SO_RCVBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = 0; err = setsockopt(mData->socket, SOL_SOCKET, SO_BSDCOMPAT, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = 1; err = setsockopt(mData->socket, SOL_IP, IP_RECVERR, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); int optLen = sizeof(mData->startTtl); getsockopt(mData->socket, IPPROTO_IP, IP_TTL, &mData->startTtl, (socklen_t *)&optLen); diff --git a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/serializeClasses.h b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/serializeClasses.h index 8e6e37401..7db29d5dd 100755 --- a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/serializeClasses.h +++ b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/Base/serializeClasses.h @@ -389,57 +389,45 @@ namespace soe { if (size < sizeof(int64)) return 0; -#if (defined(WIN32) || defined(linux)) - uint32 low = *(uint32_t *) &data; - uint32 high = *((uint32_t *)&data+1); -#elif defined(sparc) - uint32 low = *((uint32 *)&data+1); - uint32 high = *(uint32 *)(&data); -#endif - stream[BYTE1] = (unsigned char)low&0xff; - stream[BYTE2] = (unsigned char)(low>>8)&0xff; - stream[BYTE3] = (unsigned char)(low>>16)&0xff; - stream[BYTE4] = (unsigned char)(low>>24)&0xff; - stream[BYTE5] = (unsigned char)high&0xff; - stream[BYTE6] = (unsigned char)(high>>8)&0xff; - stream[BYTE7] = (unsigned char)(high>>16)&0xff; - stream[BYTE8] = (unsigned char)(high>>24)&0xff; + stream[BYTE1] = data&0xff; + stream[BYTE2] = (data>>8)&0xff; + stream[BYTE3] = (data>>16)&0xff; + stream[BYTE4] = (data>>24)&0xff; + stream[BYTE5] = (data>>32)&0xff; + stream[BYTE6] = (data>>40)&0xff; + stream[BYTE7] = (data>>48)&0xff; + stream[BYTE8] = (data>>56)&0xff; return sizeof(int64); } // 370 ns inline unsigned Write(unsigned char * stream, unsigned size, uint64 data, unsigned version = 0) { - if (size < sizeof(uint64)) + if (size < sizeof(int64)) return 0; -#if (defined(WIN32) || defined(linux)) - uint32 low = *(uint32_t *) &data; - uint32 high = *((uint32_t *)&data+1); -#elif defined(sparc) - uint32 low = *((uint32 *)&data+1); - uint32 high = *(uint32 *)(&data); -#endif - stream[BYTE1] = (unsigned char)low&0xff; - stream[BYTE2] = (unsigned char)(low>>8)&0xff; - stream[BYTE3] = (unsigned char)(low>>16)&0xff; - stream[BYTE4] = (unsigned char)(low>>24)&0xff; - stream[BYTE5] = (unsigned char)high&0xff; - stream[BYTE6] = (unsigned char)(high>>8)&0xff; - stream[BYTE7] = (unsigned char)(high>>16)&0xff; - stream[BYTE8] = (unsigned char)(high>>24)&0xff; - return sizeof(uint64); + stream[BYTE1] = data&0xff; + stream[BYTE2] = (data>>8)&0xff; + stream[BYTE3] = (data>>16)&0xff; + stream[BYTE4] = (data>>24)&0xff; + stream[BYTE5] = (data>>32)&0xff; + stream[BYTE6] = (data>>40)&0xff; + stream[BYTE7] = (data>>48)&0xff; + stream[BYTE8] = (data>>56)&0xff; + return sizeof(int64); } // 360 ns inline unsigned Write(unsigned char * stream, unsigned size, float data, unsigned version = 0) { - uint32 & dataRef = *(uint32_t *)(&data); if (size < sizeof(float)) return 0; - stream[BYTE1] = dataRef&0xff; - stream[BYTE2] = (dataRef>>8)&0xff; - stream[BYTE3] = (dataRef>>16)&0xff; - stream[BYTE4] = (dataRef>>24)&0xff; + unsigned char dataArr[sizeof(float)]; + memcpy(&dataArr, &data, sizeof(float)); + + stream[BYTE1] = dataArr[0]&0xff; + stream[BYTE2] = dataArr[1]&0xff; + stream[BYTE3] = dataArr[2]&0xff; + stream[BYTE4] = dataArr[3]&0xff; return sizeof(float); } @@ -448,21 +436,17 @@ namespace soe { if (size < sizeof(double)) return 0; -#if (defined(WIN32) || defined(linux)) - uint32 low = *(uint32_t *)(&data); - uint32 high = *((uint32_t *)&data+1); -#elif defined(sparc) - uint32 low = *((uint32 *)&data+1); - uint32 high = *(uint32 *)(&data); -#endif - stream[BYTE1] = (unsigned char)low&0xff; - stream[BYTE2] = (unsigned char)(low>>8)&0xff; - stream[BYTE3] = (unsigned char)(low>>16)&0xff; - stream[BYTE4] = (unsigned char)(low>>24)&0xff; - stream[BYTE5] = (unsigned char)high&0xff; - stream[BYTE6] = (unsigned char)(high>>8)&0xff; - stream[BYTE7] = (unsigned char)(high>>16)&0xff; - stream[BYTE8] = (unsigned char)(high>>24)&0xff; + unsigned char dataArr[sizeof(double)]; + memcpy(&dataArr, &data, sizeof(double)); + + stream[BYTE1] = dataArr[0]&0xff; + stream[BYTE2] = dataArr[1]&0xff; + stream[BYTE3] = dataArr[2]&0xff; + stream[BYTE4] = dataArr[3]&0xff; + stream[BYTE5] = dataArr[4]&0xff; + stream[BYTE6] = dataArr[5]&0xff; + stream[BYTE7] = dataArr[6]&0xff; + stream[BYTE8] = dataArr[7]&0xff; return sizeof(double); } diff --git a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/UdpLibrary/UdpLibrary.cpp b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/UdpLibrary/UdpLibrary.cpp index f86f5d7bb..c7ca918d5 100755 --- a/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/UdpLibrary/UdpLibrary.cpp +++ b/external/3rd/library/soePlatform/VChatAPI/utils2.0/utils/UdpLibrary/UdpLibrary.cpp @@ -1,3 +1,9 @@ +#ifdef NDEBUG +#define SWG_ASSERT(exp) ((void) (exp)) +#else +#define SWG_ASSERT assert +#endif + #include #include #include @@ -443,36 +449,36 @@ void UdpManager::CreateAndBindSocket(int usePort) #elif defined(sparc) ulong nb = 1; int err = ioctl(mUdpSocket, FIONBIO, &nb); - assert(err != -1); + SWG_ASSERT(err != -1); nb = udpMin(256 * 1024, mParams.outgoingBufferSize); err = setsockopt(mUdpSocket, SOL_SOCKET, SO_SNDBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = udpMin(256 * 1024, mParams.incomingBufferSize); err = setsockopt(mUdpSocket, SOL_SOCKET, SO_RCVBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); int optLen = sizeof(mStartTtl); getsockopt(mUdpSocket, IPPROTO_IP, IP_TTL, &mStartTtl, (socklen_t *)&optLen); nb = 1; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_DGRAM_ERRIND, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); #else // linux is to remain the default compile mode unsigned long nb = 1; int err = ioctl(mUdpSocket, FIONBIO, &nb); - assert(err != -1); + SWG_ASSERT(err != -1); nb = mParams.outgoingBufferSize; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_SNDBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = mParams.incomingBufferSize; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_RCVBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = 0; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_BSDCOMPAT, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = 1; err = setsockopt(mUdpSocket, SOL_IP, IP_RECVERR, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); int optLen = sizeof(mStartTtl); getsockopt(mUdpSocket, IPPROTO_IP, IP_TTL, &mStartTtl, (socklen_t *)&optLen); diff --git a/external/3rd/library/udplibrary/UdpLibrary.cpp b/external/3rd/library/udplibrary/UdpLibrary.cpp index 7862e4864..7d91ea6c2 100755 --- a/external/3rd/library/udplibrary/UdpLibrary.cpp +++ b/external/3rd/library/udplibrary/UdpLibrary.cpp @@ -1,3 +1,9 @@ +#ifdef NDEBUG +#define SWG_ASSERT(exp) ((void) (exp)) +#else +#define SWG_ASSERT assert +#endif + #include #include #include @@ -438,36 +444,36 @@ void UdpManager::CreateAndBindSocket(int usePort) #elif defined(sparc) ulong nb = 1; int err = ioctl(mUdpSocket, FIONBIO, &nb); - assert(err != -1); + SWG_ASSERT(err != -1); nb = udpMin(256 * 1024, mParams.outgoingBufferSize); err = setsockopt(mUdpSocket, SOL_SOCKET, SO_SNDBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = udpMin(256 * 1024, mParams.incomingBufferSize); err = setsockopt(mUdpSocket, SOL_SOCKET, SO_RCVBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); int optLen = sizeof(mStartTtl); getsockopt(mUdpSocket, IPPROTO_IP, IP_TTL, &mStartTtl, (socklen_t *)&optLen); nb = 1; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_DGRAM_ERRIND, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); #else // linux is to remain the default compile mode unsigned long nb = 1; int err = ioctl(mUdpSocket, FIONBIO, &nb); - assert(err != -1); + SWG_ASSERT(err != -1); nb = mParams.outgoingBufferSize; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_SNDBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = mParams.incomingBufferSize; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_RCVBUF, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = 0; err = setsockopt(mUdpSocket, SOL_SOCKET, SO_BSDCOMPAT, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); nb = 1; err = setsockopt(mUdpSocket, SOL_IP, IP_RECVERR, &nb, sizeof(nb)); - assert(err == 0); + SWG_ASSERT(err == 0); int optLen = sizeof(mStartTtl); getsockopt(mUdpSocket, IPPROTO_IP, IP_TTL, &mStartTtl, (socklen_t *)&optLen); @@ -560,7 +566,8 @@ void UdpManager::RemoveConnection(UdpConnection *con) mAddressHashTable->Remove(con, AddressHashValue(con->mIp, con->mPort)); - unsigned int addy = con->mIp.GetAddress(); + // addy is unused + // unsigned int addy = con->mIp.GetAddress(); mConnectCodeHashTable->Remove(con, con->mConnectCode); } diff --git a/external/ours/library/archive/src/shared/AutoDeltaByteStream.h b/external/ours/library/archive/src/shared/AutoDeltaByteStream.h index 64519aa06..ab6f9ed5d 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaByteStream.h +++ b/external/ours/library/archive/src/shared/AutoDeltaByteStream.h @@ -726,7 +726,7 @@ class AutoDeltaContainer : public AutoDeltaVariableBase /** pure virtual */ virtual ~AutoDeltaContainer() = 0; /** pure virtual */ - virtual const int32_t size() const = 0; + virtual const uint32_t size() const = 0; }; //----------------------------------------------------------------------- diff --git a/external/ours/library/archive/src/shared/AutoDeltaMap.h b/external/ours/library/archive/src/shared/AutoDeltaMap.h index ca223a0f8..d1fc90187 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaMap.h +++ b/external/ours/library/archive/src/shared/AutoDeltaMap.h @@ -65,7 +65,7 @@ class AutoDeltaMap : public AutoDeltaContainer void pack(ByteStream & target) const; void packDelta(ByteStream & target) const; void set(const KeyType & key, const ValueType & value); - const int32_t size() const; + const uint32_t size() const; void unpack(ReadIterator & source); void unpackDelta(ReadIterator & source); static void pack(ByteStream & target, const std::vector & data); @@ -435,7 +435,7 @@ inline void AutoDeltaMap::packDelta(ByteStream & @return the number of elements in the map */ template -inline const int32_t AutoDeltaMap::size() const +inline const uint32_t AutoDeltaMap::size() const { return container.size(); } diff --git a/external/ours/library/archive/src/shared/AutoDeltaQueue.h b/external/ours/library/archive/src/shared/AutoDeltaQueue.h index d0305e8ca..ad17937ef 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaQueue.h +++ b/external/ours/library/archive/src/shared/AutoDeltaQueue.h @@ -46,7 +46,7 @@ class AutoDeltaQueue: public AutoDeltaContainer const bool isDirty() const; void pack(ByteStream &target) const; void packDelta(ByteStream &target) const; - const int32_t size() const; + const uint32_t size() const; void unpack(ReadIterator &source); void unpackDelta(ReadIterator &source); @@ -293,7 +293,7 @@ inline void AutoDeltaQueue::packDelta(ByteStream &target) const //----------------------------------------------------------------------- template -inline const int32_t AutoDeltaQueue::size() const +inline const uint32_t AutoDeltaQueue::size() const { return container.size(); } diff --git a/external/ours/library/archive/src/shared/AutoDeltaSet.h b/external/ours/library/archive/src/shared/AutoDeltaSet.h index 14cf1e2df..67382f163 100644 --- a/external/ours/library/archive/src/shared/AutoDeltaSet.h +++ b/external/ours/library/archive/src/shared/AutoDeltaSet.h @@ -57,7 +57,7 @@ class AutoDeltaSet: public AutoDeltaContainer void packDelta(ByteStream &target) const; SetType const & get() const; - const int32_t size() const; + const uint32_t size() const; bool empty() const; bool contains(ValueType const &t) const; const_iterator find(ValueType const &t) const; @@ -402,7 +402,7 @@ inline bool AutoDeltaSet::empty() const //----------------------------------------------------------------------- template -inline const int32_t AutoDeltaSet::size() const +inline const uint32_t AutoDeltaSet::size() const { return m_set.size(); } @@ -486,7 +486,7 @@ inline void AutoDeltaSet::unpackDelta(ReadIterator &sourc { using Archive::get; Command c; - int32_t skipCount, commandCount, targetBaselineCommandCount; + uint32_t skipCount, commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); @@ -503,7 +503,7 @@ inline void AutoDeltaSet::unpackDelta(ReadIterator &sourc if (skipCount > commandCount) skipCount = commandCount; - int32_t i = 0; + uint32_t i = 0; for ( ; i < skipCount; ++i) { Archive::get(source, c.cmd); diff --git a/external/ours/library/archive/src/shared/AutoDeltaVector.h b/external/ours/library/archive/src/shared/AutoDeltaVector.h index e7979a41c..d0115f30d 100755 --- a/external/ours/library/archive/src/shared/AutoDeltaVector.h +++ b/external/ours/library/archive/src/shared/AutoDeltaVector.h @@ -39,7 +39,7 @@ class AutoDeltaVector : public AutoDeltaContainer public: AutoDeltaVector(); - explicit AutoDeltaVector(int32_t initialSize); + explicit AutoDeltaVector(uint32_t initialSize); ~AutoDeltaVector(); const ValueType & back () const; @@ -74,7 +74,7 @@ class AutoDeltaVector : public AutoDeltaContainer void setOnInsert (ObjectType * owner, void (ObjectType::*onInsert)(const unsigned int, const ValueType &)); void setOnSet (ObjectType * owner, void (ObjectType::*onSet)(const unsigned int, const ValueType &, const ValueType &)); - const int32_t size () const; + const uint32_t size () const; bool empty () const; const ValueType & operator[] (const unsigned int element) const; @@ -91,7 +91,7 @@ class AutoDeltaVector : public AutoDeltaContainer private: std::vector v; - int32_t baselineCommandCount; + uint32_t baselineCommandCount; mutable std::vector commands; std::pair * onChangedCallback; std::pair * onEraseCallback; @@ -120,7 +120,7 @@ onSetCallback(0) //----------------------------------------------------------------------- template -inline AutoDeltaVector::AutoDeltaVector(int32_t initialSize) : +inline AutoDeltaVector::AutoDeltaVector(uint32_t initialSize) : AutoDeltaContainer(), v(initialSize), baselineCommandCount(0), @@ -366,7 +366,7 @@ inline void AutoDeltaVector::onSet(const unsigned int ele template inline void AutoDeltaVector::pack(ByteStream & target) const { - Archive::put(target, static_cast (v.size())); + Archive::put(target, static_cast (v.size())); Archive::put(target, baselineCommandCount); typename std::vector::const_iterator i; for (i = v.begin(); i != v.end(); ++i) @@ -380,8 +380,8 @@ inline void AutoDeltaVector::pack(ByteStream & target) co template inline void AutoDeltaVector::pack(ByteStream & target, const std::vector & data) { - Archive::put(target, static_cast(data.size())); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(data.size())); + Archive::put(target, static_cast(0)); // baselineCommandCount typename std::vector::const_iterator i; for (i = data.begin(); i != data.end(); ++i) { @@ -394,7 +394,7 @@ inline void AutoDeltaVector::pack(ByteStream & target, co template inline void AutoDeltaVector::packDelta(ByteStream & target) const { - Archive::put(target, static_cast(commands.size())); + Archive::put(target, static_cast(commands.size())); Archive::put(target, baselineCommandCount); typename std::vector::iterator i; @@ -483,13 +483,13 @@ inline void AutoDeltaVector::resize(size_type n, ValueTyp { // expand the vector v.resize(n); - for (int32_t i = size; i < n; ++i) + for (uint32_t i = size; i < n; ++i) set(i, x); } else if (size > n) { // contract the vector - for (int32_t i = size - 1; i >= n; --i) + for (uint32_t i = size - 1; i >= n; --i) { erase(i); @@ -607,7 +607,7 @@ inline bool AutoDeltaVector::empty() const //----------------------------------------------------------------------- template -inline const int32_t AutoDeltaVector::size() const +inline const uint32_t AutoDeltaVector::size() const { return v.size(); } @@ -622,13 +622,13 @@ inline void AutoDeltaVector::unpack(ReadIterator & source v.clear(); clearDelta(); - int32_t commandCount; + uint32_t commandCount; ValueType value; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); - for (int32_t i = 0; i < commandCount; ++i) + for (uint32_t i = 0; i < commandCount; ++i) { get(source, value); v.push_back(value); @@ -644,14 +644,14 @@ inline void AutoDeltaVector::unpack(ReadIterator & source { using Archive::get; // unpacking the whole kazaba - int32_t commandCount; - int32_t bcc; + uint32_t commandCount; + uint32_t bcc; Command c; Archive::get(source, commandCount); Archive::get(source, bcc); - for (int32_t i = 0; i < commandCount; ++i) + for (uint32_t i = 0; i < commandCount; ++i) { get(source,c.value); c.index = static_cast(i); @@ -668,12 +668,12 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s { using Archive::get; Command c; - int32_t commandCount, targetBaselineCommandCount; + uint32_t commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); - for (int32_t i=0 ; i < commandCount; ++i) + for (uint32_t i=0 ; i < commandCount; ++i) { Archive::get(source, c.cmd); switch (c.cmd) @@ -708,7 +708,7 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s { using Archive::get; Command c; - int32_t skipCount, commandCount, targetBaselineCommandCount; + uint32_t skipCount, commandCount, targetBaselineCommandCount; Archive::get(source, commandCount); Archive::get(source, targetBaselineCommandCount); @@ -719,7 +719,7 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s if (skipCount > commandCount) skipCount = commandCount; - int32_t i; + uint32_t i; for (i = 0; i < skipCount; ++i) { Archive::get(source, c.cmd); @@ -727,7 +727,7 @@ inline void AutoDeltaVector::unpackDelta(ReadIterator & s Archive::get(source, c.index); if (c.cmd == Command::SETALL) { - for (unsigned int j = 0; j < c.index; ++j) + for (uint32_t j = 0; j < c.index; ++j) { ++i; get(source, c.value); From 16bf8e1c71ca5dbfca670734a716ce0ca44ea8fc Mon Sep 17 00:00:00 2001 From: Cekis Date: Thu, 27 Jan 2022 00:10:48 -0800 Subject: [PATCH 32/46] Updated method as userData is actually a 32 bit integer --- .../application/LoginServer/src/shared/SessionApiClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp b/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp index b9dc88ea7..5be50c0d7 100755 --- a/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp +++ b/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp @@ -120,7 +120,7 @@ void SessionApiClient::OnSessionValidate(const apiTrackingNumber trackingNumber, else { // attempt to validate a CS Tool associated with this request. - CSToolConnection::validateCSTool( ( uint64 )userData, result, session ); + CSToolConnection::validateCSTool( ( uint32 ) userData, result, session ); } } From 1f36461dc5caf691b48a7622a6883261333a11b2 Mon Sep 17 00:00:00 2001 From: Cekis Date: Tue, 1 Feb 2022 23:08:16 -0500 Subject: [PATCH 33/46] Fixed issues found in my own review. --- .../src/shared/command/CommandCppFuncs.cpp | 2 +- .../serverGame/src/shared/core/GameServer.cpp | 1 - .../serverGame/src/shared/core/GameServer.h | 2 +- .../src/shared/object/PlayerObject.cpp | 24 +++++++++---------- .../src/shared/object/PlayerObject.h | 4 ++-- .../GameConnectionServerMessages.cpp | 2 +- .../GameConnectionServerMessages.h | 8 +++---- .../src/shared/ServerConnection.cpp | 2 +- .../src/shared/ServerConnection.h | 16 ++++++------- .../src/shared/SystemAssignedProcessId.cpp | 4 ++-- .../src/shared/SystemAssignedProcessId.h | 4 ++-- .../library/sharedFile/src/shared/Iff.cpp | 2 +- .../src/shared/CrcStringTable.cpp | 18 -------------- .../sharedFoundation/src/shared/Misc.h | 2 +- .../src/shared/core/TextManager.cpp | 4 ++-- .../src/shared/PathSearch.cpp | 2 +- .../src/shared/LocalizedStringTable.h | 2 +- .../src/shared/StringIdArchive.cpp | 2 +- .../cleanup/TaskObjectTemplateListUpdater.cpp | 2 +- 19 files changed, 42 insertions(+), 61 deletions(-) diff --git a/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp b/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp index 333d1a2a4..d3297c87d 100755 --- a/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp +++ b/engine/server/library/serverGame/src/shared/command/CommandCppFuncs.cpp @@ -1804,7 +1804,7 @@ static void commandFuncSpatialChatInternal(Command const &, NetworkId const &act const int32_t chatSpamTimeEndInterval = playerObject->getChatSpamTimeEndInterval(); if ((chatSpamTimeEndInterval > timeNow) && (timeNow >= playerObject->getChatSpamNextTimeToNotifyPlayerWhenLimited())) { - GenericValueTypeMessage csl("ChatSpamLimited", (chatSpamTimeEndInterval - timeNow)); + GenericValueTypeMessage csl("ChatSpamLimited", (chatSpamTimeEndInterval - timeNow)); obj->getClient()->send(csl, true); playerObject->setChatSpamNextTimeToNotifyPlayerWhenLimited((timeNow + ConfigServerGame::getChatSpamNotifyPlayerWhenLimitedIntervalSeconds())); diff --git a/engine/server/library/serverGame/src/shared/core/GameServer.cpp b/engine/server/library/serverGame/src/shared/core/GameServer.cpp index e1e7b75a0..456a20d5c 100755 --- a/engine/server/library/serverGame/src/shared/core/GameServer.cpp +++ b/engine/server/library/serverGame/src/shared/core/GameServer.cpp @@ -233,7 +233,6 @@ #include "sharedFoundation/CrcConstexpr.hpp" #include -#include //----------------------------------------------------------------------- diff --git a/engine/server/library/serverGame/src/shared/core/GameServer.h b/engine/server/library/serverGame/src/shared/core/GameServer.h index 0e229b3b6..85755bd40 100755 --- a/engine/server/library/serverGame/src/shared/core/GameServer.h +++ b/engine/server/library/serverGame/src/shared/core/GameServer.h @@ -230,7 +230,7 @@ public MessageDispatch::Receiver bool m_gameServerReadyObjectIds; bool m_gameServerReadyDatabaseConnected; bool m_gameServerReadyPlanetConnected; - uint64_t m_connectionTimeout; + uint32_t m_connectionTimeout; ChatServerConnection * m_chatServerConnection; }; diff --git a/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp b/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp index 8a098bf00..f429e552d 100755 --- a/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/PlayerObject.cpp @@ -6115,7 +6115,7 @@ void PlayerObject::getByteStreamFromAutoVariable(const std::string & name, Archi { if(name == "quests") { - Archive::AutoDeltaMap(m_quests).pack(target); + Archive::AutoDeltaMap(m_quests).pack(target); } else if(name == "completedQuests") { @@ -6202,11 +6202,11 @@ void PlayerObject::setAutoVariableFromByteStream(const std::string & name, const Archive::ReadIterator ri(source); if(name == "quests") { - typedef Archive::AutoDeltaMap::Command Commands; + typedef Archive::AutoDeltaMap::Command Commands; std::vector quests; m_quests.clear(); - Archive::AutoDeltaMap(m_quests).unpack(ri, quests); + Archive::AutoDeltaMap(m_quests).unpack(ri, quests); for (std::vector::const_iterator questIter = quests.begin(); questIter != quests.end(); ++questIter) { @@ -6337,14 +6337,14 @@ void PlayerObject::setPlayedTimeAccumOnly(float playedTimeAccum) // ---------------------------------------------------------------------- -uint32_t PlayerObject::getSessionPlayTimeDuration() const +int32_t PlayerObject::getSessionPlayTimeDuration() const { - uint32_t const sessionStartPlayTime = static_cast(m_sessionStartPlayTime.get()); + int32_t const sessionStartPlayTime = m_sessionStartPlayTime.get(); if (sessionStartPlayTime > 0) { - uint32_t const now = ::time(nullptr); + int32_t const now = ::time(nullptr); if (now > sessionStartPlayTime) - return static_cast(now - sessionStartPlayTime); + return (now - sessionStartPlayTime); } return 0; @@ -6352,16 +6352,16 @@ uint32_t PlayerObject::getSessionPlayTimeDuration() const // ---------------------------------------------------------------------- -uint32_t PlayerObject::getSessionActivePlayTimeDuration() const +int32_t PlayerObject::getSessionActivePlayTimeDuration() const { - uint32_t activePlayTimeDuration = m_sessionActivePlayTimeDuration.get(); + int32_t activePlayTimeDuration = m_sessionActivePlayTimeDuration.get(); - uint32_t const sessionLastActiveTime = static_cast(m_sessionLastActiveTime.get()); + int32_t const sessionLastActiveTime = m_sessionLastActiveTime.get(); if (sessionLastActiveTime > 0) { - uint32_t const now = ::time(nullptr); + int32_t const now = ::time(nullptr); if (now > sessionLastActiveTime) - activePlayTimeDuration += static_cast(now - sessionLastActiveTime); + activePlayTimeDuration += (now - sessionLastActiveTime); } return activePlayTimeDuration; diff --git a/engine/server/library/serverGame/src/shared/object/PlayerObject.h b/engine/server/library/serverGame/src/shared/object/PlayerObject.h index 0d669f939..598cdc3bc 100755 --- a/engine/server/library/serverGame/src/shared/object/PlayerObject.h +++ b/engine/server/library/serverGame/src/shared/object/PlayerObject.h @@ -105,8 +105,8 @@ class PlayerObject : public IntangibleObject float getPlayedTimeAccumOnly() const; void setPlayedTimeAccumOnly(float playedTimeAccum); - uint32_t getSessionPlayTimeDuration() const; - uint32_t getSessionActivePlayTimeDuration() const; + int32_t getSessionPlayTimeDuration() const; + int32_t getSessionActivePlayTimeDuration() const; int32 getSessionStartPlayTime() const; int32 getSessionLastActiveTime() const; void setSessionPlayTimeInfo(int32 sessionStartPlayTime, int32 sessionLastActiveTime, uint32_t sessionActivePlayTimeDuration); diff --git a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp index 40b0e0c1a..8f9ebede8 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp +++ b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.cpp @@ -86,7 +86,7 @@ TransferControlMessage::~TransferControlMessage() //----------------------------------------------------------------------- ControlAssumed::ControlAssumed(NetworkId oid, const std::string & newSceneName, const bool skipLoadScreen, const Vector &startPos, const float startYaw, const std::string & templateName, - const int32_t t) : + const int64_t t) : GameNetworkMessage("ControlAssumed"), m_oid(oid), m_sceneName(newSceneName), diff --git a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h index a80edad45..9eddc3130 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h +++ b/engine/server/library/serverNetworkMessages/src/shared/gameConnectionServer/GameConnectionServerMessages.h @@ -118,7 +118,7 @@ class ControlAssumed : public GameNetworkMessage public: explicit ControlAssumed(NetworkId oid, const std::string & newSceneName, const bool skipLoadScreen, const Vector &startPos, const float startYaw, const std::string & templateName, - const int32_t timeSeconds); + const int64_t timeSeconds); ControlAssumed(Archive::ReadIterator & source); virtual ~ControlAssumed(); @@ -128,7 +128,7 @@ class ControlAssumed : public GameNetworkMessage const Vector & getStartPosition () const; const float getStartYaw () const; const std::string & getTemplateName () const; - const int32_t getTimeSeconds () const; + const int64_t getTimeSeconds () const; private: Archive::AutoVariable m_oid; @@ -137,7 +137,7 @@ class ControlAssumed : public GameNetworkMessage Archive::AutoVariable m_startPosition; Archive::AutoVariable m_startYaw; Archive::AutoVariable m_templateName; - Archive::AutoVariable m_timeSeconds; + Archive::AutoVariable m_timeSeconds; ControlAssumed(); @@ -188,7 +188,7 @@ inline const std::string & ControlAssumed::getTemplateName() const //----------------------------------------------------------------------- -inline const int32_t ControlAssumed::getTimeSeconds() const +inline const int64_t ControlAssumed::getTimeSeconds() const { return m_timeSeconds.get(); } diff --git a/engine/server/library/serverUtility/src/shared/ServerConnection.cpp b/engine/server/library/serverUtility/src/shared/ServerConnection.cpp index 2ea7eeb06..8b3f3fd76 100755 --- a/engine/server/library/serverUtility/src/shared/ServerConnection.cpp +++ b/engine/server/library/serverUtility/src/shared/ServerConnection.cpp @@ -290,7 +290,7 @@ void ServerConnection::onConnectionStalled(const unsigned long stallTimeMs) // ---------------------------------------------------------------------- -void ServerConnection::setProcessId(const uint32 newProcessId) +void ServerConnection::setProcessId(const uint32_t newProcessId) { processId = newProcessId; } diff --git a/engine/server/library/serverUtility/src/shared/ServerConnection.h b/engine/server/library/serverUtility/src/shared/ServerConnection.h index e53b23d6b..adc14b1d3 100755 --- a/engine/server/library/serverUtility/src/shared/ServerConnection.h +++ b/engine/server/library/serverUtility/src/shared/ServerConnection.h @@ -31,8 +31,8 @@ class ServerConnection: public Connection, public MessageDispatch::Emitter static const unsigned long makeProcessId (); static bool isMessageForwardable (unsigned long int type); - const unsigned long getProcessId () const; - const unsigned long getOsProcessId () const; + const uint32_t getProcessId () const; + const uint32_t getOsProcessId () const; virtual void onConnectionClosed (); virtual void onConnectionOpened (); virtual void onConnectionOverflowing (const unsigned int bytesPending); @@ -40,8 +40,8 @@ class ServerConnection: public Connection, public MessageDispatch::Emitter virtual void onReceive (const Archive::ByteStream & message); virtual void reportReceive (const Archive::ByteStream & bs); virtual void reportSend (const Archive::ByteStream & bs); - virtual void send (const GameNetworkMessage & message, const bool reliable); - virtual void setProcessId (const uint32 newProcessId); + virtual void send (const GameNetworkMessage & message, const bool reliable); + virtual void setProcessId (const uint32_t newProcessId); public: class MessageConnectionCallback: public MessageDispatch::MessageBase @@ -67,20 +67,20 @@ class ServerConnection: public Connection, public MessageDispatch::Emitter ServerConnection &operator=(const ServerConnection&); //disable private: - unsigned long processId; - unsigned long osProcessId; // remote's operating system assigned PID + uint32_t processId; + uint32_t osProcessId; // remote's operating system assigned PID }; //----------------------------------------------------------------------- -inline const unsigned long ServerConnection::getProcessId(void) const +inline const uint32_t ServerConnection::getProcessId(void) const { return processId; } //----------------------------------------------------------------------- -inline const unsigned long ServerConnection::getOsProcessId() const +inline const uint32_t ServerConnection::getOsProcessId() const { return osProcessId; } diff --git a/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.cpp b/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.cpp index 3ad1949b8..c22ce195f 100755 --- a/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.cpp +++ b/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.cpp @@ -9,7 +9,7 @@ //----------------------------------------------------------------------- -SystemAssignedProcessId::SystemAssignedProcessId(const unsigned long id) : +SystemAssignedProcessId::SystemAssignedProcessId(const uint32_t id) : GameNetworkMessage("SystemAssignedProcessId"), m_id(id) { @@ -34,7 +34,7 @@ SystemAssignedProcessId::~SystemAssignedProcessId() //----------------------------------------------------------------------- -const unsigned long SystemAssignedProcessId::getId() const +const uint32_t SystemAssignedProcessId::getId() const { return m_id.get(); } diff --git a/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h b/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h index 630471243..3d27bb257 100755 --- a/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h +++ b/engine/server/library/serverUtility/src/shared/SystemAssignedProcessId.h @@ -14,11 +14,11 @@ class SystemAssignedProcessId : public GameNetworkMessage { public: - explicit SystemAssignedProcessId(const unsigned long id); + explicit SystemAssignedProcessId(const uint32_t id); explicit SystemAssignedProcessId(Archive::ReadIterator & source); ~SystemAssignedProcessId(); - const unsigned long getId () const; + const uint32_t getId () const; private: SystemAssignedProcessId & operator = (const SystemAssignedProcessId & rhs); diff --git a/engine/shared/library/sharedFile/src/shared/Iff.cpp b/engine/shared/library/sharedFile/src/shared/Iff.cpp index 5eb06ec76..36e34d150 100755 --- a/engine/shared/library/sharedFile/src/shared/Iff.cpp +++ b/engine/shared/library/sharedFile/src/shared/Iff.cpp @@ -744,7 +744,7 @@ void Iff::insertForm(Tag name, bool shouldEnterForm) void Iff::insertChunk(Tag name, bool shouldEnterChunk) { - const int32 CHUNK_OVERHEAD = sizeof(Tag) + sizeof(uint32); + const int32_t CHUNK_OVERHEAD = sizeof(Tag) + sizeof(uint32); Tag t; int32 offset; diff --git a/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp b/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp index 6c962b3f0..ab00efba8 100755 --- a/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp +++ b/engine/shared/library/sharedFoundation/src/shared/CrcStringTable.cpp @@ -14,7 +14,6 @@ #include "sharedFoundation/ConstCharCrcString.h" #include -#include // ====================================================================== @@ -165,23 +164,6 @@ ConstCharCrcString const CrcStringTable::lookUp(uint32 crc) const high = mid - 1; } - low = 0; - high = m_numberOfEntries - 1; - - while (low <= high) - { - int const mid = (low + high) / 2; - uint32 const entry = m_crcTable[mid]; - - if (crc == entry) - return ConstCharCrcString(m_strings + m_stringsOffsetTable[mid], crc); - else - if (crc > entry) - low = mid + 1; - else - high = mid - 1; - } - return ConstCharCrcString("", 0); } diff --git a/engine/shared/library/sharedFoundation/src/shared/Misc.h b/engine/shared/library/sharedFoundation/src/shared/Misc.h index d0e70c941..d8a02adb5 100755 --- a/engine/shared/library/sharedFoundation/src/shared/Misc.h +++ b/engine/shared/library/sharedFoundation/src/shared/Misc.h @@ -230,7 +230,7 @@ inline void *memmove(void *destination, const void *source, int length) { DEBUG_FATAL(!destination, ("nullptr destination arg")); DEBUG_FATAL(!source, ("nullptr source arg")); - return memmove(destination, source, static_cast(length)); + return memmove(destination, source, length); } // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp b/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp index 599ee57c0..eb86ffced 100755 --- a/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp +++ b/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp @@ -120,7 +120,7 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) // Sub-string search time for words that are listed for sub-string searches Unicode::String lowerText(Unicode::toLower(text)); - size_t findStartPosition = 0; + uint32_t findStartPosition = 0; for (;;) { @@ -137,7 +137,7 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) continue; } - size_t index = lowerText.find(cussWord, findStartPosition); + uint32_t index = lowerText.find(cussWord, findStartPosition); if (index != Unicode::String::npos) { diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp index f708a3157..3713625ce 100755 --- a/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp +++ b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp @@ -193,7 +193,7 @@ PathSearchNode * PathSearchNode::createSearchNode( PathNode const * node ) PathSearchNode * searchNode = new PathSearchNode(m_search,m_graph,node); - node->setMark( 3, (int64)((void*)searchNode) ); + node->setMark( 3, (int64_t)((void*)searchNode) ); m_search->m_visitedNodes->push_back(node); diff --git a/external/ours/library/localization/src/shared/LocalizedStringTable.h b/external/ours/library/localization/src/shared/LocalizedStringTable.h index dfcc3d2b8..36ad1aabd 100755 --- a/external/ours/library/localization/src/shared/LocalizedStringTable.h +++ b/external/ours/library/localization/src/shared/LocalizedStringTable.h @@ -46,7 +46,7 @@ class LocalizedStringTable typedef std::map NameMap_t; // TODO: make this typedef platform dependent - typedef uint32_t magic_type; + typedef int32_t magic_type; static const magic_type ms_MAGIC; explicit LocalizedStringTable (const std::string & filename); diff --git a/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp b/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp index 028bbfdaf..889167c57 100755 --- a/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp +++ b/external/ours/library/localizationArchive/src/shared/StringIdArchive.cpp @@ -23,7 +23,7 @@ namespace Archive */ void get(ReadIterator & source, StringId & target) { - int32_t index = 0; + uint32_t index = 0; std::string table; std::string name; diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp index 54b181fe2..97c648f7b 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjectTemplateListUpdater.cpp @@ -32,7 +32,7 @@ bool TaskObjectTemplateListUpdater::process(DB::Session *session) int i_lines = 0; while(1) { - uint32 i_id; + int32 i_id; char s_name[4096]; int i_retval = 0; From 552af24d0a31db1e4b078a1d7f139da9375dde00 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 5 Feb 2022 15:51:47 -0500 Subject: [PATCH 34/46] Adjustments to issues when compiling in 64 bits --- .../LoginServer/src/shared/CSToolConnection.cpp | 8 ++++---- .../application/LoginServer/src/shared/CSToolConnection.h | 6 +++--- .../LoginServer/src/shared/SessionApiClient.cpp | 2 +- .../library/serverDatabase/src/shared/DatabaseProcess.cpp | 5 +++-- .../library/sharedGame/src/shared/core/TextManager.cpp | 8 ++++---- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/engine/server/application/LoginServer/src/shared/CSToolConnection.cpp b/engine/server/application/LoginServer/src/shared/CSToolConnection.cpp index 9163a15a0..6460a3300 100755 --- a/engine/server/application/LoginServer/src/shared/CSToolConnection.cpp +++ b/engine/server/application/LoginServer/src/shared/CSToolConnection.cpp @@ -21,20 +21,20 @@ namespace CSToolConnectionNamespace { - std::map< uint32, CSToolConnection * > toolsByID; + std::map< uintptr_t, CSToolConnection * > toolsByID; } uint32 CSToolConnection::m_curToolID = 0; // statics -CSToolConnection * CSToolConnection::getCSToolConnectionByToolId(uint32 id) +CSToolConnection * CSToolConnection::getCSToolConnectionByToolId(uintptr_t id) { - std::map< uint32, CSToolConnection * >::iterator it = CSToolConnectionNamespace::toolsByID.find(id); + std::map< uintptr_t, CSToolConnection * >::iterator it = CSToolConnectionNamespace::toolsByID.find(id); return it == CSToolConnectionNamespace::toolsByID.end() ? 0 : it->second; } -void CSToolConnection::validateCSTool(uint32 toolId, apiResult result, const apiSession& session) +void CSToolConnection::validateCSTool(uintptr_t toolId, apiResult result, const apiSession& session) { //find the tool CSToolConnection * p_connection = getCSToolConnectionByToolId(toolId); diff --git a/engine/server/application/LoginServer/src/shared/CSToolConnection.h b/engine/server/application/LoginServer/src/shared/CSToolConnection.h index 08651f09f..6690916d6 100755 --- a/engine/server/application/LoginServer/src/shared/CSToolConnection.h +++ b/engine/server/application/LoginServer/src/shared/CSToolConnection.h @@ -29,8 +29,8 @@ class CSToolConnection : public Connection virtual void onConnectionClosed(); void sendToClusters( const std::string & sCommand, const std::string &sCommandLine ); - static CSToolConnection * getCSToolConnectionByToolId( uint32 id ); - static void validateCSTool( uint32 toolId, apiResult result, const apiSession & session ); + static CSToolConnection * getCSToolConnectionByToolId( uintptr_t id ); + static void validateCSTool( uintptr_t toolId, apiResult result, const apiSession & session ); // cluster selection interface std::string selectCluster( const std::string & cluster ); @@ -47,7 +47,7 @@ class CSToolConnection : public Connection uint32 m_ui32PrivilegeLevel; std::string m_sInputBuffer; std::string m_sUserName; - uint32 m_toolID; + uintptr_t m_toolID; static uint32 m_curToolID; std::set< std::string > m_selectedClusters; diff --git a/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp b/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp index 5be50c0d7..6879a06d8 100755 --- a/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp +++ b/engine/server/application/LoginServer/src/shared/SessionApiClient.cpp @@ -120,7 +120,7 @@ void SessionApiClient::OnSessionValidate(const apiTrackingNumber trackingNumber, else { // attempt to validate a CS Tool associated with this request. - CSToolConnection::validateCSTool( ( uint32 ) userData, result, session ); + CSToolConnection::validateCSTool( ( uintptr_t ) userData, result, session ); } } diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp index 69aa99cdb..3972a6814 100755 --- a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp @@ -195,8 +195,9 @@ DatabaseProcess::~DatabaseProcess() void DatabaseProcess::run(void) { static bool shouldSleep = ConfigServerDatabase::getShouldSleep(); - // unused. - // bool idle=false; +#ifdef _DEBUG + bool idle = false; +#endif int loopcount=0; float nextQueryCountTime=0; diff --git a/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp b/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp index eb86ffced..3f522fcdd 100755 --- a/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp +++ b/engine/shared/library/sharedGame/src/shared/core/TextManager.cpp @@ -120,7 +120,7 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) // Sub-string search time for words that are listed for sub-string searches Unicode::String lowerText(Unicode::toLower(text)); - uint32_t findStartPosition = 0; + size_t findStartPosition = 0; for (;;) { @@ -137,7 +137,7 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) continue; } - uint32_t index = lowerText.find(cussWord, findStartPosition); + size_t index = lowerText.find(cussWord, findStartPosition); if (index != Unicode::String::npos) { @@ -145,10 +145,10 @@ void TextManagerNamespace::getAppropriateWord(Unicode::String &text) // Found a bad word, replace the word - unsigned int const letterCount = cussWord.size(); + size_t const letterCount = cussWord.size(); Unicode::String filterLetter; - for (unsigned int i = 0; i < letterCount; ++i) + for (size_t i = 0; i < letterCount; ++i) { getFilterLetter(filterLetter); From 487ddeee3120cd7db152dd8c9fcda715a464acd5 Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 7 Feb 2022 15:53:11 -0500 Subject: [PATCH 35/46] Backed out bad commit and added cleaner logging to mIFF. --- engine/client/application/Miff/src/linux/miff.cpp | 2 +- engine/client/application/Miff/src/linux/parser.lex | 6 ++++-- engine/shared/library/sharedFoundation/src/shared/Misc.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/engine/client/application/Miff/src/linux/miff.cpp b/engine/client/application/Miff/src/linux/miff.cpp index 6927490e8..454f3e329 100755 --- a/engine/client/application/Miff/src/linux/miff.cpp +++ b/engine/client/application/Miff/src/linux/miff.cpp @@ -275,7 +275,7 @@ static void callbackFunction(void) { if (!outfileHandler->writeBuffer()) { - fprintf(stderr, "MIFF: failed to write output file \"%s\"\n", local_outFileName); + fprintf(stderr, "FAILURE: failed to write output file \"%s\"\n", local_outFileName); local_errorFlag = ERR_WRITEERROR; } } diff --git a/engine/client/application/Miff/src/linux/parser.lex b/engine/client/application/Miff/src/linux/parser.lex index f80c2c9b2..44b9af408 100644 --- a/engine/client/application/Miff/src/linux/parser.lex +++ b/engine/client/application/Miff/src/linux/parser.lex @@ -326,8 +326,10 @@ EXP (e|E)(\+|-)? /* do a count on bracket matching... */ if (0 == count_brace()) { - if (!initialCompile && !globalErrorFlag) - MIFFMessage("mIFF successfully compiled!\n", 0); + if (!initialCompile && !globalErrorFlag) { + sprintf(myString, "mIFF (SUCCESS): compiled \"%s\"\n", inFileName); + MIFFMessage(myString, 0); + } } yyterminate(); /* tell yyparse() it's time to quit! DO NOT comment or delete this line! */ diff --git a/engine/shared/library/sharedFoundation/src/shared/Misc.h b/engine/shared/library/sharedFoundation/src/shared/Misc.h index d8a02adb5..d0e70c941 100755 --- a/engine/shared/library/sharedFoundation/src/shared/Misc.h +++ b/engine/shared/library/sharedFoundation/src/shared/Misc.h @@ -230,7 +230,7 @@ inline void *memmove(void *destination, const void *source, int length) { DEBUG_FATAL(!destination, ("nullptr destination arg")); DEBUG_FATAL(!source, ("nullptr source arg")); - return memmove(destination, source, length); + return memmove(destination, source, static_cast(length)); } // ---------------------------------------------------------------------- From 97e1954eb3adcf6144d4ec9ae2e18e0ed35946f0 Mon Sep 17 00:00:00 2001 From: Cekis Date: Mon, 7 Feb 2022 17:20:44 -0500 Subject: [PATCH 36/46] Removed extra line break on mIFF compiler --- engine/client/application/Miff/src/linux/parser.lex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/client/application/Miff/src/linux/parser.lex b/engine/client/application/Miff/src/linux/parser.lex index 44b9af408..2d5192c6b 100644 --- a/engine/client/application/Miff/src/linux/parser.lex +++ b/engine/client/application/Miff/src/linux/parser.lex @@ -327,7 +327,8 @@ EXP (e|E)(\+|-)? if (0 == count_brace()) { if (!initialCompile && !globalErrorFlag) { - sprintf(myString, "mIFF (SUCCESS): compiled \"%s\"\n", inFileName); + char myString[256]; + sprintf(myString, "mIFF (SUCCESS): compiled \"%s\"", inFileName); MIFFMessage(myString, 0); } } From aea98a2b4473c03fff0c0a88078ea8475803b640 Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 16 Feb 2022 16:23:53 -0500 Subject: [PATCH 37/46] Interim commit checkpoint - starts up but failure to read data after quest progresses --- .../src/shared/TaskChangeStationId.h | 4 +- .../src/shared/TaskClaimRewards.cpp | 26 +- .../src/shared/TaskCreateCharacter.h | 8 +- .../src/shared/TaskDeleteCharacter.h | 4 +- .../src/shared/TaskEnableCharacter.h | 4 +- .../src/shared/TaskGetAccountForPurge.cpp | 6 +- .../src/shared/TaskGetAvatarList.h | 10 +- .../src/shared/TaskGetClusterList.h | 14 +- .../src/shared/TaskGetValidationData.cpp | 22 +- .../LoginServer/src/shared/TaskMapAccount.h | 4 +- .../src/shared/TaskRegisterNewCluster.h | 2 +- .../src/shared/TaskRenameCharacter.h | 2 +- .../src/shared/TaskRestoreCharacter.h | 10 +- .../src/shared/TaskSetPurgeStatus.cpp | 4 +- .../src/shared/TaskToggleCharacterDisable.h | 4 +- .../src/shared/TaskToggleCompletedTutorial.h | 2 +- .../src/shared/TaskUpgradeAccount.h | 24 +- .../shared/TaskUpdateSPCharacterProfileData.h | 8 +- engine/server/library/codegen/make_queries.pl | 2 +- .../server/library/codegen/make_schema_h.pl | 10 +- .../src/shared/CharacterLocator.h | 2 +- .../src/shared/CharacterNameLocator.h | 6 +- .../src/shared/CharacterQueries.h | 6 +- .../shared/DeleteCharacterCustomPersistStep.h | 6 +- .../src/shared/FixLoadWithCustomPersistStep.h | 4 +- .../serverDatabase/src/shared/GetChunkQuery.h | 6 +- .../src/shared/GetGoldVersionNumberQuery.h | 4 +- .../src/shared/GetObjectIdsQuery.h | 2 +- .../src/shared/GetTimestampQuery.h | 2 +- .../src/shared/GetVersionNumberQuery.h | 4 +- .../src/shared/LazyDeleteQuery.h | 4 +- .../shared/MoveToPlayerCustomPersistStep.h | 4 +- .../src/shared/PreloadListQuery.h | 10 +- .../src/shared/SaveTimestampQuery.h | 2 +- .../serverDatabase/src/shared/ScriptQueries.h | 2 +- .../src/shared/StructureQueries.h | 2 +- .../serverDatabase/src/shared/TaskCSTasks.h | 8 +- .../src/shared/TaskChangeStationId.h | 4 +- .../src/shared/TaskCheckCharacterName.h | 2 +- .../src/shared/TaskGetStructuresForPurge.cpp | 4 +- .../src/shared/WorldContainerLocator.h | 4 +- .../src/shared/AvatarList.h | 2 +- .../sharedDatabaseInterface/DbBindableInt32.h | 1 - .../sharedDatabaseInterface/DbBindableLong.h | 1 + .../src/CMakeLists.txt | 4 +- .../src/shared/core/Bindable.h | 2 +- .../src/shared/core/DbBindableBase.cpp | 5 +- ...DbBindableInt32.cpp => DbBindableLong.cpp} | 18 +- .../{DbBindableInt32.h => DbBindableLong.h} | 59 +- .../src/shared/core/DbQuery.cpp | 4 +- .../src/shared/core/DbQuery.h | 6 +- .../src/shared/core/DbQueryImplementation.h | 6 +- .../src/shared/queue/DbTaskRequest.cpp | 2 +- .../src/shared/queue/DbTestQuery.h | 2 +- .../src_oci/DbBindableVarray.cpp | 1 + .../src_oci/OciQueryImplementation.cpp | 5 +- .../src_oci/OciQueryImplementation.h | 4 +- .../sharedFile/src/shared/FileManifest.cpp | 12 +- .../buffers/IndexedNetworkTableBuffer.h | 1 + .../shared/cleanup/TaskBrokenObjectCleanup.h | 2 +- .../cleanup/TaskMarketAttributesCleanup.h | 2 +- .../src/shared/cleanup/TaskMessagesCleanup.h | 2 +- .../shared/cleanup/TaskObjvarNameCleanup.h | 2 +- .../cleanup/TaskOrphanedObjectCleanup.h | 2 +- .../shared/cleanup/TaskVendorObjectCleanup.h | 2 +- .../src/shared/core/SwgSnapshot.cpp | 4 +- .../src/shared/core/SwgSnapshot.h | 4 +- .../shared/generated/ObjectQueries_h.template | 48 +- .../src/shared/generated/Schema_h.template | 586 +++++++++--------- .../shared/queries/BountyHunterTargetQuery.h | 2 +- .../src/shared/queries/CommoditiesQuery.h | 8 +- .../src/shared/queries/CommoditiesSchema.h | 34 +- .../DeleteDemandLoadedContainerQuery.h | 2 +- .../src/shared/queries/LocationQuery.h | 10 +- .../ManufactureSchematicAttributeQuery.h | 2 +- .../src/shared/queries/MessageQuery.h | 12 +- .../shared/queries/ObjectVariableQueries.h | 4 +- .../src/shared/queries/ObjectsTableQuery.h | 2 +- .../queries/OfflineMoneyCustomPersistStep.cpp | 2 +- .../src/shared/queries/PropertyListQuery.h | 10 +- .../src/shared/queries/ResourceTypeQuery.h | 2 +- .../src/shared/queries/SkillQuery.h | 4 +- .../src/shared/tasks/TaskGetAuctionList.h | 16 +- .../src/shared/tasks/TaskGetBidList.h | 4 +- .../src/shared/tasks/TaskGetLocationList.h | 12 +- .../src/shared/tasks/TaskLoadObjvarNames.h | 2 +- .../src/shared/tasks/TaskLocateStructure.h | 6 +- .../src/shared/tasks/TaskMoveToPlayer.h | 2 +- .../src/shared/tasks/TaskRestoreCharacter.h | 6 +- .../src/shared/tasks/TaskRestoreHouse.h | 2 +- .../src/shared/tasks/TaskSaveObjvarNames.h | 2 +- .../src/shared/tasks/TaskUndeleteItem.h | 2 +- .../src/shared/tasks/TaskVerifyCharacter.h | 4 +- 93 files changed, 615 insertions(+), 584 deletions(-) delete mode 100755 engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h create mode 100755 engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h rename engine/shared/library/sharedDatabaseInterface/src/shared/core/{DbBindableInt32.cpp => DbBindableLong.cpp} (71%) rename engine/shared/library/sharedDatabaseInterface/src/shared/core/{DbBindableInt32.h => DbBindableLong.h} (50%) diff --git a/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h b/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h index 6a3030008..6ed1dad44 100755 --- a/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h +++ b/engine/server/application/LoginServer/src/shared/TaskChangeStationId.h @@ -36,8 +36,8 @@ class TaskChangeStationId : public DB::TaskRequest public: ChangeStationIdQuery(); - DB::BindableInt32 destination_station_id; //lint !e1925 // public data member - DB::BindableInt32 source_station_id; //lint !e1925 // public data member + DB::BindableLong destination_station_id; //lint !e1925 // public data member + DB::BindableLong source_station_id; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp b/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp index 195ac2666..ef741b018 100755 --- a/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskClaimRewards.cpp @@ -33,11 +33,11 @@ namespace TaskClaimRewardsNamespace bool getResult() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId character_id; - DB::BindableInt32 cluster_id; + DB::BindableLong cluster_id; DB::BindableString<255> event_id; - DB::BindableInt32 result; + DB::BindableLong result; private: //disable ConsumeEventQuery(); @@ -58,11 +58,11 @@ namespace TaskClaimRewardsNamespace bool getResult() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId character_id; - DB::BindableInt32 cluster_id; + DB::BindableLong cluster_id; DB::BindableString<255> item_id; - DB::BindableInt32 result; + DB::BindableLong result; private: //disable ClaimItemQuery(); @@ -83,12 +83,12 @@ namespace TaskClaimRewardsNamespace bool getResult() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId character_id; - DB::BindableInt32 cluster_id; + DB::BindableLong cluster_id; DB::BindableString<255> item_id; - DB::BindableInt32 count_adjustment; - DB::BindableInt32 result; + DB::BindableLong count_adjustment; + DB::BindableLong result; private: //disable UpdateFeatureIdTransactionQuery(); @@ -102,7 +102,7 @@ namespace TaskClaimRewardsNamespace GetFeatureIdTransactionsQuery(StationId stationId, NetworkId const & characterId, uint32 clusterId); DB::BindableString<255> item_id; - DB::BindableInt32 count; + DB::BindableLong count; virtual void getSQL(std::string &sql); virtual bool bindParameters(); @@ -110,9 +110,9 @@ namespace TaskClaimRewardsNamespace virtual QueryMode getExecutionMode() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId character_id; - DB::BindableInt32 cluster_id; + DB::BindableLong cluster_id; private: //disable GetFeatureIdTransactionsQuery(const GetFeatureIdTransactionsQuery&); diff --git a/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h b/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h index 3004bc6d5..3c53e296c 100755 --- a/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskCreateCharacter.h @@ -33,12 +33,12 @@ class TaskCreateCharacter : public DB::TaskRequest public: CreateCharacterQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member DB::BindableString<127> character_name; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member - DB::BindableInt32 template_id; //lint !e1925 // public data member - DB::BindableInt32 character_type; //lint !e1925 // public data member + DB::BindableLong template_id; //lint !e1925 // public data member + DB::BindableLong character_type; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h b/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h index a8e391f0d..5b3130a48 100755 --- a/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskDeleteCharacter.h @@ -35,9 +35,9 @@ class TaskDeleteCharacter : public DB::TaskRequest public: DeleteCharacterQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member - DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h b/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h index a5ad5f458..1cb362f06 100755 --- a/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskEnableCharacter.h @@ -35,10 +35,10 @@ class TaskEnableCharacter : public DB::TaskRequest public: EnableCharacterQuery(); - DB::BindableInt32 station_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableLong station_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableNetworkId character_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableBool enabled; //lint !e1925 // public data member : suppressed because this is a private inner class - DB::BindableInt32 result; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableLong result; //lint !e1925 // public data member : suppressed because this is a private inner class virtual void getSQL(std::string &sql); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp b/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp index 62251e03f..061b1c4d3 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskGetAccountForPurge.cpp @@ -32,9 +32,9 @@ namespace TaskGetAccountForPurgeNamespace StationId getAccount() const; private: - DB::BindableInt32 m_account; - DB::BindableInt32 m_min_age; - DB::BindableInt32 m_purge_phase; + DB::BindableLong m_account; + DB::BindableLong m_min_age; + DB::BindableLong m_purge_phase; private: //disable GetAccountForPurgeQuery(const GetAccountForPurgeQuery&); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h b/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h index c76ed5f36..1c7c6cb1c 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h +++ b/engine/server/application/LoginServer/src/shared/TaskGetAvatarList.h @@ -37,13 +37,13 @@ class TaskGetAvatarList : public DB::TaskRequest class GetCharactersQuery : public DB::Query { public: - DB::BindableInt32 station_id; //lint !e1925 // public data member - DB::BindableInt32 cluster_group_id; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableLong cluster_group_id; //lint !e1925 // public data member DB::BindableString<128> character_name; //lint !e1925 // public data member - DB::BindableInt32 object_template_id; //lint !e1925 // public data member + DB::BindableLong object_template_id; //lint !e1925 // public data member DB::BindableNetworkId object_id; //lint !e1925 // public data member - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 character_type; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong character_type; //lint !e1925 // public data member GetCharactersQuery(); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h b/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h index 0c78ded8d..534c95f17 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h +++ b/engine/server/application/LoginServer/src/shared/TaskGetClusterList.h @@ -31,20 +31,20 @@ class TaskGetClusterList : public DB::TaskRequest class GetClustersQuery : public DB::Query { public: - DB::BindableInt32 group_id; //lint !e1925 // public data member + DB::BindableLong group_id; //lint !e1925 // public data member - DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member DB::BindableString<255> cluster_name; //lint !e1925 // public data member DB::BindableString<255> address; //lint !e1925 // public data member - DB::BindableInt32 port; //lint !e1925 // public data member + DB::BindableLong port; //lint !e1925 // public data member DB::BindableBool secret; //lint !e1925 // public data member DB::BindableBool locked; //lint !e1925 // public data member DB::BindableBool not_recommended; //lint !e1925 // public data member - DB::BindableInt32 maxCharacterPerAccount; //lint !e1925 // public data member - DB::BindableInt32 online_player_limit; //lint !e1925 // public data member - DB::BindableInt32 online_free_trial_limit; //lint !e1925 // public data member + DB::BindableLong maxCharacterPerAccount; //lint !e1925 // public data member + DB::BindableLong online_player_limit; //lint !e1925 // public data member + DB::BindableLong online_free_trial_limit; //lint !e1925 // public data member DB::BindableBool free_trial_can_create_char; //lint !e1925 // public data member - DB::BindableInt32 online_tutorial_limit; //lint !e1925 // public data member + DB::BindableLong online_tutorial_limit; //lint !e1925 // public data member GetClustersQuery(); diff --git a/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp b/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp index 82e227edc..735e9e7a5 100755 --- a/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskGetValidationData.cpp @@ -26,10 +26,10 @@ namespace TaskGetValidationDataNamespace public: GetValidationDataQuery(); - DB::BindableInt32 station_id; //lint !e1925 // public data member - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 character_type_id; //lint !e1925 // public data member - DB::BindableInt32 num_open_slots; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong character_type_id; //lint !e1925 // public data member + DB::BindableLong num_open_slots; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); @@ -46,7 +46,7 @@ namespace TaskGetValidationDataNamespace public: GetCompletedTutorialQuery(StationId stationId); - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableBool completed_tutorial; virtual void getSQL(std::string &sql); @@ -74,9 +74,9 @@ namespace TaskGetValidationDataNamespace NetworkId const getCharacterId() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableString<100> event_id; - DB::BindableInt32 cluster_id; + DB::BindableLong cluster_id; DB::BindableNetworkId character_id; private: //disable @@ -100,9 +100,9 @@ namespace TaskGetValidationDataNamespace NetworkId const getCharacterId() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableString<100> item_id; - DB::BindableInt32 cluster_id; + DB::BindableLong cluster_id; DB::BindableNetworkId character_id; private: //disable @@ -116,8 +116,8 @@ namespace TaskGetValidationDataNamespace public: IsClusterAtLimitQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 result; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong result; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/LoginServer/src/shared/TaskMapAccount.h b/engine/server/application/LoginServer/src/shared/TaskMapAccount.h index 70e34c5b8..ad7f04e18 100644 --- a/engine/server/application/LoginServer/src/shared/TaskMapAccount.h +++ b/engine/server/application/LoginServer/src/shared/TaskMapAccount.h @@ -34,8 +34,8 @@ class TaskMapAccount : public DB::TaskRequest public: MapAccountQuery(); - DB::BindableInt32 parentID; //lint !e1925 // public data member - DB::BindableInt32 childID; //lint !e1925 // public data member + DB::BindableLong parentID; //lint !e1925 // public data member + DB::BindableLong childID; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h b/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h index d2f616ff9..e756e2d9b 100755 --- a/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h +++ b/engine/server/application/LoginServer/src/shared/TaskRegisterNewCluster.h @@ -34,7 +34,7 @@ class TaskRegisterNewCluster : public DB::TaskRequest public: RegisterClusterQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member DB::BindableString<255> cluster_name; //lint !e1925 // public data member DB::BindableString<255> address; //lint !e1925 // public data member diff --git a/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h b/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h index 20ba975ba..525cc3acd 100755 --- a/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskRenameCharacter.h @@ -35,7 +35,7 @@ class TaskRenameCharacter : public DB::TaskRequest public: RenameCharacterQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member DB::BindableString<127> new_name; //lint !e1925 // public data member diff --git a/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h b/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h index 2867bd3b3..d30d6abd1 100755 --- a/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h +++ b/engine/server/application/LoginServer/src/shared/TaskRestoreCharacter.h @@ -33,13 +33,13 @@ class TaskRestoreCharacter : public DB::TaskRequest public: RestoreCharacterQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member DB::BindableString<127> character_name; //lint !e1925 // public data member DB::BindableNetworkId character_id; //lint !e1925 // public data member - DB::BindableInt32 template_id; //lint !e1925 // public data member - DB::BindableInt32 character_type; //lint !e1925 // public data member - DB::BindableInt32 result; //lint !e1925 // public data member + DB::BindableLong template_id; //lint !e1925 // public data member + DB::BindableLong character_type; //lint !e1925 // public data member + DB::BindableLong result; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp b/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp index 4ee5e65ea..3f20de28e 100755 --- a/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp +++ b/engine/server/application/LoginServer/src/shared/TaskSetPurgeStatus.cpp @@ -29,8 +29,8 @@ namespace TaskSetPurgeStatusNamespace virtual QueryMode getExecutionMode() const; private: - DB::BindableInt32 m_account; - DB::BindableInt32 m_purge_phase; + DB::BindableLong m_account; + DB::BindableLong m_purge_phase; private: //disable SetPurgeStatusQuery(const SetPurgeStatusQuery&); diff --git a/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h b/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h index 118bc4fd4..32d21cb1e 100755 --- a/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h +++ b/engine/server/application/LoginServer/src/shared/TaskToggleCharacterDisable.h @@ -35,9 +35,9 @@ class TaskToggleCharacterDisable : public DB::TaskRequest public: ToggleCharacterDisableQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableLong cluster_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableNetworkId character_id; //lint !e1925 // public data member : suppressed because this is a private inner class - DB::BindableInt32 station_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableLong station_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableBool enabled_flag; //lint !e1925 // public data member : suppressed because this is a private inner class diff --git a/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h b/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h index 8c152a11d..1e1def17e 100755 --- a/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h +++ b/engine/server/application/LoginServer/src/shared/TaskToggleCompletedTutorial.h @@ -34,7 +34,7 @@ class TaskToggleCompletedTutorial : public DB::TaskRequest public: ToggleCompletedTutorialQuery(); - DB::BindableInt32 station_id; //lint !e1925 // public data member : suppressed because this is a private inner class + DB::BindableLong station_id; //lint !e1925 // public data member : suppressed because this is a private inner class DB::BindableBool completed_flag; //lint !e1925 // public data member : suppressed because this is a private inner class virtual void getSQL(std::string &sql); diff --git a/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h b/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h index 97b56c1ef..325014ff9 100755 --- a/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h +++ b/engine/server/application/LoginServer/src/shared/TaskUpgradeAccount.h @@ -36,10 +36,10 @@ class TaskUpgradeAccount : public DB::TaskRequest public: SetCharacterTypeQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member DB::BindableNetworkId character; //lint !e1925 // public data member - DB::BindableInt32 character_type; //lint !e1925 // public data member + DB::BindableLong character_type; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); @@ -56,9 +56,9 @@ class TaskUpgradeAccount : public DB::TaskRequest public: QueryJediQuery(); - DB::BindableInt32 station_id; //lint !e1925 // public data member - DB::BindableInt32 character_type; //lint !e1925 // public data member - DB::BindableInt32 result; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableLong character_type; //lint !e1925 // public data member + DB::BindableLong result; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); @@ -76,8 +76,8 @@ class TaskUpgradeAccount : public DB::TaskRequest public: AddJediQuery(); - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 station_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); @@ -140,10 +140,10 @@ class TaskVacateUnlockedSlot : public DB::TaskRequest public: GetOnlyOpenCharacterSlotsQuery(); - DB::BindableInt32 station_id; //lint !e1925 // public data member - DB::BindableInt32 cluster_id; //lint !e1925 // public data member - DB::BindableInt32 character_type_id; //lint !e1925 // public data member - DB::BindableInt32 num_open_slots; //lint !e1925 // public data member + DB::BindableLong station_id; //lint !e1925 // public data member + DB::BindableLong cluster_id; //lint !e1925 // public data member + DB::BindableLong character_type_id; //lint !e1925 // public data member + DB::BindableLong num_open_slots; //lint !e1925 // public data member virtual void getSQL(std::string &sql); virtual bool bindParameters(); diff --git a/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h b/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h index 3a5cb54df..712b95bd6 100755 --- a/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h +++ b/engine/server/application/StationPlayersCollector/src/shared/TaskUpdateSPCharacterProfileData.h @@ -44,11 +44,11 @@ class TaskUpdateSPCharacterProfileData : public DB::TaskRequest DB::BindableDouble cash_balance; DB::BindableDouble bank_balance; DB::BindableString<500> objectTemplateName; - DB::BindableInt32 stationId; + DB::BindableLong stationId; DB::BindableNetworkId containedBy; - DB::BindableInt32 createTime; - DB::BindableInt32 playedTime; - DB::BindableInt32 numLots; + DB::BindableLong createTime; + DB::BindableLong playedTime; + DB::BindableLong numLots; virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/library/codegen/make_queries.pl b/engine/server/library/codegen/make_queries.pl index 01c72158c..7858d1c2c 100755 --- a/engine/server/library/codegen/make_queries.pl +++ b/engine/server/library/codegen/make_queries.pl @@ -126,7 +126,7 @@ sub writeHeader $i++; } - $newText.="\tDB::BindableInt32\t\t\t m_numItems;\n"; + $newText.="\tDB::BindableLong\t\t\t m_numItems;\n"; $newText.="};\n"; $newText.="\n"; diff --git a/engine/server/library/codegen/make_schema_h.pl b/engine/server/library/codegen/make_schema_h.pl index 89b5f384f..d79e1a5a9 100755 --- a/engine/server/library/codegen/make_schema_h.pl +++ b/engine/server/library/codegen/make_schema_h.pl @@ -128,7 +128,7 @@ sub parseTable } if ($tablename eq "Object") { - $decl{$tablename}.="\n\tDB::BindableInt32 container_level;\n"; + $decl{$tablename}.="\n\tDB::BindableLong container_level;\n"; } $decl{$tablename}.="\n\tvirtual void copy(const DB::Row &rhs)\n"; @@ -205,8 +205,8 @@ sub translateType my($dbtype)=@_; SWITCH: { - if ($dbtype eq "int") { $ctype="DB::BindableInt32"; last SWITCH; } - if ($dbtype eq "number") { $ctype="DB::BindableInt32"; last SWITCH; } + if ($dbtype eq "int") { $ctype="DB::BindableLong"; last SWITCH; } + if ($dbtype eq "number") { $ctype="DB::BindableLong"; last SWITCH; } if ($dbtype eq "float") { $ctype="DB::BindableDouble"; last SWITCH; } if ($dbtype eq "date") { $ctype="DB::BindableTimestamp"; last SWITCH; } if ($dbtype eq "char(1)") { $ctype="DB::BindableBool"; last SWITCH; } @@ -224,8 +224,8 @@ sub translateBufferType my($dbtype)=@_; SWITCH: { - if ($dbtype eq "int") { $ctype="DB::BindableInt32"; last SWITCH; } - if ($dbtype eq "number") { $ctype="DB::BindableInt32"; last SWITCH; } + if ($dbtype eq "int") { $ctype="DB::BindableLong"; last SWITCH; } + if ($dbtype eq "number") { $ctype="DB::BindableLong"; last SWITCH; } if ($dbtype eq "float") { $ctype="DB::BindableDouble"; last SWITCH; } if ($dbtype eq "date") { $ctype="DB::BindableTimestamp"; last SWITCH; } if ($dbtype eq "char(1)") { $ctype="DB::BindableBool"; last SWITCH; } diff --git a/engine/server/library/serverDatabase/src/shared/CharacterLocator.h b/engine/server/library/serverDatabase/src/shared/CharacterLocator.h index 8c655ee03..fc1fa2030 100755 --- a/engine/server/library/serverDatabase/src/shared/CharacterLocator.h +++ b/engine/server/library/serverDatabase/src/shared/CharacterLocator.h @@ -50,7 +50,7 @@ class CharacterLocator : public ObjectLocator LocateCharacterQuery& operator=(const LocateCharacterQuery&); //disable public: - DB::BindableInt32 object_count; + DB::BindableLong object_count; DB::BindableNetworkId object_id; private: diff --git a/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h index b33777d8b..3ca8cd557 100755 --- a/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h +++ b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h @@ -32,11 +32,11 @@ class CharacterNameLocator : public ObjectLocator struct CharacterNameRow { DB::BindableNetworkId character_id; - DB::BindableInt32 character_station_id; + DB::BindableLong character_station_id; DB::BindableString<127> character_name; DB::BindableString<127> character_full_name; - DB::BindableInt32 character_create_time; - DB::BindableInt32 character_last_login_time; + DB::BindableLong character_create_time; + DB::BindableLong character_last_login_time; }; class CharacterNameQuery : public DB::Query diff --git a/engine/server/library/serverDatabase/src/shared/CharacterQueries.h b/engine/server/library/serverDatabase/src/shared/CharacterQueries.h index b4a4b8a20..9cc1dfc87 100755 --- a/engine/server/library/serverDatabase/src/shared/CharacterQueries.h +++ b/engine/server/library/serverDatabase/src/shared/CharacterQueries.h @@ -36,7 +36,7 @@ namespace DBQuery { DB::BindableDouble x; DB::BindableDouble y; DB::BindableDouble z; - DB::BindableInt32 station_id; + DB::BindableLong station_id; }; GetCharacters() {} @@ -76,7 +76,7 @@ namespace DBQuery { virtual QueryMode getExecutionMode() const; private: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId object_id; DB::BindableString<127> character_name; DB::BindableString<127> normalized_name; @@ -105,7 +105,7 @@ namespace DBQuery { DB::BindableNetworkId object_id; DB::BindableString<127> character_name; DB::BindableString<127> normalized_name; - DB::BindableInt32 result; + DB::BindableLong result; private: RenameCharacter (const RenameCharacter&); // disable diff --git a/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h index 112c35151..0ab8a0cc5 100755 --- a/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h +++ b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h @@ -45,10 +45,10 @@ class DeleteCharacterCustomPersistStep : public CustomPersistStep virtual QueryMode getExecutionMode() const; public: - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId character_id; - DB::BindableInt32 delete_minutes; - DB::BindableInt32 result; + DB::BindableLong delete_minutes; + DB::BindableLong result; private: // disable: DeleteCharacterQuery(const DeleteCharacterQuery&); diff --git a/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h index 5f28563e0..e5e24bea1 100755 --- a/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h +++ b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h @@ -12,7 +12,7 @@ #include "Unicode.h" #include "serverDatabase/CustomPersistStep.h" -#include "sharedDatabaseInterface/DbBindableInt32.h" +#include "sharedDatabaseInterface/DbBindableLong.h" #include "sharedDatabaseInterface/BindableNetworkId.h" #include "sharedDatabaseInterface/DbQuery.h" #include "sharedFoundation/NetworkId.h" @@ -50,7 +50,7 @@ class FixLoadWithCustomPersistStep : public CustomPersistStep FixLoadWithQuery &operator=(FixLoadWithQuery const &); DB::BindableNetworkId topmost_object; DB::BindableNetworkId starting_loadwith; - DB::BindableInt32 max_depth; + DB::BindableLong max_depth; }; private: diff --git a/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h index 7ccb5abc3..b99382d21 100755 --- a/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h @@ -41,10 +41,10 @@ namespace DBQuery { GetChunkQuery& operator=(const GetChunkQuery&); //disable private: - DB::BindableInt32 object_count; + DB::BindableLong object_count; DB::BindableString<50> scene_id; - DB::BindableInt32 node_x; - DB::BindableInt32 node_z; + DB::BindableLong node_x; + DB::BindableLong node_z; std::string m_schema; }; diff --git a/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h index a79ed8778..5e854cc07 100755 --- a/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h @@ -31,8 +31,8 @@ namespace DBQuery int getMinVersionNumber(); private: - DB::BindableInt32 current_version_number; - DB::BindableInt32 min_version_number; + DB::BindableLong current_version_number; + DB::BindableLong min_version_number; private: GetGoldVersionNumberQuery (const GetGoldVersionNumberQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h index 593510839..5e8f70b31 100755 --- a/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h @@ -43,7 +43,7 @@ namespace DBQuery GetOIDsQuery(const GetOIDsQuery&); GetOIDsQuery& operator=(const GetOIDsQuery&); - DB::BindableInt32 min_count; + DB::BindableLong min_count; DB::BindableNetworkId start_id; DB::BindableNetworkId end_id; }; diff --git a/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h index 6789649c5..08563f616 100755 --- a/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h @@ -30,7 +30,7 @@ namespace DBQuery int getTimestamp(); private: - DB::BindableInt32 timestamp; + DB::BindableLong timestamp; private: GetTimestampQuery(const GetTimestampQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h index 665765be2..8871468fd 100755 --- a/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h +++ b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h @@ -31,8 +31,8 @@ namespace DBQuery int getMinVersionNumber(); private: - DB::BindableInt32 current_version_number; - DB::BindableInt32 min_version_number; + DB::BindableLong current_version_number; + DB::BindableLong min_version_number; private: GetVersionNumberQuery (const GetVersionNumberQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h index 0e6d412b3..65e40e63c 100755 --- a/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h +++ b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h @@ -34,8 +34,8 @@ class LazyDeleteQuery : public DB::Query private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; - DB::BindableInt32 m_enableDatabaseLogging; + DB::BindableLong m_numItems; + DB::BindableLong m_enableDatabaseLogging; private: LazyDeleteQuery(const LazyDeleteQuery&); //disable diff --git a/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h index 03670391c..b5851bc98 100755 --- a/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h +++ b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h @@ -12,7 +12,7 @@ #include "Unicode.h" #include "serverDatabase/CustomPersistStep.h" -#include "sharedDatabaseInterface/DbBindableInt32.h" +#include "sharedDatabaseInterface/DbBindableLong.h" #include "sharedDatabaseInterface/BindableNetworkId.h" #include "sharedDatabaseInterface/DbQuery.h" #include "sharedFoundation/NetworkId.h" @@ -52,7 +52,7 @@ class MoveToPlayerCustomPersistStep : public CustomPersistStep MoveToPlayerQuery &operator=(MoveToPlayerQuery const &); DB::BindableNetworkId object_id; DB::BindableNetworkId target_player; - DB::BindableInt32 max_depth; + DB::BindableLong max_depth; bool m_useBank; bool m_useDatapad; }; diff --git a/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h index ad7cc24b5..3f7695b8a 100755 --- a/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h +++ b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h @@ -30,11 +30,11 @@ namespace DBQuery public: DB::BindableString<50> scene_id; DB::BindableNetworkId object_id; - DB::BindableInt32 chunk_x; - DB::BindableInt32 chunk_z; - DB::BindableInt32 preload_range; - DB::BindableInt32 city_server_id; - DB::BindableInt32 wilderness_server_id; + DB::BindableLong chunk_x; + DB::BindableLong chunk_z; + DB::BindableLong preload_range; + DB::BindableLong city_server_id; + DB::BindableLong wilderness_server_id; public: virtual bool bindParameters(); diff --git a/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h index 7302ace93..77d4e0779 100755 --- a/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h +++ b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h @@ -28,7 +28,7 @@ namespace DBQuery virtual bool bindColumns(); private: - DB::BindableInt32 timestamp; + DB::BindableLong timestamp; private: SaveTimestampQuery(const SaveTimestampQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/ScriptQueries.h b/engine/server/library/serverDatabase/src/shared/ScriptQueries.h index 2f5cbf81a..ec916eec4 100755 --- a/engine/server/library/serverDatabase/src/shared/ScriptQueries.h +++ b/engine/server/library/serverDatabase/src/shared/ScriptQueries.h @@ -45,7 +45,7 @@ namespace DBQuery struct ScriptRow { DB::BindableNetworkId object_id; - DB::BindableInt32 index; + DB::BindableLong index; DB::BindableString<128> script_name; }; diff --git a/engine/server/library/serverDatabase/src/shared/StructureQueries.h b/engine/server/library/serverDatabase/src/shared/StructureQueries.h index 3893f6afb..cee4458de 100755 --- a/engine/server/library/serverDatabase/src/shared/StructureQueries.h +++ b/engine/server/library/serverDatabase/src/shared/StructureQueries.h @@ -35,7 +35,7 @@ namespace DBQuery { DB::BindableDouble y; DB::BindableDouble z; DB::BindableNetworkId character_id; - DB::BindableInt32 deleted; + DB::BindableLong deleted; }; GetStructures() {} diff --git a/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h index 2810b9ee6..db26fc168 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h +++ b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h @@ -44,7 +44,7 @@ class TaskGetCharactersForAccount:public DB::TaskRequest public: // input: - DB::BindableInt32 station_id; //lint !e1925 public data member Suppresed because it's in a private inner class + DB::BindableLong station_id; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class //output: @@ -122,7 +122,7 @@ class TaskGetDeletedItems:public DB::TaskRequest public: // input: DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class - DB::BindableInt32 page_number; + DB::BindableLong page_number; private: CSGetDeletedItemsQuery(const CSGetDeletedItemsQuery&); @@ -211,7 +211,7 @@ class TaskGetCharacterId:public DB::TaskRequest struct CharacterIdRow { DB::BindableNetworkId characterId; - DB::BindableInt32 stationId; + DB::BindableLong stationId; DB::BindableString characterName; }; @@ -310,7 +310,7 @@ class TaskCsUndeleteItem : public DB::TaskRequest private: DB::BindableNetworkId characterId; DB::BindableNetworkId itemId; - DB::BindableInt32 move; + DB::BindableLong move; private: CsUndeleteItemQuery(const CsUndeleteItemQuery &); // disable diff --git a/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h index 6a3030008..6ed1dad44 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h +++ b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h @@ -36,8 +36,8 @@ class TaskChangeStationId : public DB::TaskRequest public: ChangeStationIdQuery(); - DB::BindableInt32 destination_station_id; //lint !e1925 // public data member - DB::BindableInt32 source_station_id; //lint !e1925 // public data member + DB::BindableLong destination_station_id; //lint !e1925 // public data member + DB::BindableLong source_station_id; //lint !e1925 // public data member virtual void getSQL (std::string &sql); virtual bool bindParameters (); diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h index 1ce96cf1c..6cf4d3e95 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h @@ -44,7 +44,7 @@ class TaskCheckCharacterName : public DB::TaskRequest public: DB::BindableString<127> character_name; - DB::BindableInt32 result; + DB::BindableLong result; private: CheckCharacterNameQuery(const CheckCharacterNameQuery&); diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp index 09711a525..5ea2e6c81 100755 --- a/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp +++ b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp @@ -35,7 +35,7 @@ namespace TaskGetStructuresForPurgeNamespace NetworkId getOwnerId() const; private: - DB::BindableInt32 m_station_id; + DB::BindableLong m_station_id; DB::BindableNetworkId m_structure_id; DB::BindableNetworkId m_owner_id; @@ -59,7 +59,7 @@ namespace TaskGetStructuresForPurgeNamespace Unicode::String getVendorName() const; private: - DB::BindableInt32 m_station_id; + DB::BindableLong m_station_id; DB::BindableNetworkId m_vendor_id; DB::BindableNetworkId m_owner_id; DB::BindableUnicode<128> m_vendor_name; diff --git a/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h index 7d6a9d29d..ed8272d51 100755 --- a/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h +++ b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h @@ -58,8 +58,8 @@ class WorldContainerLocator : public ObjectLocator private: DB::BindableVarrayString container_ids; - DB::BindableInt32 num_containers; - DB::BindableInt32 num_objects_found; + DB::BindableLong num_containers; + DB::BindableLong num_objects_found; std::string m_schema; private: diff --git a/engine/server/library/serverNetworkMessages/src/shared/AvatarList.h b/engine/server/library/serverNetworkMessages/src/shared/AvatarList.h index 204161ee5..f21e4baed 100755 --- a/engine/server/library/serverNetworkMessages/src/shared/AvatarList.h +++ b/engine/server/library/serverNetworkMessages/src/shared/AvatarList.h @@ -21,7 +21,7 @@ struct AvatarRecord { Unicode::String m_name; - int m_objectTemplateId; + uint32_t m_objectTemplateId; NetworkId m_networkId; uint32 m_clusterId; int m_characterType; diff --git a/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h b/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h deleted file mode 100755 index 0689bee11..000000000 --- a/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableInt32.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../src/shared/core/DbBindableInt32.h" diff --git a/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h b/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h new file mode 100755 index 000000000..b11e3a91e --- /dev/null +++ b/engine/shared/library/sharedDatabaseInterface/include/public/sharedDatabaseInterface/DbBindableLong.h @@ -0,0 +1 @@ +#include "../../src/shared/core/DbBindableLong.h" diff --git a/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt b/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt index 39dedc43d..84c3cd983 100644 --- a/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt +++ b/engine/shared/library/sharedDatabaseInterface/src/CMakeLists.txt @@ -18,8 +18,8 @@ set(SHARED_SOURCES shared/core/DbBindableDouble.h shared/core/DbBindableInt64.cpp shared/core/DbBindableInt64.h - shared/core/DbBindableInt32.cpp - shared/core/DbBindableInt32.h + shared/core/DbBindableLong.cpp + shared/core/DbBindableLong.h shared/core/DbBindableString.cpp shared/core/DbBindableString.h shared/core/DbBindableUnicode.cpp diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h index c6f111509..03c2d7dc4 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/Bindable.h @@ -23,7 +23,7 @@ #include "sharedDatabaseInterface/DbBindableBool.h" #include "sharedDatabaseInterface/DbBindableDouble.h" #include "sharedDatabaseInterface/DbBindableInt64.h" -#include "sharedDatabaseInterface/DbBindableInt32.h" +#include "sharedDatabaseInterface/DbBindableLong.h" #include "sharedDatabaseInterface/DbBindableString.h" #include "sharedDatabaseInterface/DbBindableUnicode.h" diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableBase.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableBase.cpp index 98cd481f8..f93a990e1 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableBase.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableBase.cpp @@ -8,6 +8,9 @@ #include "sharedDatabaseInterface/FirstSharedDatabaseInterface.h" #include "sharedDatabaseInterface/DbBindableBase.h" +#include +#include + // ====================================================================== using namespace DB; @@ -35,7 +38,7 @@ Bindable::Bindable(int _indicator) : bool Bindable::isNull() const { - return (indicator==-1); + return (indicator == -1); } // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp similarity index 71% rename from engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.cpp rename to engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp index efd31d58b..8c5975456 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.cpp @@ -1,12 +1,12 @@ // ====================================================================== // -// DBBindableInt32.cpp +// DBBindableLong.cpp // copyright (c) 2001 Sony Online Entertainment // // ====================================================================== #include "sharedDatabaseInterface/FirstSharedDatabaseInterface.h" -#include "sharedDatabaseInterface/DbBindableInt32.h" +#include "sharedDatabaseInterface/DbBindableLong.h" #include @@ -14,15 +14,15 @@ using namespace DB; -BindableInt32::BindableInt32() : Bindable(), value(-999) +BindableLong::BindableLong() : Bindable(), value(-999) { } -BindableInt32::BindableInt32(int32_t _value) : Bindable(sizeof(value)), value(_value) +BindableLong::BindableLong(long _value) : Bindable(sizeof(value)), value(_value) { } -void *BindableInt32::getBuffer() +void *BindableLong::getBuffer() { return &value; //lint !e1536 // exposing private member } @@ -30,14 +30,14 @@ void *BindableInt32::getBuffer() // ---------------------------------------------------------------------- -int32_t BindableInt32::getValue() const +long BindableLong::getValue() const { return value; } // ---------------------------------------------------------------------- -BindableInt32 &BindableInt32::operator=(int32_t rhs) +BindableLong &BindableLong::operator=(long rhs) { indicator=sizeof(value); value=rhs; @@ -46,7 +46,7 @@ BindableInt32 &BindableInt32::operator=(int32_t rhs) // ---------------------------------------------------------------------- -void BindableInt32::setValue(int32_t rhs) +void BindableLong::setValue(long rhs) { indicator=sizeof(value); value=rhs; @@ -54,7 +54,7 @@ void BindableInt32::setValue(int32_t rhs) // ---------------------------------------------------------------------- -std::string BindableInt32::outputValue() const +std::string BindableLong::outputValue() const { char temp[255]; snprintf(temp,sizeof(temp),"%li",value); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h similarity index 50% rename from engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.h rename to engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h index 4fccc63ff..cd043c983 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableInt32.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableLong.h @@ -1,12 +1,18 @@ // ====================================================================== // -// DBBindableInt32.h +// DBBindableLong.h // copyright (c) 2001 Sony Online Entertainment // +// NOTE: This class needs to be flexible with the compiler such that +// when compiling using 32 bit OCI libraries this class is 4 bytes +// in size. When compiling using 64 bit OCI libraries, this class +// must be 8 bytes in size simply because the OCI libraries read +// the data type from the database of a NUMBER field and convert to +// either 4 bytes or 8 bytes depending on architecture used. // ====================================================================== -#ifndef INCLUDED_DBBindableInt32_H -#define INCLUDED_DBBindableInt32_H +#ifndef INCLUDED_DBBindableLong_H +#define INCLUDED_DBBindableLong_H // ====================================================================== @@ -19,15 +25,15 @@ namespace DB { /** * Represents a long in C++, bound to an INTEGER or NUMBER database column */ - class BindableInt32 : public Bindable + class BindableLong : public Bindable { public: - BindableInt32(); - explicit BindableInt32(int32_t _value); + BindableLong(); + explicit BindableLong(long _value); - int32_t getValue() const; - void setValue(const int32_t rhs); - BindableInt32 &operator=(const int32_t rhs); + long getValue() const; + void setValue(const long rhs); + BindableLong &operator=(const long rhs); // following alternate getValue's are provided for convenience, particularly in // the auto-generated code: @@ -35,58 +41,73 @@ namespace DB { void getValue(uint8_t &buffer) const; void getValue(int16_t &buffer) const; void getValue(uint16_t &buffer) const; - void getValue(int32_t &buffer) const; - void getValue(uint32_t &buffer) const; + void getValue(int &buffer) const; + void getValue(unsigned int &buffer) const; + void getValue(long &buffer) const; + void getValue(unsigned long &buffer) const; void *getBuffer(); virtual std::string outputValue() const; private: - int32_t value; + long value; }; //lint !e1721 !e1509 // no virtual destructor, unusual operator = } // ---------------------------------------------------------------------- -inline void DB::BindableInt32::getValue(int8_t &buffer) const +inline void DB::BindableLong::getValue(int8_t &buffer) const { buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableInt32::getValue(uint8_t &buffer) const +inline void DB::BindableLong::getValue(uint8_t &buffer) const { buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableInt32::getValue(int16_t &buffer) const +inline void DB::BindableLong::getValue(int16_t &buffer) const { buffer=getValue(); } // ---------------------------------------------------------------------- -inline void DB::BindableInt32::getValue(uint16_t &buffer) const +inline void DB::BindableLong::getValue(uint16_t &buffer) const { buffer=static_cast(getValue()); } // ---------------------------------------------------------------------- -inline void DB::BindableInt32::getValue(int32_t &buffer) const +inline void DB::BindableLong::getValue(int &buffer) const +{ + buffer=static_cast(getValue()); +} + +// ---------------------------------------------------------------------- + +inline void DB::BindableLong::getValue(unsigned int &buffer) const +{ + buffer=static_cast(getValue()); +} +// ---------------------------------------------------------------------- + +inline void DB::BindableLong::getValue(long &buffer) const { buffer=getValue(); } // ---------------------------------------------------------------------- -inline void DB::BindableInt32::getValue(uint32_t &buffer) const +inline void DB::BindableLong::getValue(unsigned long &buffer) const { - buffer=static_cast(getValue()); + buffer=static_cast(getValue()); } // ====================================================================== diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp index 9819b73c8..f78c6b2e5 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.cpp @@ -181,13 +181,13 @@ void Query::setColArrayMode(size_t skipSize, size_t numElements) impl->setColArrayMode(skipSize, numElements); } -bool Query::bindCol(BindableInt32 &buffer) +bool Query::bindCol(BindableLong &buffer) { NOT_NULL(impl); return impl->bindCol(buffer); } -bool Query::bindParameter(BindableInt32 &buffer) +bool Query::bindParameter(BindableLong &buffer) { NOT_NULL(impl); return impl->bindParameter(buffer); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h index d316bceed..e21e24c48 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQuery.h @@ -17,7 +17,7 @@ namespace DB { class Session; class QueryImpl; - class BindableInt32; + class BindableLong; class BindableVarray; class Query @@ -70,8 +70,8 @@ namespace DB { */ void setColArrayMode(size_t skipSize, size_t numElements); - bool bindCol(BindableInt32 &buffer); - bool bindParameter(BindableInt32 &buffer); + bool bindCol(BindableLong &buffer); + bool bindParameter(BindableLong &buffer); bool bindCol(BindableDouble &buffer); bool bindParameter(BindableDouble &buffer); bool bindCol(BindableStringBase &buffer); diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h index 1e13658ea..a978dd771 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbQueryImplementation.h @@ -19,7 +19,7 @@ namespace DB class BindableBool; class BindableDouble; class BindableInt64; - class BindableInt32; + class BindableLong; class BindableStringBase; class BindableUnicodeBase; class BindableVarray; @@ -54,8 +54,8 @@ namespace DB virtual void setColArrayMode(size_t skipSize, size_t numElements)=0; - virtual bool bindCol(BindableInt32 &buffer) =0; - virtual bool bindParameter(BindableInt32 &buffer) =0; + virtual bool bindCol(BindableLong &buffer) =0; + virtual bool bindParameter(BindableLong &buffer) =0; virtual bool bindCol(BindableDouble &buffer) =0; virtual bool bindParameter(BindableDouble &buffer) =0; virtual bool bindCol(BindableStringBase &buffer) =0; diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTaskRequest.cpp b/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTaskRequest.cpp index d4b6f7104..016bb8896 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTaskRequest.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTaskRequest.cpp @@ -48,7 +48,7 @@ void DB::TaskRequest::workerThreadLoop(DB::Session *ses) { if (qry.fetch() > 0) { - int result; + long result; qry.value.getValue(result); if (result == 1) { diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h b/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h index 11556487b..cca5e8912 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/queue/DbTestQuery.h @@ -7,7 +7,7 @@ class DBTestQuery : public DB::Query { public: - DB::BindableInt32 value; + DB::BindableLong value; DBTestQuery(); virtual void getSQL(std::string &sql); diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp index feb1e7cb3..f9d354938 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp @@ -13,6 +13,7 @@ #include "sharedFoundation/NetworkId.h" #include "sharedLog/Log.h" #include +#include // ====================================================================== diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp index 46e23a9cd..b9bdce1df 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp @@ -9,6 +9,7 @@ #include "OciQueryImplementation.h" #include +#include #include "sharedDatabaseInterface/Bindable.h" #include "sharedDatabaseInterface/DbBindableVarray.h" @@ -448,7 +449,7 @@ size_t DB::OCIQueryImpl::BindRec::getLengthSkipSize() // ====================================================================== -bool DB::OCIQueryImpl::bindCol(BindableInt32 &buffer) +bool DB::OCIQueryImpl::bindCol(BindableLong &buffer) { BindRec *br=addBindRec(buffer); @@ -478,7 +479,7 @@ bool DB::OCIQueryImpl::bindCol(BindableInt32 &buffer) // ---------------------------------------------------------------------- -bool DB::OCIQueryImpl::bindParameter(BindableInt32 &buffer) +bool DB::OCIQueryImpl::bindParameter(BindableLong &buffer) { BindRec *br=addBindRec(buffer); diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h index 9276c849e..6cf41e37b 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.h @@ -50,8 +50,8 @@ namespace DB virtual void setColArrayMode(size_t skipSize, size_t numElements); - virtual bool bindCol(BindableInt32 &buffer); - virtual bool bindParameter(BindableInt32 &buffer); + virtual bool bindCol(BindableLong &buffer); + virtual bool bindParameter(BindableLong &buffer); virtual bool bindCol(BindableDouble &buffer); virtual bool bindParameter(BindableDouble &buffer); virtual bool bindCol(BindableStringBase &buffer); diff --git a/engine/shared/library/sharedFile/src/shared/FileManifest.cpp b/engine/shared/library/sharedFile/src/shared/FileManifest.cpp index 26117a633..ebbd84572 100755 --- a/engine/shared/library/sharedFile/src/shared/FileManifest.cpp +++ b/engine/shared/library/sharedFile/src/shared/FileManifest.cpp @@ -216,8 +216,10 @@ void FileManifest::remove() DEBUG_REPORT_LOG_PRINT((i->second)->accesses <= s_accessThreshold, ("FileManifestAccessReport:\t%s\t%s\t%i\t%i\n", ((i->second)->name).c_str(), ((i->second)->scene).c_str(), (i->second)->size, (i->second)->accesses)); // delete the actual entry - delete i->second; - i->second = 0; + if(i->second != 0) { + delete i->second; + i->second = 0; + } } std::sort(manifestEntries.begin(), manifestEntries.end()); @@ -234,8 +236,10 @@ void FileManifest::remove() for (ManifestMap::iterator i = s_manifest.begin(); i != s_manifest.end(); ++i) { // delete the actual entry - delete i->second; - i->second = 0; + if(i->second != 0) { + delete i->second; + i->second = 0; + } } s_transitionVector.clear(); diff --git a/game/server/application/SwgDatabaseServer/src/shared/buffers/IndexedNetworkTableBuffer.h b/game/server/application/SwgDatabaseServer/src/shared/buffers/IndexedNetworkTableBuffer.h index 43595df7a..1ccd6deee 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/buffers/IndexedNetworkTableBuffer.h +++ b/game/server/application/SwgDatabaseServer/src/shared/buffers/IndexedNetworkTableBuffer.h @@ -17,6 +17,7 @@ #include #include #include +#include // ====================================================================== diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h index 0bdc0a646..ff96a9f02 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskBrokenObjectCleanup.h @@ -41,7 +41,7 @@ class TaskBrokenObjectCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableInt32 result; + DB::BindableLong result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h index 7075c4853..2d35ab60e 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMarketAttributesCleanup.h @@ -41,7 +41,7 @@ class TaskMarketAttributesCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableInt32 result; + DB::BindableLong result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h index 549ae6a6b..0efeb8609 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskMessagesCleanup.h @@ -41,7 +41,7 @@ class TaskMessagesCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableInt32 result; + DB::BindableLong result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h index 0a8561f1d..fd324d45e 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskObjvarNameCleanup.h @@ -41,7 +41,7 @@ class TaskObjvarNameCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableInt32 result; + DB::BindableLong result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h index cb097e531..baafd4c2a 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskOrphanedObjectCleanup.h @@ -41,7 +41,7 @@ class TaskOrphanedObjectCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableInt32 result; + DB::BindableLong result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h index 68348d43b..e715be43b 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h +++ b/game/server/application/SwgDatabaseServer/src/shared/cleanup/TaskVendorObjectCleanup.h @@ -41,7 +41,7 @@ class TaskVendorObjectCleanup : public DB::TaskRequest virtual bool bindColumns(); virtual QueryMode getExecutionMode() const; - DB::BindableInt32 result; + DB::BindableLong result; private: DataCleanupQuery(const DataCleanupQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp index 756c06b86..dc9f96fac 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp @@ -1033,7 +1033,7 @@ void SwgSnapshot::encodeComponents(const NetworkId &objectId, Archive::ByteStrea // ---------------------------------------------------------------------- void -SwgSnapshot::decodeLocation(Archive::ReadIterator &data, DB::BindableDouble &x, DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableInt32 &planet) const { +SwgSnapshot::decodeLocation(Archive::ReadIterator &data, DB::BindableDouble &x, DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableLong &planet) const { Location temp; Archive::get(data, temp); Vector vec = temp.getCoordinates(); @@ -1047,7 +1047,7 @@ SwgSnapshot::decodeLocation(Archive::ReadIterator &data, DB::BindableDouble &x, // ---------------------------------------------------------------------- void -SwgSnapshot::encodeLocation(Archive::ByteStream &data, const DB::BindableDouble &x, const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableInt32 &planet) const { +SwgSnapshot::encodeLocation(Archive::ByteStream &data, const DB::BindableDouble &x, const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableLong &planet) const { Location temp(Vector(static_cast(x.getValue()), static_cast(y.getValue()), static_cast(z.getValue())), cell.getValue(), planet.getValue()); Archive::put(data, temp); } diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h index 2f6e6c3a6..e1b77dba9 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h @@ -419,7 +419,7 @@ class SwgSnapshot : public Snapshot void decodeVector (Archive::ReadIterator &data, DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z) const; void decodeMatchMakingId (Archive::ReadIterator &data, DB::BufferString &column) const; void decodeComponents (NetworkId const & objectId, Archive::ReadIterator &data, bool isBaseline); - void decodeLocation (Archive::ReadIterator &data, DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableInt32 &planet) const; + void decodeLocation (Archive::ReadIterator &data, DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableNetworkId &cell, DB::BindableLong &planet) const; void decodeWaypoints (const NetworkId &objectId, Archive::ReadIterator &data, bool isBaseline); void decodeSingleWaypoint (const NetworkId &objectId, Archive::ReadIterator &data, bool isBaseline); void decodeQuests (NetworkId const & networkId, Archive::ReadIterator &data, DB::BufferString &part1, DB::BufferString &part2, DB::BufferString &part3, DB::BufferString &part4) const; @@ -439,7 +439,7 @@ class SwgSnapshot : public Snapshot void encodeVector (Archive::ByteStream &data, const DB::BindableDouble &x, const DB::BindableDouble &y, const DB::BindableDouble &z) const; void encodeMatchMakingId (Archive::ByteStream &data, const DB::BufferString &column) const; void encodeComponents (const NetworkId &objectId, Archive::ByteStream &data) const; - void encodeLocation (Archive::ByteStream &data, const DB::BindableDouble &x,const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableInt32 &planet) const; + void encodeLocation (Archive::ByteStream &data, const DB::BindableDouble &x,const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableNetworkId &cell, const DB::BindableLong &planet) const; void encodeWaypoints (const NetworkId & objectId, Archive::ByteStream &data) const; void encodeSingleWaypoint (const NetworkId & objectId, Archive::ByteStream &data) const; void encodeQuests (Archive::ByteStream &data, DB::BufferString const &part1, DB::BufferString const &part2, DB::BufferString const &part3, DB::BufferString const &part4) const; diff --git a/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template b/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template index 21d290cc6..327283d0e 100644 --- a/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template +++ b/game/server/application/SwgDatabaseServer/src/shared/generated/ObjectQueries_h.template @@ -45,7 +45,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayString m_region_names; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class BattlefieldMarkerObjectQuerySelect : public DB::Query @@ -95,7 +95,7 @@ private: DB::BindableVarrayNumber m_time_last_checkeds; DB::BindableVarrayString m_is_publics; DB::BindableVarrayNumber m_city_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class BuildingObjectQuerySelect : public DB::Query @@ -143,7 +143,7 @@ private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_cell_numbers; DB::BindableVarrayString m_is_publics; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class CellObjectQuerySelect : public DB::Query @@ -189,7 +189,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class CityObjectQuerySelect : public DB::Query @@ -274,7 +274,7 @@ private: DB::BindableVarrayNumber m_ws_xs; DB::BindableVarrayNumber m_ws_ys; DB::BindableVarrayNumber m_ws_zs; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class CreatureObjectQuerySelect : public DB::Query @@ -320,7 +320,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class FactoryObjectQuerySelect : public DB::Query @@ -366,7 +366,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class GuildObjectQuerySelect : public DB::Query @@ -419,7 +419,7 @@ private: DB::BindableVarrayString m_hopper_resources; DB::BindableVarrayNumber m_hopper_amounts; DB::BindableVarrayString m_resource_types; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class HarvesterInstallationObjectQuerySelect : public DB::Query @@ -471,7 +471,7 @@ private: DB::BindableVarrayNumber m_activate_start_times; DB::BindableVarrayNumber m_powers; DB::BindableVarrayNumber m_power_rates; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class InstallationObjectQuerySelect : public DB::Query @@ -518,7 +518,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_counts; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class IntangibleObjectQuerySelect : public DB::Query @@ -569,7 +569,7 @@ private: DB::BindableVarrayNumber m_items_per_containers; DB::BindableVarrayNumber m_manufacture_times; DB::BindableVarrayNumber m_draft_schematics; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class ManufactureSchematicObjectQuerySelect : public DB::Query @@ -615,7 +615,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class ManufactureInstallationObjectQuerySelect : public DB::Query @@ -684,7 +684,7 @@ private: DB::BindableVarrayNumber m_mission_types; DB::BindableVarrayNumber m_target_appearances; DB::BindableVarrayString m_target_names; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class MissionObjectQuerySelect : public DB::Query @@ -731,7 +731,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayString m_planet_names; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class PlanetObjectQuerySelect : public DB::Query @@ -813,7 +813,7 @@ private: DB::BindableVarrayString m_show_backpacks; DB::BindableVarrayString m_show_helmets; DB::BindableVarrayString m_collections2s; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class PlayerObjectQuerySelect : public DB::Query @@ -888,7 +888,7 @@ private: DB::BindableVarrayString m_task_description11s; DB::BindableVarrayString m_task_title12s; DB::BindableVarrayString m_task_description12s; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class PlayerQuestObjectQuerySelect : public DB::Query @@ -937,7 +937,7 @@ private: DB::BindableVarrayString m_resource_types; DB::BindableVarrayNumber m_quantitys; DB::BindableVarrayString m_sources; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class ResourceContainerObjectQuerySelect : public DB::Query @@ -1034,7 +1034,7 @@ private: DB::BindableVarrayNumber m_cargo_hold_contents_maximums; DB::BindableVarrayNumber m_cargo_hold_contents_currents; DB::BindableVarrayString m_cargo_hold_contentss; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class ShipObjectQuerySelect : public DB::Query @@ -1080,7 +1080,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class StaticObjectQuerySelect : public DB::Query @@ -1139,7 +1139,7 @@ private: DB::BindableVarrayNumber m_conditions; DB::BindableVarrayString m_creator_ids; DB::BindableVarrayNumber m_source_draft_schematics; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class TangibleObjectQuerySelect : public DB::Query @@ -1189,7 +1189,7 @@ private: DB::BindableVarrayString m_target_server_template_names; DB::BindableVarrayString m_target_shared_template_names; DB::BindableVarrayString m_waypoints; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class TokenObjectQuerySelect : public DB::Query @@ -1235,7 +1235,7 @@ public: private: DB::BindableVarrayString m_object_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class UniverseObjectQuerySelect : public DB::Query @@ -1282,7 +1282,7 @@ public: private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_boguss; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class VehicleObjectQuerySelect : public DB::Query @@ -1340,7 +1340,7 @@ private: DB::BindableVarrayNumber m_damage_radiuss; DB::BindableVarrayNumber m_min_ranges; DB::BindableVarrayNumber m_max_ranges; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class WeaponObjectQuerySelect : public DB::Query diff --git a/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template b/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template index 9d4989a04..9589c757b 100644 --- a/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template +++ b/game/server/application/SwgDatabaseServer/src/shared/generated/Schema_h.template @@ -23,38 +23,38 @@ struct PlayerObjectRow : public DB::Row enum {QUEST_DATA_SIZE=4000}; DB::BindableNetworkId object_id; - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId house_id; - DB::BindableInt32 account_num_lots; + DB::BindableLong account_num_lots; DB::BindableBool account_is_outcast; DB::BindableDouble account_cheater_level; - DB::BindableInt32 account_max_lots_adjustment; + DB::BindableLong account_max_lots_adjustment; DB::BindableString<200> personal_profile_id; DB::BindableString<200> character_profile_id; DB::BindableString<200> skill_title; - DB::BindableInt32 born_date; - DB::BindableInt32 played_time; + DB::BindableLong born_date; + DB::BindableLong played_time; DB::BindableDouble force_regen_rate; - DB::BindableInt32 force_power; - DB::BindableInt32 max_force_power; + DB::BindableLong force_power; + DB::BindableLong max_force_power; DB::BindableBitArray<2047> active_quests; DB::BindableBitArray<2047> completed_quests; - DB::BindableInt32 current_quest; + DB::BindableLong current_quest; DB::BindableString quests; - DB::BindableInt32 role_icon_choice; + DB::BindableLong role_icon_choice; DB::BindableString quests2; DB::BindableString quests3; DB::BindableString quests4; DB::BindableString<200> skill_template; DB::BindableString<200> working_skill; - DB::BindableInt32 current_gcw_points; - DB::BindableInt32 current_gcw_rating; - DB::BindableInt32 current_pvp_kills; + DB::BindableLong current_gcw_points; + DB::BindableLong current_gcw_rating; + DB::BindableLong current_pvp_kills; DB::BindableInt64 lifetime_gcw_points; - DB::BindableInt32 max_gcw_imperial_rating; - DB::BindableInt32 max_gcw_rebel_rating; - DB::BindableInt32 lifetime_pvp_kills; - DB::BindableInt32 next_gcw_rating_calc_time; + DB::BindableLong max_gcw_imperial_rating; + DB::BindableLong max_gcw_rebel_rating; + DB::BindableLong lifetime_pvp_kills; + DB::BindableLong next_gcw_rating_calc_time; DB::BindableBitArray<16000> collections; DB::BindableBool show_backpack; DB::BindableBool show_helmet; @@ -80,38 +80,38 @@ struct PlayerObjectRow : public DB::Row struct PlayerObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 station_id; + DB::BindableLong station_id; DB::BindableNetworkId house_id; - DB::BindableInt32 account_num_lots; + DB::BindableLong account_num_lots; DB::BindableBool account_is_outcast; DB::BindableDouble account_cheater_level; - DB::BindableInt32 account_max_lots_adjustment; + DB::BindableLong account_max_lots_adjustment; DB::BufferString personal_profile_id; DB::BufferString character_profile_id; DB::BufferString skill_title; - DB::BindableInt32 born_date; - DB::BindableInt32 played_time; + DB::BindableLong born_date; + DB::BindableLong played_time; DB::BindableDouble force_regen_rate; - DB::BindableInt32 force_power; - DB::BindableInt32 max_force_power; + DB::BindableLong force_power; + DB::BindableLong max_force_power; DB::BindableBitArray<2047> active_quests; DB::BindableBitArray<2047> completed_quests; - DB::BindableInt32 current_quest; + DB::BindableLong current_quest; DB::BufferString quests; - DB::BindableInt32 role_icon_choice; + DB::BindableLong role_icon_choice; DB::BufferString quests2; DB::BufferString quests3; DB::BufferString quests4; DB::BufferString skill_template; DB::BufferString working_skill; - DB::BindableInt32 current_gcw_points; - DB::BindableInt32 current_gcw_rating; - DB::BindableInt32 current_pvp_kills; + DB::BindableLong current_gcw_points; + DB::BindableLong current_gcw_rating; + DB::BindableLong current_pvp_kills; DB::BindableInt64 lifetime_gcw_points; - DB::BindableInt32 max_gcw_imperial_rating; - DB::BindableInt32 max_gcw_rebel_rating; - DB::BindableInt32 lifetime_pvp_kills; - DB::BindableInt32 next_gcw_rating_calc_time; + DB::BindableLong max_gcw_imperial_rating; + DB::BindableLong max_gcw_rebel_rating; + DB::BindableLong lifetime_pvp_kills; + DB::BindableLong next_gcw_rating_calc_time; DB::BindableBitArray<16000> collections; DB::BindableBool show_backpack; DB::BindableBool show_helmet; @@ -219,10 +219,10 @@ struct PlayerObjectBufferRow : public DB::Row struct ObjectVariableRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 name_id; - DB::BindableInt32 type; + DB::BindableLong name_id; + DB::BindableLong type; DB::BindableString<1000> value; - DB::BindableInt32 detached; + DB::BindableLong detached; virtual void copy(const DB::Row &rhs) { @@ -234,14 +234,14 @@ struct WaypointRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableNetworkId waypoint_id; - DB::BindableInt32 appearance_name_crc; + DB::BindableLong appearance_name_crc; DB::BindableDouble location_x; DB::BindableDouble location_y; DB::BindableDouble location_z; DB::BindableNetworkId location_cell; - DB::BindableInt32 location_scene; + DB::BindableLong location_scene; DB::BindableUnicode<512> name; - DB::BindableInt32 color; + DB::BindableLong color; DB::BindableBool active; DB::BindableBool detached; @@ -255,19 +255,19 @@ struct WaypointRow : public DB::Row struct ArmorRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 layer; - DB::BindableInt32 effectiveness; - DB::BindableInt32 integrity; + DB::BindableLong layer; + DB::BindableLong effectiveness; + DB::BindableLong integrity; DB::BindableString<1000> special_protections; - DB::BindableInt32 encumberance_0; - DB::BindableInt32 encumberance_1; - DB::BindableInt32 encumberance_2; - DB::BindableInt32 encumberance_3; - DB::BindableInt32 encumberance_4; - DB::BindableInt32 encumberance_5; - DB::BindableInt32 encumberance_6; - DB::BindableInt32 encumberance_7; - DB::BindableInt32 encumberance_8; + DB::BindableLong encumberance_0; + DB::BindableLong encumberance_1; + DB::BindableLong encumberance_2; + DB::BindableLong encumberance_3; + DB::BindableLong encumberance_4; + DB::BindableLong encumberance_5; + DB::BindableLong encumberance_6; + DB::BindableLong encumberance_7; + DB::BindableLong encumberance_8; DB::BindableString<255> object_template; virtual void copy(const DB::Row &rhs) @@ -279,19 +279,19 @@ struct ArmorRow : public DB::Row struct ArmorBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 layer; - DB::BindableInt32 effectiveness; - DB::BindableInt32 integrity; + DB::BindableLong layer; + DB::BindableLong effectiveness; + DB::BindableLong integrity; DB::BufferString special_protections; - DB::BindableInt32 encumberance_0; - DB::BindableInt32 encumberance_1; - DB::BindableInt32 encumberance_2; - DB::BindableInt32 encumberance_3; - DB::BindableInt32 encumberance_4; - DB::BindableInt32 encumberance_5; - DB::BindableInt32 encumberance_6; - DB::BindableInt32 encumberance_7; - DB::BindableInt32 encumberance_8; + DB::BindableLong encumberance_0; + DB::BindableLong encumberance_1; + DB::BindableLong encumberance_2; + DB::BindableLong encumberance_3; + DB::BindableLong encumberance_4; + DB::BindableLong encumberance_5; + DB::BindableLong encumberance_6; + DB::BindableLong encumberance_7; + DB::BindableLong encumberance_8; DB::BufferString object_template; ArmorBufferRow() : @@ -396,7 +396,7 @@ struct BattlefieldParticipantRow : public DB::Row { DB::BindableNetworkId region_object_id; DB::BindableNetworkId character_object_id; - DB::BindableInt32 faction_id; + DB::BindableLong faction_id; virtual void copy(const DB::Row &rhs) { @@ -408,7 +408,7 @@ struct BattlefieldParticipantBufferRow : public DB::Row { DB::BindableNetworkId region_object_id; DB::BindableNetworkId character_object_id; - DB::BindableInt32 faction_id; + DB::BindableLong faction_id; BattlefieldParticipantBufferRow() : region_object_id(), @@ -467,10 +467,10 @@ struct BountyHunterTargetBufferRow : public DB::Row struct BuildingObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 maintenance_cost; + DB::BindableLong maintenance_cost; DB::BindableDouble time_last_checked; DB::BindableBool is_public; - DB::BindableInt32 city_id; + DB::BindableLong city_id; virtual void copy(const DB::Row &rhs) { @@ -491,10 +491,10 @@ struct BuildingObjectRow : public DB::Row struct BuildingObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 maintenance_cost; + DB::BindableLong maintenance_cost; DB::BindableDouble time_last_checked; DB::BindableBool is_public; - DB::BindableInt32 city_id; + DB::BindableLong city_id; BuildingObjectBufferRow() : object_id(), @@ -533,7 +533,7 @@ struct BuildingObjectBufferRow : public DB::Row struct CellObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 cell_number; + DB::BindableLong cell_number; DB::BindableBool is_public; virtual void copy(const DB::Row &rhs) @@ -555,7 +555,7 @@ struct CellObjectRow : public DB::Row struct CellObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 cell_number; + DB::BindableLong cell_number; DB::BindableBool is_public; CellObjectBufferRow() : @@ -640,7 +640,7 @@ struct CityObjectBufferRow : public DB::Row struct ClockRow : public DB::Row { - DB::BindableInt32 last_save_time; + DB::BindableLong last_save_time; virtual void copy(const DB::Row &rhs) { @@ -650,7 +650,7 @@ struct ClockRow : public DB::Row struct ClockBufferRow : public DB::Row { - DB::BindableInt32 last_save_time; + DB::BindableLong last_save_time; ClockBufferRow() : last_save_time() @@ -673,39 +673,39 @@ struct CreatureObjectRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableDouble scale_factor; DB::BindableInt64 states; - DB::BindableInt32 posture; - DB::BindableInt32 shock_wounds; + DB::BindableLong posture; + DB::BindableLong shock_wounds; DB::BindableNetworkId master_id; - DB::BindableInt32 rank; + DB::BindableLong rank; DB::BindableDouble base_walk_speed; DB::BindableDouble base_run_speed; - DB::BindableInt32 attribute_0; - DB::BindableInt32 attribute_1; - DB::BindableInt32 attribute_2; - DB::BindableInt32 attribute_3; - DB::BindableInt32 attribute_4; - DB::BindableInt32 attribute_5; - DB::BindableInt32 attribute_6; - DB::BindableInt32 attribute_7; - DB::BindableInt32 attribute_8; - DB::BindableInt32 attribute_9; - DB::BindableInt32 attribute_10; - DB::BindableInt32 attribute_11; - DB::BindableInt32 attribute_12; - DB::BindableInt32 attribute_13; - DB::BindableInt32 attribute_14; - DB::BindableInt32 attribute_15; - DB::BindableInt32 attribute_16; - DB::BindableInt32 attribute_17; - DB::BindableInt32 attribute_18; - DB::BindableInt32 attribute_19; - DB::BindableInt32 attribute_20; - DB::BindableInt32 attribute_21; - DB::BindableInt32 attribute_22; - DB::BindableInt32 attribute_23; - DB::BindableInt32 attribute_24; - DB::BindableInt32 attribute_25; - DB::BindableInt32 attribute_26; + DB::BindableLong attribute_0; + DB::BindableLong attribute_1; + DB::BindableLong attribute_2; + DB::BindableLong attribute_3; + DB::BindableLong attribute_4; + DB::BindableLong attribute_5; + DB::BindableLong attribute_6; + DB::BindableLong attribute_7; + DB::BindableLong attribute_8; + DB::BindableLong attribute_9; + DB::BindableLong attribute_10; + DB::BindableLong attribute_11; + DB::BindableLong attribute_12; + DB::BindableLong attribute_13; + DB::BindableLong attribute_14; + DB::BindableLong attribute_15; + DB::BindableLong attribute_16; + DB::BindableLong attribute_17; + DB::BindableLong attribute_18; + DB::BindableLong attribute_19; + DB::BindableLong attribute_20; + DB::BindableLong attribute_21; + DB::BindableLong attribute_22; + DB::BindableLong attribute_23; + DB::BindableLong attribute_24; + DB::BindableLong attribute_25; + DB::BindableLong attribute_26; DB::BindableString<1000> persisted_buffs; DB::BindableDouble ws_x; DB::BindableDouble ws_y; @@ -732,39 +732,39 @@ struct CreatureObjectBufferRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableDouble scale_factor; DB::BindableInt64 states; - DB::BindableInt32 posture; - DB::BindableInt32 shock_wounds; + DB::BindableLong posture; + DB::BindableLong shock_wounds; DB::BindableNetworkId master_id; - DB::BindableInt32 rank; + DB::BindableLong rank; DB::BindableDouble base_walk_speed; DB::BindableDouble base_run_speed; - DB::BindableInt32 attribute_0; - DB::BindableInt32 attribute_1; - DB::BindableInt32 attribute_2; - DB::BindableInt32 attribute_3; - DB::BindableInt32 attribute_4; - DB::BindableInt32 attribute_5; - DB::BindableInt32 attribute_6; - DB::BindableInt32 attribute_7; - DB::BindableInt32 attribute_8; - DB::BindableInt32 attribute_9; - DB::BindableInt32 attribute_10; - DB::BindableInt32 attribute_11; - DB::BindableInt32 attribute_12; - DB::BindableInt32 attribute_13; - DB::BindableInt32 attribute_14; - DB::BindableInt32 attribute_15; - DB::BindableInt32 attribute_16; - DB::BindableInt32 attribute_17; - DB::BindableInt32 attribute_18; - DB::BindableInt32 attribute_19; - DB::BindableInt32 attribute_20; - DB::BindableInt32 attribute_21; - DB::BindableInt32 attribute_22; - DB::BindableInt32 attribute_23; - DB::BindableInt32 attribute_24; - DB::BindableInt32 attribute_25; - DB::BindableInt32 attribute_26; + DB::BindableLong attribute_0; + DB::BindableLong attribute_1; + DB::BindableLong attribute_2; + DB::BindableLong attribute_3; + DB::BindableLong attribute_4; + DB::BindableLong attribute_5; + DB::BindableLong attribute_6; + DB::BindableLong attribute_7; + DB::BindableLong attribute_8; + DB::BindableLong attribute_9; + DB::BindableLong attribute_10; + DB::BindableLong attribute_11; + DB::BindableLong attribute_12; + DB::BindableLong attribute_13; + DB::BindableLong attribute_14; + DB::BindableLong attribute_15; + DB::BindableLong attribute_16; + DB::BindableLong attribute_17; + DB::BindableLong attribute_18; + DB::BindableLong attribute_19; + DB::BindableLong attribute_20; + DB::BindableLong attribute_21; + DB::BindableLong attribute_22; + DB::BindableLong attribute_23; + DB::BindableLong attribute_24; + DB::BindableLong attribute_25; + DB::BindableLong attribute_26; DB::BufferString persisted_buffs; DB::BindableDouble ws_x; DB::BindableDouble ws_y; @@ -878,7 +878,7 @@ struct ExperiencePointRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableString<500> experience_type; - DB::BindableInt32 points; + DB::BindableLong points; virtual void copy(const DB::Row &rhs) { @@ -890,7 +890,7 @@ struct ExperiencePointBufferRow : public DB::Row { DB::BindableNetworkId object_id; DB::BufferString experience_type; - DB::BindableInt32 points; + DB::BindableLong points; ExperiencePointBufferRow() : object_id(), @@ -964,8 +964,8 @@ struct FactoryObjectBufferRow : public DB::Row struct FreeObjectIdRow : public DB::Row { - DB::BindableInt32 start_id; - DB::BindableInt32 end_id; + DB::BindableLong start_id; + DB::BindableLong end_id; virtual void copy(const DB::Row &rhs) { @@ -975,8 +975,8 @@ struct FreeObjectIdRow : public DB::Row struct FreeObjectIdBufferRow : public DB::Row { - DB::BindableInt32 start_id; - DB::BindableInt32 end_id; + DB::BindableLong start_id; + DB::BindableLong end_id; FreeObjectIdBufferRow() : start_id(), @@ -1050,9 +1050,9 @@ struct HarvesterInstallationObjectRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableDouble installed_efficiency; - DB::BindableInt32 max_extraction_rate; + DB::BindableLong max_extraction_rate; DB::BindableDouble current_extraction_rate; - DB::BindableInt32 max_hopper_amount; + DB::BindableLong max_hopper_amount; DB::BindableNetworkId hopper_resource; DB::BindableDouble hopper_amount; DB::BindableNetworkId resource_type; @@ -1077,9 +1077,9 @@ struct HarvesterInstallationObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableDouble installed_efficiency; - DB::BindableInt32 max_extraction_rate; + DB::BindableLong max_extraction_rate; DB::BindableDouble current_extraction_rate; - DB::BindableInt32 max_hopper_amount; + DB::BindableLong max_hopper_amount; DB::BindableNetworkId hopper_resource; DB::BindableDouble hopper_amount; DB::BindableNetworkId resource_type; @@ -1127,7 +1127,7 @@ struct HarvesterInstallationObjectBufferRow : public DB::Row struct InstallationObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 installation_type; + DB::BindableLong installation_type; DB::BindableBool activated; DB::BindableDouble tick_count; DB::BindableDouble activate_start_time; @@ -1153,7 +1153,7 @@ struct InstallationObjectRow : public DB::Row struct InstallationObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 installation_type; + DB::BindableLong installation_type; DB::BindableBool activated; DB::BindableDouble tick_count; DB::BindableDouble activate_start_time; @@ -1201,7 +1201,7 @@ struct InstallationObjectBufferRow : public DB::Row struct IntangibleObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 count; + DB::BindableLong count; virtual void copy(const DB::Row &rhs) { @@ -1222,7 +1222,7 @@ struct IntangibleObjectRow : public DB::Row struct IntangibleObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 count; + DB::BindableLong count; IntangibleObjectBufferRow() : object_id(), @@ -1255,8 +1255,8 @@ struct IntangibleObjectBufferRow : public DB::Row struct LoadbeaconServerMapRow : public DB::Row { DB::BindableString<255> object_template; - DB::BindableInt32 server_id; - DB::BindableInt32 secondary_server_id; + DB::BindableLong server_id; + DB::BindableLong secondary_server_id; virtual void copy(const DB::Row &rhs) { @@ -1267,8 +1267,8 @@ struct LoadbeaconServerMapRow : public DB::Row struct LoadbeaconServerMapBufferRow : public DB::Row { DB::BufferString object_template; - DB::BindableInt32 server_id; - DB::BindableInt32 secondary_server_id; + DB::BindableLong server_id; + DB::BindableLong secondary_server_id; LoadbeaconServerMapBufferRow() : object_template(255), @@ -1345,9 +1345,9 @@ struct ManufactureSchematicObjectRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableNetworkId creator_id; DB::BindableString<127> creator_name; - DB::BindableInt32 items_per_container; + DB::BindableLong items_per_container; DB::BindableDouble manufacture_time; - DB::BindableInt32 draft_schematic; + DB::BindableLong draft_schematic; virtual void copy(const DB::Row &rhs) { @@ -1370,9 +1370,9 @@ struct ManufactureSchematicObjectBufferRow : public DB::Row DB::BindableNetworkId object_id; DB::BindableNetworkId creator_id; DB::BufferString creator_name; - DB::BindableInt32 items_per_container; + DB::BindableLong items_per_container; DB::BindableDouble manufacture_time; - DB::BindableInt32 draft_schematic; + DB::BindableLong draft_schematic; ManufactureSchematicObjectBufferRow() : object_id(), @@ -1416,9 +1416,9 @@ struct MessageRow : public DB::Row DB::BindableNetworkId target; DB::BindableString<50> method; DB::BindableString<4000> data; - DB::BindableInt32 call_time; + DB::BindableLong call_time; DB::BindableBool guaranteed; - DB::BindableInt32 delivery_type; + DB::BindableLong delivery_type; virtual void copy(const DB::Row &rhs) { @@ -1437,9 +1437,9 @@ struct MessageBufferRow : public DB::Row DB::BindableNetworkId target; DB::BufferString method; DB::BufferString data; - DB::BindableInt32 call_time; + DB::BindableLong call_time; DB::BindableBool guaranteed; - DB::BindableInt32 delivery_type; + DB::BindableLong delivery_type; MessageBufferRow() : message_id(), @@ -1477,28 +1477,28 @@ struct MessageBufferRow : public DB::Row struct MissionObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 difficulty; + DB::BindableLong difficulty; DB::BindableDouble end_x; DB::BindableDouble end_y; DB::BindableDouble end_z; DB::BindableNetworkId end_cell; - DB::BindableInt32 end_scene; + DB::BindableLong end_scene; DB::BindableString<127> mission_creator; - DB::BindableInt32 reward; + DB::BindableLong reward; DB::BindableString<100> root_script_name; DB::BindableDouble start_x; DB::BindableDouble start_y; DB::BindableDouble start_z; DB::BindableNetworkId start_cell; - DB::BindableInt32 start_scene; + DB::BindableLong start_scene; DB::BindableString<100> description_table; DB::BindableString<100> description_text; DB::BindableString<100> title_table; DB::BindableString<100> title_text; DB::BindableNetworkId mission_holder_id; - DB::BindableInt32 status; - DB::BindableInt32 mission_type; - DB::BindableInt32 target_appearance; + DB::BindableLong status; + DB::BindableLong mission_type; + DB::BindableLong target_appearance; DB::BindableString<127> target_name; virtual void copy(const DB::Row &rhs) @@ -1520,28 +1520,28 @@ struct MissionObjectRow : public DB::Row struct MissionObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 difficulty; + DB::BindableLong difficulty; DB::BindableDouble end_x; DB::BindableDouble end_y; DB::BindableDouble end_z; DB::BindableNetworkId end_cell; - DB::BindableInt32 end_scene; + DB::BindableLong end_scene; DB::BufferString mission_creator; - DB::BindableInt32 reward; + DB::BindableLong reward; DB::BufferString root_script_name; DB::BindableDouble start_x; DB::BindableDouble start_y; DB::BindableDouble start_z; DB::BindableNetworkId start_cell; - DB::BindableInt32 start_scene; + DB::BindableLong start_scene; DB::BufferString description_table; DB::BufferString description_text; DB::BufferString title_table; DB::BufferString title_text; DB::BindableNetworkId mission_holder_id; - DB::BindableInt32 status; - DB::BindableInt32 mission_type; - DB::BindableInt32 target_appearance; + DB::BindableLong status; + DB::BindableLong mission_type; + DB::BindableLong target_appearance; DB::BufferString target_name; MissionObjectBufferRow() : @@ -1626,93 +1626,93 @@ struct ObjectRow : public DB::Row DB::BindableDouble quaternion_x; DB::BindableDouble quaternion_y; DB::BindableDouble quaternion_z; - DB::BindableInt32 node_x; - DB::BindableInt32 node_y; - DB::BindableInt32 node_z; - DB::BindableInt32 type_id; + DB::BindableLong node_x; + DB::BindableLong node_y; + DB::BindableLong node_z; + DB::BindableLong type_id; DB::BindableString<50> scene_id; - DB::BindableInt32 controller_type; - DB::BindableInt32 deleted; + DB::BindableLong controller_type; + DB::BindableLong deleted; DB::BindableString<127> object_name; - DB::BindableInt32 volume; + DB::BindableLong volume; DB::BindableNetworkId contained_by; - DB::BindableInt32 slot_arrangement; + DB::BindableLong slot_arrangement; DB::BindableBool player_controlled; - DB::BindableInt32 cache_version; + DB::BindableLong cache_version; DB::BindableBool load_contents; - DB::BindableInt32 cash_balance; - DB::BindableInt32 bank_balance; + DB::BindableLong cash_balance; + DB::BindableLong bank_balance; DB::BindableDouble complexity; DB::BindableString<500> name_string_table; DB::BindableString<500> name_string_text; - DB::BindableInt32 object_template_id; + DB::BindableLong object_template_id; DB::BindableString<128> static_item_name; - DB::BindableInt32 static_item_version; - DB::BindableInt32 conversion_id; + DB::BindableLong static_item_version; + DB::BindableLong conversion_id; DB::BindableNetworkId load_with; DB::BindableString<50> objvar_0_name; - DB::BindableInt32 objvar_0_type; + DB::BindableLong objvar_0_type; DB::BindableString<50> objvar_0_value; DB::BindableString<50> objvar_1_name; - DB::BindableInt32 objvar_1_type; + DB::BindableLong objvar_1_type; DB::BindableString<50> objvar_1_value; DB::BindableString<50> objvar_2_name; - DB::BindableInt32 objvar_2_type; + DB::BindableLong objvar_2_type; DB::BindableString<50> objvar_2_value; DB::BindableString<50> objvar_3_name; - DB::BindableInt32 objvar_3_type; + DB::BindableLong objvar_3_type; DB::BindableString<50> objvar_3_value; DB::BindableString<50> objvar_4_name; - DB::BindableInt32 objvar_4_type; + DB::BindableLong objvar_4_type; DB::BindableString<50> objvar_4_value; DB::BindableString<50> objvar_5_name; - DB::BindableInt32 objvar_5_type; + DB::BindableLong objvar_5_type; DB::BindableString<50> objvar_5_value; DB::BindableString<50> objvar_6_name; - DB::BindableInt32 objvar_6_type; + DB::BindableLong objvar_6_type; DB::BindableString<50> objvar_6_value; DB::BindableString<50> objvar_7_name; - DB::BindableInt32 objvar_7_type; + DB::BindableLong objvar_7_type; DB::BindableString<50> objvar_7_value; DB::BindableString<50> objvar_8_name; - DB::BindableInt32 objvar_8_type; + DB::BindableLong objvar_8_type; DB::BindableString<50> objvar_8_value; DB::BindableString<50> objvar_9_name; - DB::BindableInt32 objvar_9_type; + DB::BindableLong objvar_9_type; DB::BindableString<50> objvar_9_value; DB::BindableString<50> objvar_10_name; - DB::BindableInt32 objvar_10_type; + DB::BindableLong objvar_10_type; DB::BindableString<50> objvar_10_value; DB::BindableString<50> objvar_11_name; - DB::BindableInt32 objvar_11_type; + DB::BindableLong objvar_11_type; DB::BindableString<50> objvar_11_value; DB::BindableString<50> objvar_12_name; - DB::BindableInt32 objvar_12_type; + DB::BindableLong objvar_12_type; DB::BindableString<50> objvar_12_value; DB::BindableString<50> objvar_13_name; - DB::BindableInt32 objvar_13_type; + DB::BindableLong objvar_13_type; DB::BindableString<50> objvar_13_value; DB::BindableString<50> objvar_14_name; - DB::BindableInt32 objvar_14_type; + DB::BindableLong objvar_14_type; DB::BindableString<50> objvar_14_value; DB::BindableString<50> objvar_15_name; - DB::BindableInt32 objvar_15_type; + DB::BindableLong objvar_15_type; DB::BindableString<50> objvar_15_value; DB::BindableString<50> objvar_16_name; - DB::BindableInt32 objvar_16_type; + DB::BindableLong objvar_16_type; DB::BindableString<50> objvar_16_value; DB::BindableString<50> objvar_17_name; - DB::BindableInt32 objvar_17_type; + DB::BindableLong objvar_17_type; DB::BindableString<50> objvar_17_value; DB::BindableString<50> objvar_18_name; - DB::BindableInt32 objvar_18_type; + DB::BindableLong objvar_18_type; DB::BindableString<50> objvar_18_value; DB::BindableString<50> objvar_19_name; - DB::BindableInt32 objvar_19_type; + DB::BindableLong objvar_19_type; DB::BindableString<50> objvar_19_value; DB::BindableString<2000> script_list; - DB::BindableInt32 container_level; + DB::BindableLong container_level; virtual void copy(const DB::Row &rhs) { @@ -1740,89 +1740,89 @@ struct ObjectBufferRow : public DB::Row DB::BindableDouble quaternion_x; DB::BindableDouble quaternion_y; DB::BindableDouble quaternion_z; - DB::BindableInt32 node_x; - DB::BindableInt32 node_y; - DB::BindableInt32 node_z; - DB::BindableInt32 type_id; + DB::BindableLong node_x; + DB::BindableLong node_y; + DB::BindableLong node_z; + DB::BindableLong type_id; DB::BufferString scene_id; - DB::BindableInt32 controller_type; - DB::BindableInt32 deleted; + DB::BindableLong controller_type; + DB::BindableLong deleted; DB::BufferString object_name; - DB::BindableInt32 volume; + DB::BindableLong volume; DB::BindableNetworkId contained_by; - DB::BindableInt32 slot_arrangement; + DB::BindableLong slot_arrangement; DB::BindableBool player_controlled; - DB::BindableInt32 cache_version; + DB::BindableLong cache_version; DB::BindableBool load_contents; - DB::BindableInt32 cash_balance; - DB::BindableInt32 bank_balance; + DB::BindableLong cash_balance; + DB::BindableLong bank_balance; DB::BindableDouble complexity; DB::BufferString name_string_table; DB::BufferString name_string_text; - DB::BindableInt32 object_template_id; + DB::BindableLong object_template_id; DB::BufferString static_item_name; - DB::BindableInt32 static_item_version; - DB::BindableInt32 conversion_id; + DB::BindableLong static_item_version; + DB::BindableLong conversion_id; DB::BindableNetworkId load_with; DB::BufferString objvar_0_name; - DB::BindableInt32 objvar_0_type; + DB::BindableLong objvar_0_type; DB::BufferString objvar_0_value; DB::BufferString objvar_1_name; - DB::BindableInt32 objvar_1_type; + DB::BindableLong objvar_1_type; DB::BufferString objvar_1_value; DB::BufferString objvar_2_name; - DB::BindableInt32 objvar_2_type; + DB::BindableLong objvar_2_type; DB::BufferString objvar_2_value; DB::BufferString objvar_3_name; - DB::BindableInt32 objvar_3_type; + DB::BindableLong objvar_3_type; DB::BufferString objvar_3_value; DB::BufferString objvar_4_name; - DB::BindableInt32 objvar_4_type; + DB::BindableLong objvar_4_type; DB::BufferString objvar_4_value; DB::BufferString objvar_5_name; - DB::BindableInt32 objvar_5_type; + DB::BindableLong objvar_5_type; DB::BufferString objvar_5_value; DB::BufferString objvar_6_name; - DB::BindableInt32 objvar_6_type; + DB::BindableLong objvar_6_type; DB::BufferString objvar_6_value; DB::BufferString objvar_7_name; - DB::BindableInt32 objvar_7_type; + DB::BindableLong objvar_7_type; DB::BufferString objvar_7_value; DB::BufferString objvar_8_name; - DB::BindableInt32 objvar_8_type; + DB::BindableLong objvar_8_type; DB::BufferString objvar_8_value; DB::BufferString objvar_9_name; - DB::BindableInt32 objvar_9_type; + DB::BindableLong objvar_9_type; DB::BufferString objvar_9_value; DB::BufferString objvar_10_name; - DB::BindableInt32 objvar_10_type; + DB::BindableLong objvar_10_type; DB::BufferString objvar_10_value; DB::BufferString objvar_11_name; - DB::BindableInt32 objvar_11_type; + DB::BindableLong objvar_11_type; DB::BufferString objvar_11_value; DB::BufferString objvar_12_name; - DB::BindableInt32 objvar_12_type; + DB::BindableLong objvar_12_type; DB::BufferString objvar_12_value; DB::BufferString objvar_13_name; - DB::BindableInt32 objvar_13_type; + DB::BindableLong objvar_13_type; DB::BufferString objvar_13_value; DB::BufferString objvar_14_name; - DB::BindableInt32 objvar_14_type; + DB::BindableLong objvar_14_type; DB::BufferString objvar_14_value; DB::BufferString objvar_15_name; - DB::BindableInt32 objvar_15_type; + DB::BindableLong objvar_15_type; DB::BufferString objvar_15_value; DB::BufferString objvar_16_name; - DB::BindableInt32 objvar_16_type; + DB::BindableLong objvar_16_type; DB::BufferString objvar_16_value; DB::BufferString objvar_17_name; - DB::BindableInt32 objvar_17_type; + DB::BindableLong objvar_17_type; DB::BufferString objvar_17_value; DB::BufferString objvar_18_name; - DB::BindableInt32 objvar_18_type; + DB::BindableLong objvar_18_type; DB::BufferString objvar_18_value; DB::BufferString objvar_19_name; - DB::BindableInt32 objvar_19_type; + DB::BindableLong objvar_19_type; DB::BufferString objvar_19_value; DB::BufferString script_list; @@ -2096,8 +2096,8 @@ struct PlayerQuestObjectRow : public DB::Row DB::BindableString<256> title; DB::BindableString<4000> description; DB::BindableNetworkId creator; - DB::BindableInt32 total_tasks; - DB::BindableInt32 difficulty; + DB::BindableLong total_tasks; + DB::BindableLong difficulty; DB::BindableString<128> task_title1; DB::BindableString<4000> task_description1; DB::BindableString<128> task_title2; @@ -2145,8 +2145,8 @@ struct PlayerQuestObjectBufferRow : public DB::Row DB::BufferString title; DB::BufferString description; DB::BindableNetworkId creator; - DB::BindableInt32 total_tasks; - DB::BindableInt32 difficulty; + DB::BindableLong total_tasks; + DB::BindableLong difficulty; DB::BufferString task_title1; DB::BufferString task_description1; DB::BufferString task_title2; @@ -2259,7 +2259,7 @@ struct PlayerQuestObjectBufferRow : public DB::Row struct PropertyListRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 list_id; + DB::BindableLong list_id; DB::BindableString<500> value; virtual void copy(const DB::Row &rhs) @@ -2271,7 +2271,7 @@ struct PropertyListRow : public DB::Row struct PropertyListBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 list_id; + DB::BindableLong list_id; DB::BufferString value; PropertyListBufferRow() : @@ -2298,7 +2298,7 @@ struct ResourceContainerObjectRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableNetworkId resource_type; - DB::BindableInt32 quantity; + DB::BindableLong quantity; DB::BindableNetworkId source; virtual void copy(const DB::Row &rhs) @@ -2321,7 +2321,7 @@ struct ResourceContainerObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; DB::BindableNetworkId resource_type; - DB::BindableInt32 quantity; + DB::BindableLong quantity; DB::BindableNetworkId source; ResourceContainerObjectBufferRow() : @@ -2363,7 +2363,7 @@ struct ResourceTypeRow : public DB::Row DB::BindableString<100> resource_class; DB::BindableString<1024> attributes; DB::BindableString<1024> fractal_seeds; - DB::BindableInt32 depleted_timestamp; + DB::BindableLong depleted_timestamp; virtual void copy(const DB::Row &rhs) { @@ -2378,7 +2378,7 @@ struct ResourceTypeBufferRow : public DB::Row DB::BufferString resource_class; DB::BufferString attributes; DB::BufferString fractal_seeds; - DB::BindableInt32 depleted_timestamp; + DB::BindableLong depleted_timestamp; ResourceTypeBufferRow() : resource_id(), @@ -2409,9 +2409,9 @@ struct ResourceTypeBufferRow : public DB::Row struct ScriptRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 sequence_no; + DB::BindableLong sequence_no; DB::BindableString<100> script; - DB::BindableInt32 detached; + DB::BindableLong detached; virtual void copy(const DB::Row &rhs) { @@ -2422,9 +2422,9 @@ struct ScriptRow : public DB::Row struct ScriptBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 sequence_no; + DB::BindableLong sequence_no; DB::BufferString script; - DB::BindableInt32 detached; + DB::BindableLong detached; ScriptBufferRow() : object_id(), @@ -2454,7 +2454,7 @@ struct ShipObjectRow : public DB::Row DB::BindableDouble slide_dampener; DB::BindableDouble current_chassis_hit_points; DB::BindableDouble maximum_chassis_hit_points; - DB::BindableInt32 chassis_type; + DB::BindableLong chassis_type; DB::BindableString<400> cmp_armor_hp_maximum; DB::BindableString<400> cmp_armor_hp_current; DB::BindableString<400> cmp_efficiency_general; @@ -2499,8 +2499,8 @@ struct ShipObjectRow : public DB::Row DB::BindableNetworkId installed_dcd; DB::BindableDouble chassis_cmp_mass_maximum; DB::BindableString<400> cmp_creators; - DB::BindableInt32 cargo_hold_contents_maximum; - DB::BindableInt32 cargo_hold_contents_current; + DB::BindableLong cargo_hold_contents_maximum; + DB::BindableLong cargo_hold_contents_current; DB::BindableString<500> cargo_hold_contents; virtual void copy(const DB::Row &rhs) @@ -2525,7 +2525,7 @@ struct ShipObjectBufferRow : public DB::Row DB::BindableDouble slide_dampener; DB::BindableDouble current_chassis_hit_points; DB::BindableDouble maximum_chassis_hit_points; - DB::BindableInt32 chassis_type; + DB::BindableLong chassis_type; DB::BufferString cmp_armor_hp_maximum; DB::BufferString cmp_armor_hp_current; DB::BufferString cmp_efficiency_general; @@ -2570,8 +2570,8 @@ struct ShipObjectBufferRow : public DB::Row DB::BindableNetworkId installed_dcd; DB::BindableDouble chassis_cmp_mass_maximum; DB::BufferString cmp_creators; - DB::BindableInt32 cargo_hold_contents_maximum; - DB::BindableInt32 cargo_hold_contents_current; + DB::BindableLong cargo_hold_contents_maximum; + DB::BindableLong cargo_hold_contents_current; DB::BufferString cargo_hold_contents; ShipObjectBufferRow() : @@ -2755,19 +2755,19 @@ struct StaticObjectBufferRow : public DB::Row struct TangibleObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 max_hit_points; + DB::BindableLong max_hit_points; DB::BindableNetworkId owner_id; DB::BindableBool visible; DB::BindableString<2000> appearance_data; - DB::BindableInt32 interest_radius; - DB::BindableInt32 pvp_type; - DB::BindableInt32 pvp_faction; - DB::BindableInt32 damage_taken; + DB::BindableLong interest_radius; + DB::BindableLong pvp_type; + DB::BindableLong pvp_faction; + DB::BindableLong damage_taken; DB::BindableString<2000> custom_appearance; - DB::BindableInt32 count; - DB::BindableInt32 condition; + DB::BindableLong count; + DB::BindableLong condition; DB::BindableNetworkId creator_id; - DB::BindableInt32 source_draft_schematic; + DB::BindableLong source_draft_schematic; virtual void copy(const DB::Row &rhs) { @@ -2788,19 +2788,19 @@ struct TangibleObjectRow : public DB::Row struct TangibleObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 max_hit_points; + DB::BindableLong max_hit_points; DB::BindableNetworkId owner_id; DB::BindableBool visible; DB::BufferString appearance_data; - DB::BindableInt32 interest_radius; - DB::BindableInt32 pvp_type; - DB::BindableInt32 pvp_faction; - DB::BindableInt32 damage_taken; + DB::BindableLong interest_radius; + DB::BindableLong pvp_type; + DB::BindableLong pvp_faction; + DB::BindableLong damage_taken; DB::BufferString custom_appearance; - DB::BindableInt32 count; - DB::BindableInt32 condition; + DB::BindableLong count; + DB::BindableLong condition; DB::BindableNetworkId creator_id; - DB::BindableInt32 source_draft_schematic; + DB::BindableLong source_draft_schematic; TangibleObjectBufferRow() : object_id(), @@ -2973,7 +2973,7 @@ struct UniverseObjectBufferRow : public DB::Row struct VehicleObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 bogus; + DB::BindableLong bogus; virtual void copy(const DB::Row &rhs) { @@ -2994,7 +2994,7 @@ struct VehicleObjectRow : public DB::Row struct VehicleObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 bogus; + DB::BindableLong bogus; VehicleObjectBufferRow() : object_id(), @@ -3027,15 +3027,15 @@ struct VehicleObjectBufferRow : public DB::Row struct WeaponObjectRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 min_damage; - DB::BindableInt32 max_damage; - DB::BindableInt32 damage_type; - DB::BindableInt32 elemental_type; - DB::BindableInt32 elemental_value; + DB::BindableLong min_damage; + DB::BindableLong max_damage; + DB::BindableLong damage_type; + DB::BindableLong elemental_type; + DB::BindableLong elemental_value; DB::BindableDouble attack_speed; DB::BindableDouble wound_chance; - DB::BindableInt32 accuracy; - DB::BindableInt32 attack_cost; + DB::BindableLong accuracy; + DB::BindableLong attack_cost; DB::BindableDouble damage_radius; DB::BindableDouble min_range; DB::BindableDouble max_range; @@ -3059,15 +3059,15 @@ struct WeaponObjectRow : public DB::Row struct WeaponObjectBufferRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 min_damage; - DB::BindableInt32 max_damage; - DB::BindableInt32 damage_type; - DB::BindableInt32 elemental_type; - DB::BindableInt32 elemental_value; + DB::BindableLong min_damage; + DB::BindableLong max_damage; + DB::BindableLong damage_type; + DB::BindableLong elemental_type; + DB::BindableLong elemental_value; DB::BindableDouble attack_speed; DB::BindableDouble wound_chance; - DB::BindableInt32 accuracy; - DB::BindableInt32 attack_cost; + DB::BindableLong accuracy; + DB::BindableLong attack_cost; DB::BindableDouble damage_radius; DB::BindableDouble min_range; DB::BindableDouble max_range; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h index 3f2a06ed9..0284094be 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/BountyHunterTargetQuery.h @@ -41,7 +41,7 @@ namespace DBQuery private: DB::BindableVarrayString m_object_ids; DB::BindableVarrayString m_target_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h index 7f50272cc..55469272f 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.h @@ -51,7 +51,7 @@ class AuctionLocationsQuery : public DatabaseProcessQuery DB::BindableVarrayNumber m_status; DB::BindableVarrayString m_search_enabled; DB::BindableVarrayNumber m_entrance_charge; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class AuctionLocationsQuerySelect : public DB::Query @@ -114,7 +114,7 @@ class MarketAuctionsQuery : public DatabaseProcessQuery DB::BindableVarrayNumber m_actives; DB::BindableVarrayNumber m_item_sizes; DB::BindableVarrayNumber m_object_template_ids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class MarketAuctionsQuerySelect : public DB::Query @@ -165,7 +165,7 @@ class MarketAuctionBidsQuery : public DatabaseProcessQuery DB::BindableVarrayString m_bidder_ids; DB::BindableVarrayNumber m_bids; DB::BindableVarrayNumber m_max_proxy_bids; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class MarketAuctionBidsQuerySelect : public DB::Query @@ -215,7 +215,7 @@ class MarketAuctionsAttributesQuery : public DatabaseProcessQuery DB::BindableVarrayString m_item_ids; DB::BindableVarrayString m_attribute_names; DB::BindableVarrayString m_attribute_values; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; // ====================================================================== diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h index 0e155ad36..f9ed09f9b 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesSchema.h @@ -23,14 +23,14 @@ struct AuctionLocationsRow : public DB::Row DB::BindableNetworkId location_id; DB::BindableString<256> location_name; DB::BindableNetworkId owner_id; - DB::BindableInt32 sales_tax; + DB::BindableLong sales_tax; DB::BindableNetworkId sales_tax_bank_id; - DB::BindableInt32 empty_date; - DB::BindableInt32 last_access_date; - DB::BindableInt32 inactive_date; - DB::BindableInt32 status; + DB::BindableLong empty_date; + DB::BindableLong last_access_date; + DB::BindableLong inactive_date; + DB::BindableLong status; DB::BindableBool search_enabled; - DB::BindableInt32 entrance_charge; + DB::BindableLong entrance_charge; virtual void copy(const DB::Row &rhs) { @@ -71,17 +71,17 @@ struct MarketAuctionsRow : public DB::Row DB::BindableNetworkId owner_id; DB::BindableNetworkId creator_id; DB::BindableNetworkId location_id; - DB::BindableInt32 min_bid; - DB::BindableInt32 buy_now_price; - DB::BindableInt32 auction_timer; + DB::BindableLong min_bid; + DB::BindableLong buy_now_price; + DB::BindableLong auction_timer; DB::BindableString<4000> oob; DB::BindableUnicode<1024>user_description; - DB::BindableInt32 category; + DB::BindableLong category; DB::BindableUnicode<1024>item_name; - DB::BindableInt32 item_timer; - DB::BindableInt32 active; - DB::BindableInt32 item_size; - DB::BindableInt32 object_template_id; + DB::BindableLong item_timer; + DB::BindableLong active; + DB::BindableLong item_size; + DB::BindableLong object_template_id; virtual void copy(const DB::Row &rhs) { @@ -155,7 +155,7 @@ struct MarketAuctionsRowUpdate : public DB::Row DB::BindableNetworkId item_id; DB::BindableNetworkId owner_id; - DB::BindableInt32 active; + DB::BindableLong active; virtual void copy(const DB::Row &rhs) { @@ -193,8 +193,8 @@ struct MarketAuctionBidsRow : public DB::Row DB::BindableNetworkId item_id; DB::BindableNetworkId bidder_id; - DB::BindableInt32 bid; - DB::BindableInt32 max_proxy_bid; + DB::BindableLong bid; + DB::BindableLong max_proxy_bid; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h index 44fe7b1ca..614e36ca1 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/DeleteDemandLoadedContainerQuery.h @@ -38,7 +38,7 @@ namespace DBQuery private: DB::BindableVarrayString object_ids; DB::BindableVarrayNumber reasons; - DB::BindableInt32 num_items; + DB::BindableLong num_items; private: DeleteDemandLoadedContainerQuery(const DeleteDemandLoadedContainerQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h index 188ff1df2..21eb81f12 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/LocationQuery.h @@ -32,9 +32,9 @@ namespace DBQuery public: DB::BindableNetworkId object_id; - DB::BindableInt32 list_id; - DB::BindableInt32 index; - DB::BindableInt32 action; + DB::BindableLong list_id; + DB::BindableLong index; + DB::BindableLong action; DB::BindableUnicode<255> name; DB::BindableString<50> scene; DB::BindableDouble x; @@ -55,8 +55,8 @@ namespace DBQuery struct LocationRow { DB::BindableNetworkId object_id; - DB::BindableInt32 list_id; - DB::BindableInt32 index; + DB::BindableLong list_id; + DB::BindableLong index; DB::BindableUnicode<255> name; DB::BindableString<50> scene; DB::BindableDouble x; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h index 517cfea6c..61fa760e2 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ManufactureSchematicAttributeQuery.h @@ -21,7 +21,7 @@ namespace DBSchema struct ManufactureSchematicAttributeRow : public DB::Row { DB::BindableNetworkId object_id; - DB::BindableInt32 action; + DB::BindableLong action; DB::BindableString<500> attribute_type; DB::BindableDouble value; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h index 2f52712ba..dcd9cf559 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/MessageQuery.h @@ -46,8 +46,8 @@ namespace DBQuery DB::BindableVarrayNumber m_call_times; DB::BindableVarrayString m_guaranteeds; DB::BindableVarrayNumber m_delivery_types; - DB::BindableInt32 m_numItems; - DB::BindableInt32 m_enableDatabaseLogging; + DB::BindableLong m_numItems; + DB::BindableLong m_enableDatabaseLogging; private: SaveMessageQuery(const SaveMessageQuery&); // disable @@ -74,8 +74,8 @@ namespace DBQuery private: DB::BindableVarrayString m_message_ids; - DB::BindableInt32 m_numItems; - DB::BindableInt32 m_enableDatabaseLogging; + DB::BindableLong m_numItems; + DB::BindableLong m_enableDatabaseLogging; private: AckMessageQuery(const AckMessageQuery&); // disable @@ -94,9 +94,9 @@ namespace DBQuery DB::BindableNetworkId object_id; DB::BindableString<50> method; DB::BindableString<4000> packed_data; - DB::BindableInt32 call_time; + DB::BindableLong call_time; DB::BindableBool guaranteed; - DB::BindableInt32 delivery_type; + DB::BindableLong delivery_type; }; public: diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h index aeec7b3cd..44aef98fe 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectVariableQueries.h @@ -47,7 +47,7 @@ namespace DBQuery DB::BindableVarrayNumber m_nameIds; DB::BindableVarrayNumber m_types; DB::BindableVarrayString m_values; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class AddObjectVariableQuery : public GenericObjectVariableQuery @@ -93,7 +93,7 @@ namespace DBQuery private: DB::BindableVarrayString m_objectIds; DB::BindableVarrayNumber m_nameIds; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; /** diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h index d3640f9f6..2817fe3d8 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.h @@ -135,7 +135,7 @@ namespace DBQuery DB::BindableVarrayString m_objvar_19_values; DB::BindableVarrayString m_script_lists; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; class ObjectsTableQuerySelect : public DB::Query diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp b/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp index d1d2b1e5d..e70e9a61d 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/OfflineMoneyCustomPersistStep.cpp @@ -49,7 +49,7 @@ namespace OfflineMoneyCustomPersistStepNamespace private: DB::BindableNetworkId m_sourceObject; - DB::BindableInt32 m_amount; + DB::BindableLong m_amount; DB::BindableBool m_result; private: diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h index 76e363d47..32a49ffa1 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/PropertyListQuery.h @@ -30,8 +30,8 @@ namespace DBSchema }; DB::BindableNetworkId object_id; - DB::BindableInt32 list_id; - DB::BindableInt32 operation; + DB::BindableLong list_id; + DB::BindableLong operation; DB::BindableString<500> value; //TODO: size virtual void copy(const DB::Row &rhs) @@ -67,9 +67,9 @@ namespace DBQuery DB::BindableVarrayString m_object_ids; DB::BindableVarrayNumber m_list_ids; DB::BindableVarrayString m_values; - DB::BindableInt32 m_operations; - DB::BindableInt32 m_numItems; - DB::BindableInt32 m_enableDatabaseLogging; + DB::BindableLong m_operations; + DB::BindableLong m_numItems; + DB::BindableLong m_enableDatabaseLogging; PropertyListQuery(const PropertyListQuery&); // disable PropertyListQuery& operator=(const PropertyListQuery&); // disable diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h index 5b1103fad..3a364ddf1 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.h @@ -45,7 +45,7 @@ namespace DBQuery DB::BindableVarrayString m_attributes; DB::BindableVarrayString m_fractal_seeds; DB::BindableVarrayNumber m_depleted_timestamps; - DB::BindableInt32 m_numItems; + DB::BindableLong m_numItems; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h b/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h index 66b950e7f..b0514a7e9 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/SkillQuery.h @@ -28,8 +28,8 @@ namespace DBSchema }; DB::BindableNetworkId object_id; - DB::BindableInt32 index; - DB::BindableInt32 operation; + DB::BindableLong index; + DB::BindableLong operation; DB::BindableString<500> skill; //TODO: size virtual void copy(const DB::Row &rhs) diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h index 0ca44a375..418710dfc 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetAuctionList.h @@ -28,20 +28,20 @@ namespace DBSchema struct AuctionRow : public DB::Row { DB::BindableNetworkId creatorId; - DB::BindableInt32 minBid; - DB::BindableInt32 auctionTimer; - DB::BindableInt32 buyNowPrice; + DB::BindableLong minBid; + DB::BindableLong auctionTimer; + DB::BindableLong buyNowPrice; DB::BindableUnicode<1024> userDescription; DB::BindableString<4000> oob; DB::BindableNetworkId locationId; DB::BindableNetworkId itemId; - DB::BindableInt32 category; - DB::BindableInt32 itemTimer; + DB::BindableLong category; + DB::BindableLong itemTimer; DB::BindableUnicode<1024> itemName; DB::BindableNetworkId ownerId; - DB::BindableInt32 active; - DB::BindableInt32 itemSize; - DB::BindableInt32 itemTemplateId; + DB::BindableLong active; + DB::BindableLong itemSize; + DB::BindableLong itemTemplateId; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h index adb4f6eb9..021147a3c 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetBidList.h @@ -27,8 +27,8 @@ namespace DBSchema { DB::BindableNetworkId itemId; DB::BindableNetworkId bidderId; - DB::BindableInt32 bid; - DB::BindableInt32 maxProxyBid; + DB::BindableLong bid; + DB::BindableLong maxProxyBid; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h index 198717237..4529ad903 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskGetLocationList.h @@ -28,14 +28,14 @@ namespace DBSchema DB::BindableNetworkId locationId; DB::BindableNetworkId ownerId; DB::BindableString<256> locationString; - DB::BindableInt32 salesTax; + DB::BindableLong salesTax; DB::BindableNetworkId salesTaxBankId; - DB::BindableInt32 emptyDate; - DB::BindableInt32 lastAccessDate; - DB::BindableInt32 inactiveDate; - DB::BindableInt32 status; + DB::BindableLong emptyDate; + DB::BindableLong lastAccessDate; + DB::BindableLong inactiveDate; + DB::BindableLong status; DB::BindableBool searchEnabled; - DB::BindableInt32 entranceCharge; + DB::BindableLong entranceCharge; virtual void copy(const DB::Row &rhs) { diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h index 3b11d4c7d..0c85a1d0e 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLoadObjvarNames.h @@ -29,7 +29,7 @@ class TaskLoadObjvarNames : public DB::TaskRequest private: struct ObjvarNameRow { - DB::BindableInt32 name_id; + DB::BindableLong name_id; DB::BindableString<500> name; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h index e34903d41..9723fe220 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskLocateStructure.h @@ -42,10 +42,10 @@ class TaskLocateStructure:public DB::TaskRequest DB::BindableNetworkId item_id; //output: - DB::BindableInt32 x; - DB::BindableInt32 z; + DB::BindableLong x; + DB::BindableLong z; DB::BindableString<50> sceneId; - DB::BindableInt32 found; + DB::BindableLong found; private: LocateStructureQuery(const LocateStructureQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h index 115430096..9d1ccc699 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskMoveToPlayer.h @@ -43,7 +43,7 @@ class TaskMoveToPlayer:public DB::TaskRequest DB::BindableNetworkId player; //output: - DB::BindableInt32 result; + DB::BindableLong result; private: MoveToPlayerQuery(const MoveToPlayerQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h index d0f3eb099..2e043f3d1 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreCharacter.h @@ -43,10 +43,10 @@ class TaskRestoreCharacter:public DB::TaskRequest DB::BindableNetworkId character_id; //output: - DB::BindableInt32 result; + DB::BindableLong result; DB::BindableString<127> character_name; - DB::BindableInt32 account; - DB::BindableInt32 template_id; + DB::BindableLong account; + DB::BindableLong template_id; private: RestoreCharacterQuery(const RestoreCharacterQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h index ffe5bc901..8b04e6bd2 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskRestoreHouse.h @@ -42,7 +42,7 @@ class TaskRestoreHouse:public DB::TaskRequest DB::BindableNetworkId house_id; //output: - DB::BindableInt32 result; + DB::BindableLong result; private: RestoreHouseQuery(const RestoreHouseQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h index e7422d7bb..9dcfc58b8 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskSaveObjvarNames.h @@ -39,7 +39,7 @@ class TaskSaveObjvarNames : public DB::TaskRequest virtual QueryMode getExecutionMode () const; public: - DB::BindableInt32 name_id; + DB::BindableLong name_id; DB::BindableString<500> name; private: diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h index dd5d649fd..c5d08f766 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskUndeleteItem.h @@ -42,7 +42,7 @@ class TaskUndeleteItem:public DB::TaskRequest DB::BindableNetworkId item_id; //output: - DB::BindableInt32 result; + DB::BindableLong result; private: UndeleteItemQuery(const UndeleteItemQuery&); diff --git a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h index 5da1d837b..c9d69a693 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h +++ b/game/server/application/SwgDatabaseServer/src/shared/tasks/TaskVerifyCharacter.h @@ -47,7 +47,7 @@ class TaskVerifyCharacter:public DB::TaskRequest public: // input: - DB::BindableInt32 station_id; //lint !e1925 public data member Suppresed because it's in a private inner class + DB::BindableLong station_id; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableString<50> gold_schema; //lint !e1925 public data member Suppresed because it's in a private inner class @@ -59,7 +59,7 @@ class TaskVerifyCharacter:public DB::TaskRequest DB::BindableDouble x; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableDouble y; //lint !e1925 public data member Suppresed because it's in a private inner class DB::BindableDouble z; //lint !e1925 public data member Suppresed because it's in a private inner class - DB::BindableInt32 containment_flag; + DB::BindableLong containment_flag; private: VerifyCharacterQuery(const VerifyCharacterQuery&); From 1cadfc275bc47b1131617322587c786a39d45d0f Mon Sep 17 00:00:00 2001 From: Cekis Date: Wed, 30 Aug 2023 01:13:07 -0400 Subject: [PATCH 38/46] Added static casts to BindableLongs when storing data --- .../src_oci/DbBindableVarray.cpp | 4 +- .../src_oci/DbBindableVarray.h | 4 +- .../src/shared/queries/CommoditiesQuery.cpp | 46 ++++++------- .../src/shared/queries/ObjectsTableQuery.cpp | 68 +++++++++---------- .../src/shared/queries/ResourceTypeQuery.cpp | 2 +- 5 files changed, 62 insertions(+), 62 deletions(-) diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp index f9d354938..956482bfa 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp @@ -156,7 +156,7 @@ bool BindableVarrayNumber::push_back(int32_t value) } // ---------------------------------------------------------------------- -bool BindableVarrayNumber::push_back(int64 value) +bool BindableVarrayNumber::push_back(int64_t value) { OCINumber buffer; @@ -257,7 +257,7 @@ bool BindableVarrayNumber::push_back(bool IsNULL, int32_t value) } // ---------------------------------------------------------------------- -bool BindableVarrayNumber::push_back(bool IsNULL, int64 value) +bool BindableVarrayNumber::push_back(bool IsNULL, int64_t value) { OCINumber buffer; diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h index 2b3de3803..f29cca66b 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.h @@ -60,11 +60,11 @@ namespace DB bool push_back(bool IsNULL, int16_t value); bool push_back(bool IsNULL, double value); bool push_back(bool IsNULL, int32_t value); - bool push_back(bool IsNULL, int64 value); + bool push_back(bool IsNULL, int64_t value); bool push_back(int16_t value); bool push_back(double value); bool push_back(int32_t value); - bool push_back(int64 value); + bool push_back(int64_t value); virtual std::string outputValue() const; }; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.cpp b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.cpp index f5ae1da4e..c4ce5f64f 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/CommoditiesQuery.cpp @@ -97,28 +97,28 @@ bool AuctionLocationsQuery::addData(const DB::Row *_data) if (!m_location_ids.push_back(myData->location_id.getValueASCII())) return false; if (!m_location_names.push_back(myData->location_name.getValueASCII())) return false; if (!m_owner_ids.push_back(myData->owner_id.isNull(), myData->owner_id.getValueASCII())) return false; - if (!m_sales_taxes.push_back(myData->sales_tax.isNull(), myData->sales_tax.getValue())) return false; + if (!m_sales_taxes.push_back(myData->sales_tax.isNull(), static_cast(myData->sales_tax.getValue()))) return false; if (!m_sales_tax_bank_ids.push_back(myData->sales_tax_bank_id.isNull(), myData->sales_tax_bank_id.getValue())) return false; - if (!m_empty_date.push_back(myData->empty_date.isNull(), myData->empty_date.getValue())) return false; - if (!m_last_access_date.push_back(myData->last_access_date.isNull(), myData->last_access_date.getValue())) return false; - if (!m_inactive_date.push_back(myData->inactive_date.isNull(), myData->inactive_date.getValue())) return false; - if (!m_status.push_back(myData->status.isNull(), myData->status.getValue())) return false; + if (!m_empty_date.push_back(myData->empty_date.isNull(), static_cast(myData->empty_date.getValue()))) return false; + if (!m_last_access_date.push_back(myData->last_access_date.isNull(), static_cast(myData->last_access_date.getValue()))) return false; + if (!m_inactive_date.push_back(myData->inactive_date.isNull(), static_cast(myData->inactive_date.getValue()))) return false; + if (!m_status.push_back(myData->status.isNull(), static_cast(myData->status.getValue()))) return false; if (!m_search_enabled.push_back(myData->search_enabled.isNull(), myData->search_enabled.getValue())) return false; - if (!m_entrance_charge.push_back(myData->entrance_charge.isNull(), myData->entrance_charge.getValue())) return false; + if (!m_entrance_charge.push_back(myData->entrance_charge.isNull(), static_cast(myData->entrance_charge.getValue()))) return false; break; case mode_INSERT: if (!m_location_ids.push_back(myData->location_id.getValueASCII())) return false; if (!m_location_names.push_back(myData->location_name.getValueASCII())) return false; if (!m_owner_ids.push_back(myData->owner_id.isNull(), myData->owner_id.getValueASCII())) return false; - if (!m_sales_taxes.push_back(myData->sales_tax.isNull(), myData->sales_tax.getValue())) return false; + if (!m_sales_taxes.push_back(myData->sales_tax.isNull(), static_cast(myData->sales_tax.getValue()))) return false; if (!m_sales_tax_bank_ids.push_back(myData->sales_tax_bank_id.isNull(), myData->sales_tax_bank_id.getValue())) return false; - if (!m_empty_date.push_back(myData->empty_date.isNull(), myData->empty_date.getValue())) return false; - if (!m_last_access_date.push_back(myData->last_access_date.isNull(), myData->last_access_date.getValue())) return false; - if (!m_inactive_date.push_back(myData->inactive_date.isNull(), myData->inactive_date.getValue())) return false; - if (!m_status.push_back(myData->status.isNull(), myData->status.getValue())) return false; + if (!m_empty_date.push_back(myData->empty_date.isNull(), static_cast(myData->empty_date.getValue()))) return false; + if (!m_last_access_date.push_back(myData->last_access_date.isNull(), static_cast(myData->last_access_date.getValue()))) return false; + if (!m_inactive_date.push_back(myData->inactive_date.isNull(), static_cast(myData->inactive_date.getValue()))) return false; + if (!m_status.push_back(myData->status.isNull(), static_cast(myData->status.getValue()))) return false; if (!m_search_enabled.push_back(myData->search_enabled.isNull(), myData->search_enabled.getValue())) return false; - if (!m_entrance_charge.push_back(myData->entrance_charge.isNull(), myData->entrance_charge.getValue())) return false; + if (!m_entrance_charge.push_back(myData->entrance_charge.isNull(), static_cast(myData->entrance_charge.getValue()))) return false; break; case mode_SELECT: @@ -417,7 +417,7 @@ bool MarketAuctionsQuery::addData(const DB::Row *_data) if (!m_item_ids.push_back(myData->item_id.getValueASCII())) return false; if (!m_owner_ids.push_back(myData->owner_id.getValueASCII())) return false; - if (!m_actives.push_back(myData->active.isNull(), myData->active.getValue())) return false; + if (!m_actives.push_back(myData->active.isNull(), static_cast(myData->active.getValue()))) return false; break; } @@ -430,17 +430,17 @@ bool MarketAuctionsQuery::addData(const DB::Row *_data) if (!m_owner_ids.push_back(myData->owner_id.getValueASCII())) return false; if (!m_creator_ids.push_back(myData->creator_id.isNull(), myData->creator_id.getValueASCII())) return false; if (!m_location_ids.push_back(myData->location_id.getValueASCII())) return false; - if (!m_min_bids.push_back(myData->min_bid.isNull(), myData->min_bid.getValue())) return false; - if (!m_buy_now_prices.push_back(myData->buy_now_price.isNull(), myData->buy_now_price.getValue())) return false; - if (!m_auction_timers.push_back(myData->auction_timer.isNull(), myData->auction_timer.getValue())) return false; + if (!m_min_bids.push_back(myData->min_bid.isNull(), static_cast(myData->min_bid.getValue()))) return false; + if (!m_buy_now_prices.push_back(myData->buy_now_price.isNull(), static_cast(myData->buy_now_price.getValue()))) return false; + if (!m_auction_timers.push_back(myData->auction_timer.isNull(), static_cast(myData->auction_timer.getValue()))) return false; if (!m_oobs.push_back(myData->oob.isNull(), myData->oob.getValueASCII())) return false; if (!m_user_descriptions.push_back(myData->user_description.isNull(), myData->user_description.getValue())) return false; - if (!m_categories.push_back(myData->category.isNull(), myData->category.getValue())) return false; + if (!m_categories.push_back(myData->category.isNull(), static_cast(myData->category.getValue()))) return false; if (!m_item_names.push_back(myData->item_name.isNull(), myData->item_name.getValue())) return false; - if (!m_item_timers.push_back(myData->item_timer.isNull(), myData->item_timer.getValue())) return false; - if (!m_actives.push_back(myData->active.isNull(), myData->active.getValue())) return false; - if (!m_item_sizes.push_back(myData->item_size.isNull(), myData->item_size.getValue())) return false; - if (!m_object_template_ids.push_back(myData->object_template_id.isNull(), myData->object_template_id.getValue())) return false; + if (!m_item_timers.push_back(myData->item_timer.isNull(), static_cast(myData->item_timer.getValue()))) return false; + if (!m_actives.push_back(myData->active.isNull(), static_cast(myData->active.getValue()))) return false; + if (!m_item_sizes.push_back(myData->item_size.isNull(), static_cast(myData->item_size.getValue()))) return false; + if (!m_object_template_ids.push_back(myData->object_template_id.isNull(), static_cast(myData->object_template_id.getValue()))) return false; break; } @@ -724,8 +724,8 @@ bool MarketAuctionBidsQuery::addData(const DB::Row *_data) case mode_INSERT: if (!m_item_ids.push_back(myData->item_id.getValueASCII())) return false; if (!m_bidder_ids.push_back(myData->bidder_id.getValueASCII())) return false; - if (!m_bids.push_back(myData->bid.getValue())) return false; - if (!m_max_proxy_bids.push_back(myData->max_proxy_bid.isNull(), myData->max_proxy_bid.getValue())) return false; + if (!m_bids.push_back(static_cast(myData->bid.getValue()))) return false; + if (!m_max_proxy_bids.push_back(myData->max_proxy_bid.isNull(), static_cast(myData->max_proxy_bid.getValue()))) return false; break; case mode_SELECT: diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.cpp b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.cpp index 11624d221..3d41f50f5 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ObjectsTableQuery.cpp @@ -160,89 +160,89 @@ bool ObjectsTableQuery::addData(const DB::Row *_data) if (!m_quaternion_xs.push_back(myData->quaternion_x.isNull(), myData->quaternion_x.getValue())) return false; if (!m_quaternion_ys.push_back(myData->quaternion_y.isNull(), myData->quaternion_y.getValue())) return false; if (!m_quaternion_zs.push_back(myData->quaternion_z.isNull(), myData->quaternion_z.getValue())) return false; - if (!m_node_xs.push_back(myData->node_x.isNull(), myData->node_x.getValue())) return false; - if (!m_node_ys.push_back(myData->node_y.isNull(), myData->node_y.getValue())) return false; - if (!m_node_zs.push_back(myData->node_z.isNull(), myData->node_z.getValue())) return false; - if (!m_type_ids.push_back(myData->type_id.isNull(), myData->type_id.getValue())) return false; + if (!m_node_xs.push_back(myData->node_x.isNull(), static_cast(myData->node_x.getValue()))) return false; + if (!m_node_ys.push_back(myData->node_y.isNull(), static_cast(myData->node_y.getValue()))) return false; + if (!m_node_zs.push_back(myData->node_z.isNull(), static_cast(myData->node_z.getValue()))) return false; + if (!m_type_ids.push_back(myData->type_id.isNull(), static_cast(myData->type_id.getValue()))) return false; if (!m_scene_ids.push_back(myData->scene_id.getValueASCII())) return false; - if (!m_controller_types.push_back(myData->controller_type.isNull(), myData->controller_type.getValue())) return false; - if (!m_deleteds.push_back(myData->deleted.isNull(), myData->deleted.getValue())) return false; + if (!m_controller_types.push_back(myData->controller_type.isNull(), static_cast(myData->controller_type.getValue()))) return false; + if (!m_deleteds.push_back(myData->deleted.isNull(), static_cast(myData->deleted.getValue()))) return false; if (!m_object_names.push_back(myData->object_name.getValueASCII())) return false; - if (!m_volumes.push_back(myData->volume.isNull(), myData->volume.getValue())) return false; + if (!m_volumes.push_back(myData->volume.isNull(), static_cast(myData->volume.getValue()))) return false; if (!m_contained_bys.push_back(myData->contained_by.getValueASCII())) return false; - if (!m_slot_arrangements.push_back(myData->slot_arrangement.isNull(), myData->slot_arrangement.getValue())) return false; + if (!m_slot_arrangements.push_back(myData->slot_arrangement.isNull(), static_cast(myData->slot_arrangement.getValue()))) return false; if (!m_player_controlleds.push_back(myData->player_controlled.getValueASCII())) return false; - if (!m_cache_versions.push_back(myData->cache_version.isNull(), myData->cache_version.getValue())) return false; + if (!m_cache_versions.push_back(myData->cache_version.isNull(), static_cast(myData->cache_version.getValue()))) return false; if (!m_load_contentss.push_back(myData->load_contents.getValueASCII())) return false; - if (!m_cash_balances.push_back(myData->cash_balance.isNull(), myData->cash_balance.getValue())) return false; - if (!m_bank_balances.push_back(myData->bank_balance.isNull(), myData->bank_balance.getValue())) return false; + if (!m_cash_balances.push_back(myData->cash_balance.isNull(), static_cast(myData->cash_balance.getValue()))) return false; + if (!m_bank_balances.push_back(myData->bank_balance.isNull(), static_cast(myData->bank_balance.getValue()))) return false; if (!m_complexitys.push_back(myData->complexity.isNull(), myData->complexity.getValue())) return false; if (!m_name_string_tables.push_back(myData->name_string_table.getValueASCII())) return false; if (!m_name_string_texts.push_back(myData->name_string_text.getValueASCII())) return false; if (!m_static_item_names.push_back(myData->static_item_name.getValueASCII())) return false; - if (!m_static_item_versions.push_back(myData->static_item_version.isNull(), myData->static_item_version.getValue())) return false; - if (!m_conversion_ids.push_back(myData->conversion_id.isNull(), myData->conversion_id.getValue())) return false; - if (!m_object_template_ids.push_back(myData->object_template_id.isNull(), myData->object_template_id.getValue())) return false; + if (!m_static_item_versions.push_back(myData->static_item_version.isNull(), static_cast(myData->static_item_version.getValue()))) return false; + if (!m_conversion_ids.push_back(myData->conversion_id.isNull(), static_cast(myData->conversion_id.getValue()))) return false; + if (!m_object_template_ids.push_back(myData->object_template_id.isNull(), static_cast(myData->object_template_id.getValue()))) return false; if (!m_load_withs.push_back(myData->load_with.getValueASCII())) return false; if (!m_objvar_0_names.push_back(myData->objvar_0_name.getValueASCII())) return false; - if (!m_objvar_0_types.push_back(myData->objvar_0_type.isNull(), myData->objvar_0_type.getValue())) return false; + if (!m_objvar_0_types.push_back(myData->objvar_0_type.isNull(), static_cast(myData->objvar_0_type.getValue()))) return false; if (!m_objvar_0_values.push_back(myData->objvar_0_value.getValueASCII())) return false; if (!m_objvar_1_names.push_back(myData->objvar_1_name.getValueASCII())) return false; - if (!m_objvar_1_types.push_back(myData->objvar_1_type.isNull(), myData->objvar_1_type.getValue())) return false; + if (!m_objvar_1_types.push_back(myData->objvar_1_type.isNull(), static_cast(myData->objvar_1_type.getValue()))) return false; if (!m_objvar_1_values.push_back(myData->objvar_1_value.getValueASCII())) return false; if (!m_objvar_2_names.push_back(myData->objvar_2_name.getValueASCII())) return false; - if (!m_objvar_2_types.push_back(myData->objvar_2_type.isNull(), myData->objvar_2_type.getValue())) return false; + if (!m_objvar_2_types.push_back(myData->objvar_2_type.isNull(), static_cast(myData->objvar_2_type.getValue()))) return false; if (!m_objvar_2_values.push_back(myData->objvar_2_value.getValueASCII())) return false; if (!m_objvar_3_names.push_back(myData->objvar_3_name.getValueASCII())) return false; - if (!m_objvar_3_types.push_back(myData->objvar_3_type.isNull(), myData->objvar_3_type.getValue())) return false; + if (!m_objvar_3_types.push_back(myData->objvar_3_type.isNull(), static_cast(myData->objvar_3_type.getValue()))) return false; if (!m_objvar_3_values.push_back(myData->objvar_3_value.getValueASCII())) return false; if (!m_objvar_4_names.push_back(myData->objvar_4_name.getValueASCII())) return false; - if (!m_objvar_4_types.push_back(myData->objvar_4_type.isNull(), myData->objvar_4_type.getValue())) return false; + if (!m_objvar_4_types.push_back(myData->objvar_4_type.isNull(), static_cast(myData->objvar_4_type.getValue()))) return false; if (!m_objvar_4_values.push_back(myData->objvar_4_value.getValueASCII())) return false; if (!m_objvar_5_names.push_back(myData->objvar_5_name.getValueASCII())) return false; - if (!m_objvar_5_types.push_back(myData->objvar_5_type.isNull(), myData->objvar_5_type.getValue())) return false; + if (!m_objvar_5_types.push_back(myData->objvar_5_type.isNull(), static_cast(myData->objvar_5_type.getValue()))) return false; if (!m_objvar_5_values.push_back(myData->objvar_5_value.getValueASCII())) return false; if (!m_objvar_6_names.push_back(myData->objvar_6_name.getValueASCII())) return false; - if (!m_objvar_6_types.push_back(myData->objvar_6_type.isNull(), myData->objvar_6_type.getValue())) return false; + if (!m_objvar_6_types.push_back(myData->objvar_6_type.isNull(), static_cast(myData->objvar_6_type.getValue()))) return false; if (!m_objvar_6_values.push_back(myData->objvar_6_value.getValueASCII())) return false; if (!m_objvar_7_names.push_back(myData->objvar_7_name.getValueASCII())) return false; - if (!m_objvar_7_types.push_back(myData->objvar_7_type.isNull(), myData->objvar_7_type.getValue())) return false; + if (!m_objvar_7_types.push_back(myData->objvar_7_type.isNull(), static_cast(myData->objvar_7_type.getValue()))) return false; if (!m_objvar_7_values.push_back(myData->objvar_7_value.getValueASCII())) return false; if (!m_objvar_8_names.push_back(myData->objvar_8_name.getValueASCII())) return false; - if (!m_objvar_8_types.push_back(myData->objvar_8_type.isNull(), myData->objvar_8_type.getValue())) return false; + if (!m_objvar_8_types.push_back(myData->objvar_8_type.isNull(), static_cast(myData->objvar_8_type.getValue()))) return false; if (!m_objvar_8_values.push_back(myData->objvar_8_value.getValueASCII())) return false; if (!m_objvar_9_names.push_back(myData->objvar_9_name.getValueASCII())) return false; - if (!m_objvar_9_types.push_back(myData->objvar_9_type.isNull(), myData->objvar_9_type.getValue())) return false; + if (!m_objvar_9_types.push_back(myData->objvar_9_type.isNull(), static_cast(myData->objvar_9_type.getValue()))) return false; if (!m_objvar_9_values.push_back(myData->objvar_9_value.getValueASCII())) return false; if (!m_objvar_10_names.push_back(myData->objvar_10_name.getValueASCII())) return false; - if (!m_objvar_10_types.push_back(myData->objvar_10_type.isNull(), myData->objvar_10_type.getValue())) return false; + if (!m_objvar_10_types.push_back(myData->objvar_10_type.isNull(), static_cast(myData->objvar_10_type.getValue()))) return false; if (!m_objvar_10_values.push_back(myData->objvar_10_value.getValueASCII())) return false; if (!m_objvar_11_names.push_back(myData->objvar_11_name.getValueASCII())) return false; - if (!m_objvar_11_types.push_back(myData->objvar_11_type.isNull(), myData->objvar_11_type.getValue())) return false; + if (!m_objvar_11_types.push_back(myData->objvar_11_type.isNull(), static_cast(myData->objvar_11_type.getValue()))) return false; if (!m_objvar_11_values.push_back(myData->objvar_11_value.getValueASCII())) return false; if (!m_objvar_12_names.push_back(myData->objvar_12_name.getValueASCII())) return false; - if (!m_objvar_12_types.push_back(myData->objvar_12_type.isNull(), myData->objvar_12_type.getValue())) return false; + if (!m_objvar_12_types.push_back(myData->objvar_12_type.isNull(), static_cast(myData->objvar_12_type.getValue()))) return false; if (!m_objvar_12_values.push_back(myData->objvar_12_value.getValueASCII())) return false; if (!m_objvar_13_names.push_back(myData->objvar_13_name.getValueASCII())) return false; - if (!m_objvar_13_types.push_back(myData->objvar_13_type.isNull(), myData->objvar_13_type.getValue())) return false; + if (!m_objvar_13_types.push_back(myData->objvar_13_type.isNull(), static_cast(myData->objvar_13_type.getValue()))) return false; if (!m_objvar_13_values.push_back(myData->objvar_13_value.getValueASCII())) return false; if (!m_objvar_14_names.push_back(myData->objvar_14_name.getValueASCII())) return false; - if (!m_objvar_14_types.push_back(myData->objvar_14_type.isNull(), myData->objvar_14_type.getValue())) return false; + if (!m_objvar_14_types.push_back(myData->objvar_14_type.isNull(), static_cast(myData->objvar_14_type.getValue()))) return false; if (!m_objvar_14_values.push_back(myData->objvar_14_value.getValueASCII())) return false; if (!m_objvar_15_names.push_back(myData->objvar_15_name.getValueASCII())) return false; - if (!m_objvar_15_types.push_back(myData->objvar_15_type.isNull(), myData->objvar_15_type.getValue())) return false; + if (!m_objvar_15_types.push_back(myData->objvar_15_type.isNull(), static_cast(myData->objvar_15_type.getValue()))) return false; if (!m_objvar_15_values.push_back(myData->objvar_15_value.getValueASCII())) return false; if (!m_objvar_16_names.push_back(myData->objvar_16_name.getValueASCII())) return false; - if (!m_objvar_16_types.push_back(myData->objvar_16_type.isNull(), myData->objvar_16_type.getValue())) return false; + if (!m_objvar_16_types.push_back(myData->objvar_16_type.isNull(), static_cast(myData->objvar_16_type.getValue()))) return false; if (!m_objvar_16_values.push_back(myData->objvar_16_value.getValueASCII())) return false; if (!m_objvar_17_names.push_back(myData->objvar_17_name.getValueASCII())) return false; - if (!m_objvar_17_types.push_back(myData->objvar_17_type.isNull(), myData->objvar_17_type.getValue())) return false; + if (!m_objvar_17_types.push_back(myData->objvar_17_type.isNull(), static_cast(myData->objvar_17_type.getValue()))) return false; if (!m_objvar_17_values.push_back(myData->objvar_17_value.getValueASCII())) return false; if (!m_objvar_18_names.push_back(myData->objvar_18_name.getValueASCII())) return false; - if (!m_objvar_18_types.push_back(myData->objvar_18_type.isNull(), myData->objvar_18_type.getValue())) return false; + if (!m_objvar_18_types.push_back(myData->objvar_18_type.isNull(), static_cast(myData->objvar_18_type.getValue()))) return false; if (!m_objvar_18_values.push_back(myData->objvar_18_value.getValueASCII())) return false; if (!m_objvar_19_names.push_back(myData->objvar_19_name.getValueASCII())) return false; - if (!m_objvar_19_types.push_back(myData->objvar_19_type.isNull(), myData->objvar_19_type.getValue())) return false; + if (!m_objvar_19_types.push_back(myData->objvar_19_type.isNull(),static_cast( myData->objvar_19_type.getValue()))) return false; if (!m_objvar_19_values.push_back(myData->objvar_19_value.getValueASCII())) return false; if (!m_script_lists.push_back(myData->script_list.getValueASCII())) return false; break; diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp index dfc8a70ce..2b08edf09 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp @@ -50,7 +50,7 @@ bool ResourceTypeQuery::addData(DBSchema::ResourceTypeRow const & data) if (!m_resource_classes.push_back(data.resource_class.getValueASCII())) return false; if (!m_attributes.push_back(data.attributes.getValueASCII())) return false; if (!m_fractal_seeds.push_back(data.fractal_seeds.getValueASCII())) return false; - if (!m_depleted_timestamps.push_back(data.depleted_timestamp.isNull(), data.depleted_timestamp.getValue())) return false; + if (!m_depleted_timestamps.push_back(data.depleted_timestamp.isNull(), static_cast(data.depleted_timestamp.getValue()))) return false; m_numItems=m_numItems.getValue() + 1; return true; From eee557e84cd432bbf28ca6bd34640ee36fe1a75d Mon Sep 17 00:00:00 2001 From: Cekis Date: Thu, 31 Aug 2023 01:31:26 -0400 Subject: [PATCH 39/46] Organized CMake file a bit better --- CMakeLists.txt | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f0bbc1f8..5876eeb7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 2.8) +include(CMakePrintHelpers) project(stellabellum C CXX) @@ -35,7 +36,6 @@ set(CMAKE_CXX_FLAGS "\ ${CMAKE_CXX_FLAGS} \ -pipe \ -march=native \ - -mtune=native \ -maes \ -Wformat \ -Wno-overloaded-virtual \ @@ -47,6 +47,8 @@ set(CMAKE_CXX_FLAGS "\ -Wno-reorder \ -Wno-tautological-constant-out-of-range-compare \ -Wno-address-of-packed-member \ + -Wfatal-errors \ + -ffast-math \ ") string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) @@ -69,7 +71,7 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg -ggdb") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -pg -ggdb -no-pie") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -no-pie -flto -fwhole-program-vtables") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 ") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1") elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "CLang") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -pg -ggdb -g -fprofile-instr-generate -fcoverage-mapping") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG_LEVEL=0 -DPRODUCTION=0 -Ofast -pg -ggdb") @@ -77,6 +79,12 @@ elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "CLang") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Ofast") endif() +# Remove whitespace from flags +string(REGEX REPLACE "[ \t\r\n]+" " " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) +string(REGEX REPLACE "[ \t\r\n]+" " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) +string(REGEX REPLACE "[ \t\r\n]+" " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL}) +string(REGEX REPLACE "[ \t\r\n]+" " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) + message("Using Compiler: ${CMAKE_CXX_COMPILER_ID}") add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE) @@ -86,15 +94,14 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUA add_definitions(-DENABLE_PROFILING) endif () -message("Flags CXX: ${CMAKE_CXX_FLAGS}") if (${CMAKE_BUILD_TYPE} STREQUAL "DEBUG") - message("Flags DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") + cmake_print_variables(CMAKE_CXX_FLAGS_DEBUG) elseif (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO") - message("Flags RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + cmake_print_variables(CMAKE_CXX_FLAGS_RELWITHDEBINFO) elseif (${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL") - message("Flags MINSIZEREL: ${CMAKE_CXX_FLAGS_MINSIZEREL}") + cmake_print_variables(CMAKE_CXX_FLAGS_MINSIZEREL) elseif (${CMAKE_BUILD_TYPE} STREQUAL "RELEASE") - message("Flags RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") + cmake_print_variables(CMAKE_CXX_FLAGS_RELEASE) endif () add_subdirectory(external) From 73ecb88aeb6cb355ee3aa261cedb8e4a67bc6e60 Mon Sep 17 00:00:00 2001 From: Cekis Date: Fri, 1 Sep 2023 01:56:05 -0400 Subject: [PATCH 40/46] Removed problematic compiler flags --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5876eeb7d..424b01c4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,8 +47,6 @@ set(CMAKE_CXX_FLAGS "\ -Wno-reorder \ -Wno-tautological-constant-out-of-range-compare \ -Wno-address-of-packed-member \ - -Wfatal-errors \ - -ffast-math \ ") string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) From 8fbee785175ba3753900e2d0499e22eb836c5b23 Mon Sep 17 00:00:00 2001 From: Cekis Date: Fri, 1 Sep 2023 01:57:54 -0400 Subject: [PATCH 41/46] Fixed bugs related to database inconsistencies between 32 bit and 64 bit. --- .../src/shared/object/ResourcePoolObject.cpp | 2 +- .../serverUtility/src/shared/ServerClock.cpp | 20 +- .../serverUtility/src/shared/ServerClock.h | 22 +- .../src_oci/DbBindableVarray.cpp | 197 ++++++++++++------ .../src_oci/OciQueryImplementation.cpp | 175 +++++++++++----- .../src_oci/OciServer.cpp | 2 +- .../src_oci/OciSession.cpp | 14 +- .../src/shared/queries/ResourceTypeQuery.cpp | 2 +- 8 files changed, 288 insertions(+), 146 deletions(-) diff --git a/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp b/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp index e08354332..92d2404a6 100755 --- a/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp +++ b/engine/server/library/serverGame/src/shared/object/ResourcePoolObject.cpp @@ -54,7 +54,7 @@ ResourcePoolObject::~ResourcePoolObject() */ float ResourcePoolObject::harvest(float installedEfficiency, uint32 lastHarvestTime) const { - int elapsedTime=static_cast(std::min(ServerClock::getInstance().getGameTimeSeconds(),static_cast(m_depletedTimestamp)) - lastHarvestTime); + uint32_t elapsedTime=static_cast(std::min(ServerClock::getInstance().getGameTimeSeconds(),static_cast(m_depletedTimestamp)) - lastHarvestTime); if (elapsedTime < 0) return 0; float elapsedTicks =static_cast(elapsedTime) / static_cast(ConfigServerGame::getSecondsPerResourceTick()); diff --git a/engine/server/library/serverUtility/src/shared/ServerClock.cpp b/engine/server/library/serverUtility/src/shared/ServerClock.cpp index a5a13a8a5..a8d7c73f4 100755 --- a/engine/server/library/serverUtility/src/shared/ServerClock.cpp +++ b/engine/server/library/serverUtility/src/shared/ServerClock.cpp @@ -12,7 +12,7 @@ // ---------------------------------------------------------------------- -const unsigned long ServerClock::cms_endOfTime = static_cast(-1); +const int32_t ServerClock::cms_endOfTime = static_cast(-1); //----------------------------------------------------------------------- @@ -31,10 +31,10 @@ ServerClock::~ServerClock() //----------------------------------------------------------------------- -const unsigned long ServerClock::getGameTimeSeconds() const +const uint32_t ServerClock::getGameTimeSeconds() const { FATAL(!isSet(), ("ServerClock::getGameTimeSeconds: Clock was not set.")); - return int(lastTime - subtractInterval); + return static_cast(lastTime - subtractInterval); } //----------------------------------------------------------------------- @@ -52,16 +52,16 @@ void ServerClock::incrementServerFrame() //----------------------------------------------------------------------- -void ServerClock::setSubtractInterval(const unsigned long newSubtractInterval) +void ServerClock::setSubtractInterval(const uint32_t newSubtractInterval) { subtractInterval = newSubtractInterval; } //----------------------------------------------------------------------- -void ServerClock::setGameTimeSeconds(const unsigned long newGameTime) +void ServerClock::setGameTimeSeconds(const uint32_t newGameTime) { - subtractInterval = int(time(0) - newGameTime); + subtractInterval = static_cast(time(0) - newGameTime); LOG("ServerClock", ("Game time set to %lu (subtract interval %lu)", newGameTime, subtractInterval)); } @@ -79,11 +79,11 @@ ServerClock &ServerClock::getInstance() * Given a time in seconds, make a string that expresses how long it is. * For debug output only. In English, not localized. Not thread-safe. */ -std::string ServerClock::getDebugPrintableTimeframe(unsigned long const timeInSeconds) +std::string ServerClock::getDebugPrintableTimeframe(uint32_t const timeInSeconds) { - unsigned long const dayInSeconds = 60 * 60 * 24; - unsigned long const hourInSeconds = 60 * 60; - unsigned long const minuteInSeconds = 60; + uint32_t const dayInSeconds = 60 * 60 * 24; + uint32_t const hourInSeconds = 60 * 60; + uint32_t const minuteInSeconds = 60; static char buffer[256]; diff --git a/engine/server/library/serverUtility/src/shared/ServerClock.h b/engine/server/library/serverUtility/src/shared/ServerClock.h index 36ee93b98..9f64c3bb1 100755 --- a/engine/server/library/serverUtility/src/shared/ServerClock.h +++ b/engine/server/library/serverUtility/src/shared/ServerClock.h @@ -10,36 +10,36 @@ class ServerClock static ServerClock &getInstance(); ~ServerClock(); - const unsigned long getGameTimeSeconds () const; - const unsigned long getServerFrame() const; - const unsigned long getSubtractInterval() const; + const uint32_t getGameTimeSeconds () const; + const uint32_t getServerFrame() const; + const uint32_t getSubtractInterval() const; void incrementServerFrame(); - void setSubtractInterval(const unsigned long newSubtractInterval); - void setGameTimeSeconds (unsigned long newGameTime); + void setSubtractInterval(const uint32_t newSubtractInterval); + void setGameTimeSeconds (uint32_t newGameTime); bool isSet () const; - std::string getDebugPrintableTimeframe (const unsigned long timeInSeconds); + std::string getDebugPrintableTimeframe (const uint32_t timeInSeconds); - static const unsigned long cms_endOfTime; + static const int32_t cms_endOfTime; protected: ServerClock(); private: - unsigned long serverFrame; - unsigned long subtractInterval; + uint32_t serverFrame; + uint32_t subtractInterval; mutable time_t lastTime; }; //----------------------------------------------------------------------- -inline const unsigned long ServerClock::getServerFrame() const +inline const uint32_t ServerClock::getServerFrame() const { return serverFrame; } //----------------------------------------------------------------------- -inline const unsigned long ServerClock::getSubtractInterval() const +inline const uint32_t ServerClock::getSubtractInterval() const { return subtractInterval; } diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp index 956482bfa..255c4105f 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/DbBindableVarray.cpp @@ -57,8 +57,10 @@ bool BindableVarray::create(DB::Session *session, const std::string &name, const 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, - &m_tdo)))) + &m_tdo)))) { + LOG("DatabaseError", ("Could not create BindableVarray (OCITypeByName) for name - %s", name.c_str())); return false; + } if (! (localSession->m_server->checkerr(*localSession, OCIObjectNew (localSession->envhp, @@ -68,8 +70,10 @@ bool BindableVarray::create(DB::Session *session, const std::string &name, const m_tdo, nullptr, OCI_DURATION_DEFAULT, true, - reinterpret_cast(&m_data))))) - return false; + reinterpret_cast(&m_data))))) { + LOG("DatabaseError", ("Could not create BindableVarray (OCIObjectNew) for name - %s", name.c_str())); + return false; + } NOT_NULL(m_tdo); NOT_NULL(m_data); @@ -83,9 +87,11 @@ void BindableVarray::free() { OCISession *localSession = safe_cast(m_session); - IGNORE_RETURN(localSession->m_server->checkerr(*localSession, + if(!(localSession->m_server->checkerr(*localSession, OCIObjectFree (localSession->envhp, - localSession->errhp, m_data, 0))); + localSession->errhp, m_data, 0)))) { + LOG("DatabaseError", ("Could not free up DB object")); + }; m_initialized = false; m_tdo=nullptr; m_data=nullptr; @@ -99,10 +105,14 @@ void BindableVarray::clear() OCISession *localSession = safe_cast(m_session); sb4 size=0; - if (! (localSession->m_server->checkerr(*localSession, OCICollSize(localSession->envhp, localSession->errhp, m_data, &size)))) - return; - if (! (localSession->m_server->checkerr(*localSession, OCICollTrim(localSession->envhp, localSession->errhp, size, m_data)))) - return; + if (! (localSession->m_server->checkerr(*localSession, OCICollSize(localSession->envhp, localSession->errhp, m_data, &size)))) { + LOG("DatabaseError", ("Could not clear bindablevarray - OCICollSize")); + return; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollTrim(localSession->envhp, localSession->errhp, size, m_data)))) { + LOG("DatabaseError", ("Could not clear bindablevarray - OCICollTrim")); + return; + } } // ---------------------------------------------------------------------- @@ -129,10 +139,14 @@ bool BindableVarrayNumber::push_back(int16_t value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVArray int16 value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVArray int16 value OCICollAppend - %d", value)); + return false; + } return true; } @@ -147,10 +161,14 @@ bool BindableVarrayNumber::push_back(int32_t value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVArray int32 value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVArray int32 value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -164,10 +182,14 @@ bool BindableVarrayNumber::push_back(int64_t value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVArray int64 value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVArray int64 value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -195,10 +217,14 @@ bool BindableVarrayNumber::push_back(double value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromReal(localSession->errhp, &value, sizeof(value), &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromReal(localSession->errhp, &value, sizeof(value), &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVArray double value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVArray double value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -221,10 +247,14 @@ bool BindableVarrayNumber::push_back(bool IsNULL, int16_t value) } OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber int16 value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber int16 value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -248,10 +278,14 @@ bool BindableVarrayNumber::push_back(bool IsNULL, int32_t value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber int32 value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber int32 value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -274,10 +308,14 @@ bool BindableVarrayNumber::push_back(bool IsNULL, int64_t value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromInt(localSession->errhp, &value, sizeof(value), OCI_NUMBER_SIGNED, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber int64 value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber int64 value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -314,10 +352,14 @@ bool BindableVarrayNumber::push_back(bool IsNULL, double value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCINumberFromReal(localSession->errhp, &value, sizeof(value), &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCINumberFromReal(localSession->errhp, &value, sizeof(value), &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber double value OCINumberFromInt - %d", value)); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, &buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayNumber double value OCINumberFromInt - %d", value)); + return false; + } return true; } @@ -338,8 +380,10 @@ std::string BindableVarrayNumber::outputValue() const sb4 size; std::string result("["); - if (! (localSession->m_server->checkerr(*localSession, OCICollSize(localSession->envhp, localSession->errhp, m_data, &size)))) + if (! (localSession->m_server->checkerr(*localSession, OCICollSize(localSession->envhp, localSession->errhp, m_data, &size)))) { + LOG("DatabaseError", ("Could not get outputValue - OCICollSize - %d", size)); return "[*ERROR*]"; + } for (sb4 i=0; i < size; ++i) { @@ -366,15 +410,19 @@ std::string BindableVarrayNumber::outputValue() const buffer[sizeof(buffer)-1]='\0'; result += buffer; } - else + else { + LOG("DatabaseError", ("Could not get output value from OCINumberToReal - %d", value)); result += "*ERROR*"; + } } } else result += "*NO ELEMENT*"; } - else - result += "*ERROR*"; + else { + LOG("DatabaseError", ("Could not get output value from OCICollGetElem")); + result += "*ERROR*"; + } } result+=']'; return result; @@ -420,10 +468,14 @@ bool BindableVarrayString::push_back(const std::string &value) } } - if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), effectiveLength, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), effectiveLength, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString string value (OCIStringAssignText) - %s", value.c_str())); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString string value (OCICollAppend) - %s", value.c_str())); + return false; + } return true; } @@ -442,10 +494,14 @@ bool BindableVarrayString::push_back(bool bvalue) OCIInd buffer_indicator (OCI_IND_NOTNULL); OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), value.length(), &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), value.length(), &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString string value (OCIStringAssignText) - %s", value.c_str())); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString string value (OCICollAppend) - %s", value.c_str())); + return false; + } return true; } @@ -498,10 +554,14 @@ bool BindableVarrayString::push_back(bool IsNULL, const std::string &value) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), effectiveLength, &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) - return false; + if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), effectiveLength, &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString string value (OCIStringAssignText) - %s", value.c_str())); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString string value (OCICollAppend) - %s", value.c_str())); + return false; + } return true; } @@ -529,11 +589,14 @@ bool BindableVarrayString::push_back(bool IsNULL, bool bvalue) OCISession *localSession = safe_cast(m_session); - if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), value.length(), &buffer)))) - return false; - if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) - return false; - + if (! (localSession->m_server->checkerr(*localSession, OCIStringAssignText(localSession->envhp, localSession->errhp, reinterpret_cast(const_cast(value.c_str())), value.length(), &buffer)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString boolean value (OCIStringAssignText) - %s", value.c_str())); + return false; + } + if (! (localSession->m_server->checkerr(*localSession, OCICollAppend(localSession->envhp, localSession->errhp, buffer, &buffer_indicator, m_data)))) { + LOG("DatabaseError", ("Could not push back BindableVarrayString boolean value (OCICollAppend) - %s", value.c_str())); + return false; + } return true; } @@ -552,8 +615,10 @@ std::string BindableVarrayString::outputValue() const sb4 size; std::string result("["); - if (! (localSession->m_server->checkerr(*localSession, OCICollSize(localSession->envhp, localSession->errhp, m_data, &size)))) + if (! (localSession->m_server->checkerr(*localSession, OCICollSize(localSession->envhp, localSession->errhp, m_data, &size)))) { + LOG("DatabaseError", ("Could not get outputValue BindableVarrayString (OCICollSize)")); return "[*ERROR*]"; + } for (sb4 i=0; i < size; ++i) { @@ -582,8 +647,10 @@ std::string BindableVarrayString::outputValue() const else result += "*NO ELEMENT*"; } - else - result += "*ERROR*"; + else { + LOG("DatabaseError", ("Could not get outputValue BindableVarrayString OCICollGetElem")); + return "[*ERROR*]"; + } } result+=']'; return result; diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp index b9bdce1df..18f06e538 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciQueryImplementation.cpp @@ -63,8 +63,10 @@ bool DB::OCIQueryImpl::setup(Session *session) if (!m_server->checkerr(*m_session, OCIHandleAlloc( m_session->envhp, reinterpret_cast(&m_stmthp), - OCI_HTYPE_STMT, 0, 0))) - return false; + OCI_HTYPE_STMT, 0, 0))) { + LOG("DatabaseError", ("Could not setup query")); + return false; + } m_cursorhp=m_stmthp; // later on, we'll separate these two if needed @@ -88,15 +90,19 @@ bool DB::OCIQueryImpl::prepare() reinterpret_cast(const_cast(m_sql.c_str())), m_sql.length(), (ub4) OCI_NTV_SYNTAX, - (ub4) OCI_DEFAULT))) - return false; + (ub4) OCI_DEFAULT))) { + LOG("DatabaseError", ("Could not prepare statement - %s", m_sql.c_str())); + return false; + } if (m_query->getMode()==Query::MODE_PLSQL_REFCURSOR) { m_cursorhp=0; // may not be necessary -- OCI docs unclear if (!m_server->checkerr(*m_session, OCIHandleAlloc( m_session->envhp, (dvoid **) &m_cursorhp, - OCI_HTYPE_STMT, 0, 0))) + OCI_HTYPE_STMT, 0, 0))) { + LOG("DatabaseError", ("Could not prepare statement - could not allocate handle for statement - %s", m_sql.c_str())); return false; - + } + if (!m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &m_procBind, @@ -110,8 +116,10 @@ bool DB::OCIQueryImpl::prepare() 0, 0, 0, - OCI_DEFAULT))) + OCI_DEFAULT))) { + LOG("DatabaseError", ("Could not prepare statement - could not bind by position on statement - %s", m_sql.c_str())); return false; + } } return true; @@ -189,8 +197,10 @@ bool DB::OCIQueryImpl::exec() { WARNING_STRICT_FATAL(!m_session->isOkToFetch(),("Calling fetch after commit, without an execute in between (may cause Oracle to crash).")); sword status=OCIStmtFetch (m_cursorhp, m_session->errhp, 0, OCI_FETCH_NEXT, OCI_DEFAULT); - if (!m_server->checkerr(*m_session,status)) - return false; + if (!m_server->checkerr(*m_session,status)) { + LOG("DatabaseError", ("Could not establish session when executing statement (NO Data) - %s", m_sql.c_str())); + return false; + } } m_endOfData=true; } @@ -213,8 +223,10 @@ bool DB::OCIQueryImpl::exec() m_dataReady=true; } } - else - return false; + else { + LOG("DatabaseError", ("Could not establish session when executing statement (Data) - %s", m_sql.c_str())); + return false; + } } m_inUse=true; @@ -247,8 +259,10 @@ int DB::OCIQueryImpl::fetch() (dvoid *)& rows, (ub4 *) &sizep, OCI_ATTR_ROWS_FETCHED, m_session->errhp); sword status=OCIStmtFetch (m_cursorhp, m_session->errhp, 0, OCI_FETCH_NEXT, OCI_DEFAULT); // cancel the cursor - if (!m_server->checkerr(*m_session,status)) - return -1; + if (!m_server->checkerr(*m_session,status)) { + LOG("DatabaseError", ("Could not fetch from query (NO Data) - %s", m_sql.c_str())); + return -1; + } m_endOfData=true; if (rows!=0) { @@ -260,8 +274,10 @@ int DB::OCIQueryImpl::fetch() } else { - if (!m_server->checkerr(*m_session,status)) - return -1; + if (!m_server->checkerr(*m_session,status)) { + LOG("DatabaseError", ("Could not fetch from query (Data) - %s", m_sql.c_str())); + return -1; + } } ub4 rows; @@ -324,8 +340,11 @@ void DB::OCIQueryImpl::done() { NOT_NULL(m_stmthp); - if (m_autocommit) - m_server->checkerr(*m_session, OCITransCommit(m_session->svchp, m_session->errhp, 0)); + if (m_autocommit) { + if(!(m_server->checkerr(*m_session, OCITransCommit(m_session->svchp, m_session->errhp, 0)))) { + LOG("DatabaseError", ("Could not complete transaction - %s", m_sql.c_str())); + } + } OCIHandleFree(m_stmthp, OCI_HTYPE_STMT); if (m_cursorhp!=m_stmthp) @@ -355,7 +374,9 @@ int DB::OCIQueryImpl::rowCount() int value; - m_server->checkerr(*m_session, OCIAttrGet (m_cursorhp, OCI_HTYPE_STMT,&value,0,OCI_ATTR_ROW_COUNT,m_session->errhp)); + if(!(m_server->checkerr(*m_session, OCIAttrGet (m_cursorhp, OCI_HTYPE_STMT,&value,0,OCI_ATTR_ROW_COUNT,m_session->errhp)))) { + LOG("DatabaseError", ("Could not get row count from query - %s", m_sql.c_str())); + } return value; } @@ -453,7 +474,7 @@ bool DB::OCIQueryImpl::bindCol(BindableLong &buffer) { BindRec *br=addBindRec(buffer); - m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, + if(!(m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, &(br->defnp), m_session->errhp, nextColumn++, @@ -463,16 +484,20 @@ bool DB::OCIQueryImpl::bindCol(BindableLong &buffer) br->getIndicatorPointer(), br->getLengthPointer(), (ub2 *)0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind column (by position) - %s", m_sql.c_str())); + } if (m_numElements > 1) { - m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, + if(!(m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, m_session->errhp, m_skipSize, br->getIndicatorSkipSize(), br->getLengthSkipSize(), - 0)); + 0)))) { + LOG("DatabaseError", ("Could not bind column (define array) - %s", m_sql.c_str())); + } } return true; } @@ -483,7 +508,7 @@ bool DB::OCIQueryImpl::bindParameter(BindableLong &buffer) { BindRec *br=addBindRec(buffer); - return m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, + if(!(m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &(br->bindp), m_session->errhp, nextParameter++, @@ -495,7 +520,11 @@ bool DB::OCIQueryImpl::bindParameter(BindableLong &buffer) 0, 0, 0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind parameter of statement - %s", m_sql.c_str())); + return false; + } + return true; } // ---------------------------------------------------------------------- @@ -504,7 +533,7 @@ bool DB::OCIQueryImpl::bindCol(BindableStringBase &buffer) { BindRec *br=addBindRec(buffer); - m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, + if(!(m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, &(br->defnp), m_session->errhp, nextColumn++, @@ -514,16 +543,20 @@ bool DB::OCIQueryImpl::bindCol(BindableStringBase &buffer) br->getIndicatorPointer(), br->getLengthPointer(), (ub2 *)0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind column of statement (by position) - %s", m_sql.c_str())); + } if (m_numElements > 1) { - m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, + if(!(m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, m_session->errhp, m_skipSize, br->getIndicatorSkipSize(), br->getLengthSkipSize(), - 0)); + 0)))) { + LOG("DatabaseError", ("Could not bind column of statement (by array) - %s", m_sql.c_str())); + } } return true; } @@ -535,7 +568,7 @@ bool DB::OCIQueryImpl::bindParameter(BindableStringBase &buffer) BindRec *br=addBindRec(buffer); br->stringAdjust=true; - return m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, + if(!(m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &(br->bindp), m_session->errhp, nextParameter++, @@ -547,7 +580,11 @@ bool DB::OCIQueryImpl::bindParameter(BindableStringBase &buffer) 0, 0, 0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind parameter of statement (by position) - %s", m_sql.c_str())); + return false; + } + return true; } // ---------------------------------------------------------------------- @@ -556,7 +593,7 @@ bool DB::OCIQueryImpl::bindCol(BindableUnicodeBase &buffer) { BindRec *br=addBindRec(buffer); - m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, + if(!(m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, &(br->defnp), m_session->errhp, nextColumn++, @@ -566,16 +603,20 @@ bool DB::OCIQueryImpl::bindCol(BindableUnicodeBase &buffer) br->getIndicatorPointer(), br->getLengthPointer(), (ub2 *)0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind column of statement (by position) (BindableUnicodeBase) - %s", m_sql.c_str())); + } if (m_numElements > 1) { - m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, + if(!(m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, m_session->errhp, m_skipSize, br->getIndicatorSkipSize(), br->getLengthSkipSize(), - 0)); + 0)))) { + LOG("DatabaseError", ("Could not bind column of statement (by array) (BindableUnicodeBase) - %s", m_sql.c_str())); + } } return true; } @@ -588,7 +629,7 @@ bool DB::OCIQueryImpl::bindParameter(BindableUnicodeBase &buffer) br->stringAdjust=true; br->length=static_cast(*(buffer.getIndicator())); - return m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, + if(!(m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &(br->bindp), m_session->errhp, nextParameter++, @@ -600,7 +641,11 @@ bool DB::OCIQueryImpl::bindParameter(BindableUnicodeBase &buffer) 0, 0, 0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind parameter of statement (by position) (BindableUnicodeBase) - %s", m_sql.c_str())); + return false; + } + return true; } // ====================================================================== @@ -609,7 +654,7 @@ bool DB::OCIQueryImpl::bindCol(BindableDouble &buffer) { BindRec *br=addBindRec(buffer); - m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, + if(!(m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, &(br->defnp), m_session->errhp, nextColumn++, @@ -619,15 +664,19 @@ bool DB::OCIQueryImpl::bindCol(BindableDouble &buffer) br->getIndicatorPointer(), br->getLengthPointer(), (ub2 *)0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind column of statement (by position) (BindableDouble) - %s", m_sql.c_str())); + } if (m_numElements > 1) { - m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, + if(!(m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, m_session->errhp, m_skipSize, br->getIndicatorSkipSize(), br->getLengthSkipSize(), - 0)); + 0)))) { + LOG("DatabaseError", ("Could not bind column of statement (by array) (BindableDouble) - %s", m_sql.c_str())); + } } return true; } @@ -638,7 +687,7 @@ bool DB::OCIQueryImpl::bindParameter(BindableDouble &buffer) { BindRec *br=addBindRec(buffer); - return m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, + if(!(m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &(br->bindp), m_session->errhp, nextParameter++, @@ -650,7 +699,11 @@ bool DB::OCIQueryImpl::bindParameter(BindableDouble &buffer) 0, 0, 0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind parameter of statement (by position) (BindableDouble) - %s", m_sql.c_str())); + return false; + } + return true; } // ---------------------------------------------------------------------- @@ -659,7 +712,7 @@ bool DB::OCIQueryImpl::bindCol(BindableBool &buffer) { BindRec *br=addBindRec(buffer); - m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, + if(!(m_server->checkerr(*m_session, OCIDefineByPos(m_cursorhp, &(br->defnp), m_session->errhp, nextColumn++, @@ -669,16 +722,20 @@ bool DB::OCIQueryImpl::bindCol(BindableBool &buffer) br->getIndicatorPointer(), br->getLengthPointer(), (ub2 *)0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind column of statement (by position) (BindableBool) - %s", m_sql.c_str())); + } if (m_numElements > 1) { - m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, + if(!(m_server->checkerr(*m_session, OCIDefineArrayOfStruct(br->defnp, m_session->errhp, m_skipSize, br->getIndicatorSkipSize(), br->getLengthSkipSize(), - 0)); + 0)))) { + LOG("DatabaseError", ("Could not bind column of statement (by array) (BindableBool) - %s", m_sql.c_str())); + } } return true; } @@ -690,7 +747,7 @@ bool DB::OCIQueryImpl::bindParameter(BindableBool &buffer) BindRec *br=addBindRec(buffer); br->stringAdjust=true; - return m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, + if(!(m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &(br->bindp), m_session->errhp, nextParameter++, @@ -702,7 +759,11 @@ bool DB::OCIQueryImpl::bindParameter(BindableBool &buffer) 0, 0, 0, - OCI_DEFAULT)); + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind parameter of statement (by array) (BindableBool) - %s", m_sql.c_str())); + return false; + } + return true; } // ---------------------------------------------------------------------- @@ -711,7 +772,7 @@ bool DB::OCIQueryImpl::bindParameter(BindableVarray &buffer) { BindRec *br=addBindRec(buffer); - bool result = m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, + if(!(m_server->checkerr(*m_session, OCIBindByPos (m_stmthp, &(br->bindp), m_session->errhp, nextParameter++, @@ -723,18 +784,22 @@ bool DB::OCIQueryImpl::bindParameter(BindableVarray &buffer) 0, 0, 0, - OCI_DEFAULT)); - - if (!result) - return false; + OCI_DEFAULT)))) { + LOG("DatabaseError", ("Could not bind parameter of statement (by array) (BindableVarray) - %s", m_sql.c_str())); + return false; + } - return m_server->checkerr(*m_session, OCIBindObject (br->bindp, + if(!(m_server->checkerr(*m_session, OCIBindObject (br->bindp, m_session->errhp, buffer.getTDO(), reinterpret_cast(buffer.getBuffer()), 0, 0, - 0)); + 0)))) { + LOG("DatabaseError", ("Could not bind parameter of statement (by object) (BindableVarray) - %s", m_sql.c_str())); + return false; + } + return true; } // ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciServer.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/OciServer.cpp index ed5d8ddf9..9f821b530 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciServer.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciServer.cpp @@ -79,7 +79,7 @@ bool DB::OCIServer::checkerr(OCISession const & session, int status) REPORT_LOG(true,("Database Error - %.*s\n", 512, errbuf)); return false; default: - FATAL(true,("Unhandled Database Error - %.*s\n", 512, errbuf)); + REPORT_LOG(true,("Unhandled Database Error - %.*s\n", 512, errbuf)); break; } diff --git a/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp b/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp index f1fee1544..e5d6ecbec 100755 --- a/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp +++ b/engine/shared/library/sharedDatabaseInterface/src_oci/OciSession.cpp @@ -97,6 +97,7 @@ bool DB::OCISession::connect() if (! connected) { ++retryCount; + LOG("DatabaseError", ("Could not connect to the database (DSN=%s) after %d attempts.", m_server->getDSN(), retryCount)); DEBUG_REPORT_LOG(retryCount<5,("Retrying database connection\n")); Os::sleep(1000); } @@ -140,6 +141,7 @@ bool DB::OCISession::connect() } else { + LOG("DatabaseError", ("Invalid password provided when connecting to the database - disconnecting.")); disconnect(); // cleanup connected=false; } @@ -211,12 +213,20 @@ bool DB::OCISession::setAutoCommitMode(bool autocommit) bool DB::OCISession::commitTransaction() { m_okToFetch = false; - return m_server->checkerr(*this, OCITransCommit(svchp, errhp, 0)); + if(!(m_server->checkerr(*this, OCITransCommit(svchp, errhp, 0)))) { + LOG("DatabaseError", ("Unable to commit transaction.")); + return false; + } + return true; } bool DB::OCISession::rollbackTransaction() { - return m_server->checkerr(*this, OCITransRollback(svchp, errhp, 0)); + if(!(m_server->checkerr(*this, OCITransRollback(svchp, errhp, 0)))) { + LOG("DatabaseError", ("Unable to rollback transaction.")); + return false; + } + return true; } bool DB::OCISession::reset() diff --git a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp index 2b08edf09..43caa07d0 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/queries/ResourceTypeQuery.cpp @@ -50,7 +50,7 @@ bool ResourceTypeQuery::addData(DBSchema::ResourceTypeRow const & data) if (!m_resource_classes.push_back(data.resource_class.getValueASCII())) return false; if (!m_attributes.push_back(data.attributes.getValueASCII())) return false; if (!m_fractal_seeds.push_back(data.fractal_seeds.getValueASCII())) return false; - if (!m_depleted_timestamps.push_back(data.depleted_timestamp.isNull(), static_cast(data.depleted_timestamp.getValue()))) return false; + if (!m_depleted_timestamps.push_back(data.depleted_timestamp.isNull(), static_cast(data.depleted_timestamp.getValue()))) return false; m_numItems=m_numItems.getValue() + 1; return true; From 55c8f225f2cce71dd3a5d44e990ed76043a61ba6 Mon Sep 17 00:00:00 2001 From: Sais Date: Sat, 25 Jul 2026 02:19:32 -0400 Subject: [PATCH 42/46] Use fixed-width counts in the NetworkId and Unicode packed maps These three AutoDeltaPackedMap specializations wrote their command count as int32 but wrote the baseline count, and read both counts, as size_t. Under ILP32 size_t was 4 bytes so pack and unpack agreed. Under LP64 size_t binds to the 8-byte uint64 Archive overload, so pack writes 4+8 bytes while unpack reads 8+8 and leaves the stream misaligned by 4 bytes for every subsequent key and value. Switch both counts to int32_t, matching the generic internal_pack/ internal_unpack path and the already-converted PlayerQuestData specialization. This also keeps the serialized form identical to the 32-bit server, so data written by either architecture stays readable by the other. --- .../src/shared/AutoDeltaNetworkIdPackedMap.h | 10 +++++----- .../src/shared/NetworkIdAutoDeltaPackedMap.cpp | 10 +++++----- .../src/shared/UnicodeAutoDeltaPackedMap.cpp | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/engine/shared/library/sharedFoundation/src/shared/AutoDeltaNetworkIdPackedMap.h b/engine/shared/library/sharedFoundation/src/shared/AutoDeltaNetworkIdPackedMap.h index 62d073adf..eeed4ede9 100755 --- a/engine/shared/library/sharedFoundation/src/shared/AutoDeltaNetworkIdPackedMap.h +++ b/engine/shared/library/sharedFoundation/src/shared/AutoDeltaNetworkIdPackedMap.h @@ -32,8 +32,8 @@ namespace Archive char temp[200]; AutoDeltaMap::Command c; - Archive::put(target, countCharacter(buffer,':')); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(countCharacter(buffer,':'))); + Archive::put(target, static_cast(0)); // baselineCommandCount int tempPos = 0; for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i) @@ -64,8 +64,8 @@ namespace Archive char temp[200]; AutoDeltaMap::Command c; - size_t commandCount; - size_t baselineCommandCount; + int32_t commandCount; + int32_t baselineCommandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); @@ -76,7 +76,7 @@ namespace Archive } else { - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); Archive::get(source, c.key); diff --git a/engine/shared/library/sharedUtility/src/shared/NetworkIdAutoDeltaPackedMap.cpp b/engine/shared/library/sharedUtility/src/shared/NetworkIdAutoDeltaPackedMap.cpp index d1ba7a662..6e4c58fef 100755 --- a/engine/shared/library/sharedUtility/src/shared/NetworkIdAutoDeltaPackedMap.cpp +++ b/engine/shared/library/sharedUtility/src/shared/NetworkIdAutoDeltaPackedMap.cpp @@ -21,8 +21,8 @@ namespace Archive char value[200]; Command c; - Archive::put(target, countCharacter(buffer,':')); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(countCharacter(buffer,':'))); + Archive::put(target, static_cast(0)); // baselineCommandCount int tempPos = 0; for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i) @@ -52,8 +52,8 @@ namespace Archive char temp[200]; Command c; - size_t commandCount; - size_t baselineCommandCount; + int32_t commandCount; + int32_t baselineCommandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); @@ -64,7 +64,7 @@ namespace Archive } else { - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); Archive::get(source, c.key); diff --git a/external/ours/library/unicodeArchive/src/shared/UnicodeAutoDeltaPackedMap.cpp b/external/ours/library/unicodeArchive/src/shared/UnicodeAutoDeltaPackedMap.cpp index 8138fdbbb..513d06901 100755 --- a/external/ours/library/unicodeArchive/src/shared/UnicodeAutoDeltaPackedMap.cpp +++ b/external/ours/library/unicodeArchive/src/shared/UnicodeAutoDeltaPackedMap.cpp @@ -21,8 +21,8 @@ namespace Archive char temp[200]; Command c; - Archive::put(target, countCharacter(buffer,':')); - Archive::put(target, static_cast(0)); // baselineCommandCount + Archive::put(target, static_cast(countCharacter(buffer,':'))); + Archive::put(target, static_cast(0)); // baselineCommandCount int tempPos = 0; for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i) @@ -55,8 +55,8 @@ namespace Archive char temp[200]; Command c; - size_t commandCount; - size_t baselineCommandCount; + int32_t commandCount; + int32_t baselineCommandCount; Archive::get(source, commandCount); Archive::get(source, baselineCommandCount); @@ -67,7 +67,7 @@ namespace Archive } else { - for (size_t i = 0; i < commandCount; ++i) + for (int32_t i = 0; i < commandCount; ++i) { Archive::get(source, c.cmd); assert(c.cmd == Command::ADD); // only add is valid in unpack From ec3419dbb00c1624090d95ccb7fcbb5d75e2dff7 Mon Sep 17 00:00:00 2001 From: Sais Date: Sat, 25 Jul 2026 02:19:45 -0400 Subject: [PATCH 43/46] Store call stack addresses at pointer width DebugHelp::getCallStack() handed the caller's uint32 buffer straight to backtrace(), which writes void* entries. Under LP64 that wrote 8 bytes per frame into a 4-byte-per-frame array, overrunning every buffer by 2x: Fatal.cpp uint32[68] = 272 bytes, up to 544 written (stack) CallStack uint32[32] = 128 bytes, 208 written (heap) CallStackCollector uint32[26] = 104 bytes, 208 written (heap) Fatal.cpp's formatMessage() backs every WARNING and FATAL, so any warning that captured a stack corrupted memory. Observed as SIGSEGV inside cfree() with si_addr 0x8 after an unrelated warning fired. Capture into a native void* array and widen into a uint64 buffer, which is correct under both ILP32 and LP64, and widen the storage and printing to match. lookupAddress() already took uint64 on linux; win32 now agrees and no longer truncates StackWalk's DWORD64 address to 32 bits. Also fixes CallStackCollector copying only one element instead of the whole call stack, and CRCing only half the buffer. --- .../sharedDebug/src/linux/DebugHelp.cpp | 23 +++++++++++++++++-- .../library/sharedDebug/src/linux/DebugHelp.h | 5 +++- .../sharedDebug/src/shared/CallStack.cpp | 8 +++---- .../sharedDebug/src/shared/CallStack.h | 3 ++- .../src/shared/CallStackCollector.cpp | 16 ++++++------- .../sharedDebug/src/win32/DebugHelp.cpp | 10 ++++---- .../library/sharedDebug/src/win32/DebugHelp.h | 4 ++-- .../sharedFoundation/src/shared/Fatal.cpp | 6 ++--- 8 files changed, 49 insertions(+), 26 deletions(-) diff --git a/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp b/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp index e7a2fb7b9..0f84b864c 100755 --- a/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp +++ b/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp @@ -682,11 +682,30 @@ bool DebugHelp::lookupAddress(uint64 address, char *libName, char *fileName, int // ---------------------------------------------------------------------- -void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack) +void DebugHelp::getCallStack(uint64 *callStack, int sizeOfCallStack) { + //-- backtrace() writes sizeOfCallStack void* entries. Handing it the + // caller's buffer directly only works when sizeof(void*) happens to + // equal the element size; under LP64 it wrote 8 bytes per entry into a + // 4-byte-per-entry array and overran the buffer by 2x. Capture into a + // native pointer array and widen instead, which is correct for both + // ILP32 and LP64. + enum { cs_maximumFrameCount = 256 }; + + if (sizeOfCallStack <= 0) + return; + for (int i = 0; i < sizeOfCallStack; ++i) callStack[i] = 0; - IGNORE_RETURN(backtrace(reinterpret_cast(callStack), sizeOfCallStack)); + + if (sizeOfCallStack > static_cast(cs_maximumFrameCount)) + sizeOfCallStack = static_cast(cs_maximumFrameCount); + + void *frames[cs_maximumFrameCount]; + int const frameCount = backtrace(frames, sizeOfCallStack); + + for (int i = 0; i < frameCount; ++i) + callStack[i] = reinterpret_cast(frames[i]); } // ====================================================================== diff --git a/engine/shared/library/sharedDebug/src/linux/DebugHelp.h b/engine/shared/library/sharedDebug/src/linux/DebugHelp.h index e297f8ebf..973c07be8 100755 --- a/engine/shared/library/sharedDebug/src/linux/DebugHelp.h +++ b/engine/shared/library/sharedDebug/src/linux/DebugHelp.h @@ -19,7 +19,10 @@ class DebugHelp static void install(); static void remove(); - static void getCallStack(uint32 *callStack, int sizeOfCallStack); + //-- Entries are instruction addresses, so the buffer must be pointer-width + // capable. uint64 matches lookupAddress() below and is wide enough on + // both ILP32 and LP64. + static void getCallStack(uint64 *callStack, int sizeOfCallStack); static bool lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line); }; diff --git a/engine/shared/library/sharedDebug/src/shared/CallStack.cpp b/engine/shared/library/sharedDebug/src/shared/CallStack.cpp index 1df905321..2acb5ab92 100755 --- a/engine/shared/library/sharedDebug/src/shared/CallStack.cpp +++ b/engine/shared/library/sharedDebug/src/shared/CallStack.cpp @@ -59,9 +59,9 @@ void CallStack::debugPrint() const for (size_t i = 2; i < CALLSTACK_DEPTH; ++i) { if (DebugHelp::lookupAddress(m_callStack[i], libName, fileName, sizeof(fileName), line)) - DEBUG_REPORT_PRINT(true, (" (0x%08X) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); + DEBUG_REPORT_PRINT(true, (" (0x%016llX) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); else - DEBUG_REPORT_PRINT(true, (" unknown(0x%08X) : caller %d\n", static_cast(m_callStack[i]), i - 1)); + DEBUG_REPORT_PRINT(true, (" unknown(0x%016llX) : caller %d\n", static_cast(m_callStack[i]), i - 1)); } } @@ -76,9 +76,9 @@ void CallStack::debugLog() const for (size_t i = 2; i < CALLSTACK_DEPTH && m_callStack[i]!=0; ++i) { if (DebugHelp::lookupAddress(m_callStack[i], libName, fileName, sizeof(fileName), line)) - DEBUG_REPORT_LOG(true, (" (0x%08X) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); + DEBUG_REPORT_LOG(true, (" (0x%016llX) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); else - DEBUG_REPORT_LOG(true, (" unknown(0x%08X) : caller %d\n", static_cast(m_callStack[i]), i - 1)); + DEBUG_REPORT_LOG(true, (" unknown(0x%016llX) : caller %d\n", static_cast(m_callStack[i]), i - 1)); } } diff --git a/engine/shared/library/sharedDebug/src/shared/CallStack.h b/engine/shared/library/sharedDebug/src/shared/CallStack.h index 376f0ed3b..120791d05 100755 --- a/engine/shared/library/sharedDebug/src/shared/CallStack.h +++ b/engine/shared/library/sharedDebug/src/shared/CallStack.h @@ -40,7 +40,8 @@ class CallStack private: - uint32 m_callStack[S_callStack]; + //-- Instruction addresses; must be pointer-width capable (see DebugHelp::getCallStack). + uint64 m_callStack[S_callStack]; }; // ====================================================================== diff --git a/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp b/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp index 9e91cbb46..8162421ac 100755 --- a/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp +++ b/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp @@ -49,7 +49,7 @@ namespace CallStackCollectorNamespace ~Node(); CrcString const & getName() const; - void addCallStack(uint32 * callStack); + void addCallStack(uint64 * callStack); void debugReport() const; @@ -63,7 +63,7 @@ namespace CallStackCollectorNamespace public: - uint32 * m_callStack; + uint64 * m_callStack; int m_calls; }; @@ -125,10 +125,10 @@ CrcString const & CallStackCollectorNamespace::Node::getName() const // ---------------------------------------------------------------------- -void CallStackCollectorNamespace::Node::addCallStack(uint32 * const callStack) +void CallStackCollectorNamespace::Node::addCallStack(uint64 * const callStack) { //-- Compute crc of memory - uint32 const crc = Crc::calculate(callStack, (sizeof(uint32) * CALLSTACK_DEPTH)); + uint32 const crc = Crc::calculate(callStack, (sizeof(*callStack) * CALLSTACK_DEPTH)); //-- Find callstack in list CallStackEntryMap::iterator iter = m_callStackEntryMap.find(crc); @@ -140,8 +140,8 @@ void CallStackCollectorNamespace::Node::addCallStack(uint32 * const callStack) else { //-- Create new callstack - uint32 * const newCallStack = new uint32[CALLSTACK_DEPTH]; - memcpy(newCallStack, callStack, sizeof(*newCallStack)); + uint64 * const newCallStack = new uint64[CALLSTACK_DEPTH]; + memcpy(newCallStack, callStack, sizeof(*newCallStack) * CALLSTACK_DEPTH); CallStackEntry callStackEntry; callStackEntry.m_callStack = newCallStack; @@ -180,7 +180,7 @@ void CallStackCollectorNamespace::Node::debugReport() const if (DebugHelp::lookupAddress(callStackEntry->m_callStack[j], libName, fileName, sizeof(fileName), line)) REPORT_LOG(true, (" %s(%d) : caller %d\n", fileName, line, j - 1)); else - REPORT_LOG(true, (" unknown(0x%08X) : caller %d\n", static_cast(callStackEntry->m_callStack[j]), j - 1)); + REPORT_LOG(true, (" unknown(0x%016llX) : caller %d\n", static_cast(callStackEntry->m_callStack[j]), j - 1)); } } } @@ -218,7 +218,7 @@ void CallStackCollector::sample(char const * const name) } //-- Sample the callstack - uint32 callStack[CALLSTACK_DEPTH]; + uint64 callStack[CALLSTACK_DEPTH]; DebugHelp::getCallStack(&callStack[0], CALLSTACK_DEPTH); //-- Add to the node diff --git a/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp b/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp index b80a6a450..a138d7817 100755 --- a/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp +++ b/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp @@ -481,7 +481,7 @@ bool DebugHelp::loadSymbolsForDll(const char *name) // ---------------------------------------------------------------------- #pragma warning (disable: 4740 4748) -void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack) +void DebugHelp::getCallStack(uint64 *callStack, int sizeOfCallStack) { { for (int i = 0; i < sizeOfCallStack; ++i) @@ -525,7 +525,7 @@ void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack) if (stackWalk64(IMAGE_FILE_MACHINE_I386, process, process, &stackFrame, &context, NULL, functionTableAccess, getModuleBase, NULL)) { const DWORD64 Offset = stackFrame.AddrPC.Offset; - *callStack = DWORD(Offset); + *callStack = static_cast(Offset); } } } @@ -537,7 +537,7 @@ void DebugHelp::reportCallStack(int const maxStackDepth) // look up the call stack information int const callStackOffset = 2; int const callStackSize = callStackOffset + maxStackDepth; - uint32 * callStack = static_cast(_alloca((callStackOffset + maxStackDepth) * sizeof(uint32))); + uint64 * callStack = static_cast(_alloca((callStackOffset + maxStackDepth) * sizeof(uint64))); getCallStack(callStack, callStackOffset + maxStackDepth); // look up the caller's file and line @@ -553,7 +553,7 @@ void DebugHelp::reportCallStack(int const maxStackDepth) if (lookupAddress(callStack[i], lib, file, sizeof(file), line)) REPORT_LOG(true, ("\t%s(%d) : caller %d\n", file, line, i-callStackOffset)); else - REPORT_LOG(true, ("\tunknown(0x%08X) : caller %d\n", static_cast(callStack[i]), i-callStackOffset)); + REPORT_LOG(true, ("\tunknown(0x%016llX) : caller %d\n", static_cast(callStack[i]), i-callStackOffset)); } } } @@ -561,7 +561,7 @@ void DebugHelp::reportCallStack(int const maxStackDepth) // ---------------------------------------------------------------------- -bool DebugHelp::lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line) +bool DebugHelp::lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line) { UNREF(libName); diff --git a/engine/shared/library/sharedDebug/src/win32/DebugHelp.h b/engine/shared/library/sharedDebug/src/win32/DebugHelp.h index 74e379abe..bb7483bba 100755 --- a/engine/shared/library/sharedDebug/src/win32/DebugHelp.h +++ b/engine/shared/library/sharedDebug/src/win32/DebugHelp.h @@ -23,9 +23,9 @@ class DebugHelp static bool loadSymbolsForDll(const char *name); - static void getCallStack(uint32 *callStack, int sizeOfCallStack); + static void getCallStack(uint64 *callStack, int sizeOfCallStack); static void reportCallStack(int const maxStackDepth = 4); - static bool lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line); + static bool lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line); static bool writeMiniDump(char const *miniDumpFileName=0, PEXCEPTION_POINTERS exceptionPointers=0); }; diff --git a/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp b/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp index c684c6e45..a82a7160c 100755 --- a/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp +++ b/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp @@ -62,7 +62,7 @@ static void formatMessage(char *buffer, int bufferLength, int stackDepth, const // look up the call stack information const int callStackSize = callStackOffset + stackDepth; - uint32 callStack[callStackOffset + maxStackDepth]; + uint64 callStack[callStackOffset + maxStackDepth]; // allow complete disable of the call stack lookup if (stackDepth < 0) @@ -82,7 +82,7 @@ static void formatMessage(char *buffer, int bufferLength, int stackDepth, const if (ConfigSharedFoundation::getLookUpCallStackNames() && DebugHelp::lookupAddress(callStack[callStackOffset], lib, file, sizeof(file), line)) snprintf(buffer, bufferLength, "%s(%d) : %s %08x: \n", file, line, type, static_cast(Crc::calculate(format))); else - snprintf(buffer, bufferLength, "(0x%08X) : %s %08x: \n", static_cast(callStack[callStackOffset]), type, static_cast(Crc::calculate(format))); + snprintf(buffer, bufferLength, "(0x%016llX) : %s %08x: \n", static_cast(callStack[callStackOffset]), type, static_cast(Crc::calculate(format))); } else { @@ -126,7 +126,7 @@ static void formatMessage(char *buffer, int bufferLength, int stackDepth, const if (ConfigSharedFoundation::getLookUpCallStackNames() && DebugHelp::lookupAddress(callStack[i], lib, file, sizeof(file), line)) snprintf(buffer, bufferLength, " %s(%d) : caller %d\n", file, line, i-callStackOffset); else - snprintf(buffer, bufferLength, " (0x%08X) : caller %d\n", static_cast(callStack[i]), i-callStackOffset); + snprintf(buffer, bufferLength, " (0x%016llX) : caller %d\n", static_cast(callStack[i]), i-callStackOffset); const int length = strlen(buffer); buffer += length; From 4fac50d2e57d7764b1559dec1d468422b0392c3f Mon Sep 17 00:00:00 2001 From: Sais Date: Sat, 25 Jul 2026 02:20:03 -0400 Subject: [PATCH 44/46] Back QueryPerformanceCounter with a monotonic clock The linux shim sampled gettimeofday(), which reports CLOCK_REALTIME and can be slewed or stepped backwards by time synchronisation. Clock::update() subtracts successive samples to derive frame time, so a backwards step produced a negative elapsed time, which AlterScheduler then reported as "no forward time movement" once per affected frame. Use clock_gettime(CLOCK_MONOTONIC) and keep microsecond units so the value still matches QueryPerformanceFrequency(). Falls back to gettimeofday() if the call fails. All getFrameStartTimeMs() consumers compare values relatively, so nothing depends on the previous epoch-based origin. --- .../src/linux/PlatformGlue.cpp | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.cpp b/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.cpp index 7937a2a78..9577df855 100755 --- a/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.cpp +++ b/engine/shared/library/sharedFoundation/src/linux/PlatformGlue.cpp @@ -27,10 +27,23 @@ char* _itoa(int value, char* stringOut, int radix) bool QueryPerformanceCounter(__int64* time) { - struct timeval tv; - gettimeofday(&tv, nullptr); - *time = static_cast(tv.tv_sec); - *time = (*time * 1000000) + static_cast(tv.tv_usec); + // Must be monotonic. gettimeofday() reports CLOCK_REALTIME, which NTP can + // slew or step backwards; callers subtract successive samples to derive + // frame time, so a backwards step produced negative elapsed times (see + // AlterScheduler "no forward time movement"). CLOCK_MONOTONIC never goes + // backwards. Units stay microseconds to match QueryPerformanceFrequency(). + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + { + struct timeval tv; + gettimeofday(&tv, nullptr); + *time = static_cast(tv.tv_sec); + *time = (*time * 1000000) + static_cast(tv.tv_usec); + return TRUE; + } + + *time = static_cast(ts.tv_sec); + *time = (*time * 1000000) + static_cast(ts.tv_nsec / 1000); return TRUE; } From 750f7d8601126ae720993e874336a9c54babe73a Mon Sep 17 00:00:00 2001 From: Sais Date: Sat, 25 Jul 2026 02:20:03 -0400 Subject: [PATCH 45/46] Stop dereferencing a 32-bit frame offset in the SIGSEGV handler JavaLibrary::fatalHandler() read the faulting address from a hardcoded 0x44 byte offset into its own frame. That constant describes the 32-bit x86 frame layout; on x86-64 it is misaligned and points at unrelated stack memory, and dereferencing it from inside a SIGSEGV handler risks a recursive fault that loses the crash report entirely. The original code carried a TODO noting the offset was never verified. Restrict that probe to __i386__ and rely on the portable __builtin_return_address() probe already present below it. Zero initialise the lib and file buffers, which the strstr() checks read whenever a lookup fails. --- .../serverScript/src/shared/JavaLibrary.cpp | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp index f5f415b79..ecfedd950 100755 --- a/engine/server/library/serverScript/src/shared/JavaLibrary.cpp +++ b/engine/server/library/serverScript/src/shared/JavaLibrary.cpp @@ -781,16 +781,26 @@ void JavaLibrary::fatalHandler(int signum) { // try to see if our call stack came from C or Java void *frameAddress = __builtin_frame_address(0); - // the address that generated the segfault is stored at an offset of 0x44 from - // the frame address - // @todo: find documentation on the offset to verify it is stable - void *crashAddress1 = *((void**)((static_cast(frameAddress)) + 0x44)); + // pass the crash address to addr2line to get the file name where the crash occurred + // These are zero initialized because the strstr() checks below read them + // whenever a lookup fails. static const int BUFLEN = 2048; - char lib1[BUFLEN], lib2[BUFLEN]; - char file1[BUFLEN], file2[BUFLEN]; - int line1, line2; - bool result1 = DebugHelp::lookupAddress(reinterpret_cast(crashAddress1), lib1, file1, BUFLEN, line1); + char lib1[BUFLEN] = { '\0' }, lib2[BUFLEN] = { '\0' }; + char file1[BUFLEN] = { '\0' }, file2[BUFLEN] = { '\0' }; + int line1 = 0, line2 = 0; + bool result1 = false; + + // The faulting address used to be read from a fixed 0x44 byte offset into + // this frame. That constant describes the 32-bit x86 frame layout only; on + // x86-64 it is both misaligned and meaningless, and dereferencing it from + // inside a SIGSEGV handler risks a recursive fault that loses the crash + // report entirely. The __builtin_return_address() probe below is portable + // and already covers this case. +#if defined(__i386__) + void *crashAddress1 = *((void**)((static_cast(frameAddress)) + 0x44)); + result1 = DebugHelp::lookupAddress(reinterpret_cast(crashAddress1), lib1, file1, BUFLEN, line1); +#endif // do a second test based on the return address // it turns out that in some java crashes we don't even have 2 return From a7c14599c8a3093b8e1f7be1b6a05117aa1c7c12 Mon Sep 17 00:00:00 2001 From: Sais Date: Fri, 24 Jul 2026 21:10:27 -0400 Subject: [PATCH 46/46] Support Oracle 19 x64 Instant Client discovery --- cmake/linux/FindOracle.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/linux/FindOracle.cmake b/cmake/linux/FindOracle.cmake index d6074ead5..73cc93297 100644 --- a/cmake/linux/FindOracle.cmake +++ b/cmake/linux/FindOracle.cmake @@ -37,10 +37,11 @@ if(DEFINED ENV{ORACLE_HOME}) ${ORACLE_HOME}/OCI/include) # Oracle XE on Windows set(ORACLE_OCI_NAMES clntsh libclntsh oci) - set(ORACLE_NNZ_NAMES libnnz18 nnz18 libnnz21 nnz21 ociw32) + set(ORACLE_NNZ_NAMES libnnz18 nnz18 libnnz19 nnz19 libnnz21 nnz21 ociw32) set(ORACLE_OCCI_NAMES libocci occi oraocci10 oraocci11) set(ORACLE_LIB_DIR + ${ORACLE_HOME} ${ORACLE_HOME}/lib ${ORACLE_HOME}/sdk/lib # Oracle SDK ${ORACLE_HOME}/sdk/lib/msvc @@ -76,4 +77,4 @@ endif(DEFINED ENV{ORACLE_HOME}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Oracle DEFAULT_MSG ORACLE_LIBRARY ORACLE_INCLUDE_DIR) -mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY) \ No newline at end of file +mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY)